Index: controltower/css/common.css
===================================================================
diff -u
--- controltower/css/common.css (revision 0)
+++ controltower/css/common.css (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,499 @@
+@font-face {
+ font-family: "Nanum Gothic";
+ font-style: normal;
+ font-weight: 400;
+ src: url("../../reference/light-blue/css/font/NanumGothic/nanum-gothic-v11-latin_korean-regular.eot"); /* IE9 Compat Modes */
+ src: local("NanumGothic"),
+ url("../../reference/light-blue/css/font/NanumGothic/nanum-gothic-v11-latin_korean-regular.eot?#iefix")
+ format("embedded-opentype"),
+ /* IE6-IE8 */ url("../../reference/light-blue/css/font/NanumGothic/nanum-gothic-v11-latin_korean-regular.woff2")
+ format("woff2"),
+ /* Super Modern Browsers */
+ url("../../reference/light-blue/css/font/NanumGothic/nanum-gothic-v11-latin_korean-regular.woff") format("woff"),
+ /* Modern Browsers */
+ url("../../reference/light-blue/css/font/NanumGothic/nanum-gothic-v11-latin_korean-regular.ttf")
+ format("truetype"),
+ /* Safari, Android, iOS */
+ url("../../reference/light-blue/css/font/NanumGothic/nanum-gothic-v11-latin_korean-regular.svg#NanumGothic")
+ format("svg"); /* Legacy iOS */
+}
+html,
+body {
+ font-family: "Nanum Gothic" !important;
+}
+body {
+ background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHJhZGlhbEdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjEwJSIgY3k9IjAiIHI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9InJnYmEoMTAyLCAxMDUsIDEwNCwgMC45MCkiLz48c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0icmdiYSg5MywgMTEyLCAxMTksIDAuODkpIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSJyZ2JhKDE2MCwgMTc0LCAxNTAsIDAuOTApIi8+PC9yYWRpYWxHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4="),
+ url("../../reference/light-blue/img/bgnoise_lg_dark.png");
+ background-color: rgba(102, 105, 104, 0.9);
+ background: radial-gradient(
+ farthest-side ellipse at 10% 0,
+ rgba(139, 129, 118, 0.9),
+ rgba(78, 76, 71, 0.89),
+ rgba(102, 98, 92, 0.9)
+ ),
+ url("../../reference/light-blue/img/bgnoise_lg_dark.png");
+ background: -webkit-radial-gradient(
+ 10% 0,
+ farthest-side ellipse,
+ rgba(139, 129, 118, 0.9),
+ rgba(78, 76, 71, 0.89),
+ rgba(102, 98, 92, 0.9)
+ ),
+ url("../../reference/light-blue/img/bgnoise_lg_dark.png");
+ background: -moz-radial-gradient(
+ 10% 0,
+ farthest-side ellipse,
+ rgba(139, 129, 118, 0.9),
+ rgba(78, 76, 71, 0.89),
+ rgba(102, 98, 92, 0.9)
+ ),
+ url("../../reference/light-blue/img/bgnoise_lg_dark.png");
+ padding-bottom: 10px;
+ background-attachment: fixed;
+}
+
+/* 스크롤 테마 */
+body::-webkit-scrollbar {
+ width: 8px; /* 스크롤바의 너비 */
+ height: 8px;
+}
+
+body::-webkit-scrollbar-thumb {
+ height: 30%; /* 스크롤바의 길이 */
+ background: #313131; /* 스크롤바의 색상 */
+
+ border-radius: 10px;
+}
+
+body::-webkit-scrollbar-track {
+ background-color: #4b4b4b; /*스크롤바 뒷 배경 색상*/
+}
+
+p {
+ margin: 0;
+ /* text-align: center; 공통으로 텍스트가 가운데로 정렬되는것은 제어하기가 어려워서 주석처리 */
+}
+
+/* Font */
+.jstree-default-context {
+ font-family: "Nanum Gothic" !important;
+ font-size: 12px;
+ color: #f8f8f8;
+}
+.font10 {
+ font-family: "Nanum Gothic" !important;
+ font-size: 10px;
+ color: #f8f8f8;
+}
+.font11 {
+ font-family: "Nanum Gothic" !important;
+ font-size: 11px;
+ color: #f8f8f8;
+}
+.font12 {
+ font-family: "Nanum Gothic" !important;
+ font-size: 12px;
+ color: #f8f8f8;
+}
+.font13 {
+ font-family: "Nanum Gothic" !important;
+ font-size: 13px;
+ color: #f8f8f8;
+}
+.font14 {
+ font-family: "Nanum Gothic" !important;
+ font-size: 14px;
+ color: #f8f8f8;
+}
+.font15 {
+ font-family: "Nanum Gothic" !important;
+ font-size: 15px;
+ color: #f8f8f8;
+}
+.font16 {
+ font-family: "Nanum Gothic" !important;
+ font-size: 16px;
+ color: #f8f8f8;
+}
+.font17 {
+ font-family: "Nanum Gothic" !important;
+ font-size: 17px;
+ color: #f8f8f8;
+}
+.font18 {
+ font-family: "Nanum Gothic" !important;
+ font-size: 18px;
+ color: #f8f8f8;
+}
+
+.row {
+ overflow: hidden;
+ clear: both;
+}
+
+#topicon {
+ width: 36px;
+ height: 35px;
+ position: fixed;
+ right: 1%;
+ bottom: 15px;
+ z-index: 200;
+ transition: 0.3s;
+ cursor: pointer;
+ opacity: 0;
+ border-radius: 50%;
+ overflow: hidden;
+ padding-left: -1px;
+ animation: doongdoong 1.3s linear infinite;
+}
+
+@keyframes doongdoong {
+ 0% {
+ bottom: 15px;
+ }
+ 50% {
+ bottom: 10px;
+ }
+ 100% {
+ bottom: 15px;
+ }
+}
+
+.widgetheader {
+ border-radius: 3px;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ padding: 5px 5px 1px 5px;
+ color: #f8f8f8;
+ margin-bottom: 5px;
+ position: relative;
+}
+
+.breadcrumb {
+ padding: 0px;
+ margin: 3px;
+ list-style: none;
+ background-color: transparent;
+ border-radius: 3px;
+}
+
+.content .content-footer {
+ position: initial;
+ bottom: 0px;
+ color: #d2d2d2;
+}
+
+/* 그라디언트 보더 */
+.gradient_left_border {
+ border-left: 1px dashed transparent;
+ border-image: linear-gradient(0turn, rgb(0 0 0 / 0%), #979797, rgb(0 0 0 / 0%));
+ border-image-slice: 1;
+}
+
+.gradient_right_border {
+ border-right: 1px dashed transparent;
+ border-image: linear-gradient(0turn, rgb(0 0 0 / 0%), #979797, rgb(0 0 0 / 0%));
+ border-image-slice: 1;
+}
+.gradient_bottom_border {
+ border-bottom: 1px solid transparent;
+ border-image: linear-gradient(0.25turn, rgb(0 0 0 / 0%), #979797, rgb(0 0 0 / 0%));
+ border-image-slice: 1;
+}
+.gradient_middle_border {
+ border-bottom: 1px solid transparent;
+ border-image: linear-gradient(0.25turn, rgb(0 0 0 / 0%), #666666, rgb(0 0 0 / 0%));
+ border-image-slice: 1;
+}
+
+blockquote {
+ padding: 9px 0px 9px 18px !important;
+ margin: 9px 0 9px !important;
+ font-size: 16.25px;
+ border-left: 5px solid rgba(51, 51, 51, 0.425);
+}
+
+.widget-controls {
+ position: absolute;
+ z-index: 1;
+ top: 3px !important;
+ right: 0;
+ font-size: 12px;
+ word-spacing: 1px;
+}
+
+.alert-created {
+ width: max-content;
+ background-size: 15px 2px, 15px 2px, 2px 15px, 2px 15px;
+ padding: 1px;
+ animation: border-dance 7s infinite linear;
+ border-radius: 10px;
+}
+
+@media (min-width: 1200px) {
+ .content {
+ position: relative;
+ padding: 30px 2.5641%;
+ -webkit-transition: margin-top 0.35s ease, opacity 0.2s;
+ -o-transition: margin-top 0.35s ease, opacity 0.2s;
+ transition: margin-top 0.35s ease, opacity 0.2s;
+ max-width: none;
+ width: auto;
+ opacity: 1;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .content {
+ position: relative;
+ padding: 30px 2.5641%;
+ -webkit-transition: margin-top 0.35s ease, opacity 0.2s;
+ -o-transition: margin-top 0.35s ease, opacity 0.2s;
+ transition: margin-top 0.35s ease, opacity 0.2s;
+ max-width: none;
+ width: auto;
+ opacity: 1;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .content {
+ position: relative;
+ padding: 30px 2.5641%;
+ -webkit-transition: margin-top 0.35s ease, opacity 0.2s;
+ -o-transition: margin-top 0.35s ease, opacity 0.2s;
+ transition: margin-top 0.35s ease, opacity 0.2s;
+ max-width: none;
+ width: auto;
+ opacity: 1;
+ }
+}
+@media (max-width: 767px) {
+ .content {
+ position: relative;
+ padding: 75px 2.5641%;
+ -webkit-transition: margin-top 0.35s ease, opacity 0.2s;
+ -o-transition: margin-top 0.35s ease, opacity 0.2s;
+ transition: margin-top 0.35s ease, opacity 0.2s;
+ max-width: none;
+ width: auto;
+ opacity: 1;
+ }
+}
+
+/*****************/
+/** jNotify CSS **/
+/*****************/
+#jNotify {
+ position: absolute !important;
+ -webkit-transition: background-color 0.4s !important;
+ -o-transition: background-color 0.4s !important;
+ transition: background-color 0.4s !important;
+ border-radius: 5px !important;
+ border-color: transparent !important;
+ background-color: rgba(52, 52, 52, 0.425) !important;
+ margin-bottom: 1em !important;
+ color: #f8f8f8 !important;
+ font-weight: 500 !important;
+
+ background: #d8e6fc url("../info.png") no-repeat 15px center;
+ padding: 10px;
+ padding-left: 50px;
+ margin: 15px;
+ z-index: 99999;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ -webkit-border-radius: 5px;
+}
+#jNotify a {
+ color: #35517c !important;
+ text-decoration: none;
+}
+
+/******************/
+/** jSuccess CSS **/
+/******************/
+#jSuccess {
+ position: absolute !important;
+ -webkit-transition: background-color 0.4s !important;
+ -o-transition: background-color 0.4s !important;
+ transition: background-color 0.4s !important;
+ border-radius: 5px !important;
+ border-color: transparent !important;
+ background-color: rgba(52, 52, 52, 0.425) !important;
+ margin-bottom: 1em !important;
+ color: #f8f8f8 !important;
+ font-weight: 500 !important;
+
+ background: #e6efc2 url("../success.png") no-repeat 15px center;
+ padding: 10px;
+ padding-left: 50px;
+ margin: 15px;
+ z-index: 99999;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ -webkit-border-radius: 5px;
+}
+#jSuccess a {
+ color: #264409 !important;
+ text-decoration: none;
+}
+
+/****************/
+/** jError CSS **/
+/****************/
+#jError {
+ position: absolute !important;
+ -webkit-transition: background-color 0.4s !important;
+ -o-transition: background-color 0.4s !important;
+ transition: background-color 0.4s !important;
+ border-radius: 5px !important;
+ border-color: transparent !important;
+ background-color: rgba(52, 52, 52, 0.425) !important;
+ margin-bottom: 1em !important;
+ color: #f8f8f8 !important;
+ font-weight: 500 !important;
+
+ background: #fbe3e4 url("../error.png") no-repeat 15px center;
+ padding: 10px;
+ padding-left: 50px;
+ margin: 15px;
+ z-index: 99999;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ -webkit-border-radius: 5px;
+}
+#jError a {
+ color: #8a1f11 !important;
+ text-decoration: none;
+}
+
+/** OVERLAY **/
+#jOverlay {
+ width: 100%;
+ height: 100%;
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 99998;
+}
+
+.mailbox-content .form-email-compose .control-group {
+ margin-bottom: 10px;
+}
+
+.fileupload-buttonbar .btn,
+.fileupload-buttonbar .toggle {
+ margin-bottom: 5px;
+ background: rgba(51, 51, 51, 0.4);
+ border-color: transparent;
+ color: #fff;
+ text-shadow: none;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+ -webkit-transition: background-color 0.2s;
+ -moz-transition: background-color 0.2s;
+ -o-transition: background-color 0.2s;
+ transition: background-color 0.2s;
+}
+.fileinput-button {
+ position: relative;
+ overflow: hidden;
+ float: left;
+ margin-right: 4px;
+ color: #fff;
+ text-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ border-color: #c5c5c5;
+ border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
+ padding: 2px 10px;
+ font-size: 11.05px;
+ line-height: 1.9;
+ border-radius: 0;
+ display: inline-block;
+ margin-bottom: 0;
+ font-weight: 300;
+ text-align: center;
+ vertical-align: middle;
+ cursor: pointer;
+ background-image: none;
+ border: 1px solid transparent;
+ white-space: nowrap;
+ padding: 4px 12px;
+ font-size: 13px;
+ line-height: 20px;
+ border-radius: 1px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -o-user-select: none;
+ user-select: none;
+}
+.fileinput-button input {
+ position: absolute;
+ top: 0;
+ right: 0;
+ margin: 0;
+ opacity: 0;
+ filter: alpha(opacity=0);
+ transform: translate(-300px, 0) scale(4);
+ font-size: 23px;
+ direction: ltr;
+ cursor: pointer;
+}
+.fileupload-loading {
+ position: absolute;
+ left: 50%;
+ width: 128px;
+ height: 128px;
+ display: none;
+}
+.dropzone {
+ border: 1px dashed #eee;
+ margin-top: 10px;
+ font-size: 13px;
+ color: #eee;
+ line-height: 100px;
+ vertical-align: middle;
+}
+
+.tooltip-inner {
+ max-width: 100% !important;
+}
+
+.flex {
+ display: flex;
+}
+.flex-space-between {
+ justify-content: space-between;
+}
+
+.widget-controls > a:hover {
+ color: rgba(255, 255, 255, 0.6);
+ text-decoration: none;
+}
+
+.carousel-indicators .active {
+ margin: 0;
+ width: 12px;
+ height: 12px;
+ background-color: #e5603b;
+}
+
+.modal-content {
+ max-height: calc(100vh - 100px);
+ overflow-y: auto;
+ overflow-x: hidden;
+}
+
+/* 헤더 사람아이콘 */
+.account-picture img {
+ width: 40px;
+ margin-right: 5px;
+}
+
+.img-circle {
+ border-radius: 50%;
+}
\ No newline at end of file
Index: controltower/css/override.css
===================================================================
diff -u
--- controltower/css/override.css (revision 0)
+++ controltower/css/override.css (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,1955 @@
+@import "common.css";
+
+.notifications .alert a {
+ color: #f8f8f8;
+ font-weight: 700;
+ margin-left: 5px;
+}
+
+/* 스크롤 테마 */
+::-webkit-scrollbar {
+ width: 8px; /* 스크롤바의 너비 */
+ height: 8px;
+}
+::-webkit-scrollbar-thumb {
+ height: 30%; /* 스크롤바의 길이 */
+ background: #313131; /* 스크롤바의 색상 */
+
+ border-radius: 10px;
+}
+::-webkit-scrollbar-track {
+ background-color: #4b4b4b; /*스크롤바 뒷 배경 색상*/
+}
+.slimScrollBar {
+ background: #784a3d !important;
+}
+
+/* btn */
+.btn {
+ transition: background-color 0.2s;
+}
+.btn-transparent.active {
+ color: white;
+ background: rgba(51, 51, 51, 0.55);
+ color: #ffffff;
+ background-color: #e5603b;
+ border-color: rgba(0, 0, 0, 0.15);
+}
+.btn:focus,
+.btn.focus,
+.btn:active:focus,
+.btn:active.focus,
+.btn.active:focus,
+.btn.active.focus {
+ outline: 0px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+/* 멀티 셀렉트 할때 번지는 값 픽스 */
+.btn-block + .btn-block {
+ margin-top: 0px !important;
+}
+
+/* 멀티 셀렉트 */
+.search-input {
+ width: 100%;
+ background: rgba(51, 51, 51, 0.4) !important;
+ border: 1px solid rgba(51, 51, 51, 0.425) !important;
+}
+.select2-search__field::-webkit-input-placeholder,
+.select2-search__field::placeholder {
+ color: #999 !important;
+ padding-left: 6px;
+}
+
+/* 데이터그리드 왼쪽 상단 로우 개수 선택하는 옵션 배경값 변경 */
+select option {
+ background: #3b3d40 !important;
+}
+
+/*! Light */
+#light {
+ background-color: #000;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.8);
+ overflow: hidden;
+ padding: 0 0 4px;
+ width: 40px;
+ margin-left: 30px;
+ transform: rotate(270deg);
+}
+
+#light span {
+ border-radius: 50px;
+ display: block;
+ height: 30px;
+ margin: 4px auto 0;
+ opacity: 0.5;
+ width: 30px;
+}
+
+/*! Light colours */
+#red {
+ background-color: red;
+}
+
+#orange {
+ background-color: orange;
+}
+
+#green {
+ background-color: green;
+}
+
+/*! Active states */
+#light span.active {
+ opacity: 1;
+}
+
+#light #red.active {
+ box-shadow: 0 0 10px red;
+}
+
+#light #orange.active {
+ box-shadow: 0 0 10px orange;
+}
+
+#light #green.active {
+ box-shadow: 0 0 10px green;
+}
+
+/* Dashboard 시작 */
+.c3-tooltip {
+ color: black !important;
+}
+
+.c3-chart-arc path {
+ stroke-width: 0.4px;
+}
+/* Dashboard 종료 */
+
+/* Analysis 분석 시작 */
+@media (max-width: 1200px) {
+ #quality-img {
+ display: none;
+ }
+}
+
+.card-widget {
+ border: 0;
+ position: relative;
+}
+
+.card {
+ margin-bottom: 1rem;
+}
+
+.card {
+ position: relative;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ min-width: 0;
+ word-wrap: break-word;
+ background-clip: border-box;
+ border: 0 solid rgba(0, 0, 0, 0.125);
+ border-radius: 0.25rem;
+}
+
+.widget-user .widget-user-image > img {
+ height: auto;
+ width: 200px;
+}
+
+.widget-user .widget-user-image {
+ left: 50%;
+ margin-left: -100px;
+ position: absolute;
+ top: 300px;
+}
+
+.widget-user .widget-user-header {
+ border-top-left-radius: 0.25rem;
+ border-top-right-radius: 0.25rem;
+ height: 135px;
+ padding: 1rem;
+ text-align: center;
+}
+
+.img-circle {
+ border-radius: 50%;
+}
+
+img {
+ vertical-align: middle;
+ border-style: none;
+}
+
+/* fade in - out box 처리 */
+.fade-in-box {
+ animation: fadein 1s;
+ -moz-animation: fadein 1s; /* Firefox */
+ -webkit-animation: fadein 1s; /* Safari and Chrome */
+ -o-animation: fadein 1s; /* Opera */
+}
+
+@keyframes fadein {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@-moz-keyframes fadein {
+ /* Firefox */
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@-webkit-keyframes fadein {
+ /* Safari and Chrome */
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@-o-keyframes fadein {
+ /* Opera */
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+.fade-out-box {
+ animation: fadeout 3s;
+ -moz-animation: fadeout 3s; /* Firefox */
+ -webkit-animation: fadeout 3s; /* Safari and Chrome */
+ -o-animation: fadeout 3s; /* Opera */
+ animation-fill-mode: forwards;
+}
+
+@keyframes fadeout {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+
+@-moz-keyframes fadeout {
+ /* Firefox */
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+
+@-webkit-keyframes fadeout {
+ /* Safari and Chrome */
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+
+@-o-keyframes fadeout {
+ /* Opera */
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+
+/* 유니타이핑 */
+#blinker {
+ -webkit-animation: blink 1.2s step-end infinite;
+ -moz-animation: blink 1.2s step-end infinite;
+ animation: blink 1.2s step-end infinite;
+}
+@keyframes blink {
+ from,
+ to {
+ opacity: 0;
+ }
+ 50% {
+ opacity: 1;
+ }
+}
+@-webkit-keyframes blink {
+ from,
+ to {
+ opacity: 0;
+ }
+ 50% {
+ opacity: 1;
+ }
+}
+@-moz-keyframes blink {
+ from,
+ to {
+ opacity: 0;
+ }
+ 50% {
+ opacity: 1;
+ }
+}
+
+.darkBack {
+ background: rgba(51, 51, 51, 0.425) !important;
+ border: 1px solid rgba(51, 51, 51, 0.425) !important;
+}
+.searchDarkBack {
+ background: url(../../reference/lightblue4/docs/img/search-white.png) 5px 5px no-repeat rgba(51, 51, 51, 0.4) !important;
+ border: 1px solid rgba(51, 51, 51, 0.425) !important;
+}
+
+/*데이터피커 css 처리*/
+.xdsoft_datetimepicker .xdsoft_label {
+ display: inline;
+ position: relative;
+ z-index: 9999;
+ margin: 0;
+ padding: 5px 3px;
+ font-size: 12px;
+ line-height: 20px;
+ font-weight: bold;
+ background-color: #fff;
+ float: left;
+ width: 182px;
+ text-align: center;
+ cursor: pointer;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar th:first-child {
+ color: #ef7979 !important;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar th:last-child {
+ color: #a0a0ff !important;
+}
+
+.xdsoft_day_of_week0 {
+ color: #ef7979 !important;
+}
+
+.xdsoft_day_of_week6 {
+ color: #a0a0ff !important;
+}
+
+.dd {
+ position: relative;
+ display: block;
+ margin: 0;
+ padding: 0;
+ max-width: 600px;
+ list-style: none;
+ font-size: 13px;
+ line-height: 20px;
+}
+
+.dd-list {
+ display: block;
+ position: relative;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.dd-list .dd-list {
+ padding-left: 30px;
+}
+
+.dd-collapsed .dd-list {
+ display: none;
+}
+
+.dd-item,
+.dd-empty,
+.dd-placeholder {
+ display: block;
+ position: relative;
+ margin: 0;
+ padding: 0;
+ min-height: 20px;
+ font-size: 13px;
+ line-height: 20px;
+}
+
+.dd-handle {
+ display: block;
+ margin: 5px 0;
+ padding: 5px 10px;
+ color: #f8f8f8;
+ text-decoration: none;
+ background: rgba(51, 51, 51, 0.4);
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.dd-item > button {
+ display: block;
+ position: relative;
+ cursor: pointer;
+ float: left;
+ width: 25px;
+ height: 20px;
+ margin: 5px 0;
+ padding: 0;
+ text-indent: 100%;
+ white-space: nowrap;
+ overflow: hidden;
+ border: 0;
+ background: transparent;
+ font-size: 12px;
+ line-height: 1;
+ text-align: center;
+ font-weight: bold;
+ color: #f8f8f8;
+}
+
+.dd-item > button:before {
+ content: "+";
+ display: block;
+ position: absolute;
+ width: 100%;
+ text-align: center;
+ text-indent: 0;
+}
+
+.dd-item > button[data-action="collapse"]:before {
+ content: "-";
+}
+
+.dd-placeholder,
+.dd-empty {
+ margin: 5px 0;
+ padding: 0;
+ min-height: 30px;
+ background: rgba(51, 51, 51, 0.2);
+ border: 1px dashed rgba(255, 255, 255, 0.6);
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+}
+
+.dd-empty {
+ border: 1px dashed rgba(255, 255, 255, 0.6);
+ min-height: 100px;
+ background-size: 60px 60px;
+ background-position: 0 0, 30px 30px;
+}
+
+.dd-dragel {
+ position: absolute;
+ pointer-events: none;
+ z-index: 9999;
+}
+
+.dd-dragel > .dd-item .dd-handle {
+ margin-top: 0;
+}
+
+.dd-dragel .dd-handle {
+ -webkit-box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1);
+ box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1);
+}
+
+.dd-hover > .dd-handle {
+ background: #2ea8e5 !important;
+}
+
+.nestable-lists {
+ display: block;
+ clear: both;
+ padding: 30px 0;
+ width: 100%;
+ border: 0;
+ border-top: 2px solid #ddd;
+ border-bottom: 2px solid #ddd;
+}
+
+@media only screen and (min-width: 700px) {
+ .dd + .dd {
+ margin-left: 2%;
+ }
+}
+.dd-hover > .dd-handle {
+ background: #2ea8e5 !important;
+}
+
+/*
+* aside
+*/
+.side-nav .category-wrap {
+ margin: 0;
+ border: none;
+ border-radius: 0;
+}
+.side-nav li a,
+.side-nav .category-label {
+ color: inherit;
+ transition: background-color 0.2s;
+ text-decoration: none;
+ display: block;
+ padding: 10px;
+ border-radius: 6px;
+}
+.category-wrap li a {
+ padding: 4px 10px 4px 35px;
+}
+
+.nav-tabs > li.active > a {
+ color: #a4c6ff !important;
+}
+
+.widget-content {
+ margin: 10px 0 15px;
+}
+
+.widget-content > div {
+ margin-top: 10px;
+}
+
+.control-group p {
+ text-align: left;
+}
+
+.control-label {
+ float: left;
+ width: 160px;
+ padding-top: 5px;
+ text-align: right;
+}
+
+/*
+* 데이터테이블 커스텀
+*/
+table thead tr th {
+ overflow: hidden;
+ white-space: nowrap;
+}
+
+table tbody tr td {
+ border-bottom: 1px solid rgba(68, 68, 68, 0.7);
+ box-sizing: border-box;
+}
+
+.dataTables_scrollBody::-webkit-scrollbar {
+ height: 10px;
+}
+
+.dataTables_scrollBody:hover::-webkit-scrollbar-track {
+ background-color: #414141;
+}
+
+.dataTables_scrollBody:hover::-webkit-scrollbar-thumb {
+ background-color: #784a3d;
+}
+
+.dataTables_scrollBody::-webkit-scrollbar-track,
+.dataTables_scrollBody::-webkit-scrollbar-thumb {
+ background-color: transparent;
+}
+
+.dataTables_scrollBody::-webkit-scrollbar-thumb {
+ border-radius: 5px;
+}
+
+.ribbon {
+ /* adjust the below to control the shape */
+ --d: 5px;
+ --w: 100px;
+ --c: #333;
+ /**/
+
+ position: absolute;
+ top: 0;
+ right: 0;
+ transform: translate(29.29%, -100%) rotate(45deg); /* 29.29% = 100%*(1 - cos(45deg)) */
+ color: #fff;
+ text-align: center;
+ width: var(--w);
+ transform-origin: bottom left;
+ padding: 5px 0 calc(var(--d) + 5px);
+ background: linear-gradient(rgba(0, 0, 0, 0.6) 0 0) bottom/100% var(--d) no-repeat var(--c);
+ clip-path: polygon(
+ 0 100%,
+ 0 calc(100% - var(--d)),
+ 50% calc(100% - var(--d) - var(--w) / 2),
+ 100% calc(100% - var(--d)),
+ 100% 100%,
+ calc(100% - var(--d)) calc(100% - var(--d)),
+ var(--d) calc(100% - var(--d))
+ );
+}
+
+.landing {
+ padding: 0;
+}
+
+/*
+* Component: Timeline
+* -------------------
+*/
+.timeline {
+ position: relative;
+ margin: 0 0 30px 0;
+ padding: 0;
+ list-style: none;
+}
+.timeline:before {
+ content: "";
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 4px;
+ background: #ddd;
+ left: 31px;
+ margin: 0;
+ border-radius: 2px;
+}
+.timeline > li {
+ position: relative;
+ margin-right: 10px;
+ margin-bottom: 15px;
+}
+.timeline > li:before,
+.timeline > li:after {
+ content: " ";
+ display: table;
+}
+.timeline > li:after {
+ clear: both;
+}
+.timeline > li > .timeline-item {
+ background: rgba(51, 51, 51, 0.3);
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+ border-radius: 3px;
+ margin-top: 0;
+ color: #f8f8f8;
+ margin-left: 60px;
+ padding: 0;
+ position: relative;
+}
+.timeline > li > .timeline-item > .time {
+ color: #999;
+ float: right;
+ padding: 10px;
+ font-size: 12px;
+}
+.timeline > li > .timeline-item > .timeline-header {
+ margin: 0;
+ color: #555;
+ padding: 10px;
+ font-size: 13px;
+ line-height: 1.1;
+}
+.timeline > li > .timeline-item > .timeline-header > a {
+ font-weight: 600;
+}
+.timeline > li > .timeline-item > .timeline-body,
+.timeline > li > .timeline-item > .timeline-footer {
+ padding: 10px;
+}
+.timeline > li > .fa,
+.timeline > li > .glyphicon,
+.timeline > li > .ion {
+ width: 30px;
+ height: 30px;
+ font-size: 15px;
+ line-height: 30px;
+ position: absolute;
+ color: #000;
+ background: #d2d6de;
+ border-radius: 50%;
+ text-align: center;
+ left: 18px;
+ top: 0;
+}
+.timeline > .time-label > span {
+ font-weight: 400;
+ padding: 5px;
+ display: inline-block;
+ background-color: #fff;
+ border-radius: 4px;
+}
+.timeline-inverse > li > .timeline-item {
+ background: rgba(51, 51, 51, 0.3);
+ border-left: 2px solid rgba(26, 26, 26, 0.425);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.timeline-inverse > li > .timeline-item > .timeline-header {
+ border-bottom-color: #ddd;
+}
+
+.timeline-inverse .arrow {
+ display: block;
+ position: absolute;
+ top: 10px;
+ left: -7px;
+ width: 0;
+ height: 0;
+ border-top: 5px solid transparent;
+ border-bottom: 5px solid transparent;
+ border-right: 5px solid rgba(26, 26, 26, 0.425);
+}
+
+.modalDarkBack {
+ background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHJhZGlhbEdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjEwJSIgY3k9IjAiIHI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9InJnYmEoMTAyLCAxMDUsIDEwNCwgMC45MCkiLz48c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0icmdiYSg5MywgMTEyLCAxMTksIDAuODkpIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSJyZ2JhKDE2MCwgMTc0LCAxNTAsIDAuOTApIi8+PC9yYWRpYWxHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4="),
+ url("../../reference/light-blue/img/bgnoise_lg_dark.png");
+ background-color: rgba(102, 105, 104, 0.9);
+ padding-bottom: 10px;
+ border: 2px dotted rgb(151 151 151 / 95%) !important;
+ background: linear-gradient(
+ -45deg,
+ rgb(59 59 59 / 93%),
+ rgb(74 78 91 / 91%),
+ rgb(83 83 83 / 90%),
+ rgb(40, 40, 40, 91%)
+ );
+ background-size: 400% 400%;
+ -webkit-animation: gradient 15s ease infinite;
+ animation: gradient 15s ease infinite;
+}
+
+@-webkit-keyframes gradient {
+ 0% {
+ background-position: 0% 50%;
+ }
+ 50% {
+ background-position: 100% 50%;
+ }
+ 100% {
+ background-position: 0% 50%;
+ }
+}
+
+@keyframes gradient {
+ 0% {
+ background-position: 0% 50%;
+ }
+ 50% {
+ background-position: 100% 50%;
+ }
+ 100% {
+ background-position: 0% 50%;
+ }
+}
+
+.tooltip-inner {
+ max-width: 100% !important;
+}
+
+/*
+* Datepicker
+*/
+.datepicker {
+ top: 0;
+ left: 0;
+ padding: 4px;
+ margin-top: 1px;
+ color: #555555;
+ -webkit-border-radius: 1px;
+ -moz-border-radius: 1px;
+ -ms-border-radius: 1px;
+ -o-border-radius: 1px;
+ border-radius: 1px;
+}
+
+.datepicker:before {
+ content: "";
+ display: inline-block;
+ border-left: 7px solid transparent;
+ border-right: 7px solid transparent;
+ border-bottom: 7px solid #ccc;
+ border-bottom-color: rgba(0, 0, 0, 0.2);
+ position: absolute;
+ top: -7px;
+ left: 6px;
+}
+
+.datepicker:after {
+ content: "";
+ display: inline-block;
+ border-left: 6px solid transparent;
+ border-right: 6px solid transparent;
+ border-bottom: 6px solid white;
+ position: absolute;
+ top: -6px;
+ left: 7px;
+}
+
+.datepicker > div {
+ display: none;
+}
+
+.datepicker table {
+ width: 100%;
+ margin: 0;
+}
+
+.datepicker td,
+.datepicker th {
+ text-align: center;
+ width: 20px;
+ height: 20px;
+ -webkit-border-radius: 1px;
+ -moz-border-radius: 1px;
+ -ms-border-radius: 1px;
+ -o-border-radius: 1px;
+ border-radius: 1px;
+}
+
+.datepicker td.day:hover {
+ background: #f8f8f8;
+ cursor: pointer;
+}
+
+.datepicker td.day.disabled {
+ color: #f8f8f8;
+}
+
+.datepicker td.old,
+.datepicker td.new {
+ color: white;
+}
+
+.datepicker td.active,
+.datepicker td.active:hover {
+ background: #618fb0;
+ color: #fff;
+}
+
+.datepicker td span {
+ display: block;
+ width: 47px;
+ height: 54px;
+ line-height: 54px;
+ float: left;
+ margin: 2px;
+ cursor: pointer;
+ -webkit-border-radius: 1px;
+ -moz-border-radius: 1px;
+ -ms-border-radius: 1px;
+ -o-border-radius: 1px;
+ border-radius: 1px;
+}
+
+.datepicker td span:hover {
+ background: #eeeeee;
+}
+
+.datepicker td span.active {
+ background: #618fb0;
+ color: #fff;
+}
+
+.datepicker td span.old {
+ color: #999999;
+}
+
+.datepicker th.switch {
+ width: 145px;
+}
+
+.datepicker th.next,
+.datepicker th.prev {
+ font-size: 19.5px;
+}
+
+.datepicker thead tr:first-child th {
+ cursor: pointer;
+}
+
+.datepicker thead tr:first-child th:hover {
+ background: #eeeeee;
+}
+
+.project-date {
+ font-size: 10px;
+ color: #a4c6ff;
+}
+
+.day-progress {
+ position: absolute;
+ top: 75%;
+ left: 50%;
+ translate: -50% -50%;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.timeline:before {
+ left: 0px !important;
+ background: none;
+}
+
+.time_element {
+ overflow-x: scroll;
+ white-space: nowrap;
+}
+
+/**
+* Chart
+*/
+.echart-no-data {
+ position: relative;
+}
+
+.echart-no-data .message {
+ position: absolute;
+ transform: translateY(-50%);
+ text-align: center;
+ width: 100%;
+ top: 50%;
+ left: 0;
+}
+
+svg.overlay {
+ background-color: transparent;
+}
+
+svg .node {
+ cursor: pointer;
+}
+
+svg .node rect {
+ fill-opacity: 0.9;
+ shape-rendering: crispEdges;
+}
+
+svg .node text {
+ pointer-events: none;
+ font-size: 12px;
+}
+
+svg .link {
+ fill: none;
+ stroke: #ccc;
+ stroke-width: 1.5px;
+ stroke-opacity: 0.2;
+}
+
+svg .link:hover {
+ stroke-opacity: 0.5;
+}
+
+svg .templink {
+ fill: none;
+ stroke: red;
+ stroke-width: 3px;
+}
+svg .ghostCircle.show {
+ display: block;
+}
+
+.dashboard-top-section {
+ min-height: 230px;
+}
+
+.ms-choice {
+ height: 16px;
+ margin-top: unset;
+}
+
+.needle,
+.needle-center {
+ fill: #f1f2f6;
+}
+
+#total-icon-legend {
+ position: absolute;
+ top: 250px;
+ right: 10px;
+}
+
+#total-icon-legend > div {
+ display: flex;
+ align-items: center;
+ margin-bottom: 0.3em;
+}
+
+#total-icon-legend > div:last-child {
+ margin-bottom: 0;
+}
+
+#total-icon-legend > div > .text {
+ padding-top: 3px;
+ font-size: 10px;
+}
+
+.circle {
+ display: inline-block;
+ background-color: red;
+ width: 11px;
+ height: 11px;
+ border-radius: 50px;
+ margin-top: 4px;
+ margin-right: 8px;
+ border: 1px solid white;
+}
+
+.c3-bars path {
+ stroke: white;
+ stroke-width: 0.5px;
+}
+
+@media (max-width: 768px) {
+ #chart-product-manpower svg {
+ position: absolute;
+ top: 100%;
+ }
+}
+
+#chart-product-manpower {
+ position: relative;
+ height: 780px;
+}
+
+#chart-product-manpower svg {
+ position: absolute;
+ top: 60%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.xlarge {
+ height: 500px !important;
+}
+
+.chart-footer {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start; /* 아이템을 왼쪽으로 정렬 */
+ align-content: flex-start; /* 아이템을 위쪽으로 정렬 */
+ width: 100%;
+}
+.chart-footer .footer-item {
+ border-top: 2px solid;
+ box-sizing: border-box;
+ width: 33.33%; /* 기본 너비 설정 */
+ padding: 1px 2px;
+ background: rgba(51, 51, 51, 0.4);
+}
+.chart-footer .footer-item .item-name,
+.chart-footer .footer-item .item-value {
+ text-align: center;
+ width: 100%;
+ margin-top: 2px;
+}
+.chart-footer .footer-item .item-value {
+ font-weight: bold;
+}
+
+.chat-footer button {
+ margin-top: 0;
+}
+
+#chart-manpower-requirement,
+#chart-manpower-requirement-canvaswidget,
+#chart-manpower-requirement-canvas {
+ width: 100% !important;
+}
+
+#chart-manpower-requirement-label {
+ width: 100% !important;
+ position: relative !important;
+}
+
+/*
+* tree bar
+*/
+#tree_bar_container .link {
+ fill: none;
+ stroke: #ccc;
+ stroke-opacity: 0.4;
+ stroke-width: 1px;
+}
+#tree_bar_container text {
+ font-family: "Arial Black", Gadget, sans-serif;
+ fill: white;
+ font-weight: bold;
+ font-size: 12px;
+ text-shadow: none;
+}
+
+#tree_bar_container .xAxis .tick text {
+ fill: white;
+}
+#tree_bar_container .grid .tick line {
+ stroke: grey;
+ stroke-dasharray: 5, 10;
+ opacity: 0.7;
+}
+#tree_bar_container .grid path {
+ stroke-width: 0;
+}
+
+#tree_bar_container .node circle {
+ fill: #999;
+}
+#tree_bar_container .node--internal circle {
+ fill: #555;
+}
+
+#tree_bar_container .node--internal .root {
+ transform: translateX(10px);
+}
+
+/* gant */
+#shcedule_update {
+ height: 28px;
+}
+
+.project-progress .progress-group {
+ display: flex;
+ align-items: flex-start;
+ margin-bottom: 10px;
+}
+
+.progress-group label {
+ flex-shrink: 0;
+ width: 150px;
+ line-height: 30px;
+ text-align: right;
+ margin-right: 5px;
+}
+
+.progress-group .progress-desc {
+ display: flex;
+ align-items: flex-start;
+}
+
+.progress-group .progress-desc .icon {
+ width: 38px;
+ height: 30px;
+}
+
+.progress-group .progress-desc .progress-input {
+ flex-shrink: 0;
+ display: flex;
+ width: 125px;
+ align-items: center;
+}
+
+.project-progress input {
+ width: 63px !important;
+ margin-right: 2px;
+ padding: 5px !important;
+ text-align: right;
+}
+
+.project-progress .input-group-addon.input-desc {
+ display: flex;
+ width: auto;
+ text-align: left;
+ line-height: 18px;
+}
+.project-progress .input-group-addon .fa {
+ line-height: 15px;
+}
+
+.project-progress .input-desc .font11 {
+ margin-left: 5px;
+ white-space: normal;
+ word-break: keep-all;
+}
+
+/* vertical timeline chart */
+#vertical-timeline {
+ overflow-y: auto;
+ height: 732px;
+ padding-right: 20px;
+ margin: 0px;
+}
+
+.timeline-container {
+ margin-bottom: 20px;
+}
+
+.timeline-container ul {
+ margin: 0;
+ list-style: none;
+ position: relative;
+ color: #fff;
+ font-size: 13px;
+ padding: 15px 0 0 75px;
+}
+
+.timeline-container ul:before {
+ content: "";
+ width: 1px;
+ height: 100%;
+ position: absolute;
+ border-left: 2px dashed #fff;
+}
+
+.timeline-container .session {
+ position: relative;
+ margin-left: 30px;
+ background-color: rgba(51, 51, 51, 1);
+ padding: 14px;
+ border-radius: 6px;
+ box-shadow: 0 0 4px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.08);
+}
+
+.timeline-container .session:not(:first-child) {
+ margin-top: 40px;
+}
+
+.timeline-container .session > span {
+ width: 2px;
+ height: 100%;
+ background: #fff;
+ left: -30px;
+ top: 0;
+ position: absolute;
+}
+
+.timeline-container .session > span:before {
+ content: "";
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ border: 2px solid #fff;
+ position: absolute;
+ background: #5470c6ff;
+ left: -4px;
+ top: 0;
+}
+
+.timeline-container .session .time-range {
+ height: 100%;
+}
+
+.timeline-container .session .time-range .date {
+ position: absolute;
+ font-size: 10px;
+ top: 0;
+ left: -74px;
+ font-weight: bold;
+ line-height: normal;
+}
+
+.timeline-container .session > span:after {
+ top: calc(100% - 5px);
+}
+
+.timeline-container .session-content .version {
+ font-weight: 600;
+ font-size: 14px;
+}
+
+.timeline-container .session-content .summary {
+ margin-top: 5px;
+ font-weight: 300;
+}
+
+.timeline-container .session-content .issuekey {
+ margin-top: 5px;
+ font-weight: 600;
+ font-size: 12px;
+}
+
+.tree-container.widget.large,
+.tree-container.widget.large .body {
+ height: auto;
+}
+
+.vertical-chevron-up,
+.vertical-chevron-down {
+ position: absolute;
+ left: 48%;
+ transform: translateY(-20px);
+ font-size: 20px;
+ cursor: pointer;
+}
+
+.vertical-chevron-down {
+ transform: translateY(20px);
+}
+
+.fa-chevron-up:hover,
+.fa-chevron-down:hover {
+ opacity: 80%;
+}
+
+@media screen and (max-width: 1295px) {
+ .timeline-period {
+ flex: 1 1 auto;
+ margin-bottom: 10px;
+ }
+}
+
+.chat-message .chat-message-body {
+ margin-left: 0px !important;
+ padding: 8px 10px;
+ background: rgba(51, 51, 51, 0.3);
+ border-radius: 3px;
+ position: relative;
+}
+
+.chat-message-body.on-left .arrow {
+ border-left: 5px solid #e5603b;
+}
+
+.chat-message .chat-message-body.arrow:before {
+ content: "";
+ display: block;
+ position: absolute;
+ top: 21px;
+ left: -7px;
+ width: 0;
+ height: 0;
+ border-top: 5px solid transparent;
+ border-bottom: 5px solid transparent;
+ border-right: 5px solid #a4c6ff;
+}
+
+.detail_qna .chat-message .sender {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.detail_qna .chat-message-body .arrow {
+ top: calc(50% - 5px);
+}
+
+.detail_qna .chat-message .chat-message-body {
+ margin-left: 63px !important;
+}
+
+.detail_qna .chat-message .chat-message-body.on-left {
+ margin-left: 0px !important;
+ border-right: 2px solid #e5603b;
+}
+
+.detail_qna .chat-message-body .action-group {
+ margin-top: 15px;
+}
+
+.detail_qna .chat-message-body .action-group button {
+ margin-right: 5px;
+ border: 0;
+ background-color: transparent;
+}
+
+.detail_qna .date-separator {
+ text-align: center;
+ width: 180px;
+ margin: 30px auto;
+ padding: 6px;
+ font-size: 15px;
+ background: rgba(51, 51, 51, 0.3);
+ border-radius: 15px;
+}
+
+.detail_qna .edit-text-area {
+ width: 100%;
+ resize: vertical;
+ background: transparent;
+}
+
+.detail_qna .eidt-comment,
+.detail_qna .edit-group {
+ display: none;
+}
+
+.detail_qna .empty-message {
+ display: flex;
+ height: 550px;
+ justify-content: center;
+ align-items: center;
+}
+
+.widget > .carousel {
+ margin: 0 -12px 5px;
+}
+
+.carousel-control.left,
+.carousel-control.right {
+ background: none;
+}
+.carousel-control i {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ z-index: 5;
+ display: inline-block;
+ width: 20px;
+ height: 45px;
+ margin-left: -10px;
+ margin-top: -10px;
+}
+
+.carousel-indicators.outer {
+ bottom: -20px;
+}
+.carousel-indicators li {
+ background-color: rgba(51, 51, 51, 0.4);
+}
+
+.service-portfolio .filter-options-wrap {
+ margin: 20px 0;
+}
+.service-portfolio .filter-option {
+ position: relative;
+ margin-bottom: 8px;
+ padding-left: 13px;
+ cursor: pointer;
+}
+
+.service-portfolio .filter-active:before {
+ content: "";
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 3px;
+ background-color: #e5603b;
+}
+
+.service-portfolio .portfolio-wrap {
+ display: flex;
+ margin: 20px 0;
+}
+
+.service-portfolio .portfolio-item {
+ float: none;
+}
+
+.service-portfolio .portfolio-item-wrap {
+ position: relative;
+ height: 0;
+ padding-bottom: 100%;
+}
+
+.service-portfolio .portfolio-item-wrap img {
+ width: 100%;
+}
+
+.service-portfolio .portfolio-info {
+ opacity: 1;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ text-align: center;
+ z-index: 3;
+ transition: all ease-in-out 0.3s;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ overflow-wrap: anywhere;
+}
+
+.service-portfolio .portfolio-item-wrap:before {
+ content: "";
+ background: rgba(40, 40, 40, 0.5);
+ position: absolute;
+ left: 5px;
+ right: 5px;
+ top: 5px;
+ bottom: 5px;
+ transition: all ease-in-out 0.3s;
+ z-index: 2;
+ opacity: 0;
+}
+
+.service-portfolio .portfolio-info {
+ opacity: 0;
+ transition: all ease-in-out 0.3s;
+}
+
+.service-portfolio .portfolio-info h4,
+.service-portfolio .portfolio-info p {
+ font-size: 12px;
+}
+
+.service-portfolio .portfolio-info .portfolio-links a {
+ color: #fff;
+ margin: 5px 2px 0;
+ font-size: 20px;
+ display: inline-block;
+ transition: 0.3s;
+}
+
+.service-portfolio .portfolio-info .portfolio-links a:hover {
+ color: #148af9;
+}
+
+.service-portfolio .portfolio-item-wrap:hover:before {
+ top: -10px;
+ left: -10px;
+ right: -10px;
+ bottom: -10px;
+ opacity: 1;
+}
+
+.service-portfolio .portfolio-item-wrap:hover .portfolio-info {
+ opacity: 1;
+}
+
+.req-table,
+.req-select {
+ background: rgba(51, 51, 51, 0.8) !important;
+ border: 1px solid rgba(51, 51, 51, 0.825) !important;
+}
+
+.req-table.dropdown-menu a:hover,
+.req-table.dropdown-menu .active a,
+.req-select.dropdown-menu a:hover,
+.req-select.dropdown-menu .active a {
+ background: none;
+}
+
+.req-table.dropdown-menu a:hover,
+.req-select.dropdown-menu a:hover,
+#select2-selected_pdService-container .select2-selection__placeholder,
+.multiple-select .ms-choice > span.placeholder {
+ color: #f8f8f8;
+}
+.req-table.dropdown-menu .active a,
+.req-select.dropdown-menu .active a,
+#disabled_input_pdservice.form-control {
+ color: #a4c6ff;
+}
+
+.req-select {
+ min-width: auto;
+}
+
+#reqDataTable {
+ padding-top: 0;
+ margin-bottom: 0;
+ max-height: 745px;
+ background: 0 none;
+ overflow: auto;
+}
+
+#reqDataTable .reqTable {
+ width: max-content;
+ table-layout: fixed;
+}
+
+#reqDataTable .reqTable th {
+ padding: 20px 10px 10px;
+ text-align: center;
+ position: sticky;
+ top: 0;
+ z-index: 1;
+ background-color: rgba(51, 51, 51, 0.9);
+}
+
+#reqDataTable .reqTable td {
+ padding: 5px 10px;
+ text-align: center;
+}
+
+#reqDataTable .reqTable td.depth1,
+#reqDataTable .reqTable td.depth2,
+#reqDataTable .reqTable td.depth3,
+#reqDataTable .reqTable td.content {
+ text-align: left;
+}
+
+#reqDataTable .reqTable .tbody input {
+ width: 100%;
+ border: 0 none;
+ background: 0 none;
+}
+
+#reqDataTable .reqTable .tbody tr:nth-child(even) {
+ background-color: rgba(51, 51, 51, 0.325);
+}
+#reqDataTable .reqTable .tbody tr:first-child {
+ height: 37px !important;
+}
+#reqDataTable .reqTable .tbody tr td {
+ position: relative;
+ border-right: 2px solid #515256;
+}
+
+#reqDataTable .reqTable {
+ cursor: default;
+}
+
+#reqDataTable .reqTable th.version,
+#reqDataTable .reqTable th.category,
+#reqDataTable .reqTable th.id,
+#reqDataTable .reqTable th.status,
+#reqDataTable .reqTable th.priority,
+#reqDataTable .reqTable th.difficulty,
+#reqDataTable .reqTable th.createDate,
+#reqDataTable .reqTable th.startDate,
+#reqDataTable .reqTable th.endDate,
+#reqDataTable .reqTable th.progress {
+ cursor: pointer;
+}
+
+#reqDataTable .reqTable td.content {
+ cursor: text;
+}
+
+#reqDataTable .reqTable th.version:after,
+#reqDataTable .reqTable th.category:after,
+#reqDataTable .reqTable th.id:after,
+#reqDataTable .reqTable th.status:after,
+#reqDataTable .reqTable th.priority:after,
+#reqDataTable .reqTable th.difficulty:after,
+#reqDataTable .reqTable th.createDate:after,
+#reqDataTable .reqTable th.startDate:after,
+#reqDataTable .reqTable th.endDate:after,
+#reqDataTable .reqTable th.progress:after {
+ content: "";
+ display: inline-block;
+ width: 19px;
+ height: 19px;
+ margin-left: 10px;
+ vertical-align: middle;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-image: url(../img/datatable/sort_both.png);
+}
+
+#reqDataTable .reqTable th.asc:after {
+ background-image: url(../img/datatable/sort_asc.png);
+}
+
+#reqDataTable .reqTable th.desc:after {
+ background-image: url(../img/datatable/sort_desc.png);
+}
+#reqDataTable .root {
+ padding-left: 25px !important;
+ text-align: left !important;
+}
+
+#reqDataTable .pivotTable {
+ min-width: 120%;
+}
+
+#reqDataTable .pivotTable .highlight {
+ color: #a4c6ff;
+}
+
+#reqDataTable .pivot-toggle {
+ margin-right: 3px;
+ padding: 0 3px;
+ background-color: transparent;
+}
+#reqDataTable .pivot-toggle .fa {
+ vertical-align: text-bottom;
+ font-size: 14px;
+ color: #a4c6ff;
+}
+#reqDataTable .pivot-toggle .fa-minus-square {
+ display: none;
+}
+#reqDataTable .pivot-toggle.active .fa-plus-square {
+ display: none;
+}
+#reqDataTable .pivot-toggle.active .fa-minus-square {
+ display: block;
+}
+
+/* cost 분석 */
+
+/* 비용 입력 */
+.cost-versions {
+ margin: 30px 0;
+ /*padding-left: 20px;*/
+}
+
+.cost-version,
+.cost-input-complete {
+ margin-right: 10px;
+ padding: 3px 7px;
+ font-size: 11px;
+ font-weight: bold;
+ background-color: #5470c6ff;
+ border: none;
+ border-radius: 5px;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 3px 10px 0 rgba(0, 0, 0, 0.19);
+}
+
+.cost-input-complete {
+ font-size: 15px;
+ background-color: rgb(51, 51, 51);
+ box-shadow: none;
+ margin: 0;
+}
+
+.cost-version:hover,
+.cost-input-complete:hover {
+ background-color: #39393b;
+}
+
+.cost-input-version,
+.cost-input-manpower {
+ margin-bottom: 20px;
+ border-radius: 3px;
+ padding: 5px;
+ margin-bottom: 30px;
+ background: rgba(51, 51, 51, 0.425);
+ color: #f8f8f8;
+}
+
+.cost-version-info {
+ width: 30%;
+ margin: 10px 0 10px 0;
+ padding: 20px;
+ border-radius: 7px;
+ background-color: #4b4a4a;
+}
+
+.cost-version-info div {
+ padding-top: 10px;
+}
+
+.cost-input,
+.annual-income-input {
+ color: black;
+ width: 50%;
+ text-align: center;
+ border: none;
+ border-radius: 5px;
+ padding: 5px;
+ background: rgba(157, 156, 156, 0.22);
+}
+
+.version-input {
+ width: 70%;
+}
+
+.dt-center {
+ text-align: center;
+}
+
+.more {
+ display: inline-block;
+ border: 1px solid rgba(255, 255, 255, 0.3);
+ letter-spacing: 0;
+ z-index: 1;
+ position: relative;
+ margin-top: 10px;
+ color: #fff;
+ font-size: 13px;
+}
+
+.animated-button1 {
+ display: inline-block;
+ -webkit-transform: translate(0%, 0%);
+ transform: translate(0%, 0%);
+ overflow: hidden;
+ color: #fff;
+ font-size: 12px;
+ text-decoration: none;
+}
+
+.animated-button1::before {
+ content: "";
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: #8593ad;
+ opacity: 0;
+ -webkit-transition: 0.2s opacity ease-in-out;
+ transition: 0.2s opacity ease-in-out;
+}
+
+.animated-button1 span {
+ position: absolute;
+}
+
+@keyframes animateTop {
+ 0% {
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+
+ 100% {
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+}
+
+.animated-button1 span:nth-child(1) {
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 1px;
+ background: -webkit-gradient(linear, right top, left top, from(rgba(43, 8, 8, 0)), to(#fff));
+ background: linear-gradient(to left, rgba(43, 8, 8, 0), #fff);
+ -webkit-animation: 2s animateTop linear infinite;
+ animation: 2s animateTop linear infinite;
+}
+
+@keyframes animateRight {
+ 0% {
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+
+ 100% {
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+}
+
+.animated-button1 span:nth-child(2) {
+ top: 0px;
+ right: 0px;
+ height: 100%;
+ width: 1px;
+ background: -webkit-gradient(linear, left bottom, left top, from(rgba(43, 8, 8, 0)), to(#fff));
+ background: linear-gradient(to top, rgba(43, 8, 8, 0), #fff);
+ -webkit-animation: 2s animateRight linear -1s infinite;
+ animation: 2s animateRight linear -1s infinite;
+}
+
+@keyframes animateBottom {
+ 0% {
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+
+ 100% {
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+}
+
+.animated-button1 span:nth-child(3) {
+ bottom: 0px;
+ left: 0px;
+ width: 100%;
+ height: 1px;
+ background: -webkit-gradient(linear, left top, right top, from(rgba(43, 8, 8, 0)), to(#fff));
+ background: linear-gradient(to right, rgba(43, 8, 8, 0), #fff);
+ -webkit-animation: 2s animateBottom linear infinite;
+ animation: 2s animateBottom linear infinite;
+}
+
+@keyframes animateLeft {
+ 0% {
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+
+ 100% {
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+}
+
+.animated-button1 span:nth-child(4) {
+ top: 0px;
+ left: 0px;
+ height: 100%;
+ width: 1px;
+ background: -webkit-gradient(linear, left top, left bottom, from(rgba(43, 8, 8, 0)), to(#fff));
+ background: linear-gradient(to bottom, rgba(43, 8, 8, 0), #fff);
+ -webkit-animation: 2s animateLeft linear -1s infinite;
+ animation: 2s animateLeft linear -1s infinite;
+}
+
+.modal-dialog .modal-content {
+ padding: 20px;
+}
+
+.modal-dialog .widget-controls {
+ top: 20px !important;
+ right: 20px;
+}
+
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 80%;
+ }
+}
+
+.page-header .search-query {
+ width: 200px;
+}
+.page-header .search-query:focus {
+ width: 240px;
+}
+
+#nav-search-button {
+ display: inline-block;
+ color: rgba(51, 51, 51, 0.5);
+ width: 40px;
+ padding: 0;
+ font-size: 19.5px;
+ outline: 0;
+ background: none;
+ text-align: center;
+ vertical-align: middle;
+ line-height: 36px;
+ text-shadow: none;
+}
+
+#nav-search-button.highlight,
+#nav-search-button.highlight a {
+ background: rgba(51, 51, 51, 0.5);
+ color: #b8b8b8;
+ border-radius: 3px;
+ font-size: 17px;
+ width: 30px;
+ line-height: 30px;
+}
+
+/* 칸반 보드 */
+.kanban-top {
+ width: 100%;
+ margin-bottom: 30px;
+}
+
+.kanban-top:last-child {
+ margin-bottom: 0;
+}
+
+.kanban-container {
+ color: black;
+}
+
+.kanban-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-end;
+}
+
+.kanban-drag {
+ height: 550px !important;
+ overflow: auto;
+}
+
+.show-info {
+ cursor: pointer;
+}
\ No newline at end of file
Index: controltower/html/index/content-container.html
===================================================================
diff -u
--- controltower/html/index/content-container.html (revision 0)
+++ controltower/html/index/content-container.html (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,987 @@
+
+
+
Index: controltower/html/index/content-header.html
===================================================================
diff -u
--- controltower/html/index/content-header.html (revision 0)
+++ controltower/html/index/content-header.html (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,13 @@
+
+ Dashboard
+ Statistics and more
+
+
+
+
+ Home
+
+
+ Dashboard
+
+
FishEye: Tag 5cd07d4d43536675e4294d68d4c75c61207ab65a refers to a dead (removed) revision in file `controltower/html/template/content-footer.html'.
FishEye: No comparison available. Pass `N' to diff?
Index: controltower/html/template/page-header.html
===================================================================
diff -u
--- controltower/html/template/page-header.html (revision 0)
+++ controltower/html/template/page-header.html (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+
Index: controltower/html/template/page-logo.html
===================================================================
diff -u
--- controltower/html/template/page-logo.html (revision 0)
+++ controltower/html/template/page-logo.html (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,7 @@
+
Index: controltower/html/template/page-sidebar.html
===================================================================
diff -u
--- controltower/html/template/page-sidebar.html (revision 0)
+++ controltower/html/template/page-sidebar.html (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: controltower/img/313_logo.png
===================================================================
diff -u
Binary files differ
Index: controltower/index.html
===================================================================
diff -u
--- controltower/index.html (revision 0)
+++ controltower/index.html (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,439 @@
+
+
+
+ A-RMS By 313DEVGRP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 어플리케이션 API Data를 가져오는 중입니다...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: controltower/js/common.js
===================================================================
diff -u
--- controltower/js/common.js (revision 0)
+++ controltower/js/common.js (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,1930 @@
+////////////////////////////////////////////////////////////////////////////////////////
+//Document Ready
+////////////////////////////////////////////////////////////////////////////////////////
+$(function () {
+ var str = window.location.href;
+ if (str.indexOf("php") > 0) {
+ console.table("313DEVGRP 커뮤니티에 오신것을 환영합니다.");
+ runScript();
+ } else {
+ authUserCheck();
+ }
+});
+
+function runScript() {
+ // Page load & 상단 페이지 로드 프로그래스바
+ topbarConfig();
+ topbar.show();
+ setTimeout(function () {
+ $(".container").fadeIn("slow");
+ topbar.hide();
+ }, 2000);
+
+ /* 맨위로 아이콘 */
+ rightBottomTopForwardIcon();
+
+ var urlParams = new URL(location.href).searchParams;
+ var onlyContents = urlParams.get("withoutLayer");
+ if (isEmpty(onlyContents)) {
+ $("body").removeAttr("class");
+ } else {
+ $("body").addClass("sidebar-hidden");
+ $("header.page-header").hide();
+ }
+
+ $(document).on("shown.bs.tab", "a[data-toggle='tab']", function () {
+ window.dispatchEvent(new Event("resize"));
+ });
+
+ if (ajax_setup()) {
+ $(".loader").removeClass("hide");
+
+ var page = urlParams.get("page");
+ if (isEmpty(page)) {
+ page = "index";
+ }
+ if (includeLayout(page)) {
+ $.getScript("js/" + page + ".js", function () {
+ /* 로그인 인증 여부 체크 함수 */
+ execDocReady();
+ dwr_login(userName, userName);
+ });
+ }
+ }
+}
+
+function widgsterWrapper() {
+ var height;
+
+ $.fn.widgster.Constructor.prototype.fullscreen = function () {
+ var e = $.Event("fullscreen.widgster");
+
+ this.$element.trigger(e);
+
+ if (e.isDefaultPrevented()) return;
+
+ this.$element.css({
+ position: "fixed",
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0,
+ margin: 0,
+ overflow: "auto",
+ "z-index": 10000
+ });
+
+ var body = this.$element.find(".body");
+ var siblingsHeight = body
+ .siblings()
+ .toArray()
+ .reduce(function (acc, cur) {
+ return (acc += cur.clientHeight);
+ }, 0);
+ var margin =
+ parseInt(body.css("margin-top")) +
+ parseInt(body.css("margin-bottom")) +
+ parseInt(this.$element.css("padding-top")) +
+ parseInt(this.$element.css("padding-bottom")) +
+ parseInt(this.$element.css("margin-top")) +
+ parseInt(this.$element.css("margin-bottom"));
+
+ // height = body.css("height");
+ body.css("height", "calc(100% - " + (siblingsHeight + margin) + "px)");
+
+ $("body").css("overflow", "hidden");
+
+ this.wasCollapsed = this.collapsed;
+ this.expand(false);
+
+ this.$fullscreen.hide();
+ this.$restore.show();
+
+ this.$collapse.hide();
+ this.$expand.hide();
+
+ this.$element.addClass("fullscreened");
+
+ this.$element.addClass("modalDarkBack");
+
+ this.$element.trigger($.Event("fullscreened.widgster"));
+
+ return false;
+ };
+
+ $.fn.widgster.Constructor.prototype.restore = function () {
+ var e = $.Event("restore.widgster");
+
+ this.$element.trigger(e);
+
+ if (e.isDefaultPrevented()) return;
+
+ this.$element.css({
+ position: "",
+ top: "",
+ right: "",
+ bottom: "",
+ left: "",
+ margin: "",
+ overflow: "",
+ "z-index": ""
+ });
+
+ this.$element.find(".body").css("height", height);
+ $("body").css("overflow", "");
+
+ this.$fullscreen.show();
+ this.$restore.hide();
+
+ if (this.collapsed) {
+ this.$collapse.hide();
+ this.$expand.show();
+ } else {
+ this.$collapse.show();
+ this.$expand.hide();
+ }
+
+ this.wasCollapsed && this.collapse(false);
+
+ this.$element.removeClass("fullscreened");
+
+ this.$element.removeClass("modalDarkBack");
+
+ this.$element.trigger($.Event("restored.widgster"));
+
+ return false;
+ };
+}
+
+function 로드_완료_이후_실행_함수() {
+ 톱니바퀴_초기설정();
+ loadLocale();
+ widgsterWrapper();
+ 검색_이벤트_트리거();
+
+ 우측_상단_사용자_정보_설정();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 우측_상단_사용자_정보_설정
+////////////////////////////////////////////////////////////////////////////////////////
+function 우측_상단_사용자_정보_설정() {
+
+ var str = window.location.href;
+ if (str.indexOf("php") > 0) {
+ var account_html = "not supported ";
+ $("#login_id").append(account_html);
+ }else {
+ var account_html = "\"" + userName + "\" ";
+ $("#login_id").append(account_html);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 플러그인 로드 모듈 ( 병렬 시퀀스 )
+////////////////////////////////////////////////////////////////////////////////////////
+function loadPlugin(url) {
+ return new Promise(function (resolve, reject) {
+ if (isJavaScriptFile(url)) {
+ $(".spinner").html(
+ ' ' +
+ getFileNameFromURL(url) +
+ " 자바스크립트를 다운로드 중입니다..."
+ );
+ $.ajax({
+ url: url,
+ dataType: "script",
+ cache: true,
+ success: function () {
+ // The request was successful
+
+ console.log("[ common :: loadPlugin ] :: url = " + url + " 자바 스크립트 플러그인 로드 성공");
+ resolve(); // Promise를 성공 상태로 변경
+ },
+ error: function () {
+ // The request failed
+ console.error("[ common :: loadPlugin ] :: url = " + url + " 플러그인 로드 실패");
+ reject(); // Promise를 실패 상태로 변경
+ }
+ });
+ } else {
+ $(".spinner").html(
+ ' ' +
+ getFileNameFromURL(url) +
+ " 스타일시트를 다운로드 중입니다..."
+ );
+ $(" ", {
+ rel: "stylesheet",
+ type: "text/css",
+ href: url
+ }).appendTo("head");
+ console.log("[ common :: loadPlugin ] :: url = " + url + " 스타일시트 플러그인 로드 성공");
+ resolve();
+ }
+ });
+}
+
+function getFileNameFromURL(url) {
+ var parts = url.split("/");
+ return parts[parts.length - 1];
+}
+
+function isJavaScriptFile(filename) {
+ return filename.endsWith(".js");
+}
+
+function loadPluginGroupSequentially(group) {
+ return group.reduce(function (promise, url) {
+ return promise.then(function () {
+ return loadPlugin(url);
+ });
+ }, Promise.resolve());
+}
+
+function loadPluginGroupsParallelAndSequential(groups) {
+ var promises = groups.map(function (group) {
+ return loadPluginGroupSequentially(group);
+ });
+ return Promise.all(promises).then(function () {
+ 로드_완료_이후_실행_함수();
+ });
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// include 레이아웃 html 파일을 로드하는 함수
+////////////////////////////////////////////////////////////////////////////////////////
+function includeLayout(page) {
+ var includeArea = $("[data-include]");
+ var self, url;
+ $.each(includeArea, function () {
+ self = $(this);
+ url = self.data("include");
+ console.log("[ common :: includeLayout ] url = " + url);
+
+ var hrefLink = window.location.href;
+ var urlParams = new URL(location.href).searchParams;
+ var mode = urlParams.get("mode");
+
+ if (url.indexOf("content-header") !== -1) {
+ url = "html/" + page + "/content-header.html";
+ self.load(url, function () {
+ self.removeAttr("data-include");
+ });
+ } else if (url.indexOf("content-container") !== -1) {
+ url = "html/" + page + "/content-container.html";
+ self.load(url, function () {
+ self.removeAttr("data-include");
+ });
+ } else if (url.indexOf("page-sidebar") !== -1) {
+ if (mode == "detail" || hrefLink.indexOf("detail.html") > 0) {
+ url = "/arms/html/detail/page-sidebar.html";
+ self.load(url, function () {
+ self.removeAttr("data-include");
+ });
+ } else {
+ url = "/arms/html/template/page-sidebar.html";
+ self.load(url, function () {
+ self.removeAttr("data-include");
+ });
+ }
+ } else {
+ self.load(url, function () {
+ self.removeAttr("data-include");
+ });
+ }
+ });
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+//인증관련 공통 변수
+////////////////////////////////////////////////////////////////////////////////////////
+var userName;
+var fullName;
+var userApplicationRoles;
+var userAttributes;
+var userEnabled;
+var userGroups;
+var userID;
+var userRealmRoles;
+var permissions;
+var userEmail;
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 상단 페이지 로드 프로그래스바 설정
+////////////////////////////////////////////////////////////////////////////////////////
+function topbarConfig() {
+ topbar.config({
+ autoRun: true,
+ barThickness: 3,
+ barColors: {
+ 0: "rgba(26, 188, 156, .9)",
+ ".25": "rgba(52, 152, 219, .9)",
+ ".50": "rgba(241, 196, 15, .9)",
+ ".75": "rgba(230, 126, 34, .9)",
+ "1.0": "rgba(211, 84, 0, .9)"
+ },
+ shadowBlur: 10,
+ shadowColor: "rgba(0, 0, 0, .6)"
+ });
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+//슬림스크롤
+////////////////////////////////////////////////////////////////////////////////////////
+function makeSlimScroll(targetElement) {
+ $(targetElement).slimScroll({
+ height: "250px",
+ railVisible: true,
+ railColor: "#222",
+ railOpacity: 0.3,
+ wheelStep: 10,
+ allowPageScroll: false,
+ disableFadeOut: false
+ });
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 맨위로 아이콘
+////////////////////////////////////////////////////////////////////////////////////////
+function rightBottomTopForwardIcon() {
+ $("#topicon").click(function () {
+ $("html, body").animate({ scrollTop: 0 }, 400);
+ return false;
+ });
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 로그인 인증 여부 체크 함수
+////////////////////////////////////////////////////////////////////////////////////////
+function authUserCheck() {
+ var str = window.location.href;
+ if (str.indexOf("community") > 0) {
+ runScript();
+ } else {
+ $.ajax({
+ url: "/auth-user/me",
+ type: "GET",
+ timeout: 7313,
+ global: false,
+ statusCode: {
+ 200: function (json) {
+ console.log("[ common :: authUserCheck ] userName = " + json.preferred_username);
+ console.log("[ common :: authUserCheck ] sub = " + json.sub);
+ console.log(json.realm_access.roles);
+ userName = json.preferred_username;
+ permissions = json.realm_access.roles;
+ userID = json.sub;
+ userEmail = json.email;
+ fullName = json.name;
+
+ runScript();
+ },
+ 401: function (json) {
+ $(".loader").addClass("hide");
+ jError("클라이언트가 인증되지 않았거나, 유효한 인증 정보가 부족하여 요청이 거부되었습니다.");
+ location.href = "/oauth2/authorization/middle-proxy";
+ return false;
+ },
+ 403: function (json) {
+ jError("서버가 해당 요청을 이해했지만, 권한이 없어 요청이 거부되었습니다.");
+ return false;
+ }
+ }
+ });
+
+ return true;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 사용자 정보 로드 함수
+////////////////////////////////////////////////////////////////////////////////////////
+function getUserInfo() {
+ $.ajax({
+ url: "/auth-user/search-user/" + userName,
+ data: {
+ sendData: ""
+ },
+ type: "GET",
+ progress: true,
+ statusCode: {
+ 200: function (json) {
+ console.log("authUserCheck length = :: " + json.length);
+ if (json.length > 1) {
+ jError("중복된 사용자가 있습니다.");
+ } else if (json.length == 0) {
+ jError("사용자 정보가 조회되지 않습니다.");
+ } else {
+ userApplicationRoles = json[0].applicationRoles;
+ userAttributes = json[0].attributes;
+ userEnabled = json[0].enabled;
+ userGroups = json[0].groups;
+ userID = json[0].id;
+ userRealmRoles = json[0].realmRoles;
+ console.log("authUserCheck :: userApplicationRoles = " + userApplicationRoles);
+ console.log("authUserCheck :: userAttributes = " + userAttributes);
+ console.log("authUserCheck :: userEnabled = " + userEnabled);
+ console.log("authUserCheck :: userGroups = " + userGroups);
+ console.log("authUserCheck :: userID = " + userID);
+ console.log("authUserCheck :: userRealmRoles = " + userRealmRoles);
+ }
+ }
+ }
+ });
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 유틸 : 말줄임표
+////////////////////////////////////////////////////////////////////////////////////////
+function getStrLimit(inputStr, limitCnt) {
+ if (isEmpty(inputStr)) {
+ return "";
+ } else if (inputStr.length >= limitCnt) {
+ return inputStr.substr(0, limitCnt) + "...";
+ } else {
+ return inputStr;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+//서버 바인딩 할 수가 없어서 프로토타입 목적으로 json 을 만들어서 로드하는 함수
+////////////////////////////////////////////////////////////////////////////////////////
+var getJsonForPrototype = function (url, bindTemplate) {
+ ajaxGet(url).then(function (data) {
+ bindTemplate(data);
+ });
+};
+var ajaxGet = (url) =>
+ $.ajax({
+ url,
+ type: "GET",
+ global: false,
+ statusCode: {
+ 200: function (data) {
+ return data.responseJSON;
+ }
+ }
+ });
+
+function dateFormat(timestamp) {
+ var d = new Date(timestamp), // Convert the passed timestamp to milliseconds
+ yyyy = d.getFullYear(),
+ mm = ("0" + (d.getMonth() + 1)).slice(-2), // Months are zero based. Add leading 0.
+ dd = ("0" + d.getDate()).slice(-2), // Add leading 0.
+ hh = d.getHours(),
+ h = hh,
+ min = ("0" + d.getMinutes()).slice(-2), // Add leading 0.
+ ampm = "AM",
+ time;
+
+ if (hh > 12) {
+ h = hh - 12;
+ ampm = "PM";
+ } else if (hh === 12) {
+ h = 12;
+ ampm = "PM";
+ } else if (hh == 0) {
+ h = 12;
+ }
+
+ // ie: 2013-02-18, 8:35 AM
+ time = yyyy + "년" + mm + "월" + dd + "일 - " + h + ":" + min + " " + ampm;
+
+ return time;
+}
+
+function getToday() {
+ var date = new Date();
+ return date.getFullYear() + "/" + ("0" + (date.getMonth() + 1)).slice(-2) + "/" + ("0" + date.getDate()).slice(-2);
+}
+
+// 최대값, 최소값
+function maxValue(arr) {
+ if (isEmpty(arr)) {
+ return [];
+ } else {
+ return arr.reduce((max, val) => (max > val ? max : val));
+ }
+}
+
+function minValue(arr) {
+ if (isEmpty(arr)) {
+ return [];
+ } else {
+ return arr.reduce((min, val) => (min < val ? min : val));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// --- 왼쪽 사이드 메뉴 설정 --- //
+////////////////////////////////////////////////////////////////////////////////////////
+function setSideMenu(categoryName, listName, collapse) {
+ console.log("[ common :: setSideMenu ] :: categoryName → " + categoryName + ", listName → " + listName);
+
+ setTimeout(function () {
+ //jira_icon
+ if (categoryName === "sidebar_menu_jira") {
+ $("#side_jira_neutral_icon").removeClass("hidden");
+ $("#side_jira_white_icon").addClass("hidden");
+ } else {
+ $("#side_jira_neutral_icon").addClass("hidden");
+ $("#side_jira_white_icon").removeClass("hidden");
+ } //.jira_icon
+
+ $(`#${categoryName}`).css({ color: "#a4c6ff" });
+ $(`#${categoryName}`).css({ "font-weight": "900" });
+
+ if (isEmpty(listName)) {
+ console.log("[ common :: setSideMenu ] :: listName → is null");
+ } else {
+ $(`#${listName}`).addClass("active");
+ $(`#${listName}`).css({ color: "#a4c6ff" });
+ $(`#${listName}`).css({ "font-weight": "900" });
+ }
+ $(".spinner").html(
+ " 어플리케이션 API Data를 가져오는 중입니다..."
+ );
+ }, 1000);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// -- jstree build 설정 -- //
+////////////////////////////////////////////////////////////////////////////////////////
+function jsTreeBuild(jQueryElementID, serviceNameForURL) {
+ console.log("common :: jsTreeBuild : ( jQueryElementID ) → " + jQueryElementID);
+ console.log("common :: jsTreeBuild : ( serviceNameForURL ) → " + serviceNameForURL);
+
+ console.log("common :: jsTreeBuild : ( href ) → " + $(location).attr("href"));
+ console.log("common :: jsTreeBuild : ( protocol ) → " + $(location).attr("protocol"));
+ console.log("common :: jsTreeBuild : ( host ) → " + $(location).attr("host"));
+ console.log("common :: jsTreeBuild : ( pathname ) → " + $(location).attr("pathname"));
+ console.log("common :: jsTreeBuild : ( search ) → " + $(location).attr("search"));
+ console.log("common :: jsTreeBuild : ( hostname ) → " + $(location).attr("hostname"));
+ console.log("common :: jsTreeBuild : ( port ) → " + $(location).attr("port"));
+
+ $(jQueryElementID)
+ .bind("before.jstree", function (e, data) {
+ $("#alog").append(data.func + " ");
+ $("li:not([rel='drive']).jstree-open > a > .jstree-icon").css(
+ "background-image",
+ "url(../reference/jquery-plugins/jstree-v.pre1.0/themes/toolbar_open.png)"
+ );
+ $("li:not([rel='drive']).jstree-closed > a > .jstree-icon").css(
+ "background-image",
+ "url(../reference/jquery-plugins/jstree-v.pre1.0/themes/ic_explorer.png)"
+ );
+ })
+ .jstree({
+ // List of active plugins
+ plugins: ["themes", "json_data", "ui", "crrm", "dnd", "search", "types"],
+ themes: { theme: ["lightblue4"] },
+ //contextmenu
+ contextmenu: {
+ items: {
+ // Could be a function that should return an object like this one
+ create: {
+ separator_before: true,
+ separator_after: true,
+ label: "Create",
+ action: false,
+ submenu: {
+ create_file: {
+ seperator_before: false,
+ seperator_after: false,
+ label: "File",
+ action: function (obj) {
+ this.create(obj, "last", {
+ attr: {
+ rel: "default"
+ }
+ });
+ }
+ },
+ create_folder: {
+ seperator_before: false,
+ seperator_after: false,
+ label: "Folder",
+ action: function (obj) {
+ this.create(obj, "last", {
+ attr: {
+ rel: "folder"
+ }
+ });
+ }
+ }
+ }
+ },
+ ccp: {
+ separator_before: false,
+ separator_after: true,
+ label: "Edit",
+ action: false,
+ submenu: {
+ cut: {
+ seperator_before: false,
+ seperator_after: false,
+ label: "Cut",
+ action: function (obj) {
+ this.cut(obj, "last", {
+ attr: {
+ rel: "default"
+ }
+ });
+ }
+ },
+ paste: {
+ seperator_before: false,
+ seperator_after: false,
+ label: "Paste",
+ action: function (obj) {
+ this.paste(obj, "last", {
+ attr: {
+ rel: "folder"
+ }
+ });
+ }
+ },
+
+ changeType: {
+ seperator_before: false,
+ seperator_after: false,
+ label: "Change Type",
+ submenu: {
+ toFile: {
+ seperator_before: false,
+ seperator_after: false,
+ label: "toFile",
+ action: function (obj) {
+ this.set_type("default");
+ }
+ },
+ toFolder: {
+ seperator_before: false,
+ seperator_after: false,
+ label: "toFolder",
+ action: function (obj) {
+ this.set_type("folder");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ // I usually configure the plugin that handles the data first
+ // This example uses JSON as it is most common
+ json_data: {
+ // This tree is ajax enabled - as this is most common, and maybe a bit more complex
+ // All the options are almost the same as jQuery's AJAX (read the docs)
+ ajax: {
+ // the URL to fetch the data
+ url: serviceNameForURL + "/getChildNode.do",
+ cache: false,
+ // the `data` function is executed in the instance's scope
+ // the parameter is the node being loaded
+ // (may be -1, 0, or undefined when loading the root nodes)
+ data: function (n) {
+ // the result is fed to the AJAX request `data` option
+ console.log("[ common :: jsTreeBuild ] :: json data load = " + JSON.stringify(n));
+ return {
+ c_id: n.attr ? n.attr("id").replace("node_", "").replace("copy_", "") : 1
+ };
+ },
+ success: function (n) {
+ jSuccess("Product(service) Data Load Complete");
+ $(jQueryElementID).jstree("search", $("#text").val());
+ }
+ }
+ },
+ // Configuring the search plugin
+ search: {
+ // As this has been a common question - async search
+ // Same as above - the `ajax` config option is actually jQuery's AJAX object
+
+ /**
+ * v1 : 검색 버튼 클릭 시 API 호출 후 응답 데이터를 jstree 에 바인딩
+ ajax: {
+ url: serviceNameForURL + "/searchNode.do",
+ // You get the search string as a parameter
+ data: function (str) {
+ return {
+ searchString: str
+ };
+ },
+ success: function (n) {
+ jSuccess("search data complete");
+ }
+ }
+ */
+
+ /**
+ * v2 : 검색 버튼 클릭 시 jstree 노드 필터링을 통해 검색
+ */
+ show_only_matches: true,
+ search_callback: function (str, node) {
+ return node.data().search(str);
+ }
+ },
+ // Using types - most of the time this is an overkill
+ // read the docs carefully to decide whether you need types
+ types: {
+ // I set both options to -2, as I do not need depth and children count checking
+ // Those two checks may slow jstree a lot, so use only when needed
+ max_depth: -2,
+ max_children: -2,
+ // I want only `drive` nodes to be root nodes
+ // This will prevent moving or creating any other type as a root node
+ valid_children: ["drive"],
+ types: {
+ // The default type
+ default: {
+ // I want this type to have no children (so only leaf nodes)
+ // In my case - those are files
+ valid_children: "none",
+ // If we specify an icon for the default type it WILL OVERRIDE the theme icons
+ icon: {
+ image: "../reference/jquery-plugins/jstree-v.pre1.0/themes/attibutes.png"
+ }
+ },
+ // The `folder` type
+ folder: {
+ // can have files and other folders inside of it, but NOT `drive` nodes
+ valid_children: ["default", "folder"],
+ icon: {
+ image: "../reference/jquery-plugins/jstree-v.pre1.0/themes/ic_explorer.png"
+ }
+ },
+ // The `drive` nodes
+ drive: {
+ // can have files and folders inside, but NOT other `drive` nodes
+ valid_children: ["default", "folder"],
+ icon: {
+ image: "../reference/jquery-plugins/jstree-v.pre1.0/themes/home.png"
+ },
+ // those prevent the functions with the same name to be used on `drive` nodes
+ // internally the `before` event is used
+ start_drag: false,
+ move_node: false,
+ delete_node: false,
+ remove: false
+ }
+ }
+ },
+ // UI & core - the nodes to initially select and open will be overwritten by the cookie plugin
+
+ // the UI plugin - it handles selecting/deselecting/hovering nodes
+ ui: {
+ // this makes the node with ID node_4 selected onload
+ initially_select: ["node_4"]
+ },
+ // the core plugin - not many options here
+ core: {
+ // just open those two nodes up
+ // as this is an AJAX enabled tree, both will be downloaded from the server
+ initially_open: ["node_2", "node_3"]
+ }
+ })
+ .bind("create.jstree", function (e, data) {
+ $.post(
+ serviceNameForURL + "/addNode.do",
+ {
+ ref: data.rslt.parent.attr("id").replace("node_", "").replace("copy_", ""),
+ c_position: data.rslt.position,
+ c_title: data.rslt.name,
+ c_type: data.rslt.obj.attr("rel")
+ },
+ function (r) {
+ if (r.status) {
+ $(data.rslt.obj).attr("id", "node_" + r.id);
+ jNotify("Notification : Add Node , Complete !");
+ } else {
+ $.jstree.rollback(data.rlbk);
+ }
+ $(jQueryElementID).jstree("refresh");
+ }
+ );
+ })
+ .bind("remove.jstree", function (e, data) {
+ data.rslt.obj.each(function () {
+ $.ajax({
+ async: false,
+ type: "POST",
+ url: serviceNameForURL + "/removeNode.do",
+ data: {
+ c_id: this.id.replace("node_", "").replace("copy_", "")
+ },
+ success: function (r) {
+ jNotify("Notification : Remove Node , Complete !");
+ $(jQueryElementID).jstree("refresh");
+ }
+ });
+ });
+ })
+ .bind("rename.jstree", function (e, data) {
+ $.post(
+ serviceNameForURL + "/alterNode.do",
+ {
+ c_id: data.rslt.obj.attr("id").replace("node_", "").replace("copy_", ""),
+ c_title: data.rslt.new_name,
+ c_type: data.rslt.obj.attr("rel")
+ },
+ function (r) {
+ if (!r.status) {
+ $.jstree.rollback(data.rlbk);
+ }
+ jSuccess("Rename Node Complete");
+ $(jQueryElementID).jstree("refresh");
+ }
+ );
+ })
+ .bind("set_type.jstree", function (e, data) {
+ $.post(
+ serviceNameForURL + "/alterNodeType.do",
+ {
+ c_id: data.rslt.obj.attr("id").replace("node_", "").replace("copy_", ""),
+ c_title: data.rslt.new_name,
+ c_type: data.rslt.obj.attr("rel")
+ },
+ function (r) {
+ jSuccess("Node Type Change");
+ $(jQueryElementID).jstree("refresh");
+ }
+ );
+ })
+ .bind("move_node.jstree", function (e, data) {
+ data.rslt.o.each(function (i) {
+ console.log("##### move :::", data);
+ $.ajax({
+ async: false,
+ type: "POST",
+ url: serviceNameForURL + "/moveNode.do",
+ data: {
+ c_id: $(this).attr("id").replace("node_", "").replace("copy_", ""),
+ ref: data.rslt.cr === -1 ? 1 : data.rslt.np.attr("id").replace("node_", "").replace("copy_", ""),
+ c_position: data.rslt.cp + i,
+ c_title: data.rslt.name,
+ copy: data.rslt.cy ? 1 : 0,
+ multiCounter: i
+ },
+ success: function (r) {
+ if (r.status) {
+ $.jstree.rollback(data.rlbk);
+ } else {
+ $(data.rslt.oc).attr("id", "node_" + r.id);
+ if (data.rslt.cy && $(data.rslt.oc).children("UL").length) {
+ data.inst.refresh(data.inst._get_parent(data.rslt.oc));
+ }
+ }
+
+ jNotify("Notification : Move Node Complete !");
+
+ $(jQueryElementID).jstree("refresh");
+ }
+ });
+ });
+ })
+ .bind("select_node.jstree", function (event, data) {
+ // `data.rslt.obj` is the jquery extended node that was clicked
+ if ($.isFunction(jsTreeClick)) {
+ console.log("[ jsTreeBuild :: select_node ] :: data.rslt.obj.data('id')" + data.rslt.obj.attr("id"));
+ console.log("[ jsTreeBuild :: select_node ] :: data.rslt.obj.data('rel')" + data.rslt.obj.attr("rel"));
+ console.log("[ jsTreeBuild :: select_node ] :: data.rslt.obj.data('class')" + data.rslt.obj.attr("class"));
+ console.log("[ jsTreeBuild :: select_node ] :: data.rslt.obj.children('a')" + data.rslt.obj.children("a"));
+ console.log("[ jsTreeBuild :: select_node ] :: data.rslt.obj.children('ul')" + data.rslt.obj.children("ul"));
+ jsTreeClick(data.rslt.obj);
+ }
+ })
+ .bind("loaded.jstree", function (event, data) {
+ // 성능 이슈로 자동으로 전부 펼치기 닫음.
+ // setTimeout(function () {
+ // $(jQueryElementID).jstree("open_all");
+ // }, 1500);
+
+ $(jQueryElementID).slimscroll({
+ height: "545px"
+ });
+ });
+
+ $("#mmenu input, #mmenu button").click(function () {
+ switch (this.id) {
+ case "add_default":
+ case "add_folder":
+ $(jQueryElementID).jstree("create", null, "last", {
+ attr: {
+ rel: this.id.toString().replace("add_", "")
+ }
+ });
+ break;
+ case "search":
+ $(jQueryElementID).jstree("search", document.getElementById("text").value);
+ break;
+ case "text":
+ break;
+ default:
+ $(jQueryElementID).jstree(this.id);
+ break;
+ }
+ });
+
+ $("#mmenu .form-search").submit(function (event) {
+ event.preventDefault();
+
+ $(jQueryElementID).jstree("search", document.getElementById("text").value);
+ });
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// UTIL : 널 체크
+////////////////////////////////////////////////////////////////////////////////////////
+var isEmpty = function (value) {
+ if (
+ typeof value === "undefined" ||
+ value == "" ||
+ value == null ||
+ value == undefined ||
+ (value != null && typeof value == "object" && !Object.keys(value).length)
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+//데이터 테이블
+////////////////////////////////////////////////////////////////////////////////////////
+function dataTable_build(
+ jquerySelector,
+ ajaxUrl,
+ jsonRoot,
+ columnList,
+ rowsGroupList,
+ columnDefList,
+ selectList,
+ orderList,
+ buttonList,
+ isServerSide,
+ scrollY,
+ data,
+ isAjax = true
+) {
+ var jQueryElementID = jquerySelector;
+ var reg = /[\{\}\[\]\/?.,;:|\)*~`!^\-_+<>@\#$%&\\\=\(\'\"]/gi;
+ var jQueryElementStr = jQueryElementID.replace(reg, "");
+
+ var responsiveRender = {
+ details: {
+ renderer: function (api, rowIdx, columns) {
+ var outer = "";
+ var data = $.map(columns, function (col, i) {
+ return col.hidden
+ ? "" +
+ "
" +
+ col.title +
+ "
" +
+ "
" +
+ col.data +
+ "
" +
+ "
"
+ : "";
+ }).join("");
+ outer += data;
+ outer += " ";
+ data = outer;
+
+ return data ? $("").append(data) : false;
+ }
+ }
+ };
+
+ console.log("[ common :: dataTableBuild ] :: jQueryElementStr → " + jQueryElementStr);
+ console.log("[ common :: dataTableBuild ] :: jQueryElementID → " + jQueryElementID);
+ console.log("[ common :: dataTableBuild ] :: columnList → " + columnList);
+ console.log("[ common :: dataTableBuild ] :: rowsGroupList → " + rowsGroupList);
+ console.log("[ common :: dataTableBuild ] :: href → " + $(location).attr("href"));
+ console.log("[ common :: dataTableBuild ] :: protocol → " + $(location).attr("protocol"));
+ console.log("[ common :: dataTableBuild ] :: host → " + $(location).attr("host"));
+ console.log("[ common :: dataTableBuild ] :: pathname → " + $(location).attr("pathname"));
+ console.log("[ common :: dataTableBuild ] :: search → " + $(location).attr("search"));
+ console.log("[ common :: dataTableBuild ] :: hostname → " + $(location).attr("hostname"));
+ console.log("[ common :: dataTableBuild ] :: port → " + $(location).attr("port"));
+ console.log("[ common :: dataTableBuild ] :: ajaxUrl → " + ajaxUrl);
+
+ var options = {
+ serverSide: isServerSide,
+ stateSave: false,
+ stateDuration: -1,
+ destroy: true,
+ processing: true,
+ responsive: false,
+ columns: columnList,
+ rowsGroup: rowsGroupList,
+ columnDefs: columnDefList,
+ select: selectList,
+ order: orderList,
+ buttons: buttonList,
+ scrollX: true,
+ scrollY: scrollY,
+ // lengthMenu: [[3, 5, 7, 10], [3, 5, 7, 10]],
+ language: {
+ processing: "",
+ loadingRecords:
+ ' 데이터를 처리 중입니다. '
+ },
+ initComplete: function (settings, json) {
+ console.log("dataTableBuild :: drawCallmakeSlimScrollback");
+ if ($.isFunction(dataTableCallBack)) {
+ //데이터 테이블 그리고 난 후 시퀀스 이벤트
+ dataTableCallBack(settings, json);
+ }
+ },
+ drawCallback: function (tableInfo) {
+ console.log("dataTableBuild :: drawCallback");
+ if ($.isFunction(dataTableDrawCallback)) {
+ //데이터 테이블 그리고 난 후 시퀀스 이벤트
+ dataTableDrawCallback(tableInfo);
+ }
+ }
+ };
+
+ if (isAjax) {
+ options.ajax = {
+ url: ajaxUrl,
+ dataSrc: jsonRoot
+ };
+ } else {
+ options.data = data;
+ }
+
+ var tempDataTable = $(jQueryElementID).DataTable(options);
+
+ /*var tempDataTable = $(jQueryElementID).DataTable({
+ ajax: {
+ url: ajaxUrl,
+ dataSrc: jsonRoot
+ },
+ serverSide: isServerSide,
+ stateSave: false,
+ stateDuration: -1,
+ destroy: true,
+ processing: true,
+ responsive: false,
+ columns: columnList,
+ rowsGroup: rowsGroupList,
+ columnDefs: columnDefList,
+ select: selectList,
+ order: orderList,
+ buttons: buttonList,
+ scrollX: true,
+ scrollY: scrollY,
+ language: {
+ processing: "",
+ loadingRecords:
+ ' 데이터를 처리 중입니다. '
+ },
+ initComplete: function (settings, json) {
+ console.log("dataTableBuild :: drawCallmakeSlimScrollback");
+ if ($.isFunction(dataTableCallBack)) {
+ //데이터 테이블 그리고 난 후 시퀀스 이벤트
+ dataTableCallBack(settings, json);
+ }
+ },
+ drawCallback: function (tableInfo) {
+ console.log("dataTableBuild :: drawCallback");
+ if ($.isFunction(dataTableDrawCallback)) {
+ //데이터 테이블 그리고 난 후 시퀀스 이벤트
+ dataTableDrawCallback(tableInfo);
+ }
+ }
+ });*/
+
+ $(jQueryElementID + " tbody").on("click", "tr", function () {
+ if ($(this).hasClass("selected")) {
+ $(this).removeClass("selected");
+ } else {
+ tempDataTable.$("tr.selected").removeClass("selected");
+ $(this).addClass("selected");
+ }
+
+ var selectedData = tempDataTable.row(this).data();
+ selectedData.selectedIndex = $(this).closest("tr").index();
+
+ var info = tempDataTable.page.info();
+ selectedData.selectedPage = info.page;
+
+ dataTableClick(tempDataTable, selectedData);
+ });
+
+ // ----- 데이터 테이블 빌드 이후 스타일 구성 ------ //
+ //datatable 좌상단 datarow combobox style
+ $(".dataTables_length").find("select:eq(0)").addClass("darkBack");
+ $(".dataTables_length").find("select:eq(0)").css("min-height", "30px");
+ //min-height: 30px;
+
+ // ----- 데이터 테이블 빌드 이후 별도 스타일 구성 ------ //
+ //datatable 좌상단 datarow combobox style
+ $("body")
+ .find("[aria-controls='" + jQueryElementStr + "']")
+ .css("width", "50px");
+ $(".dataTables_filter input[type=search]").css("width", "100px");
+ $("select[name=" + jQueryElementStr + "]").css("width", "50px");
+
+ $.fn.dataTable.ext.errMode = function (settings, helpPage, message) {
+ console.log(message);
+ jError("Notification : Ajax Error , retry plz !");
+ };
+
+ return tempDataTable;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+//공통 AJAX setup 처리
+////////////////////////////////////////////////////////////////////////////////////////
+function ajax_setup() {
+ $(document)
+ .ajaxStart(function () {
+ $(".loader").removeClass("hide");
+ })
+ .ajaxSend(function (event, jqXHR, ajaxOptions) {
+ //$(".loader").addClass("hide");
+ })
+ .ajaxSuccess(function (event, jqXHR, ajaxOptions, data) {
+ //$(".loader").addClass("hide");
+ })
+ .ajaxError(function (event, jqXHR, ajaxSettings, thrownError) {
+ $(".loader").addClass("hide");
+ if (jqXHR.status == 401) {
+ jError("클라이언트가 인증되지 않았거나, 유효한 인증 정보가 부족하여 요청이 거부되었습니다.", {
+ /**
+ * [options]
+ * autoHide / Boolean Default : true - jNotify closed after TimeShown ms or by clicking on it
+ * clickOverlay / Boolean Default : false - If false, disables closing jNotify by clicking on the background overlay.
+ * MinWidth / Integer Default : 200 - In pixel, the min-width css property of the boxes.
+ * TimeShown / Integer Default : 1500 - In ms, time of the boxes appearances.
+ * ShowTimeEffect / Integer Default : 200 - In ms, duration of the Show effect
+ * HideTimeEffect / Integer Default : 200 - In ms, duration of the Hide effect
+ * LongTrip / Integer Default : 15 - Length of the move effect ('top' and 'bottom' verticals positions only)
+ * HorizontalPosition / String Default : right - Horizontal position. Can be set to 'left', 'center', 'right'
+ * VerticalPosition / String Default : top - Vertical position. Can be set to 'top', 'center', 'bottom'.
+ * ShowOverlay / Boolean Default : true - If true, a background overlay appears behind the jNotify boxes
+ * ColorOverlay / String Default : #000 - Color of the overlay background (only Hex. color code)
+ * OpacityOverlay / Integer Default : 0.3 - Opacity CSS property of the overlay background. From 0 to 1 max.
+ */
+ autoHide: true, // added in v2.0
+ TimeShown: 3000,
+ HorizontalPosition: "center",
+ VerticalPosition: "top"
+ // onCompleted : function(){ // added in v2.0
+ // alert('jNofity is completed !');
+ // }
+ });
+ location.href = "/oauth2/authorization/middle-proxy";
+ } else if (jqXHR.status == 403) {
+ jError("서버가 해당 요청을 이해했지만, 권한이 없어 요청이 거부되었습니다.", {
+ /**
+ * [options]
+ * autoHide / Boolean Default : true - jNotify closed after TimeShown ms or by clicking on it
+ * clickOverlay / Boolean Default : false - If false, disables closing jNotify by clicking on the background overlay.
+ * MinWidth / Integer Default : 200 - In pixel, the min-width css property of the boxes.
+ * TimeShown / Integer Default : 1500 - In ms, time of the boxes appearances.
+ * ShowTimeEffect / Integer Default : 200 - In ms, duration of the Show effect
+ * HideTimeEffect / Integer Default : 200 - In ms, duration of the Hide effect
+ * LongTrip / Integer Default : 15 - Length of the move effect ('top' and 'bottom' verticals positions only)
+ * HorizontalPosition / String Default : right - Horizontal position. Can be set to 'left', 'center', 'right'
+ * VerticalPosition / String Default : top - Vertical position. Can be set to 'top', 'center', 'bottom'.
+ * ShowOverlay / Boolean Default : true - If true, a background overlay appears behind the jNotify boxes
+ * ColorOverlay / String Default : #000 - Color of the overlay background (only Hex. color code)
+ * OpacityOverlay / Integer Default : 0.3 - Opacity CSS property of the overlay background. From 0 to 1 max.
+ */
+ autoHide: true, // added in v2.0
+ TimeShown: 3000,
+ HorizontalPosition: "center",
+ VerticalPosition: "top"
+ // onCompleted : function(){ // added in v2.0
+ // alert('jNofity is completed !');
+ // }
+ });
+ location.href = "/oauth2/authorization/middle-proxy";
+ } else if (jqXHR.status == 500) {
+ jError("서버가 해당 요청을 이해했지만, 실행 할 수 없습니다.");
+ }
+ })
+ .ajaxComplete(function (event, jqXHR, ajaxOptions) {
+ Ladda.stopAll();
+ })
+ .ajaxStop(function () {
+ $(".loader").addClass("hide");
+ });
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+//공통 AJAX SAMPLE
+////////////////////////////////////////////////////////////////////////////////////////
+function ajax_sample() {
+ $.ajax({
+ url: "요청을 보낼 URL",
+ type: "요청 type(GET 혹은 POST)을 명시",
+ data: "서버로 보내지는 데이터",
+ contentType: "서버로 보내지는 데이터의 content-type, 기본값은 application/x-www-form-urlencoded",
+ dataType: "서버 응답으로 받는 데이터 타입",
+ statusCode: {
+ 200: function (data) {
+ //////////////////////////////////////////////////////////
+ console.log("ajax_build :: url = " + ajaxUrl);
+ for (var key in data) {
+ var value = data[key];
+ console.log(key + "=" + value);
+ }
+
+ var loopCount = 3;
+ for (var i = 0; i < loopCount; i++) {
+ console.log("loop check i = " + i);
+ }
+ //////////////////////////////////////////////////////////
+ jSuccess("신규 제품 등록이 완료 되었습니다.");
+ }
+ },
+ beforeSend: function () {
+ //$("#regist_pdservice").hide(); 버튼 감추기
+ },
+ complete: function () {
+ //$("#regist_pdservice").show(); 버튼 보이기
+ },
+ error: function (e) {
+ jError("신규 제품 등록 중 에러가 발생했습니다.");
+ }
+ });
+}
+
+//데이터 테이블 하위에 상세 리스트 보이는거 지우기
+function hideDetail_Datagrid() {
+ $("#hostTable")
+ .DataTable()
+ .rows()
+ .every(function () {
+ // If row has details expanded
+ if (this.child.isShown()) {
+ // Collapse row details
+ this.child.hide();
+ $(this.node()).removeClass("shown");
+ }
+ });
+}
+
+//////////////////////////////////////////
+// 페이지 이동 처리
+//////////////////////////////////////////
+function goToTemplatePage(pageName) {
+ let current_page = getPageName(this.location.search);
+ console.log("[common :: goToTemplatePage] :: current_page => " + current_page);
+ if(current_page === "searchEngine") {
+ console.log("[common :: goToTemplatePage] :: 검색페이지");
+ } else {
+ console.log("[common :: goToTemplatePage] :: pageName => " + pageName);
+ window.location.href = "template.html?page=" + pageName;
+ }
+}
+
+//////////////////////////////////////////
+// 검색어 포함 페이지 이동 처리
+//////////////////////////////////////////
+function goToTemplatePageWithSearchString(pageName, searchString) {
+ console.log("[common :: goToTemplatePageWithSearchString] :: pageName => " + pageName+", 검색어 => " + searchString);
+ let current_page = getPageName(this.location.search);
+
+ if(current_page === "searchEngine") {
+ console.log("[common :: goToTemplatePageWithSearchString] :: current_page => " + current_page);
+ console.log("[common :: goToTemplatePageWithSearchString] :: 검색페이지");
+ $("#search-input").val(searchString);
+ $("#search-button").click();
+ } else {
+ console.log("[common :: goToTemplatePageWithSearchString] :: 검색어와 함께 페이지 이동");
+ window.location.href = "/arms/template.html?page=" + pageName+"&searchString="+searchString;
+ }
+}
+
+function laddaBtnSetting(라따적용_클래스이름_배열) {
+ for (i = 0; i < 라따적용_클래스이름_배열.length; i++) {
+ // add css
+ $(라따적용_클래스이름_배열[i]).addClass("ladda-button");
+
+ // Bind progress buttons and simulate loading progress
+ Ladda.bind(라따적용_클래스이름_배열[i], {
+ callback: function (instance) {
+ var progress = 0;
+ var interval = setInterval(function () {
+ progress = Math.min(progress + 0.1, 1);
+ instance.setProgress(progress);
+
+ if (progress === 1) {
+ instance.stop();
+ clearInterval(interval);
+ }
+ }, 250);
+ }
+ });
+ }
+}
+
+class UrlBuilder {
+ constructor() {
+ this.baseUrl = "";
+ this.queryParams = {};
+ }
+
+ setBaseUrl(url) {
+ this.baseUrl = url;
+ return this;
+ }
+
+ addQueryParam(key, value) {
+ this.queryParams[key] = value;
+ return this;
+ }
+
+ build() {
+ const queryString = new URLSearchParams(this.queryParams).toString();
+ return `${this.baseUrl}?${queryString}`;
+ }
+}
+
+function getCookie(cname) {
+ var name = cname + "=";
+ var decodedCookie = decodeURIComponent(document.cookie);
+ var ca = decodedCookie.split(";");
+ for (var i = 0; i < ca.length; i++) {
+ var c = ca[i];
+ while (c.charAt(0) == " ") {
+ c = c.substring(1);
+ }
+ if (c.indexOf(name) == 0) {
+ return c.substring(name.length, c.length);
+ }
+ }
+ return "";
+}
+
+/////////////////////////////////
+//투어가이드모드 쿠키 - 가져오기
+/////////////////////////////////
+function getTourGuideMode() {
+ let tourGuideMode = getCookie("tourGuideMode");
+ if (tourGuideMode) {
+ return tourGuideMode;
+ } else {
+ //쿠키가 없을 때, "on"으로 체크
+ setTourGuideMode("on");
+ return getCookie("tourGuideMode");
+ }
+}
+
+/////////////////////////////////
+//투어가이드 쿠키 저장/수정
+/////////////////////////////////
+function setTourGuideMode(mode) {
+ console.log("[ common :: setTourGuideMode ] :: mode → " + mode);
+ $.cookie("tourGuideMode", mode, { expires: 7 });
+ return mode;
+}
+
+function tourGuideStart() {
+ let pageName = getPageName(this.location.search);
+ console.log("[ common :: tourGuideStart ] :: pageName → " + pageName);
+ let tg = TourGuideApi.makeInstance(pageName);
+ tg.start();
+}
+
+function checkTourGuideMode() {
+ let tourGuideMode = getTourGuideMode();
+
+ if (!checkMobileDevice()) {
+ if (tourGuideMode === "off") {
+ console.log("common :: checkTourGuideMode : tourGuideMode is Off");
+ } else {
+ //mode 가 없거나 on 일때
+ console.log("common :: checkTourGuideMode : tourGuideMode is On");
+ setTourGuideMode("on");
+ setTimeout(function () {
+ tourGuideStart();
+ }, 1200);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+//톱니바퀴(config) 투어가이드 이벤트리스너
+////////////////////////////////////////////////////////////////////////////////////////
+function tourGuideEventListener() {
+ console.log("common :: tourGuideEventListener : tourGuideEventListener 시작");
+ let tgm = getCookie("tourGuideMode");
+ if (tgm === "off") {
+ $("#tourGuideButtons #tour_guide_off").addClass("active");
+ } else {
+ $("#tourGuideButtons #tour_guide_on").addClass("active");
+ }
+
+ $("#tourGuideButtons button").click(function () {
+ let $active_label = $(this).text().toLowerCase();
+ console.log($active_label);
+ if ($active_label === "on") {
+ setTourGuideMode("on");
+ } else {
+ setTourGuideMode("off");
+ }
+ });
+}
+
+function getPageName() {
+ const queryString = location.search;
+ const params = new URLSearchParams(queryString);
+ const page = params.get("page");
+
+ if (!isEmpty(page)) { // page param의 위치
+ return page;
+ }
+ return "페이지 이름 없음"; //페이지 이름이 없을 경우.
+}
+
+////////////////////////////////////////////////////////////////////////
+// 모바일 디바이스인지 확인
+////////////////////////////////////////////////////////////////////////
+function checkMobileDevice() {
+ // 모바일 기기에서 접근했는지 확인
+ const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
+ console.log("[ common :: checkMobileDevice] isMobile → " + isMobile);
+ return isMobile;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 헤더 :: 톱니바퀴 대응함수
+////////////////////////////////////////////////////////////////////////////////////////
+function 톱니바퀴_초기설정() {
+ //settings
+ var $settings = $("#settings"),
+ $sidebarSettings = $("#sidebar-settings"),
+ settingsState = {
+ sidebar: "left",
+ sidebarState: "auto",
+ displaySidebar: true
+ },
+ $pageHeader = $(".page-header"),
+ $body = $("body"),
+ popoverReallyHide = function () {
+ $settings.data("bs.popover").hoverState = "out"; //yeah. cool BS3 fix. popover programmatic APi works only on HOVER
+ $settings.popover("hide");
+ },
+ popoverClose = function (e) {
+ var $popover = $settings.siblings(".popover");
+ if ($popover.length && !$.contains($popover[0], e.target)) {
+ popoverReallyHide();
+ $(document).off("click", popoverClose);
+ }
+ },
+ sidebarSide = function (side) {
+ if (side == "right") {
+ $body.addClass("sidebar-on-right");
+ } else {
+ $body.removeClass("sidebar-on-right");
+ }
+ },
+ sidebarState = function (state, triggerResize) {
+ var $template = $("#sidebar-settings-template");
+ triggerResize = triggerResize == undefined ? true : false;
+ if (!$template[0]) {
+ return;
+ }
+ $sidebarSettings.html(_.template($template.html())({ sidebarState: state }));
+ if (state == "auto") {
+ $(".sidebar, .side-nav, .wrap, .logo").removeClass("sidebar-icons");
+ } else {
+ $(".sidebar, .side-nav, .wrap, .logo").addClass("sidebar-icons");
+ }
+ if (triggerResize) {
+ triggerChartsResize();
+ }
+ },
+ displaySidebar = function (display, triggerResize) {
+ triggerResize = triggerResize == undefined ? true : false;
+ if (display == true) {
+ $body.removeClass("sidebar-hidden");
+ } else {
+ $body.addClass("sidebar-hidden");
+ }
+ if (triggerResize) {
+ triggerChartsResize();
+ }
+ };
+
+ sidebarSide(settingsState.sidebar);
+ sidebarState(settingsState.sidebarState, false);
+ displaySidebar(settingsState.displaySidebar, false);
+
+ if (!$settings[0]) {
+ return;
+ }
+
+ $settings
+ .popover({
+ template:
+ '",
+ html: true,
+ animation: false,
+ placement: "bottom",
+ content: function () {
+ if (typeof _ === "undefined") {
+ return "미지원";
+ }
+ return _.template($("#settings-template").html())(settingsState);
+ }
+ })
+ .click(function (e) {
+ //close all open dropdowns
+ $(".page-header .dropdown.open .dropdown-toggle").dropdown("toggle");
+ // need to remove popover on anywhere-click
+ $(document).on("click", popoverClose);
+ $(this).focus();
+ tourGuideEventListener(); // 투어가이드 이벤트리스너 설정.
+ return false;
+ });
+
+ $(".page-header .dropdown-toggle").click(function () {
+ popoverReallyHide();
+ $(document).off("click", popoverClose);
+ });
+ //sidevar left/right
+ $pageHeader.on("click", ".popover #sidebar-toggle .btn", function () {
+ var $this = $(this),
+ side = $this.data("value");
+ sidebarSide(side);
+ settingsState.sidebar = side;
+ localStorage.setItem("settings-state", JSON.stringify(settingsState));
+ });
+
+ //sidebar visibility
+ $pageHeader.on("click", ".popover #display-sidebar-toggle .btn", function () {
+ var $this = $(this),
+ display = $this.data("value");
+ displaySidebar(display);
+ settingsState.displaySidebar = display;
+ localStorage.setItem("settings-state", JSON.stringify(settingsState));
+ });
+
+ //sidebar state {active, icons}
+ $sidebarSettings.on("click", ".btn", function () {
+ var $this = $(this),
+ state = $this.data("value");
+ if (state == "icons") {
+ closeNavigation();
+ }
+ sidebarState(state);
+ settingsState.sidebarState = state;
+ localStorage.setItem("settings-state", JSON.stringify(settingsState));
+ });
+
+ //close navigation if sidebar in icons state
+ if (($("#sidebar").is(".sidebar-icons") || $(window).width() < 1049) && $(window).width() > 767) {
+ closeNavigation();
+ }
+
+ //imitate buttons radio behavior
+ $pageHeader.on("click", ".popover [data-toggle='buttons-radio'] .btn:not(.active)", function () {
+ var $this = $(this),
+ $buttons = $this.parent().find(".btn");
+ $buttons.removeClass("active");
+ setTimeout(function () {
+ $this.addClass("active");
+ }, 0);
+ });
+}
+
+/**
+ * A global object containing theme specific colors, screen variables & color functions.
+ * @type Object
+ */
+window.LightBlue = {
+ screens: {
+ "xs-max": 767,
+ "sm-min": 768,
+ "sm-max": 991,
+ "md-min": 992,
+ "md-max": 1199,
+ "lg-min": 1200
+ },
+
+ isScreen: function (size) {
+ var screenPx = window.innerWidth;
+ return (
+ (screenPx >= this.screens[size + "-min"] || size == "xs") &&
+ (screenPx <= this.screens[size + "-max"] || size == "lg")
+ );
+ },
+
+ getScreenSize: function () {
+ var screenPx = window.innerWidth;
+ if (screenPx <= this.screens["xs-max"]) return "xs";
+ if (screenPx >= this.screens["sm-min"] && screenPx <= this.screens["sm-max"]) return "sm";
+ if (screenPx >= this.screens["md-min"] && screenPx <= this.screens["md-max"]) return "md";
+ if (screenPx >= this.screens["lg-min"]) return "lg";
+ },
+
+ //credit http://stackoverflow.com/questions/1507931/generate-lighter-darker-color-in-css-using-javascript
+ changeColor: function (color, ratio, darker) {
+ var pad = function (num, totalChars) {
+ var pad = "0";
+ num = num + "";
+ while (num.length < totalChars) {
+ num = pad + num;
+ }
+ return num;
+ };
+ // Trim trailing/leading whitespace
+ color = color.replace(/^\s*|\s*$/, "");
+
+ // Expand three-digit hex
+ color = color.replace(/^#?([a-f0-9])([a-f0-9])([a-f0-9])$/i, "#$1$1$2$2$3$3");
+
+ // Calculate ratio
+ var difference = Math.round(ratio * 256) * (darker ? -1 : 1),
+ // Determine if input is RGB(A)
+ rgb = color.match(
+ new RegExp(
+ "^rgba?\\(\\s*" +
+ "(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])" +
+ "\\s*,\\s*" +
+ "(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])" +
+ "\\s*,\\s*" +
+ "(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])" +
+ "(?:\\s*,\\s*" +
+ "(0|1|0?\\.\\d+))?" +
+ "\\s*\\)$",
+ "i"
+ )
+ ),
+ alpha = !!rgb && rgb[4] != null ? rgb[4] : null,
+ // Convert hex to decimal
+ decimal = !!rgb
+ ? [rgb[1], rgb[2], rgb[3]]
+ : color
+ .replace(/^#?([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])/i, function () {
+ return parseInt(arguments[1], 16) + "," + parseInt(arguments[2], 16) + "," + parseInt(arguments[3], 16);
+ })
+ .split(/,/),
+ returnValue;
+
+ // Return RGB(A)
+ return !!rgb
+ ? "rgb" +
+ (alpha !== null ? "a" : "") +
+ "(" +
+ Math[darker ? "max" : "min"](parseInt(decimal[0], 10) + difference, darker ? 0 : 255) +
+ ", " +
+ Math[darker ? "max" : "min"](parseInt(decimal[1], 10) + difference, darker ? 0 : 255) +
+ ", " +
+ Math[darker ? "max" : "min"](parseInt(decimal[2], 10) + difference, darker ? 0 : 255) +
+ (alpha !== null ? ", " + alpha : "") +
+ ")"
+ : // Return hex
+ [
+ "#",
+ pad(Math[darker ? "max" : "min"](parseInt(decimal[0], 10) + difference, darker ? 0 : 255).toString(16), 2),
+ pad(Math[darker ? "max" : "min"](parseInt(decimal[1], 10) + difference, darker ? 0 : 255).toString(16), 2),
+ pad(Math[darker ? "max" : "min"](parseInt(decimal[2], 10) + difference, darker ? 0 : 255).toString(16), 2)
+ ].join("");
+ },
+ lighten: function (color, ratio) {
+ return this.changeColor(color, ratio, false);
+ },
+ darken: function (color, ratio) {
+ return this.changeColor(color, ratio, true);
+ }
+};
+function triggerChartsResize() {
+ try {
+ if (window.onresize) {
+ window.onresize();
+ }
+ } catch (e) {
+ //just swallow it
+ }
+ $(window).trigger("resize");
+}
+
+function targetLink(path) {
+ const params = {};
+
+ window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi, (str, key, value) => {
+ if (!isEmpty(path) && key === "page") {
+ params[key] = path;
+ } else {
+ params[key] = value;
+ }
+ });
+ params["mode"] = "detail";
+
+ location.href = `/arms/detail.html?${new URLSearchParams(params).toString()}`;
+}
+
+function gnuboardLink(bo_table) {
+ const params = {};
+
+ window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi, (str, key, value) => {
+ if (!isEmpty(bo_table) && key === "page") {
+ params[key] = "index";
+ } else {
+ if (key == "wr_id") {
+ console.log("skip");
+ } else {
+ params[key] = value;
+ }
+ }
+ });
+
+ delete params["wr_id"];
+ params["bo_table"] = bo_table;
+ params["mode"] = "detail";
+
+ location.href = `/php/gnuboard5/bbs/board.php?${new URLSearchParams(params).toString()}`;
+}
+
+function gnuboardList(param) {
+ const params = {};
+ var userMode = false;
+ window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi, (str, key, value) => {
+ if (key == "mode") {
+ if (value == "detail") {
+ userMode = true;
+ }
+ }
+ params[key] = value;
+ });
+
+ if (userMode) {
+ params["mode"] = "detail";
+ location.href = param + `&${new URLSearchParams(params).toString()}`;
+ } else {
+ location.href = param;
+ }
+}
+
+function gnuboardIndex() {
+ const params = {};
+
+ window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi, (str, key, value) => {
+ if (key == "wr_id") {
+ console.log("skip");
+ } else {
+ params[key] = value;
+ }
+ });
+ params["page"] = "index";
+ params["mode"] = "detail";
+
+ location.href = `/php/gnuboard5/index.php?${new URLSearchParams(params).toString()}`;
+}
+////////////////////////////////////////////////////////////////////////////////////////
+// 국제화 설정
+////////////////////////////////////////////////////////////////////////////////////////
+function loadLocale() {
+ const locale = getCookie("locale");
+ changeLocale(locale || "ko");
+}
+
+function changeLocale(locale) {
+ const allowedLocale = ["ko", "jp", "en"];
+ const selectedLocale = allowedLocale.includes(locale) ? locale : "ko";
+ const $localeMenu = $(".locale-menu");
+ $localeMenu.find(".locale-item").removeClass("active");
+ $localeMenu.find(".locale-selector[data-key=" + selectedLocale + "]").closest(".locale-item").addClass("active");
+ setCookie("locale", selectedLocale, 365);
+ setLocale(selectedLocale);
+}
+
+function setLocale(locale = "ko") {
+ $.ajax({
+ url: `/arms/locales/${locale}.json`,
+ async: false,
+ dataType: "json"
+ }).done(function (data) {
+ bindLocaleText(flattenObject(data));
+ });
+}
+
+function bindLocaleText(locales) {
+ const targets = document.querySelectorAll("[data-locale]");
+
+ targets.forEach((tag) => {
+ const content = locales[tag.dataset.locale];
+ if (content === undefined) {
+ console.warn("해당 키에 대한 국제화 문자열이 없습니다.", tag.dataset.locale);
+ return;
+ }
+ if (isIncludeHTMLTag(content)) {
+ tag.innerHTML = sanitizeHTML(content);
+ } else {
+ tag.textContent = content;
+ }
+ });
+}
+
+function isIncludeHTMLTag(content) {
+ return /<\/?[a-z][\s\S]*>/i.test(content);
+}
+
+function sanitizeHTML(content) {
+ const allowedTags = ['span', 'small', 'strong', 'p', 'b', 'ul', 'li', 'br'];
+ return content.replace(/<(\w+)[^>]*>|<\/(\w+)>/g, (match, openTag, closeTag) => {
+ const tagName = (openTag || closeTag).toLowerCase();
+ if (allowedTags.includes(tagName)) {
+ return match.replace(/ on\w+="[^"]*"| on\w+='[^']*'/g, ''); // 이벤트 핸들러 속성 제거
+ }
+ return ''; // 허용되지 않은 태그 제거
+ });
+}
+
+function flattenObject(obj, parentKey) {
+ let result = {};
+
+ Object.entries(obj).forEach(([key, value]) => {
+ const _key = parentKey ? parentKey + "." + key : key;
+ if (typeof value === "object") {
+ result = { ...result, ...flattenObject(value, _key) };
+ } else {
+ result[_key] = value;
+ }
+ });
+
+ return result;
+}
+
+/////////////////////////////////////
+// 쿠키 설정
+/////////////////////////////////////
+function setCookie(name, value, exp = 1) {
+ const path = "/arms";
+ const date = new Date();
+ date.setTime(date.getTime() + exp * 24 * 60 * 60 * 1000);
+ document.cookie = `${name}=${value};expires=${date.toUTCString()};path=${path}`;
+}
+
+/////////////////////////////////////
+// 검색_이벤트_트리거
+/////////////////////////////////////
+function 검색_이벤트_트리거() {
+ $("#nav-search-input").on("focus", function(event) {
+ $("#nav-search-button").addClass("highlight");
+ });
+
+ $("#nav-search-input").on("blur", function(event) {
+ $("#nav-search-button").removeClass("highlight");
+ });
+ // nav 검색창
+ $("#search_form").on("submit", function (event) {
+ event.preventDefault();
+
+ let 검색어 = $("#nav-search-input").val().trim();
+ if (검색어) {
+ console.log("[page-header :: nav-search-start] :: 검색어 입력 값 => " + 검색어);
+ setParameter("searchString", 검색어);
+ goToTemplatePageWithSearchString("searchEngine", 검색어);
+ } else {
+ console.log("[page-header :: nav-search-start] :: 검색어가 없습니다. 검색페이지로 이동합니다");
+ goToTemplatePage("searchEngine");
+ }
+ });
+
+ $("#nav-search-button").on("click", function (event) {
+ $("#search_form").trigger("submit");
+ });
+}
+
+/////////////////////////////////////////////
+// URL 파라미터값 찾기
+/////////////////////////////////////////////
+function getParameter(param) {
+ param = param.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+ let regex = new RegExp("[\\?&]" + param + "=([^]*)"),
+ results = regex.exec(location.search);
+ return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
+}
+
+/////////////////////////////////////////////
+// URL 파라미터값 수정
+/////////////////////////////////////////////
+function setParameter(param, value) {
+ var url = new URL(window.location.href);
+ url.searchParams.set(param, value);
+ // Replace the currnt URL without reloading the page
+ window.history.pushState({path:url.href}, '', url.href);
+}
\ No newline at end of file
Index: controltower/js/common/colorPalette.js
===================================================================
diff -u
--- controltower/js/common/colorPalette.js (revision 0)
+++ controltower/js/common/colorPalette.js (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,147 @@
+colorPalette = {
+ colorPalette0: {
+ timeline: ["#FF8360", "#F4B374", "#E8E288", "#B3D885", "#7DCE82", "#5DD5AB", "#3CDBD3", "#1EEDE4", "#00FFF5"],
+ treeMap: ["#FF8360", "#F4B374", "#E8E288", "#B3D885", "#7DCE82", "#5DD5AB", "#3CDBD3", "#1EEDE4", "#00FFF5"]
+ },
+ colorPalette1: {
+ timeline: [
+ "#8EDF8A",
+ "#3ABAA1",
+ "#2C919D",
+ "rgba(7,202,209,0.7)",
+ "rgba(89,173,246,0.7)",
+ "rgba(156,148,255,0.7)",
+ "#A1AACE"
+ ],
+ treeMap: [
+ "rgba(142,223,138,0.9)",
+ "rgba(58,186,161,0.9)",
+ "rgba(44,145,157,0.9)",
+ "rgba(7,202,209,0.7)",
+ "rgba(89,173,246,0.7)",
+ "rgba(156,148,255,0.7)",
+ "#A1AACE"
+ ]
+ },
+ colorPalette2: {
+ timeline: ["#A3CEF1", "#879CB3", "#447199", "#E7ECEF", "#82B2D6", "#6096BA", "#274C77", "#97ADBD", "#8B8C89"],
+ treeMap: ["#A3CEF1", "#879CB3", "#447199", "#E7ECEF", "#82B2D6", "#6096BA", "#274C77", "#97ADBD", "#8B8C89"]
+ },
+ colorPalette3: {
+ timeline: [
+ "rgba(227,26,27,0.66)",
+ "rgba(55,125,184,0.62)",
+ "rgba(77,175,74,0.65)",
+ "rgba(255,127,0,0.7)",
+ "rgba(255,255,51,0.71)",
+ "rgba(151,78,163,0.73)",
+ "rgba(166,86,40,0.7)"
+ ],
+ treeMap: [
+ "rgba(227,26,27,0.66)",
+ "rgba(55,125,184,0.62)",
+ "rgba(77,175,74,0.65)",
+ "rgba(255,127,0,0.7)",
+ "rgba(255,255,51,0.71)",
+ "rgba(151,78,163,0.73)",
+ "rgba(166,86,40,0.7)"
+ ]
+ },
+ colorPalette4: {
+ timeline: ["#C6DEA6", "#A2CEB5", "#7EBDC3", "#A6C7AD", "#CED097", "#ACAE85", "#898C73", "#676A61"],
+ treeMap: ["#C6DEA6", "#A2CEB5", "#7EBDC3", "#A6C7AD", "#CED097", "#ACAE85", "#898C73", "#676A61"]
+ },
+
+ colorPalette5: {
+ timeline: ["#22AED1", "#5BB3C8", "#93B7BE", "#6C7F86", "#9F7832", "#FAA916", "#8DD353", "#20FC8F"],
+ treeMap: ["#22AED1", "#5BB3C8", "#93B7BE", "#6C7F86", "#9F7832", "#FAA916", "#8DD353", "#20FC8F"]
+ },
+ colorPalette6: {
+ timeline: ["#58636A", "#6C7F86", "#809BA2", "#93B7BE", "#77B5C3", "#5BB3C8", "#3FB1CD", "#22AED1"],
+ treeMap: ["#58636A", "#6C7F86", "#809BA2", "#93B7BE", "#77B5C3", "#5BB3C8", "#3FB1CD", "#22AED1"]
+ },
+ colorPalette7: {
+ timeline: ["#626277", "#766C86", "#8C7693", "#A4809E", "#BD89A5", "#6D5054", "#D09EA5"],
+ treeMap: ["#626277", "#766C86", "#8C7693", "#A4809E", "#BD89A5", "#6D5054", "#D09EA5"]
+ }
+};
+
+var dashboardPalette = {
+ dashboardPalette01: {
+ projectProgressColor: ["#e49400", "#e47e00", "#e46900", "#e45300", "#e43d00"],
+ appProgressColor: ["#138808", "#e46700", "#3D4049"],
+ statusPerWaveColor: ["#2f3238", "#E49400", "#e47a00", "#e46700", "#e43d00", "#148e08"],
+ inventoryPerWaveColor: ["#55DDE0", "#32658A", "#2F4858", "#F6AE2D", "#F48923", "#f25a19"],
+ strategyPerWaveColor: ["#e49400", "#e47e00", "#e46900", "#e45300", "#e43d00", "#f25a19"],
+ migGroupPerWaveColor: ["#3457D5", "#5D8AA8", "#1F305E"]
+ },
+ dashboardPalette02: {
+ projectProgressColor: [
+ "#E49400",
+ "#B09102",
+ "#7C8E04",
+ "#488B06",
+ "#138808",
+ "#488B06",
+ "#7C8E04",
+ "#B09102",
+ "#E49400"
+ ],
+ appProgressColor: ["#e46700", "#3D4049", "#138808"],
+ statusPerWaveColor: ["#2f3238", "#E49400", "#e47a00", "#e46700", "#e43d00", "#148e08"],
+ inventoryPerWaveColor: ["#182E3D", "#4A8FBD", "#82A5BD", "#5E7788", "#5D8AA8", "#2c5571"],
+ strategyPerWaveColor: ["#e49400", "#e47e00", "#e46900", "#e45300", "#e43d00", "#f25a19"],
+ migGroupPerWaveColor: ["#3457D5", "#5D8AA8", "#2c5571", "#1F305E"]
+ },
+ dashboardPalette03: {
+ projectProgressColor: ["rgba(55,71,85)", "rgba(200,96,54)"],
+ appProgressColor: ["rgba(55,71,85)", "rgba(200,96,54)", "rgba(87,86,86)"],
+ statusPerWaveColor: [
+ "rgba(87,86,86)",
+ "rgba(200,96,54)",
+ "rgba(170,91,61)",
+ "rgba(130,84,70)",
+ "rgba(90,78,78)",
+ "rgba(55,71,85)"
+ ],
+ inventoryPerWaveColor: [
+ "rgba(55,71,85)",
+ "rgba(74,75,82)",
+ "rgba(90,78,78)",
+ "rgba(109,81,74)",
+ "rgba(149,81,74)",
+ "rgba(200,96,54)"
+ ],
+ strategyPerWaveColor: [
+ "rgba(55,71,85)",
+ "rgba(55,71,85)",
+ "rgba(55,71,85)",
+ "rgba(55,71,85)",
+ "rgba(55,71,85)",
+ "rgba(55,71,85)"
+ ],
+ migGroupPerWaveColor: ["#6886A1", "#3F5161", "#374755", "#26313B"]
+ },
+ dashboardPalette04: {
+ projectProgressColor: [
+ "#E49400",
+ "#B09102",
+ "#7C8E04",
+ "#488B06",
+ "#138808",
+ "#488B06",
+ "#7C8E04",
+ "#B09102",
+ "#E49400"
+ ],
+ appProgressColor: ["#e46700", "#3D4049", "#138808"],
+ statusPerWaveColor: ["#2f3238", "#E49400", "#e47200", "#e45000", "#e44400", "#148e08"],
+ inventoryPerWaveColor: ["#264961", "#4A8FBD", "#82A5BD", "#5E7788", "#5D8AA8", "#2c5571"],
+ inventoryDotColor: "#bfdef3",
+ inventoryDotStrokeColor: "#182E3D",
+ inventoryPathColor: "#182E3D",
+ strategyPerWaveColor: ["#E49400", "#e47200", "#e45000", "#e44400"],
+ strategyPathColor: "#1F305E",
+ migGroupPerWaveColor: ["#3457D5", "#5D8AA8", "#2c5571", "#1F305E"]
+ }
+};
Index: controltower/js/common/dwrChat.js
===================================================================
diff -u
--- controltower/js/common/dwrChat.js (revision 0)
+++ controltower/js/common/dwrChat.js (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,83 @@
+document.write('');
+document.write('');
+document.write('');
+
+const makeSaveChatHistory = () => {
+ const chat_history = [];
+ return (userId, username, message, time) => {
+ chat_history.push({ userId, username, message, time });
+ if (chat_history.length > 10) {
+ chat_history.shift(); // 첫 번째 요소 제거 (가장 오래된 메시지)
+ }
+ console.log("chatHistory -> " + JSON.stringify(chat_history));
+ return chat_history;
+ };
+};
+
+const saveChatHistory = makeSaveChatHistory();
+
+function dwr_callback(userId, username, message, time) {
+ const lastMessage = { userId, username, message, time };
+ saveChatHistory(userId, username, message, time);
+
+ if (message.indexOf("Engine]") >= 0){
+ Messenger().post({
+ message: message,
+ type: 'success',
+ showCloseButton: true
+ });
+ }
+
+ if (message.indexOf("Server]") >= 0){
+ $(".notifications.pull-right").addClass("alert-created");
+ const alertDiv = $('
').addClass('alert pull-right');
+ const closeButton = $(' ').addClass('close').attr('data-dismiss', 'alert').text('×');
+ const infoIcon = $(' ').addClass('fa fa-info-circle').css("color","#a4c6ff").css('margin-right', '5px').css('vertical-align','middle');
+ alertDiv.append(closeButton, infoIcon, lastMessage.message);
+ $(".notifications.pull-right .alert").remove();
+ $(".notifications.pull-right").append(alertDiv);
+ }
+
+}
+
+function dwr_login(userId,username){
+ dwr.engine.setActiveReverseAjax(true);
+ dwr.engine.setNotifyServerOnPageUnload(true);
+ dwr.engine.setErrorHandler(function () {
+ Messenger().post({
+ message: "서버와의 실시간 네트워크 통신에 문제를 감지했습니다. ( 재시도 합니다 )",
+ type: 'error',
+ showCloseButton: true
+ });
+ });
+ Chat.login(userId,username);
+
+ buildMessage();
+}
+
+function buildMessage() {
+ var theme = 'air';
+
+ $.globalMessenger({ theme: theme });
+ Messenger.options = { theme: theme };
+
+ //Messenger().post("Thanks for checking out Messenger!");
+
+
+ var loc = ['bottom', 'right'];
+
+ var $lsel = $('.location-selector');
+
+ var update = function(){
+ var classes = 'messenger-fixed';
+
+ for (var i=0; i < loc.length; i++)
+ classes += ' messenger-on-' + loc[i];
+
+ $.globalMessenger({ extraClasses: classes, theme: theme });
+ Messenger.options = { extraClasses: classes, theme: theme };
+ };
+
+ update();
+
+}
\ No newline at end of file
Index: controltower/js/common/table.js
===================================================================
diff -u
--- controltower/js/common/table.js (revision 0)
+++ controltower/js/common/table.js (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,252 @@
+(function ($) {
+ "use strict";
+
+ var Table = function (selector) {
+ this.$selector = $(selector);
+ this.selector = selector;
+ this.table;
+ this.selectedData;
+ this.onDataTableClick;
+ this.onInit;
+ };
+
+ Table.prototype.onToggleCheckAll = function (element) {
+ if (!element) return;
+
+ var tr = this.table.rows().nodes();
+ var isChecked = $(element).prop("checked");
+ console.log(isChecked);
+
+ if (isChecked) {
+ this.table.rows().select();
+ } else {
+ this.table.rows().deselect();
+ }
+
+ $.each(tr, function () {
+ $(this).find('input[type="checkbox"]').prop("checked", isChecked);
+ });
+ };
+
+ Table.prototype.onToggleCheckbox = function (element) {
+ var tr = $(element);
+ var checkbox = tr.find('input[type="checkbox"]');
+ var isChecked = tr.hasClass("selected");
+
+ checkbox.prop("checked", isChecked);
+ };
+
+ Table.prototype.onRowClick = function (element, multi) {
+ var tr = $(element);
+ this.selectedData = this.table.row(tr).data();
+
+ if (tr.hasClass("selected")) {
+ tr.removeClass("selected");
+
+ if ($.isFunction(this.onDeselect)) {
+ this.onDeselect(this.selectedData, element);
+ }
+
+ this.selectedData = null;
+ } else {
+ if (!multi) {
+ this.table.$("tr.selected").removeClass("selected");
+ }
+ tr.addClass("selected");
+
+ if ($.isFunction(this.onDataTableClick)) {
+ this.onDataTableClick(this.selectedData, element);
+ }
+ }
+ };
+
+ Table.prototype.dataTableExtendBuild = function (params) {
+ var responsive = {
+ details: {
+ renderer: function (api, rowIdx, columns) {
+ var outer = "";
+
+ var data = $.map(columns, function (col, i) {
+ return col.hidden
+ ? `
+
+ ${col.title}
+
+
+ ${col.data}
+
`
+ : ``;
+ }).join(``);
+ outer += data;
+ outer += " ";
+
+ return outer ? $("").append(outer) : false;
+ }
+ }
+ };
+ var tableBuildParams = $.extend(true, {}, params, { responsive: responsive });
+
+ this.dataTableBuild(tableBuildParams);
+ };
+
+ Table.prototype.dataTableBuild = function (params) {
+ var self = this;
+ var defaults = {
+ data: [],
+ stateSave: true,
+ destroy: true,
+ processing: true,
+ serverSide: false,
+ scrollX: true,
+ responsive: false,
+ columns: this.columns,
+ rowsGroup: null,
+ columnDefs: [],
+ isAddCheckbox: false,
+ isDeleteUtil: false,
+ select: {},
+ pagingType: "simple_numbers",
+ oLanguage: {
+ oPaginate: {
+ sNext: ' ',
+ sPrevious: ' '
+ }
+ },
+ order: [[0, "asc"]],
+ buttons: [
+ "copy",
+ {
+ extend: "csv",
+ charset: "UTF-8",
+ bom: true
+ },
+ "excel",
+ "print",
+ {
+ extend: "pdfHtml5",
+ orientation: "landscape",
+ pageSize: "LEGAL"
+ }
+ ],
+ language: {
+ processing: "",
+ loadingRecords:
+ ' 데이터를 처리 중입니다. '
+ }
+ };
+
+ var tableBuildParams = $.extend({}, defaults, params);
+
+ tableBuildParams.initComplete = function () {
+ var dataTableLength = $(".dataTables_length").find("select:eq(0)");
+ var tableWrapper = $(self.selector + "_wrapper");
+
+ dataTableLength.addClass("darkBack");
+ dataTableLength.children().css("background", "#3B3D40");
+ dataTableLength.css("border-radius", "5px");
+ dataTableLength.css("min-height", "30px");
+ tableWrapper.css("border-top", "1px solid rgba(51, 51, 51, 0.3)");
+ tableWrapper.css("padding-top", "5px");
+
+ tableWrapper.find("input[type=search]").css("width", "80px");
+
+ if (tableBuildParams.isDeleteUtil) {
+ $(self.selector + "_length").remove();
+ $(self.selector + "_filter").remove();
+ $(self.selector + "_info").remove();
+ $(self.selector + "_paginate").remove();
+ }
+
+ if ($.isFunction(self.onInit)) {
+ self.onInit();
+ }
+ };
+
+ if (tableBuildParams.isAddCheckbox) {
+ tableBuildParams.columnDefs = [
+ {
+ targets: 0,
+ orderable: false,
+ searchable: false,
+ data: null,
+ defaultContent: "",
+ className: "select-checkbox"
+ },
+ { targets: 1, aDataSort: [1] }
+ ].concat(tableBuildParams.columnDefs);
+
+ tableBuildParams.columns = [
+ {
+ data: null,
+ title: ' ',
+ render: function () {
+ return ' ';
+ },
+ className: "dt-body-center"
+ }
+ ].concat(tableBuildParams.columns);
+
+ tableBuildParams.select = { style: "multi" };
+ }
+
+ this.table = this.$selector.DataTable(tableBuildParams);
+
+ $(this.selector + " tbody").on("click", "tr", function () {
+ self.onRowClick(this, tableBuildParams.isAddCheckbox);
+
+ if (tableBuildParams.isAddCheckbox) {
+ self.onToggleCheckbox(this);
+ }
+ });
+
+ if (tableBuildParams.isAddCheckbox) {
+ $(this.selector + "_wrapper .dataTables_scrollHead thead").on("change", 'input[name="checkall"]', function () {
+ self.onToggleCheckAll(this);
+ });
+ }
+
+ $.fn.dataTable.ext.errMode = function () {
+ jError("Notification : Ajax Error , retry plz !");
+ };
+ };
+
+ Table.prototype.clear = function () {
+ this.table.clear();
+ };
+
+ Table.prototype.addRows = function (rows) {
+ this.table.rows.add(rows).draw(false);
+ };
+
+ Table.prototype.reDraw = function (rows) {
+ this.selectedData = null;
+ this.clear();
+ this.addRows(rows);
+ };
+
+ Table.prototype.empty = function () {
+ this.table.destroy();
+ this.$selector.empty();
+ };
+
+ Table.prototype.removeRows = function (callback) {
+ var selectedRows = this.table.rows({ selected: true });
+ var selectedDatas = selectedRows.data().toArray();
+
+ selectedRows.remove().draw();
+
+ if ($.isFunction(callback)) {
+ callback(selectedDatas);
+ }
+ };
+
+ Table.prototype.getSelectedDataList = function () {
+ return this.table.rows({ selected: true }).data().toArray();
+ };
+
+ Table.prototype.getDatas = function () {
+ return this.table.rows().data().toArray();
+ };
+
+ $.fn.Table = Table;
+})(jQuery);
Index: controltower/js/common/tourGuide/tgApi.js
===================================================================
diff -u
--- controltower/js/common/tourGuide/tgApi.js (revision 0)
+++ controltower/js/common/tourGuide/tgApi.js (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,54 @@
+const TourGuideApi = (function () {
+
+ const makeInstance = function (pageName) {
+ let tg = new tourguide.TourGuideClient({
+ exitOnClickOutside: false,
+ steps: fetchSteps(pageName)
+ });
+ return tg;
+ }
+
+ const fetchSteps = function (pageName) {
+ let steps;
+ console.log("[ tgApi :: TourGuideApi.fetchSteps ] :: pageName → " + pageName);
+ switch (pageName) {
+ case 'dashboard':
+ break;
+ //Product Service
+ case 'pdService':
+ steps = TgGroup.tg_pdService();
+ break;
+ case 'pdServiceVersion':
+ break;
+ //Jira
+ case 'jiraServer':
+ break;
+ case 'jiraConnection':
+ break;
+
+ //Requirement
+ case 'reqAdd':
+ break;
+ case 'reqStatus':
+ break;
+
+ //Analysis
+ case 'analysisGantt':
+ break;
+ case 'analysisResource':
+ break;
+ case 'analysisTime':
+ break;
+ default:
+ console.log("[ tgApi :: TourGuideApi.fetchSteps ] :: pageName → " + pageName + " :: 일치하는 케이스 없음");
+
+ } //end of switch
+ if (steps === undefined) {
+ return TgGroup.sampleStep(pageName);
+ }
+ return steps;
+ };
+
+ return {fetchSteps : fetchSteps,
+ makeInstance :makeInstance}; // 내부 함수 key : value ( function )
+})();
\ No newline at end of file
Index: controltower/js/common/tourGuide/tgGroup.js
===================================================================
diff -u
--- controltower/js/common/tourGuide/tgGroup.js (revision 0)
+++ controltower/js/common/tourGuide/tgGroup.js (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,119 @@
+var TgGroup = ( function () {
+ var sampleStep = function (pageName) {
+ const steps = [
+ {
+ title: ' 선택한 페이지 - '+pageName+'
',
+ content: ' 페이지명과 범주를 확인할 수 있습니다.
',
+ target: ".widgetheader"
+ },
+ {
+ title: '투어가이드 설정 On/Off
',
+ content: ' 페이지가 새로 로드 될 때마다 실행됩니다. ' +
+ '가이드를 끄시려면 TourGuide Off 로 설정해주세요.
',
+ target: "#settings"
+ }
+ ];
+ return steps;
+ };
+ var tg_dashboard = function () {
+ const steps = [{
+ content: "This is a short guide to get you set up and show you where things are",
+ title: "Welcome aboard",
+ target: "#firstStep"
+ },
+ {
+ content: "Register New Product(or Service) that you want to manage",
+ title: "Register Product(or Service) Button",
+ target: "#modal_popup_id"
+ }
+ ];
+
+ return steps;
+ };
+
+ var tg_pdService = function () {
+ const steps = [
+ {
+ title: '제품서비스 목록
',
+ content: '등록한 제품서비스 목록 입니다. ' +
+ '제품서비스 명을 선택하시면 상세 정보를 확인할 수 있습니다.
',
+ target: "#firstSection"
+ },
+ {
+ title: '제품서비스 등록
',
+ content: '새로운 제품 또는 서비스를 등록할 수 있습니다.
',
+ target: "#modal_popup_id"
+ },
+ {
+ title: '제품서비스 상세
',
+ content: '목록에서 선택한 제품서비스 의 상세 정보 확인 ' +
+ '편집하고 삭제할 수 있습니다.
',
+ target: "#secondSection"
+ },
+ {
+ title: '투어가이드 설정 On/Off
',
+ content: ' 페이지가 새로 로드 될 때마다 실행됩니다. ' +
+ '가이드를 끄시려면 TourGuide 를 Off 로 설정해주세요.
',
+ target: "#settings"
+ }
+ ];
+
+ return steps;
+ };
+
+ var tg_pdServiceVersion = function () {
+
+ };
+ var tg_jiraConnection = function () {
+
+ };
+ var tg_pdServiceJira = function () {
+
+ };
+
+ var tg_reqAdd = function () {
+
+ };
+
+ var tg_reqStatus = function () {
+
+ };
+ var tg_analysisGantt = function () {
+
+ };
+
+
+ var tg_analysisTime = function () {
+
+ };
+ var tg_analysisScope = function () {
+
+ };
+ var tg_analysisResource = function () {
+
+ };
+ var tg_analysisCost = function () {
+
+ };
+
+ return { tg_dashboard : tg_dashboard,
+
+ tg_pdService : tg_pdService,
+ tg_pdServiceVersion : tg_pdServiceVersion,
+
+ tg_jiraConnection : tg_jiraConnection,
+ tg_pdServiceJira : tg_pdServiceJira,
+
+ tg_reqAdd : tg_reqAdd,
+ tg_reqStatus : tg_reqStatus,
+
+ tg_analysisGantt : tg_analysisGantt,
+ tg_analysisTime : tg_analysisTime,
+ tg_analysisScope : tg_analysisScope,
+ tg_analysisResource : tg_analysisResource,
+ tg_analysisCost : tg_analysisCost,
+
+ sampleStep : sampleStep
+ }; // 내부함수 key : value
+ }
+)();
Index: controltower/js/index.js
===================================================================
diff -u
--- controltower/js/index.js (revision 0)
+++ controltower/js/index.js (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1,1043 @@
+////////////////////////////////////////////////////////////////////////////////////////
+//Page 전역 변수
+////////////////////////////////////////////////////////////////////////////////////////
+var selectId; // 제품 아이디
+var selectName; // 제품 이름
+var selectedIndex; // 데이터테이블 선택한 인덱스
+var selectedPage; // 데이터테이블 선택한 인덱스
+var selectVersion; // 선택한 버전 아이디
+var dataTableRef; // 데이터테이블 참조 변수
+
+////////////////////////////////////////////////////////////////////////////////////////
+//Document Ready
+////////////////////////////////////////////////////////////////////////////////////////
+function execDocReady() {
+
+ var pluginGroups = [
+ [ "../reference/light-blue/lib/vendor/jquery.ui.widget.js",
+ "../reference/light-blue/lib/vendor/http_blueimp.github.io_JavaScript-Templates_js_tmpl.js",
+ "../reference/light-blue/lib/vendor/http_blueimp.github.io_JavaScript-Load-Image_js_load-image.js",
+ "../reference/light-blue/lib/vendor/http_blueimp.github.io_JavaScript-Canvas-to-Blob_js_canvas-to-blob.js",
+ "../reference/light-blue/lib/jquery.iframe-transport.js",
+ "../reference/light-blue/lib/jquery.fileupload.js",
+ "../reference/light-blue/lib/jquery.fileupload-fp.js",
+ "../reference/light-blue/lib/jquery.fileupload-ui.js"],
+
+ [ "../reference/jquery-plugins/select2-4.0.2/dist/css/select2_lightblue4.css",
+ "../reference/jquery-plugins/lou-multi-select-0.9.12/css/multiselect-lightblue4.css",
+ "../reference/jquery-plugins/multiple-select-1.5.2/dist/multiple-select-bluelight.css",
+ "../reference/jquery-plugins/select2-4.0.2/dist/js/select2.min.js",
+ "../reference/jquery-plugins/lou-multi-select-0.9.12/js/jquery.quicksearch.js",
+ "../reference/jquery-plugins/lou-multi-select-0.9.12/js/jquery.multi-select.js",
+ "../reference/jquery-plugins/multiple-select-1.5.2/dist/multiple-select.min.js"],
+
+ [ "../reference/jquery-plugins/datetimepicker-2.5.20/build/jquery.datetimepicker.min.css",
+ "../reference/light-blue/lib/bootstrap-datepicker.js",
+ "../reference/jquery-plugins/datetimepicker-2.5.20/build/jquery.datetimepicker.full.min.js",
+ "../reference/lightblue4/docs/lib/widgster/widgster.js",
+ "../reference/lightblue4/docs/lib/slimScroll/jquery.slimscroll.min.js"],
+
+ [ "../reference/jquery-plugins/dataTables-1.10.16/media/css/jquery.dataTables_lightblue4.css",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Responsive/css/responsive.dataTables_lightblue4.css",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Select/css/select.dataTables_lightblue4.css",
+ "../reference/jquery-plugins/dataTables-1.10.16/media/js/jquery.dataTables.min.js",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Responsive/js/dataTables.responsive.min.js",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Select/js/dataTables.select.min.js",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/RowGroup/js/dataTables.rowsGroup.min.js",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/dataTables.buttons.min.js",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/buttons.html5.js",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/buttons.print.js",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/jszip.min.js",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/pdfmake.min.js",
+ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/vfs_fonts.js"
+ ]
+ // 추가적인 플러그인 그룹들을 이곳에 추가하면 됩니다.
+ ];
+
+ loadPluginGroupsParallelAndSequential(pluginGroups)
+ .then(function() {
+
+ console.log('모든 플러그인 로드 완료');
+
+ // 사이드 메뉴 색상 설정
+ $('.widget').widgster();
+ setSideMenu("sidebar_menu_product", "sidebar_menu_product_manage");
+
+ })
+ .catch(function() {
+ console.error('플러그인 로드 중 오류 발생');
+ });
+
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 탭 클릭 이벤트 처리
+////////////////////////////////////////////////////////////////////////////////////////
+function tab_click_event() {
+ $('a[data-toggle="tab"]').on("shown.bs.tab", function (e) {
+ var target = $(e.target).attr("href"); // activated tab
+ console.log(target);
+
+ if (target == "#dropdown1") {
+
+ $("#pdservice_details_popup_div").addClass("hidden");
+ $("#pdservice_update_div").addClass("hidden");
+ $("#pdservice_delete_div").removeClass("hidden");
+
+ $(".body-middle").hide();
+ $(".pdservice-image-row").hide();
+ $(".file-delete-btn").hide();
+ if (isEmpty(selectId)) {
+ jError("선택된 제품(서비스)가 없습니다. 오류는 무시됩니다.");
+ } else {
+ $("#delete_text").text($("#pdservice_table").DataTable().rows(".selected").data()[0].c_title);
+ }
+ } else if (target == "#report") {
+ $(".pdservice-image-row").show();
+ $(".file-delete-btn").show();
+ $("#pdservice_details_popup_div").addClass("hidden");
+ $("#pdservice_delete_div").addClass("hidden");
+ $("#pdservice_update_div").removeClass("hidden");
+
+ } else {
+ $("#pdservice_details_popup_div").removeClass("hidden");
+ $("#pdservice_update_div").addClass("hidden");
+ $("#pdservice_delete_div").addClass("hidden");
+ $(".pdservice-image-row").hide();
+ $(".file-delete-btn").hide();
+
+ if (selectId == undefined) {
+ $(".body-middle").hide();
+ } else {
+ $(".body-middle").show();
+ }
+ }
+ });
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// --- 신규 제품(서비스) 등록 팝업 및 팝업 띄울때 사이즈 조정 -- //
+////////////////////////////////////////////////////////////////////////////////////////
+function popup_size_setting(){
+ console.log("popup_size_setting() is activated");
+ $("#modal_popup_id").click(function () {
+ console.log("modal_popup_id clicked");
+ var height = $(document).height() - 600;
+
+ //모달 초기화
+ $("#my_modal2").on("hidden.bs.modal", function (e) {
+ $(this).find('form')[0].reset();
+ $("#popup_editview_pdservice_owner").val(null).trigger("change");
+ $("#popup_editview_pdservice_reviewers").val(null).trigger("change");
+ CKEDITOR.instances.modal_editor.setData("제품(서비스)의 기획서 및 Project Charter 의 내용을 기록합니다.
"); //에디터 초기화
+ });
+
+ $(".modal-body")
+ .find(".cke_contents:eq(0)")
+ .css("height", height + "px");
+ });
+
+ // 팝업하여 편집
+ $("#extend_modal_popup_id").click(function () {
+ var height = $(document).height() - 1000;
+ $(".modal-body")
+ .find(".cke_contents:eq(0)")
+ .css("height", height + "px");
+
+ // 데이터 셋팅
+ var editorData = CKEDITOR.instances.input_pdservice_editor.getData();
+ console.log(editorData);
+ CKEDITOR.instances.extend_modal_editor.setData(editorData);
+ CKEDITOR.instances.extend_modal_editor.setReadOnly(false);
+
+ var selectedId = $("#pdservice_table").DataTable().rows(".selected").data()[0].c_id;
+ console.log("selectedId →" + selectedId);
+
+ // 제품(서비스) 이름
+ $("#extend_editview_pdservice_name").val($("#editview_pdservice_name").val());
+
+ // 오너
+ // clear
+ $("#extend_editview_pdservice_owner").val(null).trigger("change");
+
+ // 부모 페이지에서 데이터 로드
+ var owner = "none";
+ if ($("#editview_pdservice_owner").select2("data")[0] != undefined) {
+ owner = $("#editview_pdservice_owner").select2("data")[0].text;
+ }
+
+ // Modal 창에 데이터 셋팅
+ if (owner == null || owner == "none") {
+ console.log("pdServiceDataTableClick :: json.c_pdservice_owner empty");
+ } else {
+ var newOption = new Option(owner, owner, true, true);
+ $("#extend_editview_pdservice_owner").append(newOption).trigger("change");
+ }
+
+ // 리뷰어
+ //clear
+ $("#extend_editview_pdservice_reviewers").val(null).trigger("change");
+
+ var reviewer01 = "none";
+ var reviewer02 = "none";
+ var reviewer03 = "none";
+ var reviewer04 = "none";
+ var reviewer05 = "none";
+
+ if ($("#editview_pdservice_reviewers").select2("data")[0] != undefined) {
+ reviewer01 = $("#editview_pdservice_reviewers").select2("data")[0].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[1] != undefined) {
+ reviewer02 = $("#editview_pdservice_reviewers").select2("data")[1].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[2] != undefined) {
+ reviewer03 = $("#editview_pdservice_reviewers").select2("data")[2].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[3] != undefined) {
+ reviewer04 = $("#editview_pdservice_reviewers").select2("data")[3].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[4] != undefined) {
+ reviewer05 = $("#editview_pdservice_reviewers").select2("data")[4].text;
+ }
+
+ var reviewer01Option = new Option(reviewer01, reviewer01, true, true);
+ var reviewer02Option = new Option(reviewer02, reviewer02, true, true);
+ var reviewer03Option = new Option(reviewer03, reviewer03, true, true);
+ var reviewer04Option = new Option(reviewer04, reviewer04, true, true);
+ var reviewer05Option = new Option(reviewer05, reviewer05, true, true);
+
+ var multifyValue = 1;
+ if (reviewer01 == null || reviewer01 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer01 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer01Option);
+ }
+ if (reviewer02 == null || reviewer02 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer02 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer02Option);
+ }
+ if (reviewer03 == null || reviewer03 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer03 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer03Option);
+ }
+ if (reviewer04 == null || reviewer04 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer04 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer04Option);
+ }
+ if (reviewer05 == null || reviewer05 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer05 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer05Option);
+ }
+
+ $("#extend_editview_pdservice_reviewers").trigger("change");
+
+ $("#extend_editview_pdservice_reviewer").css("height", "20px");
+ setTimeout(function () {
+ var heightValue = $("#extend_editview_pdservice_reviewer").height();
+ var resultValue = heightValue + 20 * multifyValue;
+ $("#extend_editview_pdservice_reviewer").css("height", resultValue + "px");
+ }, 250);
+ });
+ // 팝업 - readOnly
+ $("#extend_modal_readOnly").click(function () {
+ var height = $(document).height() - 1000;
+ $(".modal-body")
+ .find(".cke_contents:eq(0)")
+ .css("height", height + "px");
+
+ // 데이터 셋팅
+ var editorData = CKEDITOR.instances.input_pdservice_editor.getData();
+ CKEDITOR.instances.extend_modal_editor.setData(editorData);
+ CKEDITOR.instances.extend_modal_editor.setReadOnly(true); // 읽기전용
+
+ var selectedId = $("#pdservice_table").DataTable().rows(".selected").data()[0].c_id;
+ console.log("selectedId →" + selectedId);
+
+ // 제품(서비스) 이름
+ $("#extend_editview_pdservice_name").val($("#editview_pdservice_name").val());
+
+ // 오너
+ // clear
+ $("#extend_editview_pdservice_owner").val(null).trigger("change");
+
+ // 부모 페이지에서 데이터 로드
+ var owner = "none";
+ if ($("#editview_pdservice_owner").select2("data")[0] != undefined) {
+ owner = $("#editview_pdservice_owner").select2("data")[0].text;
+ }
+
+ // Modal 창에 데이터 셋팅
+ if (owner == null || owner == "none") {
+ console.log("pdServiceDataTableClick :: json.c_pdservice_owner empty");
+ } else {
+ var newOption = new Option(owner, owner, true, true);
+ $("#extend_editview_pdservice_owner").append(newOption).trigger("change");
+ }
+
+ // 리뷰어
+ //clear
+ $("#extend_editview_pdservice_reviewers").val(null).trigger("change");
+
+ var reviewer01 = "none";
+ var reviewer02 = "none";
+ var reviewer03 = "none";
+ var reviewer04 = "none";
+ var reviewer05 = "none";
+
+ if ($("#editview_pdservice_reviewers").select2("data")[0] != undefined) {
+ reviewer01 = $("#editview_pdservice_reviewers").select2("data")[0].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[1] != undefined) {
+ reviewer02 = $("#editview_pdservice_reviewers").select2("data")[1].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[2] != undefined) {
+ reviewer03 = $("#editview_pdservice_reviewers").select2("data")[2].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[3] != undefined) {
+ reviewer04 = $("#editview_pdservice_reviewers").select2("data")[3].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[4] != undefined) {
+ reviewer05 = $("#editview_pdservice_reviewers").select2("data")[4].text;
+ }
+
+ var reviewer01Option = new Option(reviewer01, reviewer01, true, true);
+ var reviewer02Option = new Option(reviewer02, reviewer02, true, true);
+ var reviewer03Option = new Option(reviewer03, reviewer03, true, true);
+ var reviewer04Option = new Option(reviewer04, reviewer04, true, true);
+ var reviewer05Option = new Option(reviewer05, reviewer05, true, true);
+
+ var multifyValue = 1;
+ if (reviewer01 == null || reviewer01 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer01 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer01Option);
+ }
+ if (reviewer02 == null || reviewer02 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer02 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer02Option);
+ }
+ if (reviewer03 == null || reviewer03 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer03 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer03Option);
+ }
+ if (reviewer04 == null || reviewer04 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer04 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer04Option);
+ }
+ if (reviewer05 == null || reviewer05 == "none") {
+ console.log("extend_modal_popup_id Click :: reviewer05 empty");
+ } else {
+ multifyValue = multifyValue + 1;
+ $("#extend_editview_pdservice_reviewers").append(reviewer05Option);
+ }
+
+ $("#extend_editview_pdservice_reviewers").trigger("change");
+
+ $("#extend_editview_pdservice_reviewer").css("height", "20px");
+ setTimeout(function () {
+ var heightValue = $("#extend_editview_pdservice_reviewer").height();
+ var resultValue = heightValue + 20 * multifyValue;
+ $("#extend_editview_pdservice_reviewer").css("height", resultValue + "px");
+ }, 250);
+ });
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// --- select2 (사용자 자동완성 검색 ) 설정 --- //
+////////////////////////////////////////////////////////////////////////////////////////
+function select2_setting() {
+ $(".js-data-example-ajax").select2({
+ maximumSelectionLength: 5,
+ width: "resolve",
+ ajax: {
+ url: function (params) {
+ return "/auth-user/search-user/" + params.term;
+ },
+ dataType: "json",
+ delay: 250,
+ //data: function (params) {
+ // return {
+ // q: params.term, // search term
+ // page: params.page,
+ // };
+ //},
+ processResults: function (data, params) {
+ // parse the results into the format expected by Select2
+ // since we are using custom formatting functions we do not need to
+ // alter the remote JSON data, except to indicate that infinite
+ // scrolling can be used
+ params.page = params.page || 1;
+
+ return {
+ results: data,
+ pagination: {
+ more: params.page * 30 < data.total_count
+ }
+ };
+ },
+ cache: true
+ },
+ placeholder: "리뷰어 설정을 위한 계정명을 입력해 주세요",
+ minimumInputLength: 1,
+ templateResult: formatUser,
+ templateSelection: formatUserSelection
+ });
+}
+
+////////////////////////////////////////////////////////////////////¸////////////////////
+// --- select2 (사용자 자동완성 검색 ) templateResult 설정 --- //
+////////////////////////////////////////////////////////////////////////////////////////
+function formatUser(jsonData) {
+ console.log("formatUser");
+ console.log(jsonData)
+ var $container = $(
+ ""
+ );
+
+ $container.find(".select2-result-jsonData__username").text(jsonData.username);
+ $container.find(".select2-result-jsonData__id").text(jsonData.id);
+
+ return $container;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// --- select2 (사용자 자동완성 검색 ) templateSelection 설정 --- //
+////////////////////////////////////////////////////////////////////////////////////////
+function formatUserSelection(jsonData) {
+ console.log("formatUserSelection");
+ console.log(jsonData)
+ if (jsonData.id == "") {
+ jsonData.text = "placeholder";
+ } else {
+ if (jsonData.username == undefined) {
+ jsonData.text = jsonData.id;
+ } else {
+ jsonData.text = "[" + jsonData.username + "] - " + jsonData.id;
+ }
+ }
+ return jsonData.text;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// --- file upload --- //
+////////////////////////////////////////////////////////////////////////////////////////
+function file_upload_setting() {
+
+ // Initialize the jQuery File Upload widget:
+ var $fileupload = $("#fileupload");
+ $fileupload.fileupload({
+ // Uncomment the following to send cross-domain cookies:
+ //xhrFields: {withCredentials: true},
+ autoUpload: true,
+ url: "/auth-user/api/arms/pdService/uploadFileToNode.do",
+ dropZone: $("#dropzone")
+ });
+
+
+ $("#fileupload").bind("fileuploadsubmit", function (e, data) {
+ // The example input, doesn't have to be part of the upload form:
+ var input = $("#fileIdlink");
+ data.formData = { pdservice_link: input.val() };
+ if (!data.formData.pdservice_link) {
+ data.context.find("button").prop("disabled", false);
+ input.focus();
+ return false;
+ }
+ });
+
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// --- 데이터 테이블 설정 --- //
+////////////////////////////////////////////////////////////////////////////////////////
+function dataTableLoad() {
+ // 데이터 테이블 컬럼 및 열그룹 구성
+ var columnList = [
+ { name: "c_id", title: "제품(서비스) 아이디", data: "c_id", visible: false },
+ {
+ name: "c_title",
+ title: "제품(서비스) 이름",
+ data: "c_title",
+ render: function (data, type, row, meta) {
+ if (type === "display") {
+ return '' + data + " ";
+ }
+ return data;
+ },
+ className: "dt-body-left",
+ visible: true
+ }
+ ];
+ var rowsGroupList = [];
+ var columnDefList = [];
+ var selectList = {};
+ var orderList = [[0, "asc"]];
+ var buttonList = [
+ "copy",
+ "excel",
+ "print",
+ {
+ extend: "csv",
+ text: "Export csv",
+ charset: "utf-8",
+ extension: ".csv",
+ fieldSeparator: ",",
+ fieldBoundary: "",
+ bom: true
+ },
+ {
+ extend: "pdfHtml5",
+ orientation: "landscape",
+ pageSize: "LEGAL"
+ }
+ ];
+
+ var jquerySelector = "#pdservice_table";
+ var ajaxUrl = "/auth-user/api/arms/pdServicePure/getPdServiceMonitor.do";
+ var jsonRoot = "response";
+ var isServerSide = false;
+
+ dataTableRef = dataTable_build(
+ jquerySelector,
+ ajaxUrl,
+ jsonRoot,
+ columnList,
+ rowsGroupList,
+ columnDefList,
+ selectList,
+ orderList,
+ buttonList,
+ isServerSide
+ );
+
+ $("#copychecker").on("click", function () {
+ dataTableRef.button(".buttons-copy").trigger();
+ });
+ $("#printchecker").on("click", function () {
+ dataTableRef.button(".buttons-print").trigger();
+ });
+ $("#csvchecker").on("click", function () {
+ dataTableRef.button(".buttons-csv").trigger();
+ });
+ $("#excelchecker").on("click", function () {
+ dataTableRef.button(".buttons-excel").trigger();
+ });
+ $("#pdfchecker").on("click", function () {
+ dataTableRef.button(".buttons-pdf").trigger();
+ });
+}
+
+
+// 데이터 테이블 구성 이후 꼭 구현해야 할 메소드 : 열 클릭시 이벤트
+function dataTableClick(tempDataTable, selectedData) {
+ selectedIndex = selectedData.selectedIndex;
+ selectedPage = selectedData.selectedPage;
+ selectId = selectedData.c_id;
+ $("#fileIdlink").val(selectedData.c_id);
+ selectName = selectedData.c_title;
+ pdServiceDataTableClick(selectedData.c_id);
+
+ //제품 클릭 시, 상세보기 tab을 기본값으로 세팅.
+ $('ul.nav-tabs li').removeClass('active');
+ $('.nav-tabs-stats').addClass('active');
+
+ //파일 업로드 관련 레이어 보이기 처리
+ $(".body-middle").show();
+ // 이미지 CRUD 관련 HTML 태그 hide 처리. <편집하기> tab 에서만 보여준다.
+ $(".pdservice-image-row").hide();
+
+ //파일 리스트 초기화
+ $("table tbody.files").empty();
+ // Load existing files:
+ var $fileupload = $("#fileupload");
+
+ $.ajax({
+ // Uncomment the following to send cross-domain cookies:
+ //xhrFields: {withCredentials: true},
+ url: "/auth-user/api/arms/fileRepository/getFilesByNode.do",
+ data: { fileIdLink: selectId },
+ dataType: "json",
+ context: $fileupload[0]
+ }).done(function (result) {
+ $(this).fileupload("option", "done").call(this, null, { result: result });
+ $(".file-delete-btn").hide(); // 파일 리스트에서 delete 버튼 display none 처리 -> 편집하기 tab 에서만 보여준다.
+ });
+}
+
+//데이터 테이블 ajax load 이후 콜백.
+function dataTableCallBack(settings, json) {
+}
+
+function dataTableDrawCallback(tableInfo) {
+ $("#" + tableInfo.sInstance)
+ .DataTable()
+ .columns.adjust()
+ .responsive.recalc();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+//제품(서비스) 클릭할 때 동작하는 함수
+//1. 상세보기 데이터 바인딩
+//2. 편집하기 데이터 바인딩
+////////////////////////////////////////////////////////////////////////////////////////
+function pdServiceDataTableClick(c_id) {
+ selectVersion = c_id;
+
+ $.ajax({
+ url: "/auth-user/api/arms/pdServicePure/getNode.do", // 클라이언트가 HTTP 요청을 보낼 서버의 URL 주소
+ data: { c_id: c_id }, // HTTP 요청과 함께 서버로 보낼 데이터
+ method: "GET", // HTTP 요청 메소드(GET, POST 등)
+ dataType: "json", // 서버에서 보내줄 데이터의 타입
+ beforeSend: function () {
+ $(".loader").removeClass("hide");
+ }
+ })
+ // HTTP 요청이 성공하면 요청한 데이터가 done() 메소드로 전달됨.
+ .done(function (json) {
+ //$("#detailview_pdservice_name").val(json.c_title);
+ var selectedHtml =
+ `
+
+
+ 선택된 제품(서비스) :
+
+ ` + json.c_title +
+ `
+
+
+
+ `;
+
+ $(".list-group-item").html(selectedHtml);
+
+ $("#detailview_pdservice_name").val(json.c_title);
+ if (isEmpty(json.c_pdservice_owner) || json.c_pdservice_owner == "none") {
+ $("#detailview_pdservice_owner").val("책임자가 존재하지 않습니다.");
+ } else {
+ $("#detailview_pdservice_owner").val(json.c_pdservice_owner);
+ }
+
+ if (isEmpty(json.c_pdservice_reviewer01) || json.c_pdservice_reviewer01 == "none") {
+ $("#detailview_pdservice_reviewer01").val("리뷰어(연대책임자)가 존재하지 않습니다.");
+ } else {
+ $("#detailview_pdservice_reviewer01").val(json.c_pdservice_reviewer01);
+ }
+
+ if (isEmpty(json.c_pdservice_reviewer02) || json.c_pdservice_reviewer02 == "none") {
+ $("#detailview_pdservice_reviewer02").val("2번째 리뷰어(연대책임자) 없음");
+ } else {
+ $("#detailview_pdservice_reviewer02").val(json.c_pdservice_reviewer02);
+ }
+
+ if (isEmpty(json.c_pdservice_reviewer03) || json.c_pdservice_reviewer03 == "none") {
+ $("#detailview_pdservice_reviewer03").val("3번째 리뷰어(연대책임자) 없음");
+ } else {
+ $("#detailview_pdservice_reviewer03").val(json.c_pdservice_reviewer03);
+ }
+
+ if (isEmpty(json.c_pdservice_reviewer04) || json.c_pdservice_reviewer04 == "none") {
+ $("#detailview_pdservice_reviewer04").val("4번째 리뷰어(연대책임자) 없음");
+ } else {
+ $("#detailview_pdservice_reviewer04").val(json.c_pdservice_reviewer04);
+ }
+
+ if (isEmpty(json.c_pdservice_reviewer05) || json.c_pdservice_reviewer05 == "none") {
+ $("#detailview_pdservice_reviewer05").val("5번째 리뷰어(연대책임자) 없음");
+ } else {
+ $("#detailview_pdservice_reviewer05").val(json.c_pdservice_reviewer05);
+ }
+
+ CKEDITOR.instances.detailview_pdservice_contents.setData(json.c_pdservice_contents);
+
+ $("#editview_pdservice_name").val(json.c_title);
+
+ //clear
+ $("#editview_pdservice_owner").val(null).trigger("change");
+
+ if (json.c_pdservice_owner == null || json.c_pdservice_owner == "none") {
+ console.log("pdServiceDataTableClick :: json.c_pdservice_owner empty");
+ } else {
+ var newOption = new Option(json.c_pdservice_owner, json.c_pdservice_owner, true, true);
+ $("#editview_pdservice_owner").append(newOption).trigger("change");
+ }
+ // -------------------- reviewer setting -------------------- //
+ //reviewer clear
+ $("#editview_pdservice_reviewers").val(null).trigger("change");
+
+ var selectedReviewerArr = [];
+ if (json.c_pdservice_reviewer01 == null || json.c_pdservice_reviewer01 == "none") {
+ console.log("pdServiceDataTableClick :: json.c_pdservice_reviewer01 empty");
+ } else {
+ selectedReviewerArr.push(json.c_pdservice_reviewer01);
+ // Set the value, creating a new option if necessary
+ if ($("#editview_pdservice_reviewers").find("option[value='" + json.c_pdservice_reviewer01 + "']").length) {
+ console.log('option[value=\'" + json.c_pdservice_reviewer01 + "\']"' + "already exist");
+ } else {
+ // Create a DOM Option and pre-select by default
+ var newOption01 = new Option(json.c_pdservice_reviewer01, json.c_pdservice_reviewer01, true, true);
+ // Append it to the select
+ $("#editview_pdservice_reviewers").append(newOption01).trigger("change");
+ }
+ }
+ if (json.c_pdservice_reviewer02 == null || json.c_pdservice_reviewer02 == "none") {
+ console.log("pdServiceDataTableClick :: json.c_pdservice_reviewer02 empty");
+ } else {
+ selectedReviewerArr.push(json.c_pdservice_reviewer02);
+ // Set the value, creating a new option if necessary
+ if ($("#editview_pdservice_reviewers").find("option[value='" + json.c_pdservice_reviewer02 + "']").length) {
+ console.log('option[value=\'" + json.c_pdservice_reviewer02 + "\']"' + "already exist");
+ } else {
+ // Create a DOM Option and pre-select by default
+ var newOption02 = new Option(json.c_pdservice_reviewer02, json.c_pdservice_reviewer02, true, true);
+ // Append it to the select
+ $("#editview_pdservice_reviewers").append(newOption02).trigger("change");
+ }
+ }
+ if (json.c_pdservice_reviewer03 == null || json.c_pdservice_reviewer03 == "none") {
+ console.log("pdServiceDataTableClick :: json.c_pdservice_reviewer03 empty");
+ } else {
+ selectedReviewerArr.push(json.c_pdservice_reviewer03);
+ // Set the value, creating a new option if necessary
+ if ($("#editview_pdservice_reviewers").find("option[value='" + json.c_pdservice_reviewer03 + "']").length) {
+ console.log('option[value=\'" + json.c_pdservice_reviewer03 + "\']"' + "already exist");
+ } else {
+ // Create a DOM Option and pre-select by default
+ var newOption03 = new Option(json.c_pdservice_reviewer03, json.c_pdservice_reviewer03, true, true);
+ // Append it to the select
+ $("#editview_pdservice_reviewers").append(newOption03).trigger("change");
+ }
+ }
+ if (json.c_pdservice_reviewer04 == null || json.c_pdservice_reviewer04 == "none") {
+ console.log("pdServiceDataTableClick :: json.c_pdservice_reviewer04 empty");
+ } else {
+ selectedReviewerArr.push(json.c_pdservice_reviewer04);
+ // Set the value, creating a new option if necessary
+ if ($("#editview_pdservice_reviewers").find("option[value='" + json.c_pdservice_reviewer04 + "']").length) {
+ console.log('option[value=\'" + json.c_pdservice_reviewer04 + "\']"' + "already exist");
+ } else {
+ // Create a DOM Option and pre-select by default
+ var newOption04 = new Option(json.c_pdservice_reviewer04, json.c_pdservice_reviewer04, true, true);
+ // Append it to the select
+ $("#editview_pdservice_reviewers").append(newOption04).trigger("change");
+ }
+ }
+ if (json.c_pdservice_reviewer05 == null || json.c_pdservice_reviewer05 == "none") {
+ console.log("pdServiceDataTableClick :: json.c_pdservice_reviewer05 empty");
+ } else {
+ selectedReviewerArr.push(json.c_pdservice_reviewer05);
+ // Set the value, creating a new option if necessary
+ if ($("#editview_pdservice_reviewers").find("option[value='" + json.c_pdservice_reviewer05 + "']").length) {
+ console.log('option[value=\'" + json.c_pdservice_reviewer05 + "\']"' + "already exist");
+ } else {
+ // Create a DOM Option and pre-select by default
+ var newOption05 = new Option(json.c_pdservice_reviewer05, json.c_pdservice_reviewer05, true, true);
+ // Append it to the select
+ $("#editview_pdservice_reviewers").append(newOption05).trigger("change");
+ }
+ }
+ $("#editview_pdservice_reviewers").val(selectedReviewerArr).trigger("change");
+
+ // ------------------------- reviewer end --------------------------------//
+
+ CKEDITOR.instances.input_pdservice_editor.setData(json.c_pdservice_contents);
+ })
+ // HTTP 요청이 실패하면 오류와 상태에 관한 정보가 fail() 메소드로 전달됨.
+ .fail(function (xhr, status, errorThrown) {
+ console.log(xhr + status + errorThrown);
+ })
+ //
+ .always(function (xhr, status) {
+ console.log(xhr + status);
+ $(".loader").addClass("hide");
+ });
+
+ $("#delete_text").text($("#pdservice_table").DataTable().rows(".selected").data()[0].c_title);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 신규 제품(서비스) 등록 버튼
+////////////////////////////////////////////////////////////////////////////////////////
+function save_btn_click() {
+ $("#regist_pdservice").click(function () {
+ var reviewers01 = "none";
+ var reviewers02 = "none";
+ var reviewers03 = "none";
+ var reviewers04 = "none";
+ var reviewers05 = "none";
+ if ($("#popup_editview_pdservice_reviewers").select2("data")[0] != undefined) {
+ reviewers01 = $("#popup_editview_pdservice_reviewers").select2("data")[0].text;
+ }
+ if ($("#popup_editview_pdservice_reviewers").select2("data")[1] != undefined) {
+ reviewers02 = $("#popup_editview_pdservice_reviewers").select2("data")[1].text;
+ }
+ if ($("#popup_editview_pdservice_reviewers").select2("data")[2] != undefined) {
+ reviewers03 = $("#popup_editview_pdservice_reviewers").select2("data")[2].text;
+ }
+ if ($("#popup_editview_pdservice_reviewers").select2("data")[3] != undefined) {
+ reviewers04 = $("#popup_editview_pdservice_reviewers").select2("data")[3].text;
+ }
+ if ($("#popup_editview_pdservice_reviewers").select2("data")[4] != undefined) {
+ reviewers05 = $("#popup_editview_pdservice_reviewers").select2("data")[4].text;
+ }
+
+ const cTitle = $("#popup_editview_pdservice_name").val();
+
+ $.ajax({
+ url: "/auth-user/api/arms/pdService/addPdServiceNode.do",
+ type: "POST",
+ data: {
+ ref: 2,
+ c_title: cTitle,
+ c_type: "default",
+ c_pdservice_owner: $("#popup_editview_pdservice_owner").select2("data")[0].text,
+ c_pdservice_reviewer01: reviewers01,
+ c_pdservice_reviewer02: reviewers02,
+ c_pdservice_reviewer03: reviewers03,
+ c_pdservice_reviewer04: reviewers04,
+ c_pdservice_reviewer05: reviewers05,
+ c_pdservice_contents: CKEDITOR.instances.modal_editor.getData()
+ },
+ statusCode: {
+ 200: function () {
+ //모달 팝업 끝내고
+ $("#close_pdservice").trigger("click");
+ //데이터 테이블 데이터 재 로드
+ reloadDataWithSameOrdering(cTitle);
+ jSuccess("신규 제품 등록이 완료 되었습니다.");
+ }
+ },
+ beforeSend: function () {
+ $("#regist_pdservice").hide();
+ },
+ complete: function () {
+ $("#regist_pdservice").show();
+ },
+ error: function (e) {
+ jError("신규 제품 등록 중 에러가 발생했습니다.");
+ }
+ });
+ });
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 신규 제품(서비스) 삭제 버튼
+////////////////////////////////////////////////////////////////////////////////////////
+function delete_btn_click(){
+ $("#delete_pdservice").click(function () {
+ $.ajax({
+ url: "/auth-user/api/arms/pdService/removeNode.do",
+ type: "delete",
+ data: {
+ c_id: $("#pdservice_table").DataTable().rows(".selected").data()[0].c_id
+ },
+ statusCode: {
+ 200: function () {
+ jError($("#editview_pdservice_name").val() + "데이터가 삭제되었습니다.");
+ //데이터 테이블 데이터 재 로드
+ reloadDataWithSameOrdering("");
+ }
+ }
+ });
+ });
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 제품(서비스) 변경 저장 버튼
+////////////////////////////////////////////////////////////////////////////////////////
+function update_btn_click() {
+ $("#pdservice_update").click(function () {
+ var owner = "none";
+ if ($("#editview_pdservice_owner").select2("data")[0] != undefined) {
+ owner = $("#editview_pdservice_owner").select2("data")[0].text;
+ }
+ const cId = $("#pdservice_table").DataTable().rows(".selected").data()[0].c_id;
+ const cTitle = $("#pdservice_table").DataTable().rows(".selected").data()[0].c_title;
+ var reviewers01 = "none";
+ var reviewers02 = "none";
+ var reviewers03 = "none";
+ var reviewers04 = "none";
+ var reviewers05 = "none";
+ if ($("#editview_pdservice_reviewers").select2("data")[0] != undefined) {
+ reviewers01 = $("#editview_pdservice_reviewers").select2("data")[0].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[1] != undefined) {
+ reviewers02 = $("#editview_pdservice_reviewers").select2("data")[1].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[2] != undefined) {
+ reviewers03 = $("#editview_pdservice_reviewers").select2("data")[2].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[3] != undefined) {
+ reviewers04 = $("#editview_pdservice_reviewers").select2("data")[3].text;
+ }
+ if ($("#editview_pdservice_reviewers").select2("data")[4] != undefined) {
+ reviewers05 = $("#editview_pdservice_reviewers").select2("data")[4].text;
+ }
+
+ $.ajax({
+ url: "/auth-user/api/arms/pdService/updateNode.do",
+ type: "put",
+ data: {
+ c_id: cId,
+ c_title: cTitle,
+ c_pdservice_owner: owner,
+ c_pdservice_reviewer01: reviewers01,
+ c_pdservice_reviewer02: reviewers02,
+ c_pdservice_reviewer03: reviewers03,
+ c_pdservice_reviewer04: reviewers04,
+ c_pdservice_reviewer05: reviewers05,
+ c_pdservice_contents: CKEDITOR.instances.input_pdservice_editor.getData()
+ },
+ statusCode: {
+ 200: function () {
+ jSuccess($("#editview_pdservice_name").val() + "의 데이터가 변경되었습니다.");
+
+ //데이터 테이블 데이터 재 로드
+ reloadDataWithSameOrdering(cTitle);
+ }
+ }
+ });
+ });
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 팝업에서 제품(서비스) 변경 저장 버튼
+////////////////////////////////////////////////////////////////////////////////////////
+function popup_update_btn_click() {
+ $("#extendupdate_pdservice").click(function () {
+ var owner = "none";
+ if ($("#extend_editview_pdservice_owner").select2("data")[0] != undefined) {
+ owner = $("#extend_editview_pdservice_owner").select2("data")[0].text;
+ }
+
+ var reviewers01 = "none";
+ var reviewers02 = "none";
+ var reviewers03 = "none";
+ var reviewers04 = "none";
+ var reviewers05 = "none";
+ if ($("#extend_editview_pdservice_reviewers").select2("data")[0] != undefined) {
+ reviewers01 = $("#extend_editview_pdservice_reviewers").select2("data")[0].text;
+ }
+ if ($("#extend_editview_pdservice_reviewers").select2("data")[1] != undefined) {
+ reviewers02 = $("#extend_editview_pdservice_reviewers").select2("data")[1].text;
+ }
+ if ($("#extend_editview_pdservice_reviewers").select2("data")[2] != undefined) {
+ reviewers03 = $("#extend_editview_pdservice_reviewers").select2("data")[2].text;
+ }
+ if ($("#extend_editview_pdservice_reviewers").select2("data")[3] != undefined) {
+ reviewers04 = $("#extend_editview_pdservice_reviewers").select2("data")[3].text;
+ }
+ if ($("#extend_editview_pdservice_reviewers").select2("data")[4] != undefined) {
+ reviewers05 = $("#extend_editview_pdservice_reviewers").select2("data")[4].text;
+ }
+
+ $.ajax({
+ url: "/auth-user/api/arms/pdService/updateNode.do",
+ type: "put",
+ data: {
+ c_id: $("#pdservice_table").DataTable().rows(".selected").data()[0].c_id,
+ c_title: $("#extend_editview_pdservice_name").val(),
+ c_pdservice_owner: owner,
+ c_pdservice_reviewer01: reviewers01,
+ c_pdservice_reviewer02: reviewers02,
+ c_pdservice_reviewer03: reviewers03,
+ c_pdservice_reviewer04: reviewers04,
+ c_pdservice_reviewer05: reviewers05,
+ c_pdservice_contents: CKEDITOR.instances.extend_modal_editor.getData()
+ },
+ statusCode: {
+ 200: function () {
+ //모달 팝업 끝내고
+ $("#extendclose_pdservice").trigger("click");
+
+ jSuccess($("#extend_editview_pdservice_name").val() + "의 데이터가 변경되었습니다.");
+
+ $("#fileIdlink").val(selectId);
+ pdServiceDataTableClick(selectId);
+
+ //파일 업로드 관련 레이어 보이기 처리
+ $(".body-middle").show();
+
+ //파일 리스트 초기화
+ $("table tbody.files").empty();
+ // Load existing files:
+ var $fileupload = $("#fileupload");
+ // Load existing files:
+ $.ajax({
+ // Uncomment the following to send cross-domain cookies:
+ //xhrFields: {withCredentials: true},
+ url: "/auth-user/api/arms/fileRepository/getFilesByNode.do",
+ data: { fileIdlink: selectId },
+ dataType: "json",
+ context: $fileupload[0]
+ }).done(function (result) {
+ $(this).fileupload("option", "done").call(this, null, { result: result });
+ });
+ }
+ }
+ });
+ });
+}
+
+///////////////////////////////
+// 팝업 띄울 때, UI 일부 수정되도록
+////////////////////////////////
+function modalPopup(popupName) {
+ console.log("popupName= " + popupName);
+ if (popupName === "modal_popup_readonly") {
+ //modal_popup_readOnly = 새 창으로 제품(서비스 보기)
+ $("#my_modal1_title").text("제품(서비스) 내용 보기 팝업");
+ $("#my_modal1_sub").text("새 창으로 제품(서비스)의 정보를 확인합니다.")
+ $("#extendupdate_pdservice").addClass("hidden");
+
+
+ } else { //팝업 창으로 편집하기
+
+ $("#my_modal1_title").text("신규 제품(서비스) 수정 팝업");
+ $("#my_modal1_sub").text("A-RMS에 신규 제품(서비스)의 정보를 수정합니다.")
+ $("#extendupdate_pdservice").removeClass("hidden");
+
+
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 최초 dataTable_build 시 정렬 기준을 dataTableRef.ajax.reload 때마다 가져와서 세팅한다.
+// 일관 된 정렬을 보장하기 위한 함수이다.
+////////////////////////////////////////////////////////////////////////////////////////
+function reloadDataWithSameOrdering(cTitle) {
+ const currentOrder = dataTableRef.order();
+ dataTableRef.ajax.reload(function() {
+ dataTableRef.order(currentOrder).draw();
+ if(cTitle === "") return false;
+ $("#pdservice_table tbody tr").each(function() {
+ const rowTitle = $(this).find("td label").text();
+ if (rowTitle === cTitle) {
+ $(this).click();
+ return false;
+ }
+ });
+ });
+}
Index: controltower/nv.d3.min.js.map
===================================================================
diff -u
--- controltower/nv.d3.min.js.map (revision 0)
+++ controltower/nv.d3.min.js.map (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1 @@
+{}
\ No newline at end of file
Index: controltower/pdfmake.min.js.map
===================================================================
diff -u
--- controltower/pdfmake.min.js.map (revision 0)
+++ controltower/pdfmake.min.js.map (revision b4e0eb3622174702570e139565b080d84999f5a5)
@@ -0,0 +1 @@
+{}
\ No newline at end of file