add files
This commit is contained in:
commit
0e61ff5f8d
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"workbench.colorCustomizations": {
|
||||||
|
"activityBar.background": "#452236",
|
||||||
|
"titleBar.activeBackground": "#61304C",
|
||||||
|
"titleBar.activeForeground": "#FCF9FB"
|
||||||
|
}
|
||||||
|
}
|
34
apis/taskApi.js
Normal file
34
apis/taskApi.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
export default {
|
||||||
|
workingHours: {
|
||||||
|
list: "general/get",
|
||||||
|
load: "general/load",
|
||||||
|
add: "general/add",
|
||||||
|
taskAdd: "details/add",
|
||||||
|
taskEdit: "details/edit",
|
||||||
|
day: "details/page/day",
|
||||||
|
delete: "details/delete",
|
||||||
|
deleteHours: "general/delete/time",
|
||||||
|
complitionAll: "details/complition/title",
|
||||||
|
complition: "details/complition/title/{{query}}",
|
||||||
|
copy: "general/copy",
|
||||||
|
move: "general/move",
|
||||||
|
},
|
||||||
|
taskChart: {
|
||||||
|
donut: "chart/getCategory",
|
||||||
|
},
|
||||||
|
taskTeams: {
|
||||||
|
getList: "group/list",
|
||||||
|
delete: "group/delete ",
|
||||||
|
edit: "group/edit ",
|
||||||
|
add:"group/add",
|
||||||
|
members:"perm/list",
|
||||||
|
addMembers:"perm/add",
|
||||||
|
deleteMembers:"perm/delete",
|
||||||
|
editMembers:"perm/edit",
|
||||||
|
},
|
||||||
|
taskReport: {
|
||||||
|
getList: "general/getList",
|
||||||
|
groupList:"group/list",
|
||||||
|
sortgroup:"general/load/group",
|
||||||
|
},
|
||||||
|
};
|
568
assets/task/scss/components/_mian.scss
Normal file
568
assets/task/scss/components/_mian.scss
Normal file
|
@ -0,0 +1,568 @@
|
||||||
|
.main-page__content {
|
||||||
|
// height: calc(100dvh - 68px);
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
min-height: calc(100% - 70px);
|
||||||
|
margin-right: var(--sidebar-collapsed-width);
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.menu-bar__content {
|
||||||
|
position: static !important;
|
||||||
|
flex: 1 1 100%;
|
||||||
|
max-width: 30em;
|
||||||
|
// max-width: 20em;
|
||||||
|
width: auto;
|
||||||
|
// min-width: 40em;
|
||||||
|
|
||||||
|
&.show-list-panel {
|
||||||
|
right: 0 !important;
|
||||||
|
}
|
||||||
|
.date-picker {
|
||||||
|
.vpd-input-group {
|
||||||
|
.vpd-icon-btn {
|
||||||
|
height: 1.8em;
|
||||||
|
}
|
||||||
|
// .form-control {
|
||||||
|
// width: 18em;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.alert {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
border-radius: 0.25em !important;
|
||||||
|
margin-bottom: 0.5em !important;
|
||||||
|
&-secondary {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
&-light {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
border-radius: 0.25em !important;
|
||||||
|
display: flex;
|
||||||
|
&-header {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
&-body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.year-dropdown {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
.mounth-dropdown {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-item {
|
||||||
|
.group-row {
|
||||||
|
.group-picture-container {
|
||||||
|
.group-picture.mini-mode {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.group-picture {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.groups-header {
|
||||||
|
.left-icons {
|
||||||
|
color: #bdc6d0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#accordionExample {
|
||||||
|
// max-height: 51em !important;
|
||||||
|
max-height: calc(100dvh - 13em)!important;
|
||||||
|
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
.rotate-icon {
|
||||||
|
transform-origin: center center;
|
||||||
|
transition: transform 0.3s ease; /* افکت دوران با سرعت 0.3 ثانیه */
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate-icon.rotated {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
.main-page {
|
||||||
|
&_header {
|
||||||
|
display: flex;
|
||||||
|
// margin-top: 1em;
|
||||||
|
}
|
||||||
|
&_total {
|
||||||
|
border: 1px rgb(223 223 223) solid;
|
||||||
|
border-radius: 0.25em !important;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
&-1 {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
&_a {
|
||||||
|
color: var(--color-items-4);
|
||||||
|
}
|
||||||
|
&_b {
|
||||||
|
color: var(--color-items-5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-2 {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
&_a {
|
||||||
|
color: var(--color-items-4);
|
||||||
|
}
|
||||||
|
&_b {
|
||||||
|
color: var(--color-items-3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&_date {
|
||||||
|
border-radius: 0.25em !important;
|
||||||
|
// padding: 1em;
|
||||||
|
&-daysweek {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
color: var(--color-items-5);
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
&-icon-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
&-icon-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
#typeNumber {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--color-items-5);
|
||||||
|
}
|
||||||
|
.form-control {
|
||||||
|
border-radius: 0.5em !important;
|
||||||
|
height: calc(2em + 0.35rem + 2px) !important;
|
||||||
|
padding: 0.5em;
|
||||||
|
width: 6em;
|
||||||
|
&.multiselect {
|
||||||
|
border: 1px solid var(--primary-color);
|
||||||
|
width: 14em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_body {
|
||||||
|
// border: 1px rgb(223 223 223) solid;
|
||||||
|
height: 30em;
|
||||||
|
margin-top: 1em;
|
||||||
|
|
||||||
|
border-radius: 0.25em;
|
||||||
|
// &-form-outline{
|
||||||
|
// max-height: 4em !important;
|
||||||
|
// overflow: auto !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .tasks_form {
|
||||||
|
// min-height: 18em;
|
||||||
|
// height: auto;
|
||||||
|
// overflow-y: auto;
|
||||||
|
// max-height: calc(100vh - 30em);
|
||||||
|
// }
|
||||||
|
|
||||||
|
&-items {
|
||||||
|
height: 3.5em;
|
||||||
|
&-move-copy {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
.date-picker {
|
||||||
|
input {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
svg {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.vpd-icon-btn {
|
||||||
|
padding: unset !important ;
|
||||||
|
|
||||||
|
background-color: unset !important;
|
||||||
|
margin-bottom: unset !important;
|
||||||
|
}
|
||||||
|
// :hover {
|
||||||
|
// color: #6acfef;
|
||||||
|
// transition-duration: 0.3s;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.task-form-control {
|
||||||
|
border: unset;
|
||||||
|
|
||||||
|
border-radius: unset !important;
|
||||||
|
&.Description {
|
||||||
|
border-left: unset !important;
|
||||||
|
text-align: center;
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
&.task-title {
|
||||||
|
text-align: center;
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// &.record{
|
||||||
|
// cursor: pointer;
|
||||||
|
// }
|
||||||
|
&-icon {
|
||||||
|
// font-size:2rem;
|
||||||
|
color: var(--color-items-3);
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
&-record {
|
||||||
|
color: var(--color-items-6);
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
height: 2.5em;
|
||||||
|
}
|
||||||
|
&-close {
|
||||||
|
color: unset !important;
|
||||||
|
}
|
||||||
|
&-add {
|
||||||
|
color: var(--color-items-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-text-record {
|
||||||
|
color: var(--color-items-6);
|
||||||
|
}
|
||||||
|
&-first {
|
||||||
|
background-color: #f7fafe;
|
||||||
|
border: 1px rgb(223 223 223) solid;
|
||||||
|
}
|
||||||
|
.label-0 {
|
||||||
|
display: flex;
|
||||||
|
border-left: 1px var(--color-items-7) solid;
|
||||||
|
align-items: center;
|
||||||
|
height: 2em;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.label-1 {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
height: 2em;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.label-2 {
|
||||||
|
display: flex;
|
||||||
|
height: 2em;
|
||||||
|
border-left: 1px var(--color-items-7) solid;
|
||||||
|
border-right: 1px var(--color-items-7) solid;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
|
.label-3 {
|
||||||
|
display: flex;
|
||||||
|
height: 2em;
|
||||||
|
justify-content: center;
|
||||||
|
border-left: 1px var(--color-items-7) solid !important;
|
||||||
|
border-right: 1px var(--color-items-7) solid;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.label-Description {
|
||||||
|
display: flex;
|
||||||
|
height: 2em;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.label-4 {
|
||||||
|
display: flex;
|
||||||
|
height: 2em;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
|
&.labels {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
|
&.items {
|
||||||
|
color: var(--color-items-4);
|
||||||
|
&-bottom {
|
||||||
|
border-top: unset;
|
||||||
|
}
|
||||||
|
&-top {
|
||||||
|
border-bottom: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.total {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
.total-all-text {
|
||||||
|
color: var(--color-items-4);
|
||||||
|
}
|
||||||
|
.total-all-number {
|
||||||
|
color: black;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
.indecisive {
|
||||||
|
color: var(--color-items-4);
|
||||||
|
&-number {
|
||||||
|
color: var(--color-items-3);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-icon {
|
||||||
|
font-size: 2rem;
|
||||||
|
color: var(--color-items-2);
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
&-close {
|
||||||
|
font-size: 2rem;
|
||||||
|
color: var(--color-items-3);
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
&-add {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.items-form-control {
|
||||||
|
width: 6em;
|
||||||
|
margin-right: 1em;
|
||||||
|
border-radius: 0.5em !important;
|
||||||
|
height: calc(2.2em + 0.35rem + 2px) !important;
|
||||||
|
margin-right: 0.2em;
|
||||||
|
}
|
||||||
|
.form-label {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
color: var(--color-items-4);
|
||||||
|
margin-left: 8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.alert {
|
||||||
|
display: flex;
|
||||||
|
border: 1px rgb(223 223 223) solid;
|
||||||
|
border-radius: 0.25em !important;
|
||||||
|
margin-bottom: 0.5em !important;
|
||||||
|
&-secondary {
|
||||||
|
}
|
||||||
|
&-light {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.coolinput {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: fit-content;
|
||||||
|
position: relative;
|
||||||
|
max-width: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolinput label.text {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--color-items-4);
|
||||||
|
font-weight: 700;
|
||||||
|
position: absolute;
|
||||||
|
top: 0.5rem;
|
||||||
|
margin: 0 0 0 3em;
|
||||||
|
padding: 0 3px;
|
||||||
|
background: #fff;
|
||||||
|
width: auto !important;
|
||||||
|
|
||||||
|
top: -0.8em;
|
||||||
|
right: 2em;
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolinput input[type="text"].input {
|
||||||
|
padding: 11px 10px;
|
||||||
|
font-size: 1rem;
|
||||||
|
border: 1px #eee solid;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolinput input[type="text"].input:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
text-align: center;
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
.multiselect {
|
||||||
|
input {
|
||||||
|
text-align: right !important ;
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
&-lable {
|
||||||
|
width: 5em !important;
|
||||||
|
color: var(--color-items-5);
|
||||||
|
background-color: #fff;
|
||||||
|
z-index: 99;
|
||||||
|
margin: 0 0 0 10em !important;
|
||||||
|
font-size: 0.58rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.task-Form-Organ {
|
||||||
|
border-left: 1px var(--color-items-7) solid !important;
|
||||||
|
}
|
||||||
|
// .tasks_form{
|
||||||
|
// max-height: 20em;
|
||||||
|
// overflow: auto;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .right-section-mobile{
|
||||||
|
// // position: fixed;
|
||||||
|
// // z-index: 99;
|
||||||
|
// // top: 0;
|
||||||
|
// // right: -20em;
|
||||||
|
// // height:80% ;
|
||||||
|
// // -webkit-box-shadow: -5px 0 6px 0 #666;
|
||||||
|
// // box-shadow: -5px 0 6px 0 #666;
|
||||||
|
// // width: 30em;
|
||||||
|
// // background-color: #fff;
|
||||||
|
// }
|
||||||
|
.btn-copy {
|
||||||
|
font-size: 1rem;
|
||||||
|
width: 14em;
|
||||||
|
height: 35px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.164);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.btn-move {
|
||||||
|
font-size: 1rem;
|
||||||
|
width: 14em;
|
||||||
|
height: 35px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.164);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.text-move {
|
||||||
|
width: 90%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
// color: white;
|
||||||
|
background-color: rgb(2, 153, 153);
|
||||||
|
}
|
||||||
|
.text-copy {
|
||||||
|
width: 90%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
// color: white;
|
||||||
|
background-color: #196f93;
|
||||||
|
}
|
||||||
|
.svgIcon-move {
|
||||||
|
width: 20%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: teal;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.svgIcon-copy {
|
||||||
|
width: 20%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #004761;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.btn-move:hover .text-move {
|
||||||
|
background-color: rgb(0, 133, 133);
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
}
|
||||||
|
.btn-copy:hover .text-copy {
|
||||||
|
background-color: #03688d;
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-move:hover .svgIcon-move {
|
||||||
|
background-color: rgb(0, 105, 105);
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
}
|
||||||
|
.btn-copy:hover .svgIcon-copy {
|
||||||
|
background-color: #015370;
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card-header {
|
||||||
|
padding: 0.65rem 0.35rem !important;
|
||||||
|
&_titles {
|
||||||
|
&-icon {
|
||||||
|
font-size: 0.6rem;
|
||||||
|
}
|
||||||
|
&.text-1 {
|
||||||
|
color: var(--color-items-1);
|
||||||
|
padding-right: unset !important;
|
||||||
|
padding-left: unset !important;
|
||||||
|
}
|
||||||
|
&.text-2 {
|
||||||
|
color: var(--color-items-1);
|
||||||
|
// margin-right: 4em;
|
||||||
|
// margin-left: 4em;
|
||||||
|
padding-right: unset !important;
|
||||||
|
padding-left: unset !important;
|
||||||
|
}
|
||||||
|
&.text-3 {
|
||||||
|
color: var(--color-items-2);
|
||||||
|
padding-right: unset !important;
|
||||||
|
padding-left: unset !important;
|
||||||
|
}
|
||||||
|
&.text-4 {
|
||||||
|
color: var(--color-items-3);
|
||||||
|
// margin-right: 4em;
|
||||||
|
padding-right: unset !important;
|
||||||
|
padding-left: unset !important;
|
||||||
|
|
||||||
|
// margin-left: 4em;
|
||||||
|
}
|
||||||
|
&.text-5 {
|
||||||
|
color: var(--color-items-3);
|
||||||
|
// margin-left: 4em;
|
||||||
|
}
|
||||||
|
&.tavasi {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
// margin-right: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&_items {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
&.item-1 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
267
assets/task/scss/components/_responsive.scss
Normal file
267
assets/task/scss/components/_responsive.scss
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
.form-outline2 {
|
||||||
|
padding-right: unset !important;
|
||||||
|
padding-left: unset !important;
|
||||||
|
max-width: 4em !important;
|
||||||
|
}
|
||||||
|
.main-page_header {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
flex-direction: column-reverse !important;
|
||||||
|
}
|
||||||
|
.main-page_body-items-move-copy {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.main-page_date .form-control {
|
||||||
|
border-radius: 0.5em !important;
|
||||||
|
height: calc(2em + 0.35rem + 2px) !important;
|
||||||
|
padding: 0.5em;
|
||||||
|
width: 4em;
|
||||||
|
}
|
||||||
|
.breadcrumbs{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @media only screen and (min-width: 576px) and (max-width: 767.98px) {
|
||||||
|
// .main-page_header {
|
||||||
|
// max-height: 10em;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
@media only screen and (min-width: 768px) and (max-width: 991.98px) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 992px) and (max-width: 1049.98px) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 1050px) and (max-width: 1399.99px) {
|
||||||
|
}
|
||||||
|
@media (min-width: 1400px) {
|
||||||
|
}
|
||||||
|
@media (max-width: 1400px) {
|
||||||
|
.menu-bar__content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
// .multiselect-lable{
|
||||||
|
// display: none;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
}
|
||||||
|
@media (max-width: 992px) {
|
||||||
|
.menu-bar__content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.hiddens {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.main-page_total {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
height: 6em;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
width: 1em !important;
|
||||||
|
}
|
||||||
|
.main-page_body .form-label {
|
||||||
|
margin-right: 0.5em !important;
|
||||||
|
}
|
||||||
|
.main-page_header {
|
||||||
|
flex-direction: column-reverse !important;
|
||||||
|
}
|
||||||
|
.items-form-control {
|
||||||
|
width: 5em !important;
|
||||||
|
}
|
||||||
|
.total-all-number,
|
||||||
|
.indecisive-number {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.hours-form {
|
||||||
|
height: 5em !important;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
}
|
||||||
|
.main-page_body-items.labels {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.main-page_body-items .label-1 {
|
||||||
|
border-right: 1px var(--color-items-7) solid !important;
|
||||||
|
}
|
||||||
|
.main-page_body-items .label-3 {
|
||||||
|
}
|
||||||
|
.task-form-control {
|
||||||
|
border-left: unset !important;
|
||||||
|
}
|
||||||
|
// .coolinput input[type="text"].input {
|
||||||
|
// font-size: 0.75rem !important;
|
||||||
|
// }
|
||||||
|
.coolinput {
|
||||||
|
padding-right: unset !important;
|
||||||
|
padding-left: unset !important;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
&-basic {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-label {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
color: var(--color-items-4);
|
||||||
|
margin-left: 2em !important;
|
||||||
|
}
|
||||||
|
.main-page_date-daysweek {
|
||||||
|
font-size: 1.5rem !important;
|
||||||
|
}
|
||||||
|
.icon-Component-358--1 {
|
||||||
|
width: 1.5em !important;
|
||||||
|
}
|
||||||
|
.icon-Component-359--1 {
|
||||||
|
width: 1.5em !important;
|
||||||
|
}
|
||||||
|
.coolinput label.text {
|
||||||
|
margin: 0 0 0 2em;
|
||||||
|
}
|
||||||
|
.tribute-container.mini {
|
||||||
|
width: 18em;
|
||||||
|
}
|
||||||
|
.multiselect__single {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
.form-outline {
|
||||||
|
&.day {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
&.year {
|
||||||
|
margin-right: 2.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.multiselect {
|
||||||
|
&.template {
|
||||||
|
border: 3px solid rgb(127, 170, 170);
|
||||||
|
padding: 0.7em !important;
|
||||||
|
width: 15em;
|
||||||
|
}
|
||||||
|
&-lable {
|
||||||
|
margin: 0 0 0 10em !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.multiselect__content-wrapper {
|
||||||
|
z-index: 99;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.main-page_body-items.total {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.main-page_body-items-move-copy.in-desktop {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.btn-copy {
|
||||||
|
width: 4em !important;
|
||||||
|
}
|
||||||
|
.btn-move {
|
||||||
|
width: 4em !important;
|
||||||
|
}
|
||||||
|
.svgIcon-move {
|
||||||
|
width: 0% !important;
|
||||||
|
}
|
||||||
|
.svgIcon-copy {
|
||||||
|
width: 0% !important;
|
||||||
|
}
|
||||||
|
.text-move {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
.text-copy {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
.prevDay,
|
||||||
|
.nextDay {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.main-page_date {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: column !important;
|
||||||
|
}
|
||||||
|
.form-control.multiselect {
|
||||||
|
width: 26em !important;
|
||||||
|
}
|
||||||
|
.task-dashboard {
|
||||||
|
.my-card {
|
||||||
|
&.Gantt {
|
||||||
|
margin-top: 1.5em !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.pages-content-container {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
padding-right: 0 !important;
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
|
.pages-content {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
margin-left: 0 !important;
|
||||||
|
margin-right: 0.8em !important;
|
||||||
|
}
|
||||||
|
.selects {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
.jahat-pagination {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column !important;
|
||||||
|
}
|
||||||
|
.table-responsive {
|
||||||
|
max-height: calc(100dvh + -18.5em) !important ;
|
||||||
|
|
||||||
|
}
|
||||||
|
.page-border-top {
|
||||||
|
justify-content: flex-start !important;
|
||||||
|
}
|
||||||
|
.all-selects {
|
||||||
|
flex-direction: column !important;
|
||||||
|
}
|
||||||
|
.grouping,
|
||||||
|
.form-sorting_user {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .tasks_form{
|
||||||
|
// max-height: 20em;
|
||||||
|
// overflow: auto;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .main-page_date{
|
||||||
|
// padding-right: unset !important;
|
||||||
|
// padding-left: unset !important;
|
||||||
|
// }
|
||||||
|
// .main-page_header{
|
||||||
|
// padding-right: unset !important;
|
||||||
|
// padding-left: unset !important;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.hiddens {
|
||||||
|
display: inline-block !important;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
&-mobile {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.task-navbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.main-page_body-items-move-copy.in-mobile {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// .tasks_form{
|
||||||
|
// max-height: 28em;
|
||||||
|
// overflow: auto;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .avatar{
|
||||||
|
// display: none !important
|
||||||
|
// }
|
0
assets/task/scss/components/_variabels.scss
Normal file
0
assets/task/scss/components/_variabels.scss
Normal file
60
assets/task/scss/components/multiselect.scss
Normal file
60
assets/task/scss/components/multiselect.scss
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
.multiselect__tags {
|
||||||
|
border: unset !important;
|
||||||
|
|
||||||
|
}
|
||||||
|
.multiselect__content-wrapper {
|
||||||
|
z-index: 99;
|
||||||
|
// right: -0.6em;
|
||||||
|
// width: 24em;
|
||||||
|
// max-height: 30em !important;
|
||||||
|
}
|
||||||
|
// .multiselect__select{
|
||||||
|
// left: 1.5em !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// <!-- #region multiselect styles -->
|
||||||
|
// <style lang="scss">
|
||||||
|
.multiselect__option--selected.multiselect__option--highlight:after {
|
||||||
|
content: "\e940";
|
||||||
|
font-family: "tavasi" !important;
|
||||||
|
speak: never;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
color: #fff !important;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
.multiselect__option--highlight:after {
|
||||||
|
content: "\e994";
|
||||||
|
font-family: "tavasi" !important;
|
||||||
|
speak: never;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
color: #fff !important;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiselect__option--selected:after {
|
||||||
|
content: "\e994";
|
||||||
|
font-family: "tavasi" !important;
|
||||||
|
speak: never;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
color: green !important;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
|
color: #aaa;
|
||||||
|
background: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// </style>
|
||||||
|
// <!-- #endregion -->
|
7
assets/task/scss/task.scss
Normal file
7
assets/task/scss/task.scss
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
@import "./components/_variabels";
|
||||||
|
|
||||||
|
.task-system {
|
||||||
|
@import "./components/mian";
|
||||||
|
@import "./components/responsive";
|
||||||
|
@import "./components/multiselect";
|
||||||
|
}
|
668
components/AddMemberToTeamModal.vue
Normal file
668
components/AddMemberToTeamModal.vue
Normal file
|
@ -0,0 +1,668 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="modal fade share-modal__modal"
|
||||||
|
id="share-modal"
|
||||||
|
tabindex="-1"
|
||||||
|
aria-labelledby="exampleModalLabel"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content popUp-tab share-modal">
|
||||||
|
<div class="popUp-tab__content tab-content share-modal__content">
|
||||||
|
<div class="share-modal__search-content">
|
||||||
|
<div class="share-modal__content">
|
||||||
|
<div class="share-modal__search-top p-3">
|
||||||
|
<!-- <i class="tavasi tavasi-Component-360--58"
|
||||||
|
><span class="path1"></span><span class="path2"></span
|
||||||
|
></i> -->
|
||||||
|
<span class="text__gray me-1"> انتخاب عضو </span>
|
||||||
|
</div>
|
||||||
|
<div class="share-modal__search">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="جستجوی عضو جدید..."
|
||||||
|
id="searchForName"
|
||||||
|
v-model="query"
|
||||||
|
@keyup="showSearchResult"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="user-search-recommend"
|
||||||
|
class="share-modal__search-recommend"
|
||||||
|
:class="{ show: suggestionMode }"
|
||||||
|
>
|
||||||
|
<div class="search-recommend">
|
||||||
|
<div
|
||||||
|
class="search-users__item"
|
||||||
|
v-for="(user, i) in userSuggestions"
|
||||||
|
:key="'h' + i"
|
||||||
|
>
|
||||||
|
<div class="search-users__pic">
|
||||||
|
<img :src="userAvatar(user)" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="search-users__content">
|
||||||
|
<div class="search-users__name">
|
||||||
|
{{ user.full_name }}
|
||||||
|
</div>
|
||||||
|
<div class="search-users__id">@{{ user.username }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="search-users__type">
|
||||||
|
<div class="order-select main-page__date-select">
|
||||||
|
<select
|
||||||
|
@change="addUser($event, user)"
|
||||||
|
class="form-control d-block"
|
||||||
|
>
|
||||||
|
<option selected disabled :value="undefined">
|
||||||
|
دسترسی
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
v-for="role in roles"
|
||||||
|
:key="role.id"
|
||||||
|
:value="role.id"
|
||||||
|
>
|
||||||
|
{{ role.title }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "sharemodal",
|
||||||
|
props: ["item", "itemType"],
|
||||||
|
mounted() {
|
||||||
|
this.httpService = new HttpService(this.loginMicroServiceName);
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
httpService: undefined,
|
||||||
|
newItemType: 0,
|
||||||
|
suggestionMode: false,
|
||||||
|
query: "",
|
||||||
|
userSuggestions: [],
|
||||||
|
userToAdd: [],
|
||||||
|
roles: [
|
||||||
|
{ title: "عادی",id:1},
|
||||||
|
{ title: "مشاهده",id:10},
|
||||||
|
{ title: "سرگروه",id:500},
|
||||||
|
{ title: "مالک",id:1000 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// formData(url, data = []) {
|
||||||
|
// const formData = new FormData();
|
||||||
|
// for (const [key, value] of Object.entries(data)) {
|
||||||
|
// if (value !== undefined && value !== null) formData.append(key, value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return axios.post(url, formData);
|
||||||
|
// },
|
||||||
|
showSearchResult() {
|
||||||
|
var vm = this;
|
||||||
|
if (this.query.length > 2) {
|
||||||
|
this.httpService
|
||||||
|
.postRequest("user/suggestion", { query: this.query })
|
||||||
|
.then((response) => {
|
||||||
|
var items = response.data;
|
||||||
|
vm.userSuggestions = items;
|
||||||
|
vm.suggestionMode = true;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
vm.userSuggestions = [];
|
||||||
|
vm.suggestionMode = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addUser(ev, item) {
|
||||||
|
this.userToAdd.push(item);
|
||||||
|
this.suggestionMode = false;
|
||||||
|
|
||||||
|
this.$emit("update-member", {
|
||||||
|
user_id: item.user_id,
|
||||||
|
perm_type: +ev.target.value,
|
||||||
|
});
|
||||||
|
// this.addPerm(ev, item);
|
||||||
|
},
|
||||||
|
addPerm(ev, item) {
|
||||||
|
// var guid = this.item.guid;
|
||||||
|
// this.userToAdd.forEach(function (item) {
|
||||||
|
// ApiService.post(this, "perm/set", {
|
||||||
|
// pid: guid,
|
||||||
|
// act: "add",
|
||||||
|
// read: 1,
|
||||||
|
// write: 0,
|
||||||
|
// username: item.username,
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
@import "../../../assets/permit/scss/permit.scss";
|
||||||
|
</style>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.share-modal {
|
||||||
|
height: 20em;
|
||||||
|
background-color: #fff;
|
||||||
|
top: 7em;
|
||||||
|
left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-modal__search-top {
|
||||||
|
background-color: #eee;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-modal__search-recommend {
|
||||||
|
opacity: 1;
|
||||||
|
display: block;
|
||||||
|
position: static;
|
||||||
|
visibility: visible;
|
||||||
|
height: calc(100% - 12.5em);
|
||||||
|
overflow: auto;
|
||||||
|
display: none;
|
||||||
|
opacity: unset;
|
||||||
|
visibility: hidden;
|
||||||
|
top: 117px;
|
||||||
|
right: 0px;
|
||||||
|
width: 100%;
|
||||||
|
background: white;
|
||||||
|
-webkit-transition: all 0.3s ease-in-out;
|
||||||
|
transition: all 0.3s ease-in-out;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
display: none;
|
||||||
|
z-index: 10;
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
position: static !important;
|
||||||
|
opacity: 1 !important;
|
||||||
|
display: block !important;
|
||||||
|
visibility: visible !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.share-modal {
|
||||||
|
width: 30em !important;
|
||||||
|
&__content {
|
||||||
|
width: 30em !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 35.938em) {
|
||||||
|
.share-modal {
|
||||||
|
width: 23em !important;
|
||||||
|
&__content {
|
||||||
|
width: 23em !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// &__modal {
|
||||||
|
// .modal-dialog {
|
||||||
|
// transform: unset !important;
|
||||||
|
// transition: unset !important;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__content {
|
||||||
|
// position: relative;
|
||||||
|
// width: 337px;
|
||||||
|
// height: 385px;
|
||||||
|
// display: flex;
|
||||||
|
// flex-direction: column;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__search-content {
|
||||||
|
// position: absolute;
|
||||||
|
// top: 0;
|
||||||
|
// left: 0;
|
||||||
|
// width: 100%;
|
||||||
|
// height: 100%;
|
||||||
|
// transition: all 0.3s ease-in-out;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__search {
|
||||||
|
// border-bottom: 1px solid #f1f1f1;
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
// padding-top: 15px;
|
||||||
|
// padding-bottom: 15px;
|
||||||
|
|
||||||
|
// span {
|
||||||
|
// font-size: 16px;
|
||||||
|
// // color: var(--color-2);
|
||||||
|
// width: 50px;
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
|
||||||
|
// i {
|
||||||
|
// cursor: pointer;
|
||||||
|
// color: #92a2b2;
|
||||||
|
// font-size: 24px;
|
||||||
|
// width: 70px;
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
// align-items: center;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #get-back {
|
||||||
|
// width: 70px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// input {
|
||||||
|
// flex-grow: 2;
|
||||||
|
// border: unset;
|
||||||
|
// outline: unset;
|
||||||
|
// // color: var(--color-2);
|
||||||
|
// font-size: 14px;
|
||||||
|
|
||||||
|
// &::placeholder {
|
||||||
|
// color: #92a2b2;
|
||||||
|
// font-size: 14px;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__add-person {
|
||||||
|
// width: 50px;
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
|
||||||
|
// i {
|
||||||
|
// font-size: 24px;
|
||||||
|
// -webkit-transition: all 0.5s ease-in-out;
|
||||||
|
// transition: all 0.5s ease-in-out;
|
||||||
|
// font-size: 23px;
|
||||||
|
// background: -webkit-linear-gradient(#a9bdc4 0%, #c6cfda 100%);
|
||||||
|
// background-clip: border-box;
|
||||||
|
// -webkit-background-clip: text;
|
||||||
|
// -webkit-text-fill-color: transparent;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &:hover {
|
||||||
|
// i {
|
||||||
|
// background: -webkit-linear-gradient(#00b6e3 0%, #81e6ff 100%);
|
||||||
|
// background-clip: border-box;
|
||||||
|
// -webkit-background-clip: text;
|
||||||
|
// -webkit-text-fill-color: transparent;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__search-recommend {
|
||||||
|
// display: none;
|
||||||
|
// opacity: unset;
|
||||||
|
// visibility: hidden;
|
||||||
|
// position: absolute;
|
||||||
|
// top: 57px;
|
||||||
|
// right: 0px;
|
||||||
|
// width: 100%;
|
||||||
|
// height: calc(100% - 57px);
|
||||||
|
// background: white;
|
||||||
|
// transition: all 0.3s ease-in-out;
|
||||||
|
// opacity: 0;
|
||||||
|
// visibility: hidden;
|
||||||
|
// display: none;
|
||||||
|
// z-index: 10;
|
||||||
|
|
||||||
|
// .os-host {
|
||||||
|
// height: 100%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .os-host-resize-disabled.os-host-scrollbar-horizontal-hidden > .os-scrollbar-vertical {
|
||||||
|
// bottom: 0;
|
||||||
|
// right: 7px;
|
||||||
|
// top: 17px;
|
||||||
|
// width: 0px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .os-theme-dark > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle {
|
||||||
|
// background: rgba(0, 0, 0, 0.16);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__users {
|
||||||
|
// flex-grow: 1;
|
||||||
|
// max-height: 259px;
|
||||||
|
|
||||||
|
// .os-scrollbar-vertical {
|
||||||
|
// width: 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__icon {
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
// align-items: center;
|
||||||
|
// margin-bottom: 18px;
|
||||||
|
|
||||||
|
// img {
|
||||||
|
// width: 142px;
|
||||||
|
// padding-top: 42px;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__text {
|
||||||
|
// color: #92a2b2;
|
||||||
|
// font-size: 14px;
|
||||||
|
// padding-bottom: 37px;
|
||||||
|
// width: 246px;
|
||||||
|
// text-align: center;
|
||||||
|
// margin-right: auto;
|
||||||
|
// margin-left: auto;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__search-content-footer {
|
||||||
|
// display: flex;
|
||||||
|
// align-items: flex-end;
|
||||||
|
// justify-content: space-between;
|
||||||
|
// padding-top: 15px;
|
||||||
|
// padding-bottom: 15px;
|
||||||
|
// border-top: 1px solid #bac4ce;
|
||||||
|
// padding-right: 22px;
|
||||||
|
// padding-left: 22px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__sign {
|
||||||
|
// display: flex;
|
||||||
|
// flex-direction: column;
|
||||||
|
|
||||||
|
// span {
|
||||||
|
// font-size: 12px;
|
||||||
|
// color: #92a2b2;
|
||||||
|
// display: block;
|
||||||
|
// margin-bottom: 2px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// a {
|
||||||
|
// // color: var(--color-1);
|
||||||
|
// font-size: 12px;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__settings {
|
||||||
|
// a {
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__settings-btn {
|
||||||
|
// font-size: 14px;
|
||||||
|
// // color: var(--color-1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__settings-content {
|
||||||
|
// position: absolute;
|
||||||
|
// top: 0;
|
||||||
|
// left: 0;
|
||||||
|
// width: 100%;
|
||||||
|
// height: 100%;
|
||||||
|
// transition: all 0.3s ease-in-out;
|
||||||
|
// opacity: 0;
|
||||||
|
// visibility: hidden;
|
||||||
|
// display: none;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__title {
|
||||||
|
// padding-top: 15px;
|
||||||
|
// padding-bottom: 15px;
|
||||||
|
// border-bottom: 1px solid #f1f1f1;
|
||||||
|
// padding-right: 22px;
|
||||||
|
// padding-left: 22px;
|
||||||
|
|
||||||
|
// h4 {
|
||||||
|
// font-size: 16px;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__form {
|
||||||
|
// padding-right: 22px;
|
||||||
|
// padding-left: 22px;
|
||||||
|
|
||||||
|
// &-question {
|
||||||
|
// font-size: 14px;
|
||||||
|
// font-weight: 500;
|
||||||
|
// text-shadow: 0 -0.75px #6b6b6b;
|
||||||
|
// margin-bottom: 17px;
|
||||||
|
// color: #444444;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &-item {
|
||||||
|
// padding-top: 17px;
|
||||||
|
|
||||||
|
// &:last-child {
|
||||||
|
// margin-bottom: 17px;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &-radio-item {
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
|
||||||
|
// &:not(:last-child) {
|
||||||
|
// margin-bottom: 20px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// input {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// label {
|
||||||
|
// color: #444444;
|
||||||
|
// font-size: 14px;
|
||||||
|
// margin-right: 16px;
|
||||||
|
// margin-bottom: 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &-btn {
|
||||||
|
// min-width: 57px;
|
||||||
|
// height: 32px;
|
||||||
|
// border-radius: 20px;
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
// align-items: center;
|
||||||
|
// margin-right: 10px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &-radio {
|
||||||
|
// position: relative;
|
||||||
|
|
||||||
|
// input {
|
||||||
|
// position: absolute;
|
||||||
|
// opacity: 0;
|
||||||
|
// cursor: pointer;
|
||||||
|
// height: 20px;
|
||||||
|
// width: 20px;
|
||||||
|
// z-index: 5;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// span {
|
||||||
|
// display: flex;
|
||||||
|
// height: 20px;
|
||||||
|
// width: 20px;
|
||||||
|
// border-radius: 50%;
|
||||||
|
// border: 2px solid #bac4ce;
|
||||||
|
// transition: all 0.3s ease-in-out;
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
// align-items: center;
|
||||||
|
|
||||||
|
// &::before {
|
||||||
|
// content: " ";
|
||||||
|
// width: 10px;
|
||||||
|
// height: 10px;
|
||||||
|
// border-radius: 50%;
|
||||||
|
// display: flex;
|
||||||
|
// background: linear-gradient(#3def90 0%, #1ed975 100%);
|
||||||
|
// opacity: 0;
|
||||||
|
// transition: all 0.3s ease-in-out;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// input:checked ~ span::before {
|
||||||
|
// opacity: 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__form-btn--deactive {
|
||||||
|
// font-size: 14px;
|
||||||
|
// // color: var(--color-2);
|
||||||
|
|
||||||
|
// &:hover {
|
||||||
|
// opacity: 0.8;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__from-btn--active {
|
||||||
|
// // border: 2px solid var(--color-1);
|
||||||
|
// // color: var(--color-1);
|
||||||
|
// font-size: 14px;
|
||||||
|
|
||||||
|
// &:hover {
|
||||||
|
// color: white;
|
||||||
|
// // background: var(--color-1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__setting-footer {
|
||||||
|
// margin-top: auto;
|
||||||
|
// border-top: 1px solid #f1f1f1;
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: flex-end;
|
||||||
|
// padding: 16px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__people-search {
|
||||||
|
// background: #fff;
|
||||||
|
// position: absolute;
|
||||||
|
// top: 0;
|
||||||
|
// display: none;
|
||||||
|
|
||||||
|
// left: 0;
|
||||||
|
// width: 100%;
|
||||||
|
// height: 100%;
|
||||||
|
// transition: all 0.3s ease-in-out;
|
||||||
|
// opacity: 0;
|
||||||
|
// visibility: hidden;
|
||||||
|
|
||||||
|
// .os-host {
|
||||||
|
// height: 100%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .os-host-resize-disabled.os-host-scrollbar-horizontal-hidden > .os-scrollbar-vertical {
|
||||||
|
// bottom: 0;
|
||||||
|
// right: 7px;
|
||||||
|
// top: 17px;
|
||||||
|
// width: 0px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .os-theme-dark > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle {
|
||||||
|
// background: rgba(0, 0, 0, 0.16);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__user-search-content {
|
||||||
|
// opacity: unset;
|
||||||
|
|
||||||
|
// width: 100%;
|
||||||
|
// height: calc(100% - 57px);
|
||||||
|
// background: white;
|
||||||
|
// transition: all 0.3s ease-in-out;
|
||||||
|
// top: 57px;
|
||||||
|
// display: none;
|
||||||
|
|
||||||
|
// .os-host {
|
||||||
|
// height: 100%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .os-host-resize-disabled.os-host-scrollbar-horizontal-hidden > .os-scrollbar-vertical {
|
||||||
|
// bottom: 0;
|
||||||
|
// right: 7px;
|
||||||
|
// top: 17px;
|
||||||
|
// width: 0px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .os-theme-dark > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle {
|
||||||
|
// background: rgba(0, 0, 0, 0.16);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__users-footer {
|
||||||
|
// display: flex;
|
||||||
|
// flex-direction: column;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__textarea {
|
||||||
|
// border-top: 1px solid #f1f1f1;
|
||||||
|
// padding-top: 12px;
|
||||||
|
// padding-bottom: 12px;
|
||||||
|
// padding-right: 22px;
|
||||||
|
// padding-left: 22px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__invite-row {
|
||||||
|
// border-top: 1px solid #f1f1f1;
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
// padding-top: 17.5px;
|
||||||
|
// padding-bottom: 26px;
|
||||||
|
// justify-content: space-between;
|
||||||
|
// padding-right: 22px;
|
||||||
|
// padding-left: 22px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__select {
|
||||||
|
// font-size: 14px;
|
||||||
|
|
||||||
|
// .main-page__date-select .select-selected {
|
||||||
|
// border: unset;
|
||||||
|
// padding: 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .main-page__date-select .select-selected {
|
||||||
|
// height: 32px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .select-items {
|
||||||
|
// width: 160px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .main-page__date-select .select-items {
|
||||||
|
// top: unset;
|
||||||
|
// bottom: calc(5px + 100%);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__send-invite {
|
||||||
|
// a {
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
// align-items: center;
|
||||||
|
// min-width: 120px;
|
||||||
|
// border-radius: 20px;
|
||||||
|
// // border: 2px solid var(--color-1);
|
||||||
|
// height: 32px;
|
||||||
|
// font-size: 14px;
|
||||||
|
|
||||||
|
// &:hover {
|
||||||
|
// color: white;
|
||||||
|
// // background: var(--color-1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
</style>
|
270
components/HoursForm.vue
Normal file
270
components/HoursForm.vue
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
<template>
|
||||||
|
<form class="hours-form mb-1">
|
||||||
|
<div class="row-hours">
|
||||||
|
<div class="form-group col coolinput">
|
||||||
|
<label for="input" class="form-label text"> ورود :</label>
|
||||||
|
<input
|
||||||
|
name="input"
|
||||||
|
v-model="hourswork.inTime"
|
||||||
|
v-on:blur="inTimeCorrect(hourswork.inTime, $event)"
|
||||||
|
v-on:focus="timeFocus('intime', hourswork.inTime)"
|
||||||
|
placeholder="00:00"
|
||||||
|
ref="intime"
|
||||||
|
type="text"
|
||||||
|
maxlength="5"
|
||||||
|
class="form-control items-form-control input"
|
||||||
|
pattern="/^\d{1,2}:\d{1,2}$/gm"
|
||||||
|
required="required"
|
||||||
|
:class="{ invalid: invalidInTime }"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col coolinput">
|
||||||
|
<label for="input" class="form-label text">خروج :</label>
|
||||||
|
<input
|
||||||
|
name="input"
|
||||||
|
v-model="hourswork.outTime"
|
||||||
|
v-on:blur="outTimeCorrect(hourswork.outTime, $event)"
|
||||||
|
v-on:focus="timeFocus('outtime', hourswork.outTime)"
|
||||||
|
placeholder="00:00"
|
||||||
|
ref="outtime"
|
||||||
|
type="text"
|
||||||
|
maxlength="5"
|
||||||
|
required="required"
|
||||||
|
pattern="/^\d{1,2}:\d{1,2}$/gm"
|
||||||
|
class="form-control items-form-control input"
|
||||||
|
:class="{ invalid: invalidOutTime }"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col coolinput">
|
||||||
|
<label for="input" class="form-label text">غیرمفید :</label>
|
||||||
|
<input
|
||||||
|
name="input"
|
||||||
|
v-model="hourswork.noWorkTime"
|
||||||
|
v-on:blur="noWorkTimeCorrect(hourswork.noWorkTime)"
|
||||||
|
v-on:focus="timeFocus('noworktime', hourswork.noWorkTime)"
|
||||||
|
placeholder="00:00"
|
||||||
|
ref="noworktime"
|
||||||
|
type="text"
|
||||||
|
class="form-control items-form-control input"
|
||||||
|
@keydown.tab="saveHoursWork()"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-auto d-flex me-auto align-items-center">
|
||||||
|
<button-component
|
||||||
|
v-if="hoursFormsLenght <= 1"
|
||||||
|
@click="deleteMainTime()"
|
||||||
|
buttonText=""
|
||||||
|
v-tooltip="'حذف زمان کاری'"
|
||||||
|
>
|
||||||
|
<span class="text-danger">
|
||||||
|
<svg class="icon icon-Component-295--1">
|
||||||
|
<use xlink:href="#icon-Component-295--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button-component>
|
||||||
|
|
||||||
|
<span
|
||||||
|
@click="saveHoursWork()"
|
||||||
|
title=" ثبت"
|
||||||
|
class="btn main-page_body-icon"
|
||||||
|
>
|
||||||
|
<svg class="icon icon-Component-233--1 main-page_body-icon-add">
|
||||||
|
<use xlink:href="#icon-Component-233--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-if="!itemIndex && hoursFormsLenght < 3"
|
||||||
|
title=" اضافه کردن"
|
||||||
|
class="btn main-page_body-icon pe-0 ps-0"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
title="اضافه کردن"
|
||||||
|
@click="openFormHoursInformation()"
|
||||||
|
class="icon icon-Component-133--1"
|
||||||
|
>
|
||||||
|
<use xlink:href="#icon-Component-133--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
title="حذف"
|
||||||
|
@click="deleteFormHoursInformation(hourswork)"
|
||||||
|
class="btn main-page_body-icon-close pe-0 ps-0"
|
||||||
|
>
|
||||||
|
<svg class="icon icon-Component-21--1">
|
||||||
|
<use xlink:href="#icon-Component-21--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
itemIndex: {
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
hoursFormsLenght: {
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
hourswork: {
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
inTime: "",
|
||||||
|
outTime: "",
|
||||||
|
noWorkTime: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ["delete-form-hours", "save-form-hours", "add-new-record"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
invalidInTime: false,
|
||||||
|
invalidOutTime: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// ...mapGetters(["currentUser"]),
|
||||||
|
// ...mapGetters("list", ["listGetter"]),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
timeFocus(ref, value) {
|
||||||
|
if (!value) value = "00:00";
|
||||||
|
this.$refs[ref].select();
|
||||||
|
},
|
||||||
|
inTimeCorrect(value) {
|
||||||
|
if (!value) value = "00:00";
|
||||||
|
let res = this.timeCorrect(value);
|
||||||
|
if (res) this.hourswork.inTime = res;
|
||||||
|
},
|
||||||
|
outTimeCorrect(value) {
|
||||||
|
if (!value) value = "00:00";
|
||||||
|
let res = this.timeCorrect(value);
|
||||||
|
if (res) this.hourswork.outTime = res;
|
||||||
|
},
|
||||||
|
noWorkTimeCorrect(value) {
|
||||||
|
if (!value) value = "00:00";
|
||||||
|
let res = this.timeCorrect(value);
|
||||||
|
if (res) this.hourswork.noWorkTime = res;
|
||||||
|
},
|
||||||
|
timeCorrect(value) {
|
||||||
|
// if (value.charCodeAt()) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (value == null) return value;
|
||||||
|
value = value.trim();
|
||||||
|
value = value.replace(".", ":");
|
||||||
|
value = value.replace(" ", ":");
|
||||||
|
|
||||||
|
if (value.indexOf(":") == -1) {
|
||||||
|
if (value.length == 0) value = "00:00";
|
||||||
|
else if (value.length == 1) value = "0" + value + ":00";
|
||||||
|
else if (value.length == 2) value = value + ":00";
|
||||||
|
else if (value.length == 3)
|
||||||
|
value = "0" + value.substring(0, 1) + ":" + value.substring(1);
|
||||||
|
else if (value.length == 4)
|
||||||
|
value =
|
||||||
|
value.substring(0, 2) + ":" + value.substring(2).padStart(2, "0");
|
||||||
|
else if (value.length > 4)
|
||||||
|
value = value.substring(0, 2) + ":" + value.substring(3, 5);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
deleteMainTime() {
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار!!!",
|
||||||
|
html: "تمامی کارهای امروز پاک خواهد. آیا مطمئن هستید؟ ",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.$emit("delete-form-hours");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteFormHoursInformation() {
|
||||||
|
this.$emit("delete-form-hours");
|
||||||
|
},
|
||||||
|
saveHoursWork() {
|
||||||
|
const inTimeIsInvalid1 = this.hourswork.inTime == null;
|
||||||
|
const inTimeIsInvalid2 = this.hourswork.inTime?.indexOf("00:00") > -1;
|
||||||
|
// const inTimeIsInvalid3 = this.hourswork.inTime?.indexOf("0:00") > -1;
|
||||||
|
|
||||||
|
const outTimeIsInvalid1 = this.hourswork.outTime == null;
|
||||||
|
const outTimeIsInvalid2 = this.hourswork.outTime?.indexOf("00:00") > -1;
|
||||||
|
// const outTimeIsInvalid3 = this.hourswork.outTime?.indexOf("0:00") > -1;
|
||||||
|
|
||||||
|
if (
|
||||||
|
inTimeIsInvalid1 ||
|
||||||
|
inTimeIsInvalid2 ||
|
||||||
|
// inTimeIsInvalid3 ||
|
||||||
|
outTimeIsInvalid1 ||
|
||||||
|
outTimeIsInvalid2
|
||||||
|
// || outTimeIsInvalid3
|
||||||
|
) {
|
||||||
|
this.invalidInTime = inTimeIsInvalid1 || inTimeIsInvalid2;
|
||||||
|
this.invalidOutTime = outTimeIsInvalid1 || outTimeIsInvalid2;
|
||||||
|
|
||||||
|
this.mySwalToast({
|
||||||
|
icon: "error",
|
||||||
|
title: "ورودی نامعتبر",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.invalidInTime = false;
|
||||||
|
this.invalidOutTime = false;
|
||||||
|
|
||||||
|
this.noWorkTimeCorrect(this.hourswork.noWorkTime);
|
||||||
|
this.$emit("save-form-hours");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openFormHoursInformation() {
|
||||||
|
const inTimeIsInvalid =
|
||||||
|
this.hourswork.inTime == null || this.hourswork.inTime == "00:00";
|
||||||
|
const outTimeIsInvalid =
|
||||||
|
this.hourswork.outTime == null || this.hourswork.outTime == "00:00";
|
||||||
|
|
||||||
|
if (inTimeIsInvalid || outTimeIsInvalid) {
|
||||||
|
this.invalidInTime = inTimeIsInvalid;
|
||||||
|
this.invalidOutTime = outTimeIsInvalid;
|
||||||
|
|
||||||
|
this.mySwalToast({
|
||||||
|
icon: "error",
|
||||||
|
title: "ورودی نامعتبر",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.invalidInTime = false;
|
||||||
|
this.invalidOutTime = false;
|
||||||
|
|
||||||
|
this.$emit("add-new-record");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.hours-form {
|
||||||
|
border: 1px rgb(223, 223, 223) solid;
|
||||||
|
height: 5em;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
}
|
||||||
|
.form-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.row-hours {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
&.invalid {
|
||||||
|
border: 1px solid red !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
863
components/MainSection.vue
Normal file
863
components/MainSection.vue
Normal file
|
@ -0,0 +1,863 @@
|
||||||
|
<template>
|
||||||
|
<div class="main-page container-fluid">
|
||||||
|
<div class="row d-flex justify-content-center">
|
||||||
|
<div class="col-12 main-page_header d-flex">
|
||||||
|
<!-- <SelectTemplate class="col-sm-12 col-md-2 task-Form-category">
|
||||||
|
|
||||||
|
</SelectTemplate> -->
|
||||||
|
<div class="col-12 main-page_date mt-3 d-flex align-items-center">
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<h4 class="main-page_date-daysweek m-0">{{ weekDay }}</h4>
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<div class="row d-flex justify-content-center">
|
||||||
|
<div class="main-page_date-icon-right col-auto px-1">
|
||||||
|
<span class="d-flex btn" title="روز بعد" @click="nextDay()">
|
||||||
|
<svg class="icon icon-Component-358--1">
|
||||||
|
<use xlink:href="#icon-Component-358--1"></use>
|
||||||
|
</svg>
|
||||||
|
<span class="nextDay">بعدی</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-outline day col-auto px-1 coolinput">
|
||||||
|
<label class="form-label text" for="typeNumber">روز:</label>
|
||||||
|
<input
|
||||||
|
name="input"
|
||||||
|
v-model.number="workDay"
|
||||||
|
min="0"
|
||||||
|
max="32"
|
||||||
|
placeholder="--"
|
||||||
|
type="number"
|
||||||
|
id="typeNumber"
|
||||||
|
class="main-page_date form-control input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-outline form-outline2 col-auto px-1 coolinput">
|
||||||
|
<label class="form-label text" for="typeNumber">ماه:</label>
|
||||||
|
<input
|
||||||
|
v-model.number="workMonth"
|
||||||
|
min="01"
|
||||||
|
max="12"
|
||||||
|
placeholder="--"
|
||||||
|
type="number"
|
||||||
|
id="typeNumber"
|
||||||
|
class="main-page_date form-control input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-outline year col-auto px-1 coolinput">
|
||||||
|
<label class="form-label text" for="typeNumber">سال:</label>
|
||||||
|
<input
|
||||||
|
min="1400"
|
||||||
|
v-model.number="workYear"
|
||||||
|
placeholder="14--"
|
||||||
|
type="number"
|
||||||
|
id="typeNumber"
|
||||||
|
class="main-page_date form-control input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="main-page_date-icon-left col-auto px-1">
|
||||||
|
<span class="d-flex btn" title="روز قبل" @click="prevDay()">
|
||||||
|
<span class="prevDay">قبلی</span>
|
||||||
|
<svg class="icon icon-Component3601">
|
||||||
|
<use xlink:href="#icon-Component3601"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-can="'times_user_search'"
|
||||||
|
class="coolinput select-template d-flex align-items-center mb-2 mb-md-0 ms-lg-2"
|
||||||
|
>
|
||||||
|
<label class="multiselect-lable text no-wrap width-auto" for="users"
|
||||||
|
>جستجوی کاربر:</label
|
||||||
|
>
|
||||||
|
<multiselect
|
||||||
|
class="multiselect template form-control input w-auto"
|
||||||
|
id="users"
|
||||||
|
track-by="user_id"
|
||||||
|
placeholder="جستجوی..."
|
||||||
|
v-model="selectedUser"
|
||||||
|
:show-labels="false"
|
||||||
|
:options="foundUsers"
|
||||||
|
:searchable="true"
|
||||||
|
:preserve-search="true"
|
||||||
|
:internal-search="false"
|
||||||
|
:clearOnSelect="false"
|
||||||
|
:clear-on-select="false"
|
||||||
|
:close-on-select="true"
|
||||||
|
:options-limit="300"
|
||||||
|
:limit="3"
|
||||||
|
:limit-text="limitText"
|
||||||
|
:max-height="350"
|
||||||
|
:customLabel="
|
||||||
|
(item) => {
|
||||||
|
return `${item.first_name} ${item.last_name}`;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@search-change="asyncFind"
|
||||||
|
@select="addUserToGroup"
|
||||||
|
@close="resetFoundUsers"
|
||||||
|
>
|
||||||
|
</multiselect>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="coolinput select-template d-flex align-items-center">
|
||||||
|
<label class="multiselect-lable text" for="input">نوع قالب</label>
|
||||||
|
<multiselect
|
||||||
|
class="multiselect template form-control input w-auto"
|
||||||
|
v-model="templateValue"
|
||||||
|
:options="multiSelectOptions"
|
||||||
|
:max-height="250"
|
||||||
|
@select="setTagTemplate"
|
||||||
|
label="name"
|
||||||
|
track-by="title"
|
||||||
|
></multiselect>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="main-page_body">
|
||||||
|
<div class="main-page_body-form-outline">
|
||||||
|
<hours-form
|
||||||
|
v-for="(hourswork, index) in hoursForms"
|
||||||
|
:key="index"
|
||||||
|
:itemIndex="index"
|
||||||
|
:hourswork="hourswork"
|
||||||
|
:hoursFormsLenght="hoursForms.length"
|
||||||
|
@add-new-record="openFormHoursInformation(index)"
|
||||||
|
@delete-form-hours="deleteFormHoursInformation(index)"
|
||||||
|
@save-form-hours="saveHoursWork(hourswork, index)"
|
||||||
|
></hours-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="overlay3 overlay3-entrance1 3-entrance2 3-entrance3">
|
||||||
|
<div class="main-page_body-items labels d-flex align-items-center">
|
||||||
|
<label
|
||||||
|
v-if="templateValue.title == 'multi-org_workbase'"
|
||||||
|
class="col-1 label-0"
|
||||||
|
style="background-color: #97f295 !important"
|
||||||
|
>سازمان</label
|
||||||
|
>
|
||||||
|
<label class="col-2 label-1">*دسته</label>
|
||||||
|
<label class="col-3 label-2">*عنوان</label>
|
||||||
|
<label class="col-1 label-3">*مدت</label>
|
||||||
|
<label class="col-4 label-Description">چالش،پیشنهاد،توضیح</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tasks_form">
|
||||||
|
<task-form
|
||||||
|
v-for="(taskForm, index) in taskForms"
|
||||||
|
:key="index"
|
||||||
|
:hoursFormsLenght="index"
|
||||||
|
:taskForm="taskForm"
|
||||||
|
:itemIndex="index"
|
||||||
|
:templateValue="templateValue"
|
||||||
|
@add-new-record="openFormTaskInformation()"
|
||||||
|
@close-form-tasks="closeFormTaskInformation(taskForm.id, index)"
|
||||||
|
@save-form-tasks="postInTaskWork"
|
||||||
|
></task-form>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="main-page_body-items record d-flex justify-content-center align-items-center col-12"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
title="رکورد جدید"
|
||||||
|
@click="openFormTaskInformation()"
|
||||||
|
class="btn main-page_body-items-icon-record align-items-center"
|
||||||
|
>
|
||||||
|
<svg class="icon icon-Component-133--1">
|
||||||
|
<use xlink:href="#icon-Component-133--1"></use>
|
||||||
|
</svg>
|
||||||
|
<span class="main-page_body-items-text-record">رکورد جدید</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="main-page_body-items total d-flex align-items-center col-12">
|
||||||
|
<label class="col total-all-text"
|
||||||
|
>جمع کل : <span class="total-all-number ms-3">{{ sum }}</span></label
|
||||||
|
>
|
||||||
|
|
||||||
|
<label class="col indecisive"
|
||||||
|
>بلاتکلیف : <span class="indecisive-number">{{ noWork }}</span></label
|
||||||
|
>
|
||||||
|
<div class="main-page_body-items-move-copy in-desktop mt-2">
|
||||||
|
<div class="btn-move move ms-3">
|
||||||
|
<date-picker
|
||||||
|
title="انتقال"
|
||||||
|
label="انتقال محتوا به تاریخ دیگر"
|
||||||
|
class="date-picker text-move"
|
||||||
|
v-model="dateValueMove"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
display-format="jYYYY-jMM-jDD"
|
||||||
|
@input="PostDateToMoveInformation()"
|
||||||
|
/>
|
||||||
|
<span class="svgIcon-move" title="انتقال">
|
||||||
|
<svg class="icon icon-forward">
|
||||||
|
<use xlink:href="#icon-forward"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="copy btn-copy">
|
||||||
|
<date-picker
|
||||||
|
title="کپی"
|
||||||
|
label="کپی محتوا به تاریخ دیگر"
|
||||||
|
class="date-picker text-copy"
|
||||||
|
v-model="dateValueCopy"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
display-format="jYYYY-jMM-jDD"
|
||||||
|
@input="PostDateToCopyInformation()"
|
||||||
|
/>
|
||||||
|
<span class="svgIcon-copy" title="کپی">
|
||||||
|
<svg class="icon icon-copy2">
|
||||||
|
<use xlink:href="#icon-copy2"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main-page_body-items-move-copy in-mobile mt-2">
|
||||||
|
<div class="btn-move move ms-3">
|
||||||
|
<date-picker
|
||||||
|
title="انتقال"
|
||||||
|
label="انتقال"
|
||||||
|
class="date-picker text-move"
|
||||||
|
v-model="dateValueMove"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
display-format="jYYYY-jMM-jDD"
|
||||||
|
@input="PostDateToMoveInformation()"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span class="svgIcon-move" title="انتقال">
|
||||||
|
<svg class="icon icon-forward">
|
||||||
|
<use xlink:href="#icon-forward"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="copy btn-copy">
|
||||||
|
<date-picker
|
||||||
|
title="کپی"
|
||||||
|
label="کپی"
|
||||||
|
class="date-picker text-copy"
|
||||||
|
v-model="dateValueCopy"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
display-format="jYYYY-jMM-jDD"
|
||||||
|
@input="PostDateToCopyInformation()"
|
||||||
|
/>
|
||||||
|
<span class="svgIcon-copy" title="کپی">
|
||||||
|
<svg class="icon icon-copy2">
|
||||||
|
<use xlink:href="#icon-copy2"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// import ImageUploader from "vue-image-upload-resize";
|
||||||
|
// import keyValueApi from "@apis/keyValueApi";
|
||||||
|
// import { mapActions, mapGetters, mapMutations } from "vuex";
|
||||||
|
import taskApi from "@apis/taskApi";
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
import VuePersianDatetimePicker from "vue-persian-datetime-picker";
|
||||||
|
import { p2e } from "@plugins/persianNumber";
|
||||||
|
import { mapGetters, mapMutations } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.setCurrentUserData();
|
||||||
|
|
||||||
|
var d = new Date().toLocaleDateString("fa-IR");
|
||||||
|
let items = d.split("/");
|
||||||
|
|
||||||
|
let year = p2e(items[0]);
|
||||||
|
let month = p2e(items[1]);
|
||||||
|
let day = p2e(items[2]);
|
||||||
|
let weekDay = new Date().toLocaleDateString("fa-IR", { weekday: "short" });
|
||||||
|
this.setDate(day, month, year, weekDay);
|
||||||
|
|
||||||
|
this.getDetailsDay();
|
||||||
|
|
||||||
|
|
||||||
|
if(this.taskSchemaGetter?.organTypeOptions){
|
||||||
|
this.multiSelectOptions = this.taskSchemaGetter?.organTypeOptions;
|
||||||
|
this.templateValue = this.taskSchemaGetter?.organTypeOptions[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
foundUsers: [],
|
||||||
|
selectedUser: {
|
||||||
|
id: undefined,
|
||||||
|
user_id: undefined,
|
||||||
|
first_name: undefined,
|
||||||
|
last_name: undefined,
|
||||||
|
username: undefined,
|
||||||
|
full_name: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
color: undefined,
|
||||||
|
},
|
||||||
|
multiSelectOptions: [],
|
||||||
|
templateValue: {
|
||||||
|
name: "تک سازمانی - کارمحور",
|
||||||
|
title: "single-org_workbase",
|
||||||
|
},
|
||||||
|
hoursForms: [
|
||||||
|
{
|
||||||
|
inTime: "",
|
||||||
|
outTime: "",
|
||||||
|
noWorkTime: "",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
taskForms: [
|
||||||
|
{
|
||||||
|
organ: "",
|
||||||
|
category: "",
|
||||||
|
title: "",
|
||||||
|
duration: "",
|
||||||
|
description: "",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
inTime: "",
|
||||||
|
outTime: "",
|
||||||
|
noWorkTime: "",
|
||||||
|
workDay: "",
|
||||||
|
workMonth: "",
|
||||||
|
workYear: "",
|
||||||
|
weekDay: "",
|
||||||
|
// useFullTime: "",
|
||||||
|
// allTime: "",
|
||||||
|
taskId: "",
|
||||||
|
noWork: "",
|
||||||
|
sum: "",
|
||||||
|
itemsId: "",
|
||||||
|
loading: false,
|
||||||
|
hoursformCount: 1,
|
||||||
|
isMultiOrgan: false,
|
||||||
|
dateValueCopy: "",
|
||||||
|
dateValueMove: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(["currentUser", "taskSchemaGetter"]),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setCurrentUserData() {
|
||||||
|
this.selectedUser = {
|
||||||
|
id: this.currentUser.user_id,
|
||||||
|
user_id: this.currentUser.user_id,
|
||||||
|
first_name: this.currentUser.user_data.first_name,
|
||||||
|
last_name: this.currentUser.user_data.last_name,
|
||||||
|
username: this.currentUser.user_data.username,
|
||||||
|
full_name: null,
|
||||||
|
avatar: this.currentUser.user_data.username,
|
||||||
|
color: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
limitText(count) {
|
||||||
|
return `و ${count} کاربر دیگر`;
|
||||||
|
},
|
||||||
|
asyncFind(query) {
|
||||||
|
const url = this.loginMicroServiceName + "/user/suggestion";
|
||||||
|
|
||||||
|
if (query.trim().length) {
|
||||||
|
this.httpService.postRequest(url, { query }).then((response) => {
|
||||||
|
this.foundUsers = response.data ?? [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addUserToGroup(selectedUser) {
|
||||||
|
this.$root.$emit("request-based-on-new-user-data", selectedUser.id);
|
||||||
|
},
|
||||||
|
resetFoundUsers() {
|
||||||
|
// this.foundUsers = [];
|
||||||
|
// this.fetchingData = false;
|
||||||
|
},
|
||||||
|
getDetailsDay() {
|
||||||
|
this.hoursForms = [];
|
||||||
|
let payload = {
|
||||||
|
user_id: this.selectedUser.user_id,
|
||||||
|
};
|
||||||
|
const url = this.taskMicroServiceName + taskApi.workingHours.day;
|
||||||
|
|
||||||
|
if (this.workDay) {
|
||||||
|
payload.taskDate =
|
||||||
|
this.workYear + "-" + this.workMonth + "-" + this.workDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.httpService.postRequest(url, payload).then((res) => {
|
||||||
|
if (res.hourswork?.length) {
|
||||||
|
this.hoursForms = res.hourswork;
|
||||||
|
this.itemsId = res.task_id;
|
||||||
|
} else
|
||||||
|
this.hoursForms.push({
|
||||||
|
inTime: null,
|
||||||
|
outTime: null,
|
||||||
|
noWorkTime: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.taskForms = res.data;
|
||||||
|
this.taskForms.push({
|
||||||
|
organ: "",
|
||||||
|
category: "",
|
||||||
|
title: "",
|
||||||
|
duration: "",
|
||||||
|
description: "",
|
||||||
|
});
|
||||||
|
this.noWork = res.day_sum.noWork;
|
||||||
|
this.sum = res.day_sum.sum;
|
||||||
|
|
||||||
|
let { day, month, year, weekDay } = res;
|
||||||
|
this.setDate(day, month, year, weekDay);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setDate(day, month, year, weekDay) {
|
||||||
|
this.weekDay = weekDay;
|
||||||
|
this.workDay = day;
|
||||||
|
this.workMonth = month;
|
||||||
|
this.workYear = year;
|
||||||
|
},
|
||||||
|
|
||||||
|
// openFormHoursInformation(index) {
|
||||||
|
|
||||||
|
// if (
|
||||||
|
// this.hoursForms[index].inTime !== null &&
|
||||||
|
// this.hoursForms[index].outTime !== null &&
|
||||||
|
// this.hoursForms[index].noWorkTime !== null
|
||||||
|
// ) {
|
||||||
|
// this.hoursForms.push({
|
||||||
|
// inTime: "",
|
||||||
|
// outTime: "",
|
||||||
|
// noWorkTime: "",
|
||||||
|
// });
|
||||||
|
// this.saveHoursWork();
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
openFormHoursInformation(index) {
|
||||||
|
this.hoursformCount++;
|
||||||
|
|
||||||
|
this.hoursForms.push({
|
||||||
|
inTime: "",
|
||||||
|
outTime: "",
|
||||||
|
noWorkTime: "",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteFormHoursInformation(index) {
|
||||||
|
this.hoursformCount--;
|
||||||
|
|
||||||
|
const url = this.taskMicroServiceName + taskApi.workingHours.deleteHours;
|
||||||
|
let payload = { id: this.itemsId, index: this.hoursForms[index].index ?? (index + 1) };
|
||||||
|
if (
|
||||||
|
this.hoursForms[index].inTime != "" ||
|
||||||
|
this.hoursForms[index].outTime != ""
|
||||||
|
) {
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار!!!",
|
||||||
|
html: "از حذف این مورد مطمئن هستید؟",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.httpService.postRequest(url, payload).then((response) => {
|
||||||
|
this.getDetailsDay();
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "مورد با موفقیت حذف شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.hoursForms.splice(index, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openFormTaskInformation() {
|
||||||
|
// if (this.itemsId == "") {
|
||||||
|
// this.saveHoursWork(this.hoursForms[0], 0, false);
|
||||||
|
// }
|
||||||
|
|
||||||
|
this.taskForms.push({
|
||||||
|
organ: "",
|
||||||
|
category: "",
|
||||||
|
title: "",
|
||||||
|
duration: "",
|
||||||
|
description: "",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
closeFormTaskInformation(taskFormsId, index) {
|
||||||
|
const url = this.taskMicroServiceName + taskApi.workingHours.delete;
|
||||||
|
const payload = { id: taskFormsId };
|
||||||
|
|
||||||
|
if (taskFormsId) {
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار!!!",
|
||||||
|
html: "از حذف این مورد مطمئن هستید؟",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.httpService.postRequest(url, payload).then((response) => {
|
||||||
|
this.getDetailsDay();
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "مورد با موفقیت حذف شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (
|
||||||
|
this.taskForms[index].organ != "" ||
|
||||||
|
this.taskForms[index].category != "" ||
|
||||||
|
this.taskForms[index].duration != "" ||
|
||||||
|
this.taskForms[index].title != ""
|
||||||
|
) {
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار!!!",
|
||||||
|
html: "از حذف این مورد مطمئن هستید؟",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.taskForms.splice(index, 1);
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "مورد با موفقیت حذف شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.taskForms.splice(index, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validTime(value) {
|
||||||
|
const regex = /^\d{1,2}:\d{1,2}$/gm;
|
||||||
|
let isValid = value.match(regex);
|
||||||
|
return isValid;
|
||||||
|
},
|
||||||
|
timeCorrect(value) {
|
||||||
|
if (value == null) return value;
|
||||||
|
value = value.trim();
|
||||||
|
value = value.replace(".", ":");
|
||||||
|
value = value.replace(" ", ":");
|
||||||
|
|
||||||
|
if (value.indexOf(":") == -1) {
|
||||||
|
if (value.length == 0) value = "00:00";
|
||||||
|
else if (value.length == 1) value = "0" + value + ":00";
|
||||||
|
else if (value.length == 2) value = value + ":00";
|
||||||
|
else if (value.length == 3)
|
||||||
|
value = "0" + value.substring(0, 1) + ":" + value.substring(1);
|
||||||
|
else if (value.length == 4)
|
||||||
|
value =
|
||||||
|
value.substring(0, 2) + ":" + value.substring(2).padStart(2, "0");
|
||||||
|
else if (value.length > 4)
|
||||||
|
value = value.substring(0, 2) + ":" + value.substring(2, 2);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
saveHoursWork(hourswork, index, refreshPage = true) {
|
||||||
|
if (!this.validTime(hourswork.inTime)) {
|
||||||
|
if (!hourswork.inTime) hourswork.inTime = "00:00";
|
||||||
|
hourswork.inTime = timeCorrect(hourswork.inTime);
|
||||||
|
}
|
||||||
|
if (!this.validTime(hourswork.outTime)) {
|
||||||
|
if (!hourswork.outTime) hourswork.outTime = "00:00";
|
||||||
|
hourswork.outTime = timeCorrect(hourswork.outTime);
|
||||||
|
}
|
||||||
|
if (!this.validTime(hourswork.noWorkTime)) {
|
||||||
|
if (!hourswork.noWorkTime) hourswork.noWorkTime = "00:00";
|
||||||
|
hourswork.noWorkTime = timeCorrect(hourswork.noWorkTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
taskDate: this.workYear + "-" + this.workMonth + "-" + this.workDay,
|
||||||
|
inTime: hourswork.inTime ?? "00:00",
|
||||||
|
outTime: hourswork.outTime ?? "00:00",
|
||||||
|
noWorkTime: hourswork.noWorkTime ?? "00:00",
|
||||||
|
index: index + 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const url = this.taskMicroServiceName + taskApi.workingHours.add;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
.then((res) => {
|
||||||
|
this.itemsId = res.id;
|
||||||
|
|
||||||
|
// let { day, month, year, weekDay } = res;
|
||||||
|
// this.setDate(day, month, year, weekDay);
|
||||||
|
|
||||||
|
this.mySwalToast({
|
||||||
|
title: res.message,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.finally(() => {
|
||||||
|
// if (refreshPage) this.getWorkingHours(false);
|
||||||
|
this.getDetailsDay();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
postInTaskWork(taskForm) {
|
||||||
|
if (this.loading) return;
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
let payload = {
|
||||||
|
id: taskForm.id ?? undefined,
|
||||||
|
task_id: this.itemsId,
|
||||||
|
category: taskForm.category,
|
||||||
|
organ: taskForm.organ,
|
||||||
|
title: taskForm.title,
|
||||||
|
duration: taskForm.duration,
|
||||||
|
description: taskForm.description,
|
||||||
|
};
|
||||||
|
|
||||||
|
let url = taskForm.id
|
||||||
|
? taskApi.workingHours.taskEdit
|
||||||
|
: taskApi.workingHours.taskAdd;
|
||||||
|
|
||||||
|
url = this.taskMicroServiceName + url;
|
||||||
|
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
.then((res) => {
|
||||||
|
this.mySwalToast({
|
||||||
|
title: res.message,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.getDetailsDay();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setWorkDay(value) {
|
||||||
|
this.workDay = 26;
|
||||||
|
},
|
||||||
|
nextDay(nextDay) {
|
||||||
|
this.workDay += 1;
|
||||||
|
this.getDetailsDay();
|
||||||
|
},
|
||||||
|
prevDay(prevDay) {
|
||||||
|
if (this.workDay > 1) this.workDay -= 1;
|
||||||
|
else {
|
||||||
|
if (this.workMonth == 1) {
|
||||||
|
this.workMonth = 12;
|
||||||
|
this.workYear -= 1;
|
||||||
|
} else {
|
||||||
|
this.workMonth -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.workMonth == 12) this.workDay = 29;
|
||||||
|
else if (this.workMonth > 6) this.workDay = 30;
|
||||||
|
//if(this.workMonth < 6)
|
||||||
|
else this.workDay = 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getDetailsDay();
|
||||||
|
},
|
||||||
|
setCurrentDate(date) {
|
||||||
|
this.workDay = date.day;
|
||||||
|
this.workMonth = date.month;
|
||||||
|
this.workYear = date.year;
|
||||||
|
|
||||||
|
this.getDetailsDay();
|
||||||
|
},
|
||||||
|
setTagTemplate(newTag) {
|
||||||
|
this.templateValue = newTag;
|
||||||
|
},
|
||||||
|
datefa(item) {
|
||||||
|
var m = item;
|
||||||
|
var d = new Date(m).toLocaleDateString("fa-IR");
|
||||||
|
return d;
|
||||||
|
},
|
||||||
|
PostDateToMoveInformation() {
|
||||||
|
let oldDateMove =
|
||||||
|
this.workYear + "/" + this.workMonth + "/" + this.workDay;
|
||||||
|
let newDateMove = this.datefa(this.dateValueMove);
|
||||||
|
let payload = {
|
||||||
|
user_id: this.$store.getters.currentUser.user_id,
|
||||||
|
oldDate: oldDateMove,
|
||||||
|
newDate: newDateMove,
|
||||||
|
id: this.itemsId,
|
||||||
|
};
|
||||||
|
let payloadReplace = {
|
||||||
|
user_id: this.$store.getters.currentUser.user_id,
|
||||||
|
oldDate: oldDateMove,
|
||||||
|
newDate: newDateMove,
|
||||||
|
id: this.itemsId,
|
||||||
|
replace: 1,
|
||||||
|
append: 0,
|
||||||
|
};
|
||||||
|
let payloadAppend = {
|
||||||
|
user_id: this.$store.getters.currentUser.user_id,
|
||||||
|
oldDate: oldDateMove,
|
||||||
|
newDate: newDateMove,
|
||||||
|
id: this.itemsId,
|
||||||
|
replace: 0,
|
||||||
|
append: 1,
|
||||||
|
};
|
||||||
|
const url = this.taskMicroServiceName + taskApi.workingHours.move;
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار!!!",
|
||||||
|
html:
|
||||||
|
"آیا از انتقال موارد از تاریخ:" +
|
||||||
|
" " +
|
||||||
|
"«" +
|
||||||
|
oldDateMove +
|
||||||
|
"»" +
|
||||||
|
" " +
|
||||||
|
"به تاریخ:" +
|
||||||
|
" " +
|
||||||
|
"«" +
|
||||||
|
newDateMove +
|
||||||
|
"»" +
|
||||||
|
" " +
|
||||||
|
"مطمئن هستید؟",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.httpService.postRequest(url, payload).then((response) => {
|
||||||
|
// console.log(response);
|
||||||
|
if (response?.check_replace == 1) {
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار!!!",
|
||||||
|
html: "برای این تاریخ موارد مشابه وجود دارد آیا مایل به اضافه یا جایگزینی هستید؟",
|
||||||
|
showDenyButton: true,
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "جایگزین",
|
||||||
|
denyButtonText: `اضافه`,
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payloadReplace)
|
||||||
|
.then((response) => {});
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "محتوا با موفقیت جایگزین شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
this.getDetailsDay();
|
||||||
|
} else if (result.isDenied) {
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payloadAppend)
|
||||||
|
.then((response) => {});
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "محتوا با موفقیت اضافه شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
this.getDetailsDay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "محتوا با موفقیت منتقل شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
this.getDetailsDay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PostDateToCopyInformation() {
|
||||||
|
let oldDateCopy =
|
||||||
|
this.workYear + "/" + this.workMonth + "/" + this.workDay;
|
||||||
|
let newDateCopy = this.datefa(this.dateValueCopy);
|
||||||
|
let payload = {
|
||||||
|
user_id: this.$store.getters.currentUser.user_id,
|
||||||
|
oldDate: oldDateCopy,
|
||||||
|
newDate: newDateCopy,
|
||||||
|
id: this.itemsId,
|
||||||
|
};
|
||||||
|
let payloadReplace = {
|
||||||
|
user_id: this.$store.getters.currentUser.user_id,
|
||||||
|
oldDate: oldDateCopy,
|
||||||
|
newDate: newDateCopy,
|
||||||
|
id: this.itemsId,
|
||||||
|
replace: 1,
|
||||||
|
append: 0,
|
||||||
|
};
|
||||||
|
let payloadAppend = {
|
||||||
|
user_id: this.$store.getters.currentUser.user_id,
|
||||||
|
oldDate: oldDateCopy,
|
||||||
|
newDate: newDateCopy,
|
||||||
|
id: this.itemsId,
|
||||||
|
replace: 0,
|
||||||
|
append: 1,
|
||||||
|
};
|
||||||
|
const url = this.taskMicroServiceName + taskApi.workingHours.copy;
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار!!!",
|
||||||
|
html:
|
||||||
|
"آیا از کپی موارد از تاریخ:" +
|
||||||
|
" " +
|
||||||
|
"«" +
|
||||||
|
oldDateCopy +
|
||||||
|
"»" +
|
||||||
|
" " +
|
||||||
|
"به تاریخ:" +
|
||||||
|
" " +
|
||||||
|
"«" +
|
||||||
|
newDateCopy +
|
||||||
|
"»" +
|
||||||
|
" " +
|
||||||
|
"مطمئن هستید؟",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.httpService.postRequest(url, payload).then((response) => {
|
||||||
|
if (response?.check_replace == 1) {
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار!!!",
|
||||||
|
html: "برای این تاریخ موارد مشابه وجود دارد آیا مایل به اضافه یا جایگزینی هستید؟",
|
||||||
|
confirmButtonText: "جایگزین",
|
||||||
|
denyButtonText: `اضافه`,
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payloadReplace)
|
||||||
|
.then((response) => {});
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "محتوا با موفقیت جایگزین شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
this.getDetailsDay();
|
||||||
|
} else if (result.isDenied) {
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payloadAppend)
|
||||||
|
.then((response) => {});
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "محتوا با موفقیت اضافه شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
this.getDetailsDay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "موارد با موفقیت کپی شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
this.getDetailsDay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
TaskForm: () => import("@task/components/TaskForm"),
|
||||||
|
HoursForm: () => import("@task/components/HoursForm"),
|
||||||
|
|
||||||
|
Multiselect: () => import("vue-multiselect"),
|
||||||
|
datePicker: VuePersianDatetimePicker,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss"></style>
|
450
components/MembersSearch.vue
Normal file
450
components/MembersSearch.vue
Normal file
|
@ -0,0 +1,450 @@
|
||||||
|
<template>
|
||||||
|
<div class="user-search-list">
|
||||||
|
<form class="search-filter" role="search" @submit.prevent="sendQuery">
|
||||||
|
<div class="mb-3">
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<span class="tavasi tavasi-Component-198--1"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
ref="search-input"
|
||||||
|
dir="rtl"
|
||||||
|
v-model.trim="searchText"
|
||||||
|
type="search"
|
||||||
|
required
|
||||||
|
class="form-control"
|
||||||
|
id="search-query"
|
||||||
|
placeholder="جستجو..."
|
||||||
|
name="search-query"
|
||||||
|
aria-label="جستجو در اسناد، عناوین و واژگان"
|
||||||
|
aria-describedby="basic-addon1"
|
||||||
|
size="50"
|
||||||
|
@keyup="sendQuery()"
|
||||||
|
@keydown="onKeyDown()"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
v-if="searchText.length"
|
||||||
|
@click="resetFormAndList"
|
||||||
|
type="button"
|
||||||
|
class="btn clear-search p-0"
|
||||||
|
>
|
||||||
|
<svg class="icon icon-Component-294--1">
|
||||||
|
<use xlink:href="#icon-Component-294--1"></use>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="d-flex justify-content-between alert alert-secondary">
|
||||||
|
<div class="col-6">نام و نام خانوادگی</div>
|
||||||
|
<div class="col-4 d-flex justify-content-center">دسترسی</div>
|
||||||
|
<div class="col-2 me-3">حذف</div>
|
||||||
|
</div>
|
||||||
|
<div class="user-list">
|
||||||
|
<div
|
||||||
|
v-for="list in listMember"
|
||||||
|
class="d-flex justify-content-between alert alert-light col-12"
|
||||||
|
>
|
||||||
|
<div class="col-6">
|
||||||
|
{{ list.description }}
|
||||||
|
</div>
|
||||||
|
<div class="order-select main-page__date-select col-4">
|
||||||
|
<select @change="addUser( $event,list)" class="form-control d-block">
|
||||||
|
<option selected disabled :value="undefined">
|
||||||
|
{{ list.perm }}
|
||||||
|
</option>
|
||||||
|
<option v-for="role in roles" :key="role.id" :value="role.id">
|
||||||
|
{{ role.title }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-2 d-flex">
|
||||||
|
<!-- <span class="btn" title="ویرایش" @click="editMember(list)">
|
||||||
|
<svg class="icon edit-member icon-Component-242--1">
|
||||||
|
<use xlink:href="#icon-Component-242--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span> -->
|
||||||
|
<span class="btn me-3" title="حذف" @click="deleteMember(list)">
|
||||||
|
<svg class="icon delete-member icon-Component-295--1">
|
||||||
|
<use xlink:href="#icon-Component-295--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
item: "",
|
||||||
|
parentLoading: false,
|
||||||
|
searchResults: {
|
||||||
|
default() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
listMember: {
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
searchResults(newValu) {
|
||||||
|
this.users = newValu;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.users = this.searchResults;
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
roles: [
|
||||||
|
{ title: "عادی", id: 1 },
|
||||||
|
{ title: "مشاهده", id: 10 },
|
||||||
|
{ title: "سرگروه", id: 500 },
|
||||||
|
{ title: "مالک", id: 1000 },
|
||||||
|
],
|
||||||
|
users: [],
|
||||||
|
typingTimer: 0,
|
||||||
|
doneTypingInterval: 1000,
|
||||||
|
searchText: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectUserAsAdmin(user) {
|
||||||
|
this.$emit("set-as-admin", user);
|
||||||
|
},
|
||||||
|
getGroupAvatar(user = undefined) {
|
||||||
|
try {
|
||||||
|
if (user) {
|
||||||
|
if (isValidHttpUrl(user.avatar)) return user.avatar;
|
||||||
|
else {
|
||||||
|
if ("name" in user) {
|
||||||
|
const nameArray = user.name?.split(" ");
|
||||||
|
if (nameArray?.length > 1) {
|
||||||
|
const initials =
|
||||||
|
nameArray[0].charAt(0) + nameArray[1].charAt(0);
|
||||||
|
return this.generateAvatarFromChars(initials);
|
||||||
|
} else {
|
||||||
|
const initials = nameArray[0].charAt(0);
|
||||||
|
return this.generateAvatarFromChars(initials);
|
||||||
|
}
|
||||||
|
} else if ("lastname" in user) {
|
||||||
|
const nameArray = user.lastname?.split(" ");
|
||||||
|
if (nameArray?.length > 1) {
|
||||||
|
const initials =
|
||||||
|
nameArray[0].charAt(0) + nameArray[1].charAt(0);
|
||||||
|
return this.generateAvatarFromChars(initials);
|
||||||
|
} else {
|
||||||
|
const initials = nameArray[0].charAt(0);
|
||||||
|
return this.generateAvatarFromChars(initials);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ("username" in user) {
|
||||||
|
const nameArray = user.username?.split(" ");
|
||||||
|
if (nameArray?.length > 1) {
|
||||||
|
const initials =
|
||||||
|
nameArray[0].charAt(0) + nameArray[1].charAt(0);
|
||||||
|
return this.generateAvatarFromChars(initials);
|
||||||
|
} else {
|
||||||
|
const initials = nameArray[0].charAt(0);
|
||||||
|
return this.generateAvatarFromChars(initials);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return require("@assets/common/img/default.svg");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sendQuery() {
|
||||||
|
clearTimeout(this.typingTimer);
|
||||||
|
|
||||||
|
this.typingTimer = setTimeout(() => {
|
||||||
|
this.search();
|
||||||
|
}, this.doneTypingInterval);
|
||||||
|
},
|
||||||
|
onKeyDown() {
|
||||||
|
clearTimeout(this.typingTimer);
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
this.$emit("on-send", this.searchText);
|
||||||
|
},
|
||||||
|
resetFormAndList() {
|
||||||
|
this.searchText = "";
|
||||||
|
this.users = [];
|
||||||
|
},
|
||||||
|
deleteMember(list) {
|
||||||
|
this.$emit("delete-member", list);
|
||||||
|
},
|
||||||
|
addUser(event, item) {
|
||||||
|
this.$emit("edit-member", {
|
||||||
|
user_id: item.user_id,
|
||||||
|
id: item.id,
|
||||||
|
perm_type: +event.target.value,
|
||||||
|
});
|
||||||
|
// this.addPerm(ev, item);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.delete-member {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: rgb(189, 61, 87);
|
||||||
|
}
|
||||||
|
.alert {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
%unread-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 0 0.2em;
|
||||||
|
margin: 0;
|
||||||
|
color: #888;
|
||||||
|
color: #888;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-left: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.user-search-list {
|
||||||
|
// max-width: 25em;
|
||||||
|
.search-filter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
// position: absolute;
|
||||||
|
z-index: 999;
|
||||||
|
// top: 24px;
|
||||||
|
// background-color: #fff;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
// background-color: red;
|
||||||
|
.input-group {
|
||||||
|
border-radius: 1.6em;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-text {
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: center;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
// border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-append {
|
||||||
|
.tavasi {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-text {
|
||||||
|
// border-top-right-radius: 0.5em;
|
||||||
|
// border-bottom-right-radius: 0.5em;
|
||||||
|
// background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.input-group-prepend {
|
||||||
|
position: relative;
|
||||||
|
.clear-search {
|
||||||
|
position: absolute;
|
||||||
|
right: -3em;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.input-group-text {
|
||||||
|
// background-color: transparent;
|
||||||
|
// border-top-left-radius: 0.5em;
|
||||||
|
// border-bottom-left-radius: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
height: 2.5em;
|
||||||
|
border-color: transparent;
|
||||||
|
border-radius: 2.5em;
|
||||||
|
&::-webkit-search-decoration,
|
||||||
|
&::-webkit-search-cancel-button,
|
||||||
|
&::-webkit-search-results-button,
|
||||||
|
&::-webkit-search-results-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-search {
|
||||||
|
color: #7f8891;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-list {
|
||||||
|
height: calc(100dvh - 18em);
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.group-item {
|
||||||
|
.group-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
&.enable-hover:hover {
|
||||||
|
.group-picture-container {
|
||||||
|
// .context-menu-dropdown {
|
||||||
|
// display: flex;
|
||||||
|
// }
|
||||||
|
// .group-picture {
|
||||||
|
// display: none;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
.group-content {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-picture-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
// margin-left: 0.5em;
|
||||||
|
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
width: 2.3em;
|
||||||
|
height: 2.3em;
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.context-menu-dropdown {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.group-picture {
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: center;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-content {
|
||||||
|
flex: 1;
|
||||||
|
border-radius: 0;
|
||||||
|
position: relative;
|
||||||
|
padding: 0.3em;
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
background-color: #d8f8fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-title-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
flex-direction: column;
|
||||||
|
label {
|
||||||
|
color: #6f6f6f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-description-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.group-unread-indicator {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
background-color: #00b6e3;
|
||||||
|
font-family: "sahel-light";
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 0.4em;
|
||||||
|
}
|
||||||
|
.group-description {
|
||||||
|
color: #6f6f6f;
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin: 0;
|
||||||
|
flex: 1;
|
||||||
|
text-align: right;
|
||||||
|
// @include textOverflow(15em);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.unread-button {
|
||||||
|
.unread-message-label {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: #6f6f6f;
|
||||||
|
margin-left: 0.3em;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin-bottom: 0.2em;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.lobbies {
|
||||||
|
padding-right: 1.5em;
|
||||||
|
|
||||||
|
&.has-indicator::after {
|
||||||
|
left: auto;
|
||||||
|
right: 0em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.group-description-container .group-description {
|
||||||
|
max-width: 11em !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.unreads-box {
|
||||||
|
@extend %unread-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.unReads:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.unreads-box {
|
||||||
|
box-shadow: 0px 0px 5px 2px #ebebeb;
|
||||||
|
border-radius: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
146
components/Navbar.vue
Normal file
146
components/Navbar.vue
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
<template>
|
||||||
|
<nav
|
||||||
|
class="navbar navbar-expand-md fixed-top"
|
||||||
|
:class="{ expanded: !isSidebarCollapsed }"
|
||||||
|
>
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<!-- <div class="d-md-none dropdown-hamburger">
|
||||||
|
<router-link
|
||||||
|
:to="{ name: 'defaultRoute' }"
|
||||||
|
title="سامانه ها"
|
||||||
|
class="btn ps-0"
|
||||||
|
>
|
||||||
|
<svg class="icon icon-Home-21 main-page_body-items-icon-close">
|
||||||
|
<use xlink:href="#icon-Home-21"></use>
|
||||||
|
</svg>
|
||||||
|
</router-link>
|
||||||
|
</div> -->
|
||||||
|
<div class="d-md-none">
|
||||||
|
<button
|
||||||
|
name="button"
|
||||||
|
type="button"
|
||||||
|
class="toggle-mobile-nav dropdown-hamburger"
|
||||||
|
@click.prevent="toggleSidebarMenu()"
|
||||||
|
>
|
||||||
|
<span class="sr-only">باز کردن منوی کنار</span>
|
||||||
|
<svg class="s18" data-testid="sidebar-icon">
|
||||||
|
<use href="@assets/common/img/icons.svg#sidebar"></use>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<!-- <div v-if="$route.name === 'taskTimes'" class="d-md-none dropdown-hamburger">
|
||||||
|
<router-link :to="{ name: 'taskDashboard' }" title="داشبورد" class="btn ps-0">
|
||||||
|
<svg class="icon icon-projects main-page_body-items-icon-close">
|
||||||
|
<use xlink:href="#icon-projects"></use>
|
||||||
|
</svg>
|
||||||
|
</router-link>
|
||||||
|
</div> -->
|
||||||
|
<!-- <div v-if="$route.name === 'taskDashboard'" class="d-md-none dropdown-hamburger pt-2"> -->
|
||||||
|
<!-- <router-link :to="{ name: 'taskTimes' }" title="وظایف" class="btn ps-0">
|
||||||
|
<svg class="icon icon-task-list main-page_body-items-icon-close">
|
||||||
|
<use xlink:href="#icon-task-list"></use>
|
||||||
|
</svg>
|
||||||
|
</router-link> -->
|
||||||
|
<!-- </div> -->
|
||||||
|
</div>
|
||||||
|
<ul class="navbar-nav ms-md-3 me-auto">
|
||||||
|
<!-- <li class="nav-item">
|
||||||
|
<notification></notification>
|
||||||
|
</li> -->
|
||||||
|
|
||||||
|
<!-- <li v-if="!isMajlesBuild" class="nav-item">
|
||||||
|
<select-language-dropdown
|
||||||
|
:class="buildName"
|
||||||
|
toggleClass="dropdown-toggle"
|
||||||
|
></select-language-dropdown>
|
||||||
|
</li> -->
|
||||||
|
<li class="nav-item" v-if="!isMajlesBuild">
|
||||||
|
<user-avatar-dropdown
|
||||||
|
:class="buildName + '-navbar'"
|
||||||
|
class="position-static task-avatar"
|
||||||
|
></user-avatar-dropdown>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters, mapMutations, mapActions } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
beforeMount() {
|
||||||
|
// clearBodyClass();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// this.setBodyClass("list-system");
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
// clearBodyClass();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// #region mehdi
|
||||||
|
statusPag: 0,
|
||||||
|
nomber: 0,
|
||||||
|
statusPagHedear: 1,
|
||||||
|
// #endregion
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(["getPanelStatus", "getRefreshForm", "isSidebarCollapsed"]),
|
||||||
|
navTitle() {
|
||||||
|
return process.env.VUE_APP_TITLE;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
searchStart(e) {
|
||||||
|
let text = e.target.elements.searchinput.value;
|
||||||
|
if (text == "") {
|
||||||
|
} else {
|
||||||
|
this.$router.push({
|
||||||
|
name: "searchResult",
|
||||||
|
query: { q: text },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleSidebarMenu() {
|
||||||
|
this.$store.commit("TOGGLE_SIDEBAR_MENU");
|
||||||
|
},
|
||||||
|
// ...mapActions(["setBodyClass"]),
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Navbar: () =>
|
||||||
|
import(
|
||||||
|
"@dashboard/majles/components/Navbar"
|
||||||
|
),
|
||||||
|
// MySystem: () =>
|
||||||
|
// import(
|
||||||
|
// "@dashboard/default/pages/MySystem"
|
||||||
|
// ),
|
||||||
|
// Notification: () =>
|
||||||
|
// import( "@notifications/components/Notification.vue"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.navbar {
|
||||||
|
// position:fixed!important;
|
||||||
|
// margin-right: var(--sidebar-collapsed-width);
|
||||||
|
border-bottom: none;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
.dropdown-toggle {
|
||||||
|
color: #fff;
|
||||||
|
margin-right: 1.5em;
|
||||||
|
}
|
||||||
|
.dropdown-toggle:hover {
|
||||||
|
color: #00b6e3 !important;
|
||||||
|
}
|
||||||
|
.nav-logo {
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
.dropdown-menu {
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
</style>
|
400
components/RightSection.vue
Normal file
400
components/RightSection.vue
Normal file
|
@ -0,0 +1,400 @@
|
||||||
|
<template>
|
||||||
|
<div class="menu-bar__content home-list p-3">
|
||||||
|
<div class="home-list-header">
|
||||||
|
<div class="d-flex justify-content-between">
|
||||||
|
<div class="home-list-header form-control w-30">
|
||||||
|
<span class="main-page_total-1_a"> خالص ماهانه :</span
|
||||||
|
><span class="main-page_total-1_b me-1">{{ useFullTime }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="home-list-header form-control me-1 ms-1 w-30">
|
||||||
|
<span class="main-page_total-2_a"> کل ماهانه :</span
|
||||||
|
><span class="main-page_total-2_b me-1">{{ allTime }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="home-list-header form-control w-30">
|
||||||
|
<span class="main-page_total-1_a"> میانگین روزانه:</span
|
||||||
|
><span class="main-page_total-1_b me-1">{{ dailyAve }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-secondary" role="alert">
|
||||||
|
<!-- <select
|
||||||
|
id="month-select"
|
||||||
|
class="form-select ms-1"
|
||||||
|
v-model="selectedMonth"
|
||||||
|
@change="getWorkingHoursInformation()"
|
||||||
|
>
|
||||||
|
<option v-for="month in months" :key="month" :value="month">
|
||||||
|
{{ getPersianMonthName(month) }}
|
||||||
|
</option>
|
||||||
|
</select> -->
|
||||||
|
<Multiselect
|
||||||
|
v-model="selectedMonth"
|
||||||
|
id="month-select"
|
||||||
|
:options="months"
|
||||||
|
:custom-label="getPersianMonthName"
|
||||||
|
placeholder="ماه را انتخاب کنید"
|
||||||
|
@input="getWorkingHoursInformation"
|
||||||
|
:searchable="false"
|
||||||
|
:close-on-select="true"
|
||||||
|
:show-labels="false"
|
||||||
|
class="ms-1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="col-1 main-page_date-icon-left">
|
||||||
|
<span class="btn" title="ماه قبل">
|
||||||
|
<svg class="icon icon-Component3601">
|
||||||
|
<use xlink:href="#icon-Component3601"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!-- <select
|
||||||
|
id="year-select"
|
||||||
|
class="form-select"
|
||||||
|
v-model="selectedYear"
|
||||||
|
@change="getWorkingHoursInformation()"
|
||||||
|
>
|
||||||
|
<option v-for="year in years" :key="year" :value="year">
|
||||||
|
{{ year }}
|
||||||
|
</option>
|
||||||
|
</select> -->
|
||||||
|
<Multiselect
|
||||||
|
v-model="selectedYear"
|
||||||
|
:options="years"
|
||||||
|
placeholder="سال را انتخاب کنید"
|
||||||
|
@input="getWorkingHoursInformation"
|
||||||
|
:searchable="false"
|
||||||
|
:close-on-select="true"
|
||||||
|
:show-labels="false"
|
||||||
|
class=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="accordion" id="accordionExample">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header col-12">
|
||||||
|
<!-- <h2 class="mb-0"> -->
|
||||||
|
<button
|
||||||
|
class="btn d-flex justify-content-between collapsed w-100 pe-0"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
>
|
||||||
|
<span class="card-header_titles text-1 col-3">روز </span>
|
||||||
|
<span class="card-header_titles text-2 col-3"> تاریخ </span>
|
||||||
|
<span class="card-header_titles text-3 col-3">
|
||||||
|
<!-- <span class="card-header_titles-icon">
|
||||||
|
<svg class="icon icon-arrow-down">
|
||||||
|
<use xlink:href="#icon-arrow-down"></use>
|
||||||
|
</svg>
|
||||||
|
</span> -->
|
||||||
|
جمع کل</span
|
||||||
|
>
|
||||||
|
<span class="card-header_titles text-4 col-3">
|
||||||
|
<!-- <span class="card-header_titles-icon">
|
||||||
|
<svg class="icon icon-arrow-up-1">
|
||||||
|
<use xlink:href="#icon-arrow-up-1"></use>
|
||||||
|
</svg>
|
||||||
|
</span> -->
|
||||||
|
بلاتکلیف</span
|
||||||
|
>
|
||||||
|
<span class="card-header_titles text-5"></span>
|
||||||
|
<i
|
||||||
|
class="card-header_titles rotate-icon tavasi tavasi-Component-22--1"
|
||||||
|
></i>
|
||||||
|
<!-- </div> -->
|
||||||
|
</button>
|
||||||
|
<!-- </h2> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion" id="accordionExample">
|
||||||
|
<div class="card" v-for="items in list" :key="items.id">
|
||||||
|
<div class="card-header col-12" :id="'heading' + items.id">
|
||||||
|
<!-- <h2 class="mb-0"> -->
|
||||||
|
<button
|
||||||
|
class="btn d-flex justify-content-between collapsed w-100 pe-0"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
:data-bs-target="'#collapse' + items.id"
|
||||||
|
:aria-controls="'collapse' + items.id"
|
||||||
|
@click.stop="selectDate(items)"
|
||||||
|
:aria-expanded="isOpenAccordion(items.id)"
|
||||||
|
>
|
||||||
|
<!-- <div class="card-header_titles"> -->
|
||||||
|
<span class="card-header_titles text-1 col-3"
|
||||||
|
>{{ getDayOfWeekFromTimestamp(items.taskDate) }}
|
||||||
|
</span>
|
||||||
|
<span class="card-header_titles text-2 col-3">{{
|
||||||
|
items.oldDate
|
||||||
|
}}</span>
|
||||||
|
<span class="card-header_titles text-3 col-3">
|
||||||
|
<!-- <span class="card-header_titles-icon">
|
||||||
|
<svg class="icon icon-arrow-down">
|
||||||
|
<use xlink:href="#icon-arrow-down"></use>
|
||||||
|
</svg>
|
||||||
|
</span> -->
|
||||||
|
{{ items.minuteDay }}</span
|
||||||
|
>
|
||||||
|
<span class="card-header_titles text-4 col-3">
|
||||||
|
<!-- <span class="card-header_titles-icon">
|
||||||
|
<svg class="icon icon-arrow-up-1">
|
||||||
|
<use xlink:href="#icon-arrow-up-1"></use>
|
||||||
|
</svg>
|
||||||
|
</span> -->
|
||||||
|
{{ items.noWork }}</span
|
||||||
|
>
|
||||||
|
<span class="card-header_titles text-5">{{
|
||||||
|
items.noWorkTime
|
||||||
|
}}</span>
|
||||||
|
<i
|
||||||
|
:class="{ rotated: rotated }"
|
||||||
|
class="card-header_titles rotate-icon tavasi tavasi-Component-22--1"
|
||||||
|
></i>
|
||||||
|
<!-- </div> -->
|
||||||
|
</button>
|
||||||
|
<!-- </h2> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="isOpenAccordion(items.id)"
|
||||||
|
:id="'collapse' + items.id"
|
||||||
|
class="collapse show"
|
||||||
|
:aria-labelledby="'heading' + items.id"
|
||||||
|
data-parent="#accordionExample"
|
||||||
|
>
|
||||||
|
<div class="card-body">
|
||||||
|
<span class="card-body_items item-1">مدل سازی</span>
|
||||||
|
<span class="card-body_items item-2">اجرائیات</span>
|
||||||
|
<span class="card-body_items item-3">120</span>
|
||||||
|
<span class="card-body_items item-4"></span>
|
||||||
|
<span class="card-body_items item-5">{{ items.description }} </span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import taskApi from "@apis/taskApi";
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
import VuePersianDatetimePicker from "vue-persian-datetime-picker";
|
||||||
|
import { p2e } from "@plugins/persianNumber";
|
||||||
|
import thiqatRoutes from "../../../routes/thiqatRoutes";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// mixins: [dragDropMoveMixin],
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService(this.taskMicroServiceName);
|
||||||
|
|
||||||
|
this.activeUserId = this.currentUser.user_id;
|
||||||
|
// event fired from MainSection.vue.
|
||||||
|
this.$root.$on("request-based-on-new-user-data", (userId) => {
|
||||||
|
this.activeUserId = userId;
|
||||||
|
this.getWorkingHoursInformation();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
var d = new Date().toLocaleDateString("fa-IR");
|
||||||
|
let items = d.split("/");
|
||||||
|
|
||||||
|
this.selectedYear = p2e(items[0]);
|
||||||
|
this.selectedMonth = p2e(items[1]);
|
||||||
|
|
||||||
|
this.getWorkingHoursInformation();
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
months: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
|
||||||
|
years: ["1400", "1401", "1402", "1403", "1404", "1405"],
|
||||||
|
selectedMonth: "0",
|
||||||
|
selectedYear: "1402",
|
||||||
|
useFullTime: "",
|
||||||
|
allTime: "",
|
||||||
|
dailyAve: "",
|
||||||
|
entranceTime: [],
|
||||||
|
departureTime: [],
|
||||||
|
uselessTime: [],
|
||||||
|
list: [],
|
||||||
|
selectedAccordion: null,
|
||||||
|
rotated: false,
|
||||||
|
activeUserId: undefined,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
// ...mapGetters([
|
||||||
|
// "isSidebarCollapsed",
|
||||||
|
// "getForwardItem",
|
||||||
|
// "userPermisionGetter",
|
||||||
|
// "getPanelStatus",
|
||||||
|
// "sidebarListStatusGetter",
|
||||||
|
// ]),
|
||||||
|
...mapGetters("list", ["listGetter"]),
|
||||||
|
...mapGetters(["currentUser"]),
|
||||||
|
taskMicroServiceName() {
|
||||||
|
return process.env.VUE_APP_TASK;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// ...mapMutations([
|
||||||
|
// "TOGGLE_PANEL",
|
||||||
|
// "checkPermissions",
|
||||||
|
// "SET_SIDEBAR_LIST_STATUS",
|
||||||
|
// ]),
|
||||||
|
// ...mapMutations("list", ["SET_LIST"]),
|
||||||
|
|
||||||
|
getWorkingHoursInformation() {
|
||||||
|
const payload = {
|
||||||
|
user_id: this.activeUserId,
|
||||||
|
offset: 0,
|
||||||
|
limit: 50,
|
||||||
|
sortby: "taskDate",
|
||||||
|
sortorder: "desc",
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
};
|
||||||
|
// console.log(this.activeUserId)
|
||||||
|
// console.log(payload)
|
||||||
|
|
||||||
|
const url = taskApi.workingHours.load;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
|
||||||
|
.then((res) => {
|
||||||
|
this.list = res.data;
|
||||||
|
this.useFullTime = res.useFullTime;
|
||||||
|
this.allTime = res.allTime;
|
||||||
|
this.dailyAve = res.dailyAve;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getDetailsMonth() {
|
||||||
|
this.hoursForms = [];
|
||||||
|
let payload = {};
|
||||||
|
const url = taskApi.workingHours.day;
|
||||||
|
|
||||||
|
if (this.workMonth) {
|
||||||
|
payload.taskDate =
|
||||||
|
this.workYear + "-" + this.workMonth + "-" + this.workDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.httpService.postRequest(url, payload).then((res) => {
|
||||||
|
if (res.hourswork?.length) {
|
||||||
|
this.hoursForms = res.hourswork;
|
||||||
|
this.itemsId = res.task_id;
|
||||||
|
} else
|
||||||
|
this.hoursForms.push({
|
||||||
|
inTime: null,
|
||||||
|
outTime: null,
|
||||||
|
noWorkTime: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.taskForms = res.data;
|
||||||
|
this.taskForms.push({
|
||||||
|
organ: "",
|
||||||
|
category: "",
|
||||||
|
title: "",
|
||||||
|
duration: "",
|
||||||
|
description: "",
|
||||||
|
});
|
||||||
|
this.noWork = res.day_sum.noWork;
|
||||||
|
this.sum = res.day_sum.sum;
|
||||||
|
|
||||||
|
let { day, month, year, weekDay } = res;
|
||||||
|
this.setDate(day, month, year, weekDay);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setDate(day, month, year, weekDay) {
|
||||||
|
this.weekDay = weekDay;
|
||||||
|
this.workDay = day;
|
||||||
|
this.workMonth = month;
|
||||||
|
this.workYear = year;
|
||||||
|
},
|
||||||
|
datefa(item) {
|
||||||
|
let m = item * 1000;
|
||||||
|
let d = new Date(m).toLocaleDateString("fa-IR");
|
||||||
|
return d;
|
||||||
|
},
|
||||||
|
getDayOfWeekFromTimestamp(timestamp) {
|
||||||
|
let m = timestamp * 1000;
|
||||||
|
let d = new Date(m);
|
||||||
|
|
||||||
|
let options = { weekday: "long" };
|
||||||
|
let dayOfWeek = new Intl.DateTimeFormat("fa-IR", options).format(d);
|
||||||
|
|
||||||
|
return dayOfWeek;
|
||||||
|
},
|
||||||
|
toggleAccordion(accordionId) {
|
||||||
|
if (this.selectedAccordion === accordionId) {
|
||||||
|
this.selectedAccordion = null;
|
||||||
|
} else {
|
||||||
|
this.selectedAccordion = accordionId;
|
||||||
|
}
|
||||||
|
this.rotateIcon();
|
||||||
|
},
|
||||||
|
|
||||||
|
isOpenAccordion(accordionId) {
|
||||||
|
return this.selectedAccordion === accordionId;
|
||||||
|
},
|
||||||
|
rotateIcon() {
|
||||||
|
this.rotated = !this.rotated;
|
||||||
|
},
|
||||||
|
nextMonth(nextMonth) {
|
||||||
|
this.workMonth += 1;
|
||||||
|
this.getDetailsDay();
|
||||||
|
},
|
||||||
|
prevMonth(prevMonth) {
|
||||||
|
this.workMonth -= 1;
|
||||||
|
this.getDetailsDay();
|
||||||
|
},
|
||||||
|
|
||||||
|
selectDate(items) {
|
||||||
|
if (items.oldDate) {
|
||||||
|
let item = items.oldDate.split("-");
|
||||||
|
let date = {};
|
||||||
|
date.day = item[2];
|
||||||
|
date.month = item[1];
|
||||||
|
date.year = item[0];
|
||||||
|
|
||||||
|
this.$emit("select-day", date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getPersianMonthName(month) {
|
||||||
|
const monthNames = [
|
||||||
|
"فروردین",
|
||||||
|
"اردیبهشت",
|
||||||
|
"خرداد",
|
||||||
|
"تیر",
|
||||||
|
"مرداد",
|
||||||
|
"شهریور",
|
||||||
|
"مهر",
|
||||||
|
"آبان",
|
||||||
|
"آذر",
|
||||||
|
"دی",
|
||||||
|
"بهمن",
|
||||||
|
"اسفند",
|
||||||
|
];
|
||||||
|
return monthNames[month - 1];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
datePicker: VuePersianDatetimePicker,
|
||||||
|
Multiselect: () => import("vue-multiselect"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.home-list-header {
|
||||||
|
&.form-control {
|
||||||
|
padding: 0.175rem 0.35rem !important;
|
||||||
|
box-shadow: 0 0.4688rem 2.1875rem rgba(4, 9, 20, 0.03),
|
||||||
|
0 0.9375rem 1.4063rem rgba(4, 9, 20, 0.03),
|
||||||
|
0 0.25rem 0.5313rem rgba(4, 9, 20, 0.03),
|
||||||
|
0 0.125rem 0.1875rem rgba(4, 9, 20, 0.03);
|
||||||
|
border: unset !important;
|
||||||
|
border-radius: 0.25em;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
141
components/SortingByDayTasksAdmin.vue
Normal file
141
components/SortingByDayTasksAdmin.vue
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
<template>
|
||||||
|
<div class="form-sort">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="" id="accordion">
|
||||||
|
<div class="card" v-for="(listItem, j) in workList" :key="j">
|
||||||
|
<div class="card-header" :id="'heading' + j">
|
||||||
|
<button
|
||||||
|
@click="getDetailsDay(listItem, j)"
|
||||||
|
class="btn d-flex justify-content-between collapsed w-100 pe-0"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
:data-bs-target="'#collapse' + j"
|
||||||
|
:aria-controls="'collapse' + j"
|
||||||
|
>
|
||||||
|
<span class="card-header_titles text-1 col-3"
|
||||||
|
>{{ getDayOfWeekFromTimestamp(listItem.taskDate) }}
|
||||||
|
</span>
|
||||||
|
<span class="card-header_titles text-2 col-3">{{
|
||||||
|
listItem.oldDate
|
||||||
|
}}</span>
|
||||||
|
<span class="card-header_titles text-3 col-3">
|
||||||
|
{{ listItem.minuteDay }}</span
|
||||||
|
>
|
||||||
|
<span class="card-header_titles text-4 col-2">
|
||||||
|
{{ listItem.noWork }}</span
|
||||||
|
>
|
||||||
|
<span class="card-header_titles col-1 text-5 rotate-icon">
|
||||||
|
<i
|
||||||
|
class="card-header_titles rotate-icon tavasi tavasi-Component-25--1"
|
||||||
|
></i
|
||||||
|
></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
:id="'collapse' + j"
|
||||||
|
class="collapse"
|
||||||
|
:class="{ show: 'collapse' + j == 'collapse0' }"
|
||||||
|
:aria-labelledby="'heading' + j"
|
||||||
|
data-parent="#accordion"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="(taskItem, k) in listItem.tasks"
|
||||||
|
:key="k"
|
||||||
|
class="card-body d-flex justify-content-between align-items-center"
|
||||||
|
>
|
||||||
|
<span class="card-body_items item-1"
|
||||||
|
>{{ taskItem.category }}
|
||||||
|
</span>
|
||||||
|
<span class="card-body_items item-2">{{ taskItem.title }}</span>
|
||||||
|
<span class="card-body_items item-3">{{
|
||||||
|
taskItem.duration
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
import taskApi from "@apis/taskApi";
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
workList: [],
|
||||||
|
userId: "",
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService( this.taskMicroServiceName
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
taskMicroServiceName() {
|
||||||
|
return process.env.VUE_APP_TASK;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getDayOfWeekFromTimestamp(timestamp) {
|
||||||
|
let m = timestamp * 1000;
|
||||||
|
let d = new Date(m);
|
||||||
|
|
||||||
|
let options = { weekday: "long" };
|
||||||
|
let dayOfWeek = new Intl.DateTimeFormat("fa-IR", options).format(d);
|
||||||
|
|
||||||
|
return dayOfWeek;
|
||||||
|
},
|
||||||
|
getDetailsDay(hourItem) {
|
||||||
|
this.hoursForms = [];
|
||||||
|
let payload = {
|
||||||
|
user_id: this.userId,
|
||||||
|
taskDate: hourItem.oldDate,
|
||||||
|
};
|
||||||
|
const url = taskApi.workingHours.day;
|
||||||
|
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
.then((res) => {
|
||||||
|
this.$set(hourItem, "tasks", res.data);
|
||||||
|
// this.sortForms = res.data;
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
// .form-group {
|
||||||
|
// max-width: 44em !important;
|
||||||
|
// height: 4em;
|
||||||
|
// overflow: auto;
|
||||||
|
// border: 1px rgb(223 223 223) solid;
|
||||||
|
// border-radius: 0.25em;
|
||||||
|
// margin-top: 0;
|
||||||
|
// margin-bottom: 0;
|
||||||
|
// font-size: 0.8rem;
|
||||||
|
// }
|
||||||
|
#accordion {
|
||||||
|
width: 100% !important;
|
||||||
|
// min-width: 36em !important;
|
||||||
|
height: calc(100vh - 11em);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.card-header,
|
||||||
|
.card {
|
||||||
|
border-radius: 0.25em !important;
|
||||||
|
// min-width: 35em !important;
|
||||||
|
}
|
||||||
|
.table-responsive {
|
||||||
|
height: calc(100vh + -13em) !important;
|
||||||
|
}
|
||||||
|
.card-body {
|
||||||
|
border-bottom: 1px rgb(223 223 223) solid;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
</style>
|
104
components/SortingTasksAdmin.vue
Normal file
104
components/SortingTasksAdmin.vue
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
<template>
|
||||||
|
<div class="form-sort" :style="{ width: $attrs.width,}">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div
|
||||||
|
class="row align-items-center justify-content-center style-label p-3"
|
||||||
|
>
|
||||||
|
<div v-for="item in columns" :class="item.class">
|
||||||
|
{{ item.label }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container-fluid set-scroll firefox-scrollbar">
|
||||||
|
<div class="row">
|
||||||
|
<div v-for="item in listItem" class="col-12">
|
||||||
|
<div
|
||||||
|
class="row align-items-center justify-content-center my-border-bottom"
|
||||||
|
>
|
||||||
|
<div class="col-style" v-for="col in columns" :class="col.class">
|
||||||
|
{{ getValue(item, col.key) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
listItem: [],
|
||||||
|
columns: {
|
||||||
|
default() {
|
||||||
|
return [
|
||||||
|
{ label: "تاریخ", key: "normalDate", class: "col-2" },
|
||||||
|
{ label: "دسته", key: "category", class: "col-3" },
|
||||||
|
{ label: "عنوان", key: "title", class: "col-6" },
|
||||||
|
{ label: "مدت", key: "duration", class: "col-1" },
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods : {
|
||||||
|
|
||||||
|
getValue(item, key){
|
||||||
|
if(item[key] && item[key] != "")
|
||||||
|
return item[key]
|
||||||
|
else
|
||||||
|
return "نامشخص"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.form-sort {
|
||||||
|
padding: 1em;
|
||||||
|
// width: 40em;
|
||||||
|
// border-radius: 0.25em;
|
||||||
|
// border: 1px rgb(223 223 223) solid;
|
||||||
|
box-shadow: -1px 2px 11px 3px #eee;
|
||||||
|
|
||||||
|
.set-scroll {
|
||||||
|
height: calc(100vh - 18em);
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
.my-border-bottom {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content:'';
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 75%;
|
||||||
|
margin: auto;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
.col-style {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 3;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
// height: 4em;
|
||||||
|
// border-bottom: 1px rgb(223 223 223) solid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.style-label {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
493
components/TaskForm.vue
Normal file
493
components/TaskForm.vue
Normal file
|
@ -0,0 +1,493 @@
|
||||||
|
<template>
|
||||||
|
<form class="task-form">
|
||||||
|
<div class="row row-basic mx-0 justify-content-end">
|
||||||
|
<div
|
||||||
|
class="main-page_body-items items items-top d-flex align-items-center col-12"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="templateValue.title == 'multi-org_workbase'"
|
||||||
|
class="col-1 ps-0 pe-0 task-Form-Organ"
|
||||||
|
style="color: #97f295 !important"
|
||||||
|
>
|
||||||
|
<multiselect
|
||||||
|
v-model.number="taskForm.organ"
|
||||||
|
class="multiselect Organ"
|
||||||
|
tag-placeholder="Add this as new tag"
|
||||||
|
placeholder="سازمان"
|
||||||
|
:options="organOptions"
|
||||||
|
:taggable="true"
|
||||||
|
:close-on-select="true"
|
||||||
|
:clear-on-select="false"
|
||||||
|
:searchable="true"
|
||||||
|
:max-height="250"
|
||||||
|
:preserve-search="true"
|
||||||
|
@tag="addTagOrgan"
|
||||||
|
@select="organSelect"
|
||||||
|
></multiselect>
|
||||||
|
</div>
|
||||||
|
<div class="col-2 ps-0 pe-0 task-Form-category">
|
||||||
|
<multiselect
|
||||||
|
class="multiselect category"
|
||||||
|
id="task-Form-category"
|
||||||
|
v-model.number="taskForm.category"
|
||||||
|
tag-placeholder="Add this as new tag"
|
||||||
|
placeholder="دسته"
|
||||||
|
:options="categoryOptions"
|
||||||
|
:taggable="true"
|
||||||
|
:close-on-select="true"
|
||||||
|
:clear-on-select="false"
|
||||||
|
:searchable="true"
|
||||||
|
:max-height="250"
|
||||||
|
:preserve-search="true"
|
||||||
|
@tag="addTagCategury"
|
||||||
|
></multiselect>
|
||||||
|
<!-- <pre
|
||||||
|
class="language-json"
|
||||||
|
><code>{{ taskForm.category }}</code></pre> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<vue-tribute
|
||||||
|
class="col-3 ps-0 pe-0 tribute-container"
|
||||||
|
:options="tributeOptions"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="label-1 form-control task-form-control task-title"
|
||||||
|
placeholder="عنوان"
|
||||||
|
v-model="taskForm.title"
|
||||||
|
cols="20"
|
||||||
|
rows="3"
|
||||||
|
@tribute-no-match="noMatchFound"
|
||||||
|
@tribute-replaced="textReplaced"
|
||||||
|
@keydown.tab="foucsNext('duration')"
|
||||||
|
/>
|
||||||
|
</vue-tribute>
|
||||||
|
<div class="col-1">
|
||||||
|
<input
|
||||||
|
v-model="taskForm.duration"
|
||||||
|
ref="duration"
|
||||||
|
type="text"
|
||||||
|
placeholder="مدت "
|
||||||
|
@blur="timeCorrect(taskForm.duration)"
|
||||||
|
v-on:focus="timeFocus('duration', taskForm.duration)"
|
||||||
|
class="label-3 form-control task-form-control"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 label-4">
|
||||||
|
<input
|
||||||
|
v-model="taskForm.description"
|
||||||
|
type="text"
|
||||||
|
placeholder="گویا و مختصر بنویسید"
|
||||||
|
class="label-4 form-control task-form-control Description"
|
||||||
|
@keydown.tab="postInTaskWork(taskForm)"
|
||||||
|
/>
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span
|
||||||
|
@click="postInTaskWork(taskForm)"
|
||||||
|
title="ثبت"
|
||||||
|
class="btn main-page_body-items-icon ps-0"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="icon icon-Component-233--1 main-page_body-items-icon-add"
|
||||||
|
>
|
||||||
|
<use xlink:href="#icon-Component-233--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<button-component
|
||||||
|
@click="closeFormTaskInformation(taskForm)"
|
||||||
|
buttonText=""
|
||||||
|
v-tooltip="'حذف فرایند'"
|
||||||
|
>
|
||||||
|
<span class="text-danger">
|
||||||
|
<svg class="icon icon-Component-295--1">
|
||||||
|
<use xlink:href="#icon-Component-295--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button-component>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-mobile mx-0 justify-content-end">
|
||||||
|
<div
|
||||||
|
class="main-page_body-items items items-top d-flex align-items-center col-12"
|
||||||
|
>
|
||||||
|
<!-- <vue-tribute class="col-6 ps-0 pe-0" :options="tributeOptions"> -->
|
||||||
|
<div
|
||||||
|
v-if="templateValue.title == 'multi-org_workbase'"
|
||||||
|
class="col-6"
|
||||||
|
style="color: #97f295 !important"
|
||||||
|
>
|
||||||
|
<multiselect
|
||||||
|
v-model.number="taskForm.organ"
|
||||||
|
class="multiselect Organ Organ-mobile"
|
||||||
|
tag-placeholder="Add this as new tag"
|
||||||
|
placeholder="سازمان"
|
||||||
|
:options="organOptions"
|
||||||
|
:taggable="true"
|
||||||
|
:close-on-select="true"
|
||||||
|
:clear-on-select="false"
|
||||||
|
:searchable="true"
|
||||||
|
:max-height="250"
|
||||||
|
:preserve-search="true"
|
||||||
|
@tag="addTagOrgan"
|
||||||
|
@select="organSelect"
|
||||||
|
></multiselect>
|
||||||
|
<!-- <pre
|
||||||
|
class="language-json"
|
||||||
|
><code>{{ taskForm.category }}</code></pre> -->
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<multiselect
|
||||||
|
id="task-Form-category"
|
||||||
|
v-model.number="taskForm.category"
|
||||||
|
tag-placeholder="Add this as new tag"
|
||||||
|
placeholder="دسته"
|
||||||
|
:options="categoryOptions"
|
||||||
|
:taggable="true"
|
||||||
|
:close-on-select="true"
|
||||||
|
:clear-on-select="false"
|
||||||
|
:searchable="true"
|
||||||
|
:max-height="250"
|
||||||
|
:preserve-search="true"
|
||||||
|
@tag="addTagCategury"
|
||||||
|
></multiselect>
|
||||||
|
</div>
|
||||||
|
<!-- </vue-tribute> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="col-12 label-4 main-page_body-items items items-bottom d-flex align-items-center mb-1"
|
||||||
|
>
|
||||||
|
<vue-tribute class="col-5 ps-0 pe-0" :options="tributeOptions">
|
||||||
|
<input
|
||||||
|
class="label-1 form-control task-form-control task-title"
|
||||||
|
placeholder="عنوان"
|
||||||
|
v-model="taskForm.title"
|
||||||
|
cols="20"
|
||||||
|
rows="3"
|
||||||
|
@tribute-no-match="noMatchFound"
|
||||||
|
@tribute-replaced="textReplaced"
|
||||||
|
/>
|
||||||
|
</vue-tribute>
|
||||||
|
<input
|
||||||
|
v-model="taskForm.duration"
|
||||||
|
ref="duration2"
|
||||||
|
type="text"
|
||||||
|
placeholder="مدت "
|
||||||
|
@blur="timeCorrect(taskForm.duration)"
|
||||||
|
v-on:focus="timeFocus('duration2', taskForm.duration)"
|
||||||
|
class="col-2 label-3 form-control task-form-control"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-model="taskForm.description"
|
||||||
|
type="text"
|
||||||
|
placeholder="توضیحات(گویا،مختصر)"
|
||||||
|
class="label-5 form-control task-form-control Description"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center ms-2">
|
||||||
|
<span
|
||||||
|
@click="postInTaskWork(taskForm)"
|
||||||
|
title="ثبت"
|
||||||
|
class="btn main-page_body-items-icon ps-0"
|
||||||
|
>
|
||||||
|
<svg class="icon icon-Component-233--1 main-page_body-items-icon-add">
|
||||||
|
<use xlink:href="#icon-Component-233--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span title="حذف" class="btn ps-0">
|
||||||
|
<svg
|
||||||
|
@click="closeFormTaskInformation(taskForm)"
|
||||||
|
class="icon icon-Component-295--1 main-page_body-items-icon-close"
|
||||||
|
>
|
||||||
|
<use xlink:href="#icon-Component-295--1"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import taskApi from "@apis/taskApi";
|
||||||
|
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
import VueTribute from "vue-tribute";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
itemIndex: {
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
isMultiOrgan: {
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
taskForm: {
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
organ: "",
|
||||||
|
category: "",
|
||||||
|
title: "",
|
||||||
|
duration: "",
|
||||||
|
description: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
templateValue: {
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
name: "تک سازمانی - کارمحور",
|
||||||
|
title: "single-org_workbase",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ["close-form-tasks", "save-form-tasks", "add-new-record"],
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService(this.taskMicroServiceName);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.taskSchemaGetter?.categoryOptions)
|
||||||
|
this.categoryOptions = this.taskSchemaGetter?.categoryOptions;
|
||||||
|
|
||||||
|
if (this.taskSchemaGetter?.organOptions) {
|
||||||
|
this.organOptions = this.taskSchemaGetter?.organOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( this.taskForm.organ == "" && this.organOptions.length ){
|
||||||
|
this.taskForm.organ = this.organOptions[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
categoryOptions: [],
|
||||||
|
organOptions: [],
|
||||||
|
showOrgan: this.isMultiOrgan,
|
||||||
|
userLang: "fa-IR",
|
||||||
|
|
||||||
|
tributeOptions: {
|
||||||
|
// symbol or string that starts the lookup
|
||||||
|
trigger: "",
|
||||||
|
|
||||||
|
// element to target for @mentions
|
||||||
|
iframe: null,
|
||||||
|
|
||||||
|
// class added in the flyout menu for active item
|
||||||
|
selectClass: "highlight",
|
||||||
|
|
||||||
|
// class added to the menu container
|
||||||
|
containerClass: "tribute-container mini",
|
||||||
|
|
||||||
|
// class added to each list item
|
||||||
|
itemClass: "my-tribute-class",
|
||||||
|
|
||||||
|
// function called on select that returns the content to insert
|
||||||
|
selectTemplate: function (item) {
|
||||||
|
return item.original.title;
|
||||||
|
// return "@" + item.original.value;
|
||||||
|
},
|
||||||
|
|
||||||
|
// template for displaying item in menu
|
||||||
|
menuItemTemplate: function (item) {
|
||||||
|
return item.original.title;
|
||||||
|
},
|
||||||
|
|
||||||
|
// template for when no match is found (optional),
|
||||||
|
// If no template is provided, menu is hidden.
|
||||||
|
noMatchTemplate:
|
||||||
|
'<span class="no-result">مورد مشابهی ثبت نشده است.</span>',
|
||||||
|
|
||||||
|
// specify an alternative parent container for the menu
|
||||||
|
// container must be a positioned element for the menu to appear correctly ie. `position: relative;`
|
||||||
|
// default container is the body
|
||||||
|
menuContainer: document.body,
|
||||||
|
|
||||||
|
// column to search against in the object (accepts function or string)
|
||||||
|
lookup: "title",
|
||||||
|
|
||||||
|
// column that contains the content to insert by default
|
||||||
|
fillAttr: "title",
|
||||||
|
|
||||||
|
// REQUIRED: array of objects to match or a function that returns data (see 'Loading remote data' for an example)
|
||||||
|
// values: [
|
||||||
|
// {
|
||||||
|
// key: null,
|
||||||
|
// value: "sghl",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// values: ["سلام", "باسلام", "علیک سلام", "بی سلام", "صدتا سلام"],
|
||||||
|
values: (text, cb) => {
|
||||||
|
this.remoteSearch(text, (items) => cb(items));
|
||||||
|
},
|
||||||
|
// When your values function is async, an optional loading template to show
|
||||||
|
loadingItemTemplate: null,
|
||||||
|
|
||||||
|
// specify whether a space is required before the trigger string
|
||||||
|
requireLeadingSpace: true,
|
||||||
|
|
||||||
|
// specify whether a space is allowed in the middle of mentions
|
||||||
|
allowSpaces: true,
|
||||||
|
|
||||||
|
// optionally specify a custom suffix for the replace text
|
||||||
|
// (defaults to empty space if undefined)
|
||||||
|
// replaceTextSuffix: "",
|
||||||
|
|
||||||
|
// specify whether the menu should be positioned. Set to false and use in conjuction with menuContainer to create an inline menu
|
||||||
|
// (defaults to true)
|
||||||
|
positionMenu: true,
|
||||||
|
|
||||||
|
// when the spacebar is hit, select the current match
|
||||||
|
spaceSelectsMatch: false,
|
||||||
|
|
||||||
|
// turn tribute into an autocomplete
|
||||||
|
autocompleteMode: true,
|
||||||
|
|
||||||
|
// Customize the elements used to wrap matched strings within the results list
|
||||||
|
// defaults to <span></span> if undefined
|
||||||
|
searchOpts: {
|
||||||
|
pre: '<span style="color:red">',
|
||||||
|
post: "</span>",
|
||||||
|
skip: false, // true will skip local search, useful if doing server-side search
|
||||||
|
},
|
||||||
|
|
||||||
|
// Limits the number of items in the menu
|
||||||
|
menuItemLimit: 25,
|
||||||
|
|
||||||
|
// specify the minimum number of characters that must be typed before menu appears
|
||||||
|
menuShowMinLength: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(["taskSchemaGetter"]),
|
||||||
|
taskMicroServiceName() {
|
||||||
|
return process.env.VUE_APP_TASK;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
organSelect($event) {
|
||||||
|
// console.log($event);
|
||||||
|
// console.log(this.taskForm?.organ);
|
||||||
|
// console.log(this.taskSchemaGetter?.organCategories);
|
||||||
|
if (
|
||||||
|
this.taskForm?.organ &&
|
||||||
|
this.taskSchemaGetter?.organCategories &&
|
||||||
|
this.taskSchemaGetter?.organCategories[this.taskForm?.organ]
|
||||||
|
) {
|
||||||
|
// console.log("this.taskForm.organ");
|
||||||
|
this.categoryOptions =
|
||||||
|
this.taskSchemaGetter?.organCategories[this.taskForm?.organ];
|
||||||
|
} else {
|
||||||
|
this.categoryOptions = this.taskSchemaGetter?.categoryOptions;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
foucsNext(ref) {
|
||||||
|
this.$refs[ref].focus();
|
||||||
|
},
|
||||||
|
// setMultiOrgan(value){
|
||||||
|
// this.isMultiOrgan = value;
|
||||||
|
// },
|
||||||
|
timeFocus(ref, value) {
|
||||||
|
//if (value == "00:00" || value == "" || value == "مدت")
|
||||||
|
this.$refs[ref].select();
|
||||||
|
},
|
||||||
|
timeCorrect(duration) {
|
||||||
|
duration = duration.trim();
|
||||||
|
duration = duration.replace(".", ":");
|
||||||
|
duration = duration.replace(" ", ":");
|
||||||
|
|
||||||
|
if (duration.indexOf(":") == -1) {
|
||||||
|
if (duration.length == 0) duration = "00:00";
|
||||||
|
else if (duration.length == 1) duration = "0" + duration + ":00";
|
||||||
|
else if (duration.length == 2) duration = duration + ":00";
|
||||||
|
else if (duration.length == 3)
|
||||||
|
duration =
|
||||||
|
"0" + duration.substring(0, 1) + ":" + duration.substring(1);
|
||||||
|
else if (duration.length == 4)
|
||||||
|
duration =
|
||||||
|
duration.substring(0, 2) +
|
||||||
|
":" +
|
||||||
|
duration.substring(2).padStart(2, "0");
|
||||||
|
else if (duration.length > 4)
|
||||||
|
duration = duration.substring(0, 2) + ":" + duration.substring(3, 5);
|
||||||
|
}
|
||||||
|
this.taskForm.duration = duration;
|
||||||
|
},
|
||||||
|
noMatchFound(args) {
|
||||||
|
// console.info(args);
|
||||||
|
},
|
||||||
|
textReplaced(args) {
|
||||||
|
// console.info(args);
|
||||||
|
},
|
||||||
|
|
||||||
|
closeFormTaskInformation() {
|
||||||
|
this.$emit("close-form-tasks");
|
||||||
|
},
|
||||||
|
postInTaskWork(taskForm) {
|
||||||
|
this.$emit("save-form-tasks", taskForm);
|
||||||
|
},
|
||||||
|
openFormTaskInformation() {
|
||||||
|
this.$emit("add-new-record");
|
||||||
|
},
|
||||||
|
addTagCategury(newTag) {
|
||||||
|
// const tag = {
|
||||||
|
// name: newTag,
|
||||||
|
// };
|
||||||
|
this.taskForm.category = newTag;
|
||||||
|
},
|
||||||
|
addTagOrgan(newTag) {
|
||||||
|
// const tag = {
|
||||||
|
// name: newTag,
|
||||||
|
// };
|
||||||
|
this.taskForm.organ = newTag;
|
||||||
|
},
|
||||||
|
addTagTitle(newTag) {
|
||||||
|
// const tag = {
|
||||||
|
// name: newTag,
|
||||||
|
// };
|
||||||
|
|
||||||
|
this.taskForm.title = newTag;
|
||||||
|
},
|
||||||
|
remoteSearch(text, cb) {
|
||||||
|
let url = taskApi.workingHours.complition.replace("{{query}}", text);
|
||||||
|
if (text == "") url = taskApi.workingHours.complitionAll;
|
||||||
|
this.httpService.getRequest(url).then((response) => {
|
||||||
|
cb(response.data);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
isNumberKey(evt) {
|
||||||
|
var charCode = evt.which ? evt.which : evt.keyCode;
|
||||||
|
if (charCode > 31 && (charCode < 48 || charCode > 57)) return false;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
VueTribute: () => import("vue-tribute"),
|
||||||
|
Multiselect: () => import("vue-multiselect"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
// input::placeholder {
|
||||||
|
// color: #d4dce3;
|
||||||
|
// }
|
||||||
|
// textarea::placeholder {
|
||||||
|
// color: #d4dce3;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.row {
|
||||||
|
border: 1px rgb(223 223 223) solid;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.task-Form-title {
|
||||||
|
border-right: 1px var(--color-items-7) solid;
|
||||||
|
}
|
||||||
|
// .my-tribute-class {
|
||||||
|
// background: #d4dce3;
|
||||||
|
// }
|
||||||
|
</style>
|
772
components/TaskGroupReport.vue
Normal file
772
components/TaskGroupReport.vue
Normal file
|
@ -0,0 +1,772 @@
|
||||||
|
<template>
|
||||||
|
<div class=" container-fluid">
|
||||||
|
<div class="all-selects justify-content-between col-12">
|
||||||
|
<div class="selects col-md-4 justify-content-start align-items-center">
|
||||||
|
<div>
|
||||||
|
<label class="teams-label"> ماه: </label>
|
||||||
|
<select
|
||||||
|
id="month-select"
|
||||||
|
class="form-control ms-1"
|
||||||
|
v-model="selectedMonth"
|
||||||
|
@change="getMainList"
|
||||||
|
>
|
||||||
|
<option v-for="month in months" :key="month" :value="month">
|
||||||
|
{{ getPersianMonthName(month) }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="me-3 ms-3">
|
||||||
|
<label class="teams-label"> سال: </label>
|
||||||
|
<select
|
||||||
|
id="year-select"
|
||||||
|
class="form-select form-control"
|
||||||
|
v-model="selectedYear"
|
||||||
|
@change="getMainList"
|
||||||
|
>
|
||||||
|
<option v-for="year in years" :key="year" :value="year">
|
||||||
|
{{ year }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="teams-label">تیم ها:</label>
|
||||||
|
<select v-model="group_id" @change="getMainList" class="form-select form-control">
|
||||||
|
<option selected value="">همه</option>
|
||||||
|
<option v-for="item in groups" :value="item.id">
|
||||||
|
{{ item.title }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<!-- <div>
|
||||||
|
<button
|
||||||
|
title="شروع"
|
||||||
|
type="button"
|
||||||
|
class="btn btn-primary btn-start"
|
||||||
|
@click.prevent="setActiveTab(navItem)"
|
||||||
|
>
|
||||||
|
شروع
|
||||||
|
</button>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="d-flex align-items-center grouping col-md-8 justify-content-end"
|
||||||
|
>
|
||||||
|
<div class="select-teams">
|
||||||
|
<label class="teams-label-Grouping"> گروه بندی:</label>
|
||||||
|
<select
|
||||||
|
v-model="groupType"
|
||||||
|
@change="getsorting()"
|
||||||
|
class="form-control"
|
||||||
|
>
|
||||||
|
<option selected value="nogroup">بدون گروه بندی</option>
|
||||||
|
<option value="day">روز</option>
|
||||||
|
<option value="category">دسته</option>
|
||||||
|
<option value="title">عنوان</option>
|
||||||
|
<option value="organ">سازمان</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="switch-component">
|
||||||
|
<switch-component
|
||||||
|
name="switch-view-mode"
|
||||||
|
@change-mode="showchart($event)"
|
||||||
|
class="task-admin-switch"
|
||||||
|
texts1="Normal"
|
||||||
|
texts2="Chartical"
|
||||||
|
></switch-component>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<main
|
||||||
|
class="pages-content-container"
|
||||||
|
:class="{ expanded: !isSidebarCollapsed }"
|
||||||
|
>
|
||||||
|
<div class="pages-content pt-3">
|
||||||
|
<div class="" :class="{ 'd-flex': showPanel || showPanelTeams }">
|
||||||
|
<template v-if="canView">
|
||||||
|
<my-table
|
||||||
|
class="p-0 ms-3 col-4"
|
||||||
|
:tableActions="tableActions"
|
||||||
|
height="calc(100vh + -14em)"
|
||||||
|
minHeight="25em"
|
||||||
|
maxHeight="calc(100dvh + -13em)"
|
||||||
|
:paginationInfo="pagination"
|
||||||
|
:sortingInfo="sorting"
|
||||||
|
:items="mainList"
|
||||||
|
:fetchingData="fetchingData"
|
||||||
|
:tableColumns="tableColumns"
|
||||||
|
:totalPages="pagination.pages"
|
||||||
|
:showActions="false"
|
||||||
|
@search="searchUsers"
|
||||||
|
@reset-form="searchUsers"
|
||||||
|
@edit-table-item="toggleUsersPanel"
|
||||||
|
@page-changed="pageChanged"
|
||||||
|
@page-limit-changed="pageLimitChanged"
|
||||||
|
@sort-changed="sortChanged"
|
||||||
|
>
|
||||||
|
</my-table>
|
||||||
|
</template>
|
||||||
|
<no-data v-else>
|
||||||
|
<the-content-loading v-if="fetchingData"></the-content-loading>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="d-flex justify-content-center align-items-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="alert alert-warning d-flex justify-content-center align-items-center"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="tavasi tavasi-warning-circle color-inherit ms-1 text__32"
|
||||||
|
></span>
|
||||||
|
عدم دسترسی
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</no-data>
|
||||||
|
<div class="col-md-8 form-sorting_group">
|
||||||
|
<component
|
||||||
|
v-if="showcomponent"
|
||||||
|
:is="changeSorting()"
|
||||||
|
:listItem="listItem"
|
||||||
|
:columns="columnGroup"
|
||||||
|
:workList="workList"
|
||||||
|
:userId="userId"
|
||||||
|
></component>
|
||||||
|
|
||||||
|
<pie-donut
|
||||||
|
class="mt-5"
|
||||||
|
v-if="showChart"
|
||||||
|
:dataPie="dataPie"
|
||||||
|
:PieOptions="PieOptions"
|
||||||
|
width="90%"
|
||||||
|
height="300px"
|
||||||
|
></pie-donut>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters, mapActions } from "vuex";
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
import menu from "@task/json/menu.json";
|
||||||
|
import adminApi from "@apis/adminApi";
|
||||||
|
import taskApi from "@apis/taskApi";
|
||||||
|
import { p2e } from "@plugins/persianNumber";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService( this.taskMicroServiceName
|
||||||
|
);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.checkPermisionBeforGetList();
|
||||||
|
|
||||||
|
var d = new Date().toLocaleDateString("fa-IR");
|
||||||
|
let items = d.split("/");
|
||||||
|
this.selectedYear = p2e(items[0]);
|
||||||
|
this.selectedMonth = p2e(items[1]);
|
||||||
|
|
||||||
|
this.getWorkingHoursInformation();
|
||||||
|
this.getTaskGroups();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
PieOptions: {
|
||||||
|
radius: ["40%", "70%"],
|
||||||
|
selectedMode: "single",
|
||||||
|
},
|
||||||
|
|
||||||
|
showChart: false,
|
||||||
|
showcomponent: true,
|
||||||
|
listItem: [],
|
||||||
|
group_id: "",
|
||||||
|
groupType: "nogroup",
|
||||||
|
userId: "",
|
||||||
|
tasks: [{ category: "", title: "", duration: "" }],
|
||||||
|
groups: [],
|
||||||
|
months: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
|
||||||
|
years: ["1400", "1401", "1402", "1403", "1404", "1405"],
|
||||||
|
selectedYear: "",
|
||||||
|
selectedMonth: "",
|
||||||
|
|
||||||
|
mainList: [],
|
||||||
|
menu: menu,
|
||||||
|
firstTimeSearching: false,
|
||||||
|
httpService: undefined,
|
||||||
|
tableActions: [
|
||||||
|
{
|
||||||
|
showOutside: true,
|
||||||
|
show: true,
|
||||||
|
icon: "Component-242--1",
|
||||||
|
title: "تعیین مدیر",
|
||||||
|
to: {
|
||||||
|
name: "undefined",
|
||||||
|
},
|
||||||
|
selected: false,
|
||||||
|
disabled: false,
|
||||||
|
howToOpen: "",
|
||||||
|
href: "",
|
||||||
|
class: "edit-btn",
|
||||||
|
action: "edit-table-item",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
showOutside: true,
|
||||||
|
show: true,
|
||||||
|
icon: "Component-295--1",
|
||||||
|
title: "حذف",
|
||||||
|
to: {
|
||||||
|
name: "undefined",
|
||||||
|
},
|
||||||
|
selected: false,
|
||||||
|
disabled: false,
|
||||||
|
howToOpen: "",
|
||||||
|
href: "",
|
||||||
|
class: "delete-btn",
|
||||||
|
action: "delete-table-item",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
canView: false,
|
||||||
|
fetchingData: false,
|
||||||
|
tableColumns: [
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "firstName",
|
||||||
|
title: "نام",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "lastname",
|
||||||
|
title: "نام خانوادگی",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "team",
|
||||||
|
title: "تیم",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "useTime",
|
||||||
|
title: "خالص ماهانه",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
sorting: {
|
||||||
|
sortby: "",
|
||||||
|
sortorder: "", // asc | desc | none
|
||||||
|
},
|
||||||
|
selectedItem: {},
|
||||||
|
selectedItemClone: {},
|
||||||
|
|
||||||
|
cloneItems: [],
|
||||||
|
prevSelectedItemIndex: undefined,
|
||||||
|
|
||||||
|
users: [],
|
||||||
|
loading: false,
|
||||||
|
showPanel: true,
|
||||||
|
showPanelTeams: false,
|
||||||
|
workList: [],
|
||||||
|
rotated: false,
|
||||||
|
|
||||||
|
dataPie: [],
|
||||||
|
allUserId: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
columnGroup() {
|
||||||
|
if (this.groupType == "category")
|
||||||
|
return [
|
||||||
|
{ label: "دسته", key: "category", class: "col-6" },
|
||||||
|
{ label: "تعداد روز", key: "day_count", class: "col-2" },
|
||||||
|
{ label: "تعداد فرآیند", key: "task_count", class: "col-2" },
|
||||||
|
{ label: "مدت", key: "duration", class: "col-2" },
|
||||||
|
];
|
||||||
|
|
||||||
|
else if (this.groupType == "organ")
|
||||||
|
return [
|
||||||
|
{ label: "سازمان", key: "organ", class: "col-6" },
|
||||||
|
{ label: "تعداد روز", key: "day_count", class: "col-2" },
|
||||||
|
{ label: "تعداد فرآیند", key: "task_count", class: "col-2" },
|
||||||
|
{ label: "مدت", key: "duration", class: "col-2" },
|
||||||
|
];
|
||||||
|
|
||||||
|
else if (this.groupType == "title")
|
||||||
|
return [
|
||||||
|
{ label: "عنوان", key: "title", class: "col-6" },
|
||||||
|
{ label: "تعداد روز", key: "day_count", class: "col-2" },
|
||||||
|
{ label: "تعداد فرآیند", key: "category_count", class: "col-2" },
|
||||||
|
{ label: "مدت", key: "duration", class: "col-2" },
|
||||||
|
];
|
||||||
|
|
||||||
|
else return [
|
||||||
|
{ label: "تاریخ", key: "normalDate", class: "col-2" },
|
||||||
|
{ label: "دسته", key: "category", class: "col-3" },
|
||||||
|
{ label: "عنوان", key: "title", class: "col-6" },
|
||||||
|
{ label: "مدت", key: "duration", class: "col-1" },
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
buildName() {
|
||||||
|
return process.env.VUE_APP_BUILD_NAME + "-sidebar";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapGetters(["isSidebarCollapsed"]),
|
||||||
|
...mapActions(["checkPermissions"]),
|
||||||
|
|
||||||
|
checkPermisionBeforGetList() {
|
||||||
|
if (this.fetchingData) return;
|
||||||
|
this.fetchingData = true;
|
||||||
|
|
||||||
|
this.checkPermissions({ _this: this, permission: "admin_list" })
|
||||||
|
.then(() => {
|
||||||
|
this.getMainList()
|
||||||
|
.then(() => {
|
||||||
|
this.canView = true;
|
||||||
|
this.fetchingData = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.canView = false;
|
||||||
|
this.fetchingData = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.canView = false;
|
||||||
|
this.fetchingData = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async getMainList() {
|
||||||
|
let url = taskApi.taskReport.getList;
|
||||||
|
let payload = {
|
||||||
|
group_id: this.group_id,
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
...this.sorting,
|
||||||
|
...this.pagination,
|
||||||
|
};
|
||||||
|
return await this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
.then((res) => {
|
||||||
|
// console.log("mainList", res.data);
|
||||||
|
this.mainList = res.data;
|
||||||
|
this.allUserId = this.mainList.map((item) => item.user_id).join(",");
|
||||||
|
this.pagination = { ...this.pagination, ...res.pagination };
|
||||||
|
|
||||||
|
// this.onLinkedTitleClick({
|
||||||
|
// rowItem: this.markActive(0),
|
||||||
|
// tableColumn: {},
|
||||||
|
// index: 0,
|
||||||
|
// });
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.info(err);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.getsorting();
|
||||||
|
if (this.showChart) {
|
||||||
|
this.getvalueChartDonut();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
markActive(index) {
|
||||||
|
if (this.prevSelectedItemIndex !== undefined) {
|
||||||
|
this.$set(this.mainList[this.prevSelectedItemIndex], "active", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.prevSelectedItemIndex = index;
|
||||||
|
this.$set(this.mainList[index], "active", true);
|
||||||
|
|
||||||
|
this.selectedItemClone = structuredClone(this.mainList[index]);
|
||||||
|
return this.selectedItemClone;
|
||||||
|
},
|
||||||
|
// onLinkedTitleClick({ rowItem, tableColumn, index }) {
|
||||||
|
// // console.log(this.group_id)
|
||||||
|
// this.userId = rowItem.user_id;
|
||||||
|
|
||||||
|
// let payload = {
|
||||||
|
// user_id: this.userId,
|
||||||
|
// year: this.selectedYear,
|
||||||
|
// month: this.selectedMonth,
|
||||||
|
// };
|
||||||
|
// const url = taskApi.workingHours.load;
|
||||||
|
// this.httpService
|
||||||
|
// .postRequest(url, payload)
|
||||||
|
// .then((res) => {
|
||||||
|
// this.workList = res.data;
|
||||||
|
// this.showPanel = true;
|
||||||
|
|
||||||
|
// this.markActive(index);
|
||||||
|
// })
|
||||||
|
// .finally(() => {
|
||||||
|
// if (this.showChart) {
|
||||||
|
// this.getvalueChartDonut();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// this.getsorting();
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
|
||||||
|
getWorkingHoursInformation() {
|
||||||
|
// console.log(this.currentUser);
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
user_id: this.currentUser.user_id,
|
||||||
|
// offset: 0,
|
||||||
|
// limit: 50,
|
||||||
|
sortby: "taskDate",
|
||||||
|
sortorder: "desc",
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
};
|
||||||
|
const url = taskApi.workingHours.load;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
|
||||||
|
.then((res) => {
|
||||||
|
this.workList = res.data;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.getsorting();
|
||||||
|
if (this.showChart) {
|
||||||
|
this.getvalueChartDonut();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
datefa(item) {
|
||||||
|
let m = item * 1000;
|
||||||
|
let d = new Date(m).toLocaleDateString("fa-IR");
|
||||||
|
return d;
|
||||||
|
},
|
||||||
|
selectDate(items) {
|
||||||
|
if (items.oldDate) {
|
||||||
|
let item = items.oldDate.split("-");
|
||||||
|
let date = {};
|
||||||
|
date.day = item[2];
|
||||||
|
date.month = item[1];
|
||||||
|
date.year = item[0];
|
||||||
|
|
||||||
|
this.$emit("select-day", date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateUrl(url, query = "") {
|
||||||
|
url = url.replace("@offset", this.pagination.offset);
|
||||||
|
url = url.replace("@limit", this.pagination.limit);
|
||||||
|
url = url.replace("@sortby", this.sorting.sortby);
|
||||||
|
url = url.replace("@sortorder", this.sorting.sortorder);
|
||||||
|
|
||||||
|
// for searching groups.
|
||||||
|
if (query?.length) url = url.replace("@query", query);
|
||||||
|
else url = url.replace("/@query", query);
|
||||||
|
return url;
|
||||||
|
},
|
||||||
|
searchUsers(query = "") {
|
||||||
|
this.resetPagination();
|
||||||
|
this[groupType](query);
|
||||||
|
|
||||||
|
// this.getGroupsWithoutAdmin(query);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
toggleUsersPanel(index = undefined) {
|
||||||
|
if (index !== undefined) {
|
||||||
|
if (this.prevSelectedItemIndex !== undefined)
|
||||||
|
this.mainList[this.prevSelectedItemIndex].active = false;
|
||||||
|
|
||||||
|
this.prevSelectedItemIndex = index;
|
||||||
|
this.$set(this.mainList[index], "active", true);
|
||||||
|
this.selectedItemClone = structuredClone(this.mainList[index]);
|
||||||
|
|
||||||
|
this.showPanel = true;
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
} else {
|
||||||
|
this.resetForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
this.selectedItemClone = undefined;
|
||||||
|
this.users = [];
|
||||||
|
this.showPanel = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
// pagination and sorting
|
||||||
|
resetPagination() {
|
||||||
|
this.pagination = {
|
||||||
|
pages: 0,
|
||||||
|
total: 0,
|
||||||
|
page: 1,
|
||||||
|
offset: 0,
|
||||||
|
limit: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
pageLimitChanged(paging) {
|
||||||
|
this.resetPagination();
|
||||||
|
this.pagination.limit = paging.limit;
|
||||||
|
this.getMainList();
|
||||||
|
// this[this.searchType]();
|
||||||
|
},
|
||||||
|
pageChanged(paging) {
|
||||||
|
let page = paging.pageNumber;
|
||||||
|
page -= 1;
|
||||||
|
this.pagination.offset = page * paging.limit;
|
||||||
|
this.pagination.limit = paging.limit;
|
||||||
|
this.pagination.page = paging.pageNumber;
|
||||||
|
this.getMainList();
|
||||||
|
|
||||||
|
// this[this.searchType]();
|
||||||
|
},
|
||||||
|
sortChanged(sorting) {
|
||||||
|
this.pagination.page = this.pagination.offset = 0;
|
||||||
|
this.sorting = sorting;
|
||||||
|
this.getMainList();
|
||||||
|
|
||||||
|
// this[this.searchType]();
|
||||||
|
},
|
||||||
|
updateList() {
|
||||||
|
this.resetPagination();
|
||||||
|
this.getMainList();
|
||||||
|
},
|
||||||
|
|
||||||
|
openCreatePanel() {
|
||||||
|
if (this.showPanelTeams) {
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
} else {
|
||||||
|
this.showPanelTeams = true;
|
||||||
|
this.showPanel = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeShowPanelTeams() {
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
},
|
||||||
|
save(formData = undefined) {
|
||||||
|
if (this.loading) return;
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
const url = formData.id ? apis.users.update : apis.users.create;
|
||||||
|
|
||||||
|
formData;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, formData)
|
||||||
|
.then((res) => {
|
||||||
|
this.getUsers().then(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mySwalToast({
|
||||||
|
html: res.message,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.showPanel = false;
|
||||||
|
this.resetForm();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getPersianMonthName(month) {
|
||||||
|
const monthNames = [
|
||||||
|
"فروردین",
|
||||||
|
"اردیبهشت",
|
||||||
|
"خرداد",
|
||||||
|
"تیر",
|
||||||
|
"مرداد",
|
||||||
|
"شهریور",
|
||||||
|
"مهر",
|
||||||
|
"آبان",
|
||||||
|
"آذر",
|
||||||
|
"دی",
|
||||||
|
"بهمن",
|
||||||
|
"اسفند",
|
||||||
|
];
|
||||||
|
return monthNames[parseInt(month) - 1];
|
||||||
|
},
|
||||||
|
|
||||||
|
getTaskGroups() {
|
||||||
|
const payload = {
|
||||||
|
organ: "",
|
||||||
|
sortby: "title",
|
||||||
|
sortorder: "asc",
|
||||||
|
};
|
||||||
|
const url = taskApi.taskReport.groupList;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
|
||||||
|
.then((res) => {
|
||||||
|
this.groups = res.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
changeSorting() {
|
||||||
|
if (this.groupType == "day") {
|
||||||
|
return "SortingByDayTasksAdmin";
|
||||||
|
} else {
|
||||||
|
return "SortingTasksAdmin";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getsorting() {
|
||||||
|
let payload = {
|
||||||
|
users_id: this.allUserId,
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
group: this.groupType,
|
||||||
|
};
|
||||||
|
const url = taskApi.taskReport.sortgroup;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
|
||||||
|
.then((res) => {
|
||||||
|
this.listItem = res.data;
|
||||||
|
// console.log("listItem:", res.data);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
return "SortingTasksAdmin";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showchart(value) {
|
||||||
|
if (!value) {
|
||||||
|
this.showChart = true;
|
||||||
|
this.showcomponent = false;
|
||||||
|
this.getvalueChartDonut();
|
||||||
|
|
||||||
|
return "PieDonut";
|
||||||
|
} else {
|
||||||
|
this.showChart = false;
|
||||||
|
this.showcomponent = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getvalueChartDonut() {
|
||||||
|
let payload = {
|
||||||
|
users_id: this.allUserId,
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
};
|
||||||
|
let url = taskApi.taskChart.donut;
|
||||||
|
var vm = this;
|
||||||
|
this.httpService.postRequest(url, payload).then((res) => {
|
||||||
|
// console.log("chart", res.data);
|
||||||
|
vm.dataPie = [];
|
||||||
|
res.data.forEach((element) => {
|
||||||
|
vm.dataPie.push({
|
||||||
|
y: element.Percent,
|
||||||
|
name: element.category,
|
||||||
|
// color: colors[5],
|
||||||
|
drilldown: {
|
||||||
|
categories: [element.category],
|
||||||
|
data: [element.Total],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
UsersSearch: () =>
|
||||||
|
import(
|
||||||
|
"@admin/components/UsersSearch"
|
||||||
|
),
|
||||||
|
TeamForm: () =>
|
||||||
|
import( "@task/components/TeamForm"),
|
||||||
|
SortingTasksAdmin: () =>
|
||||||
|
import(
|
||||||
|
"@task/components/SortingTasksAdmin"
|
||||||
|
),
|
||||||
|
SortingByDayTasksAdmin: () =>
|
||||||
|
import(
|
||||||
|
"@task/components/SortingByDayTasksAdmin"
|
||||||
|
),
|
||||||
|
PieDonut: () => import("@components/charts/PieDonut.vue"),
|
||||||
|
SwitchComponent: () => import("@components/SwitchComponent.vue"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.task-system {
|
||||||
|
.table-container {
|
||||||
|
.table-responsive {
|
||||||
|
height: calc(100vh + -15em) !important;
|
||||||
|
.table {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.form-control {
|
||||||
|
border-radius: 0.5em;
|
||||||
|
height: 2.5em;
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
// .side-panel {
|
||||||
|
// padding: 1em;
|
||||||
|
// width: 30em;
|
||||||
|
// max-width: 100%;
|
||||||
|
// background-color: #fafafa;
|
||||||
|
// border-right: 1px solid #eee;
|
||||||
|
// }
|
||||||
|
// .pages-content-container {
|
||||||
|
// margin-right: 6em;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.selects {
|
||||||
|
display: flex;
|
||||||
|
// margin-right: 4em;
|
||||||
|
}
|
||||||
|
.all-selects {
|
||||||
|
display: flex;
|
||||||
|
width: 96%;
|
||||||
|
}
|
||||||
|
.select-teams {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
// width: 13em;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
.teams-label {
|
||||||
|
// min-width: 3em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
position: relative;
|
||||||
|
top: 1.4em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
right: 1em;
|
||||||
|
background-color: white;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.teams-label-Grouping {
|
||||||
|
// min-width: 5em;
|
||||||
|
width: 47%;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
position: relative;
|
||||||
|
bottom: 1.3em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
right: 6em;
|
||||||
|
background-color: white;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header,
|
||||||
|
.card {
|
||||||
|
border-radius: 0.25em !important;
|
||||||
|
}
|
||||||
|
.card-body {
|
||||||
|
border-bottom: 1px rgb(223 223 223) solid;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.component {
|
||||||
|
padding-left: 5em !important;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.btn-start {
|
||||||
|
margin-top: 2em;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
.form-control{
|
||||||
|
width: 6em;
|
||||||
|
}
|
||||||
|
</style>
|
40
components/TaskLayout.vue
Normal file
40
components/TaskLayout.vue
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<template>
|
||||||
|
<router-view :key="$route.fullPath"></router-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions } from "vuex";
|
||||||
|
import { clearBodyClass } from "@utilities/utilities";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
userLastStateIsLoaded: true,
|
||||||
|
modalComponentName: "",
|
||||||
|
actionMode: 1,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
...mapActions(["setBodyClass", "getState"]),
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeCreate() {
|
||||||
|
ApiService.init(process.env.VUE_APP_LIST_BASE_URL);
|
||||||
|
},
|
||||||
|
beforeMount() {
|
||||||
|
clearBodyClass();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.setBodyClass(process.env.VUE_APP_TASK_SYSTEM);
|
||||||
|
document.title = process.env.VUE_APP_CHAT_PAGE_TITLE;
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
clearBodyClass();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "../../assets/task/scss/task";
|
||||||
|
</style>
|
912
components/TaskUserReport.vue
Normal file
912
components/TaskUserReport.vue
Normal file
|
@ -0,0 +1,912 @@
|
||||||
|
<template>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div>
|
||||||
|
<div class="all-selects justify-content-between col-12">
|
||||||
|
<div class="selects col-md-6 justify-content-start">
|
||||||
|
<div>
|
||||||
|
<label class="teams-label"> ماه: </label>
|
||||||
|
<select
|
||||||
|
id="month-select"
|
||||||
|
class="form-control ms-1"
|
||||||
|
v-model="selectedMonth"
|
||||||
|
@change="getMainList"
|
||||||
|
>
|
||||||
|
<option v-for="month in months" :key="month" :value="month">
|
||||||
|
{{ getPersianMonthName(month) }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="me-3 ms-3">
|
||||||
|
<label class="teams-label"> سال: </label>
|
||||||
|
<select
|
||||||
|
id="year-select"
|
||||||
|
class="form-control"
|
||||||
|
v-model="selectedYear"
|
||||||
|
@change="getMainList"
|
||||||
|
>
|
||||||
|
<option v-for="year in years" :key="year" :value="year">
|
||||||
|
{{ year }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="teams-label">تیم ها:</label>
|
||||||
|
<select
|
||||||
|
v-model="group_id"
|
||||||
|
@change="getMainList"
|
||||||
|
class="form-select form-control"
|
||||||
|
>
|
||||||
|
<option selected value="">همه</option>
|
||||||
|
<option v-for="item in groups" :value="item.id">
|
||||||
|
{{ item.title }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="d-flex align-items-center grouping col-md-6 justify-content-end"
|
||||||
|
>
|
||||||
|
<div class="select-teams">
|
||||||
|
<label class="teams-label-Grouping"> گروه بندی:</label>
|
||||||
|
<select
|
||||||
|
v-model="groupType"
|
||||||
|
@change="getsorting()"
|
||||||
|
class="form-control"
|
||||||
|
>
|
||||||
|
<option selected value="nogroup">بدون گروه بندی</option>
|
||||||
|
<option value="day">روز</option>
|
||||||
|
<option value="category">دسته</option>
|
||||||
|
<option value="title">عنوان</option>
|
||||||
|
<option value="organ">سازمان</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="switch-component">
|
||||||
|
<switch-component
|
||||||
|
name="switch-view-mode"
|
||||||
|
@change-mode="showchart($event)"
|
||||||
|
class="task-admin-switch"
|
||||||
|
texts1="Normal"
|
||||||
|
texts2="Chartical"
|
||||||
|
></switch-component>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<main class="pages-content-container">
|
||||||
|
<div class="pages-content pt-3">
|
||||||
|
<div class="" :class="{ 'd-flex': showPanel || showPanelTeams }">
|
||||||
|
<template v-if="canView">
|
||||||
|
<my-table
|
||||||
|
class="p-0 ms-3 col-12 col-md-6"
|
||||||
|
:tableActions="tableActions"
|
||||||
|
height="calc(100vh + -14em)"
|
||||||
|
minHeight="25em"
|
||||||
|
maxHeight="calc(100dvh + -13em)"
|
||||||
|
:paginationInfo="pagination"
|
||||||
|
:sortingInfo="sorting"
|
||||||
|
:items="mainList"
|
||||||
|
:fetchingData="fetchingData"
|
||||||
|
:tableColumns="tableColumns"
|
||||||
|
:totalPages="pagination.pages"
|
||||||
|
:showActions="false"
|
||||||
|
@search="searchUsers"
|
||||||
|
@reset-form="searchUsers"
|
||||||
|
@delete-table-item="deleteItem"
|
||||||
|
@edit-table-item="toggleUsersPanel"
|
||||||
|
@page-changed="pageChanged"
|
||||||
|
@page-limit-changed="pageLimitChanged"
|
||||||
|
@sort-changed="sortChanged"
|
||||||
|
@on-linked-title-click="onLinkedTitleClick"
|
||||||
|
>
|
||||||
|
</my-table>
|
||||||
|
<div class="col-6 form-sorting_user">
|
||||||
|
<component
|
||||||
|
v-if="showcomponent"
|
||||||
|
:is="changeSorting()"
|
||||||
|
:listItem="listItem"
|
||||||
|
:columns="columnGroup"
|
||||||
|
:workList="workList"
|
||||||
|
:userId="userId"
|
||||||
|
></component>
|
||||||
|
|
||||||
|
<pie-donut
|
||||||
|
class="mt-5 me-5 d-flex justify-content-end"
|
||||||
|
v-if="showChart"
|
||||||
|
:dataPie="dataPie"
|
||||||
|
:PieOptions="PieOptions"
|
||||||
|
width="100%"
|
||||||
|
height="300px"
|
||||||
|
></pie-donut>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<no-data v-else>
|
||||||
|
<the-content-loading v-if="fetchingData"></the-content-loading>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="d-flex justify-content-center align-items-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="alert alert-warning d-flex justify-content-center align-items-center"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="tavasi tavasi-warning-circle color-inherit ms-1 text__32"
|
||||||
|
></span>
|
||||||
|
عدم دسترسی
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</no-data>
|
||||||
|
|
||||||
|
<!-- <div class="side-panel" v-if="showPanel">
|
||||||
|
<div
|
||||||
|
class="side-panel-header d-flex mb-3 pb-3 border-bottom align-items-center"
|
||||||
|
>
|
||||||
|
<h5 class="m-0">جستجو و انتخاب مدیر گروه</h5>
|
||||||
|
|
||||||
|
<button
|
||||||
|
@click.prevent="toggleUsersPanel()"
|
||||||
|
class="btn me-auto"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<svg class="icon icon-Component-294--1">
|
||||||
|
<use xlink:href="#icon-Component-294--1"></use>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="side-panel-content">
|
||||||
|
<users-search
|
||||||
|
v-if="showPanel"
|
||||||
|
:searchResults="users"
|
||||||
|
@on-send="searchUsers"
|
||||||
|
@set-as-admin="setAsAdmin"
|
||||||
|
></users-search>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<!-- <div class="side-panel" v-if="showPanelTeams">
|
||||||
|
<div
|
||||||
|
class="side-panel-header d-flex mb-3 pb-3 border-bottom align-items-center"
|
||||||
|
>
|
||||||
|
<h6 class="m-0">مدیریت کاربران</h6>
|
||||||
|
|
||||||
|
<button
|
||||||
|
@click.prevent="closeShowPanelTeams()"
|
||||||
|
class="btn btn-outline-primary me-auto"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
x
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="side-panel-content">
|
||||||
|
<TeamForm
|
||||||
|
v-if="showPanelTeams"
|
||||||
|
@on-pass-by-emit="save"
|
||||||
|
></TeamForm>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters, mapActions } from "vuex";
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
import menu from "@task/json/menu.json";
|
||||||
|
import adminApi from "@apis/adminApi";
|
||||||
|
import taskApi from "@apis/taskApi";
|
||||||
|
import { p2e } from "@plugins/persianNumber";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService(this.taskMicroServiceName);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.checkPermisionBeforGetList();
|
||||||
|
|
||||||
|
var d = new Date().toLocaleDateString("fa-IR");
|
||||||
|
let items = d.split("/");
|
||||||
|
this.selectedYear = p2e(items[0]);
|
||||||
|
this.selectedMonth = p2e(items[1]);
|
||||||
|
|
||||||
|
this.getWorkingHoursInformation();
|
||||||
|
this.getTaskGroups();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
PieOptions: {
|
||||||
|
radius: ["40%", "70%"],
|
||||||
|
selectedMode: "single",
|
||||||
|
},
|
||||||
|
|
||||||
|
showChart: false,
|
||||||
|
showcomponent: true,
|
||||||
|
listItem: [],
|
||||||
|
group_id: "",
|
||||||
|
groupType: "nogroup",
|
||||||
|
userId: "",
|
||||||
|
tasks: [{ category: "", title: "", duration: "" }],
|
||||||
|
groups: [],
|
||||||
|
months: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
|
||||||
|
years: ["1400", "1401", "1402", "1403", "1404", "1405"],
|
||||||
|
selectedYear: "",
|
||||||
|
selectedMonth: "",
|
||||||
|
|
||||||
|
mainList: [],
|
||||||
|
menu: menu,
|
||||||
|
firstTimeSearching: false,
|
||||||
|
httpService: undefined,
|
||||||
|
tableActions: [
|
||||||
|
{
|
||||||
|
showOutside: true,
|
||||||
|
show: true,
|
||||||
|
icon: "Component-242--1",
|
||||||
|
title: "تعیین مدیر",
|
||||||
|
to: {
|
||||||
|
name: "undefined",
|
||||||
|
},
|
||||||
|
selected: false,
|
||||||
|
disabled: false,
|
||||||
|
howToOpen: "",
|
||||||
|
href: "",
|
||||||
|
class: "edit-btn",
|
||||||
|
action: "edit-table-item",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
showOutside: true,
|
||||||
|
show: true,
|
||||||
|
icon: "Component-295--1",
|
||||||
|
title: "حذف",
|
||||||
|
to: {
|
||||||
|
name: "undefined",
|
||||||
|
},
|
||||||
|
selected: false,
|
||||||
|
disabled: false,
|
||||||
|
howToOpen: "",
|
||||||
|
href: "",
|
||||||
|
class: "delete-btn",
|
||||||
|
action: "delete-table-item",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
canView: false,
|
||||||
|
fetchingData: false,
|
||||||
|
tableColumns: [
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "team",
|
||||||
|
title: "تیم",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "firstName",
|
||||||
|
title: "نام",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "lastname",
|
||||||
|
title: "نام خانوادگی",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "useTime",
|
||||||
|
title: "جمع خالص ماهانه",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "allTime",
|
||||||
|
title: "جمع کل ماهانه",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "noWorkTime",
|
||||||
|
title: " ساعات غیر کاری",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "averageDay",
|
||||||
|
title: "میانگین روز",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "alldays",
|
||||||
|
title: "تعداد روز",
|
||||||
|
width: "2",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
sorting: {
|
||||||
|
sortby: "",
|
||||||
|
sortorder: "", // asc | desc | none
|
||||||
|
},
|
||||||
|
selectedItem: {},
|
||||||
|
selectedItemClone: {},
|
||||||
|
|
||||||
|
cloneItems: [],
|
||||||
|
prevSelectedItemIndex: undefined,
|
||||||
|
|
||||||
|
users: [],
|
||||||
|
loading: false,
|
||||||
|
showPanel: true,
|
||||||
|
showPanelTeams: false,
|
||||||
|
workList: [],
|
||||||
|
rotated: false,
|
||||||
|
|
||||||
|
dataPie: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(["isSidebarCollapsed"]),
|
||||||
|
|
||||||
|
columnGroup() {
|
||||||
|
if (this.groupType == "category")
|
||||||
|
return [
|
||||||
|
{ label: "دسته", key: "category", class: "col-6" },
|
||||||
|
{ label: "تعداد روز", key: "day_count", class: "col-2" },
|
||||||
|
{ label: "تعداد فرآیند", key: "task_count", class: "col-2" },
|
||||||
|
{ label: "مدت", key: "duration", class: "col-2" },
|
||||||
|
];
|
||||||
|
|
||||||
|
else if (this.groupType == "organ")
|
||||||
|
return [
|
||||||
|
{ label: "سازمان", key: "organ", class: "col-6" },
|
||||||
|
{ label: "تعداد روز", key: "day_count", class: "col-2" },
|
||||||
|
{ label: "تعداد فرآیند", key: "task_count", class: "col-2" },
|
||||||
|
{ label: "مدت", key: "duration", class: "col-2" },
|
||||||
|
];
|
||||||
|
|
||||||
|
else if (this.groupType == "title")
|
||||||
|
return [
|
||||||
|
{ label: "عنوان", key: "title", class: "col-6" },
|
||||||
|
{ label: "تعداد روز", key: "day_count", class: "col-2" },
|
||||||
|
{ label: "تعداد فرآیند", key: "category_count", class: "col-2" },
|
||||||
|
{ label: "مدت", key: "duration", class: "col-2" },
|
||||||
|
];
|
||||||
|
|
||||||
|
else return [
|
||||||
|
{ label: "تاریخ", key: "normalDate", class: "col-2" },
|
||||||
|
{ label: "دسته", key: "category", class: "col-3" },
|
||||||
|
{ label: "عنوان", key: "title", class: "col-6" },
|
||||||
|
{ label: "مدت", key: "duration", class: "col-1" },
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
buildName() {
|
||||||
|
return process.env.VUE_APP_BUILD_NAME + "-sidebar";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(["checkPermissions"]),
|
||||||
|
|
||||||
|
checkPermisionBeforGetList() {
|
||||||
|
if (this.fetchingData) return;
|
||||||
|
this.fetchingData = true;
|
||||||
|
|
||||||
|
this.checkPermissions({ _this: this, permission: "admin_list" })
|
||||||
|
.then(() => {
|
||||||
|
this.getMainList()
|
||||||
|
.then(() => {
|
||||||
|
this.canView = true;
|
||||||
|
this.fetchingData = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.canView = false;
|
||||||
|
this.fetchingData = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.canView = false;
|
||||||
|
this.fetchingData = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async getMainList() {
|
||||||
|
let url = taskApi.taskReport.getList;
|
||||||
|
let payload = {
|
||||||
|
group_id: this.group_id,
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
...this.sorting,
|
||||||
|
...this.pagination,
|
||||||
|
};
|
||||||
|
return await this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
.then((res) => {
|
||||||
|
this.mainList = res.data;
|
||||||
|
this.pagination = { ...this.pagination, ...res.pagination };
|
||||||
|
|
||||||
|
this.onLinkedTitleClick({
|
||||||
|
rowItem: this.markActive(0),
|
||||||
|
tableColumn: {},
|
||||||
|
index: 0,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.info(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
markActive(index) {
|
||||||
|
if (this.prevSelectedItemIndex !== undefined) {
|
||||||
|
this.$set(this.mainList[this.prevSelectedItemIndex], "active", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.prevSelectedItemIndex = index;
|
||||||
|
this.$set(this.mainList[index], "active", true);
|
||||||
|
|
||||||
|
this.selectedItemClone = structuredClone(this.mainList[index]);
|
||||||
|
return this.selectedItemClone;
|
||||||
|
},
|
||||||
|
onLinkedTitleClick({ rowItem, tableColumn, index }) {
|
||||||
|
this.userId = rowItem.user_id;
|
||||||
|
|
||||||
|
let payload = {
|
||||||
|
user_id: this.userId,
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
};
|
||||||
|
const url = taskApi.workingHours.load;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
.then((res) => {
|
||||||
|
this.workList = res.data;
|
||||||
|
this.showPanel = true;
|
||||||
|
|
||||||
|
this.markActive(index);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
if (this.showChart) {
|
||||||
|
this.getvalueChartDonut();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getsorting();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getWorkingHoursInformation() {
|
||||||
|
// console.log(this.currentUser);
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
user_id: this.currentUser.user_id,
|
||||||
|
// offset: 0,
|
||||||
|
// limit: 50,
|
||||||
|
sortby: "taskDate",
|
||||||
|
sortorder: "desc",
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
};
|
||||||
|
const url = taskApi.workingHours.load;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
|
||||||
|
.then((res) => {
|
||||||
|
this.workList = res.data;
|
||||||
|
// console.log("111 ", this.workList);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.getsorting();
|
||||||
|
if (this.showChart) {
|
||||||
|
this.getvalueChartDonut();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
datefa(item) {
|
||||||
|
let m = item * 1000;
|
||||||
|
let d = new Date(m).toLocaleDateString("fa-IR");
|
||||||
|
return d;
|
||||||
|
},
|
||||||
|
selectDate(items) {
|
||||||
|
if (items.oldDate) {
|
||||||
|
let item = items.oldDate.split("-");
|
||||||
|
let date = {};
|
||||||
|
date.day = item[2];
|
||||||
|
date.month = item[1];
|
||||||
|
date.year = item[0];
|
||||||
|
|
||||||
|
this.$emit("select-day", date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// async getGroupsWithoutAdmin(query = "") {
|
||||||
|
// let url = `${this.messageMicroServiceName}/${adminApi.groups.groupsWithoutAdmin}`;
|
||||||
|
|
||||||
|
// return await this.httpService
|
||||||
|
// .getRequest(this.updateUrl(url, query))
|
||||||
|
// .then((res) => {
|
||||||
|
// this.groups = res.data;
|
||||||
|
// this.pagination = { ...this.pagination, ...res.pagination };
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// getGroupsWithAdmin() {
|
||||||
|
// if (this.fetchingData) return;
|
||||||
|
// this.fetchingData = true;
|
||||||
|
|
||||||
|
// let url = `${this.messageMicroServiceName}/${adminApi.groups.groupsWithAdmin}`;
|
||||||
|
|
||||||
|
// this.httpService
|
||||||
|
// .getRequest(this.updateUrl(url))
|
||||||
|
// .then((response) => {
|
||||||
|
// this.groups = response.data;
|
||||||
|
// this.pagination = { ...this.pagination, ...response.pagination };
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// .finally(() => {
|
||||||
|
// this.fetchingData = false;
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
updateUrl(url, query = "") {
|
||||||
|
url = url.replace("@offset", this.pagination.offset);
|
||||||
|
url = url.replace("@limit", this.pagination.limit);
|
||||||
|
url = url.replace("@sortby", this.sorting.sortby);
|
||||||
|
url = url.replace("@sortorder", this.sorting.sortorder);
|
||||||
|
|
||||||
|
// for searching groups.
|
||||||
|
if (query?.length) url = url.replace("@query", query);
|
||||||
|
else url = url.replace("/@query", query);
|
||||||
|
return url;
|
||||||
|
},
|
||||||
|
searchUsers(query = "") {
|
||||||
|
this.resetPagination();
|
||||||
|
this[groupType](query);
|
||||||
|
|
||||||
|
// this.getGroupsWithoutAdmin(query);
|
||||||
|
},
|
||||||
|
// setSearchType(groupType) {
|
||||||
|
// this.searchType = groupType;
|
||||||
|
|
||||||
|
// this.resetPagination();
|
||||||
|
// this[groupType]();
|
||||||
|
// },
|
||||||
|
|
||||||
|
setAsAdmin(user) {
|
||||||
|
if (this.loading) return;
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
const url = this.messageMicroServiceName + "/" + chatApi.groups.setAdmin;
|
||||||
|
|
||||||
|
let payload = {
|
||||||
|
user_id: user.id,
|
||||||
|
group_id: this.selectedItemClone.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
.then((res) => {
|
||||||
|
this.getGroupsWithoutAdmin().then(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mySwalToast({
|
||||||
|
html: res.message,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.showPanel = false;
|
||||||
|
this.resetForm();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleUsersPanel(index = undefined) {
|
||||||
|
if (index !== undefined) {
|
||||||
|
if (this.prevSelectedItemIndex !== undefined)
|
||||||
|
this.mainList[this.prevSelectedItemIndex].active = false;
|
||||||
|
|
||||||
|
this.prevSelectedItemIndex = index;
|
||||||
|
this.$set(this.mainList[index], "active", true);
|
||||||
|
this.selectedItemClone = structuredClone(this.mainList[index]);
|
||||||
|
|
||||||
|
this.showPanel = true;
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
} else {
|
||||||
|
this.resetForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
this.selectedItemClone = undefined;
|
||||||
|
this.users = [];
|
||||||
|
this.showPanel = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
// pagination and sorting
|
||||||
|
resetPagination() {
|
||||||
|
this.pagination = {
|
||||||
|
pages: 0,
|
||||||
|
total: 0,
|
||||||
|
page: 1,
|
||||||
|
offset: 0,
|
||||||
|
limit: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
pageLimitChanged(paging) {
|
||||||
|
this.resetPagination();
|
||||||
|
this.pagination.limit = paging.limit;
|
||||||
|
this.getMainList();
|
||||||
|
// this[this.searchType]();
|
||||||
|
},
|
||||||
|
pageChanged(paging) {
|
||||||
|
let page = paging.pageNumber;
|
||||||
|
page -= 1;
|
||||||
|
this.pagination.offset = page * paging.limit;
|
||||||
|
this.pagination.limit = paging.limit;
|
||||||
|
this.pagination.page = paging.pageNumber;
|
||||||
|
this.getMainList();
|
||||||
|
|
||||||
|
// this[this.searchType]();
|
||||||
|
},
|
||||||
|
sortChanged(sorting) {
|
||||||
|
this.pagination.page = this.pagination.offset = 0;
|
||||||
|
this.sorting = sorting;
|
||||||
|
this.getMainList();
|
||||||
|
|
||||||
|
// this[this.searchType]();
|
||||||
|
},
|
||||||
|
updateList() {
|
||||||
|
this.resetPagination();
|
||||||
|
this.getMainList();
|
||||||
|
},
|
||||||
|
|
||||||
|
// not used yet.
|
||||||
|
deleteItem(index) {
|
||||||
|
if (this.loading) return;
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
let groupId = this.mainList[index].id;
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
group_id: groupId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const url = `${this.messageMicroServiceName}/${adminApi.groups.delete}`;
|
||||||
|
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار",
|
||||||
|
html: "با حذف گروه، تمامی مسائل و پاسخ های آن نیز حذف خواهد شد.",
|
||||||
|
icon: "warning",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.httpService.postRequest(url, payload).then((res) => {
|
||||||
|
this[this.searchType]().then(() => {
|
||||||
|
this.loading = false;
|
||||||
|
// this.showPanel = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mySwalToast({
|
||||||
|
html: res.message,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
openCreatePanel() {
|
||||||
|
if (this.showPanelTeams) {
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
} else {
|
||||||
|
this.showPanelTeams = true;
|
||||||
|
this.showPanel = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeShowPanelTeams() {
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
},
|
||||||
|
save(formData = undefined) {
|
||||||
|
if (this.loading) return;
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
const url = formData.id ? apis.users.update : apis.users.create;
|
||||||
|
|
||||||
|
formData;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, formData)
|
||||||
|
.then((res) => {
|
||||||
|
this.getUsers().then(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mySwalToast({
|
||||||
|
html: res.message,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.showPanel = false;
|
||||||
|
this.resetForm();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getPersianMonthName(month) {
|
||||||
|
const monthNames = [
|
||||||
|
"فروردین",
|
||||||
|
"اردیبهشت",
|
||||||
|
"خرداد",
|
||||||
|
"تیر",
|
||||||
|
"مرداد",
|
||||||
|
"شهریور",
|
||||||
|
"مهر",
|
||||||
|
"آبان",
|
||||||
|
"آذر",
|
||||||
|
"دی",
|
||||||
|
"بهمن",
|
||||||
|
"اسفند",
|
||||||
|
];
|
||||||
|
return monthNames[parseInt(month) - 1];
|
||||||
|
},
|
||||||
|
|
||||||
|
getTaskGroups() {
|
||||||
|
const payload = {
|
||||||
|
organ: "",
|
||||||
|
sortby: "title",
|
||||||
|
sortorder: "asc",
|
||||||
|
};
|
||||||
|
const url = taskApi.taskReport.groupList;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
|
||||||
|
.then((res) => {
|
||||||
|
this.groups = res.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
changeSorting() {
|
||||||
|
if (this.groupType == "day") {
|
||||||
|
return "SortingByDayTasksAdmin";
|
||||||
|
} else {
|
||||||
|
return "SortingTasksAdmin";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getsorting() {
|
||||||
|
let payload = {
|
||||||
|
user_id: this.userId,
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
group: this.groupType,
|
||||||
|
};
|
||||||
|
const url = taskApi.taskReport.sortgroup;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, payload)
|
||||||
|
|
||||||
|
.then((res) => {
|
||||||
|
this.listItem = res.data;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
return "SortingTasksAdmin";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showchart(value) {
|
||||||
|
if (!value) {
|
||||||
|
this.showChart = true;
|
||||||
|
this.showcomponent = false;
|
||||||
|
this.getvalueChartDonut();
|
||||||
|
|
||||||
|
return "PieDonut";
|
||||||
|
} else {
|
||||||
|
this.showChart = false;
|
||||||
|
this.showcomponent = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getvalueChartDonut() {
|
||||||
|
let payload = {
|
||||||
|
user_id: this.userId,
|
||||||
|
year: this.selectedYear,
|
||||||
|
month: this.selectedMonth,
|
||||||
|
};
|
||||||
|
let url = taskApi.taskChart.donut;
|
||||||
|
var vm = this;
|
||||||
|
this.httpService.postRequest(url, payload).then((res) => {
|
||||||
|
vm.dataPie = [];
|
||||||
|
res.data.forEach((element) => {
|
||||||
|
vm.dataPie.push({
|
||||||
|
y: element.Percent,
|
||||||
|
name: element.category,
|
||||||
|
// color: colors[5],
|
||||||
|
drilldown: {
|
||||||
|
categories: [element.category],
|
||||||
|
data: [element.Total],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
UsersSearch: () => import("@admin/components/UsersSearch"),
|
||||||
|
TeamForm: () => import("@task/components/TeamForm"),
|
||||||
|
SortingTasksAdmin: () => import("@task/components/SortingTasksAdmin"),
|
||||||
|
SortingByDayTasksAdmin: () =>
|
||||||
|
import("@task/components/SortingByDayTasksAdmin"),
|
||||||
|
PieDonut: () => import("@components/charts/PieDonut.vue"),
|
||||||
|
|
||||||
|
SwitchComponent: () => import("@components/SwitchComponent.vue"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.task-system {
|
||||||
|
.table-container {
|
||||||
|
.table-responsive {
|
||||||
|
height: calc(100vh + -15em) !important;
|
||||||
|
.table {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.form-control {
|
||||||
|
border-radius: 0.5em;
|
||||||
|
height: 2.5em;
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
// .side-panel {
|
||||||
|
// padding: 1em;
|
||||||
|
// width: 30em;
|
||||||
|
// max-width: 100%;
|
||||||
|
// background-color: #fafafa;
|
||||||
|
// border-right: 1px solid #eee;
|
||||||
|
// }
|
||||||
|
// .pages-content-container {
|
||||||
|
// margin-right: 6em;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.selects {
|
||||||
|
display: flex;
|
||||||
|
// margin-right: 6em;
|
||||||
|
}
|
||||||
|
.all-selects {
|
||||||
|
display: flex;
|
||||||
|
width: 96%;
|
||||||
|
}
|
||||||
|
.select-teams {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
// width: 13em;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
.teams-label {
|
||||||
|
// min-width: 3em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
position: relative;
|
||||||
|
top: 1.4em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
right: 1em;
|
||||||
|
background-color: white;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.teams-label-Grouping {
|
||||||
|
// min-width: 5em;
|
||||||
|
width: 47%;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
position: relative;
|
||||||
|
bottom: 1.3em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
right: 6em;
|
||||||
|
background-color: white;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header,
|
||||||
|
.card {
|
||||||
|
border-radius: 0.25em !important;
|
||||||
|
}
|
||||||
|
.card-body {
|
||||||
|
border-bottom: 1px rgb(223 223 223) solid;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.component {
|
||||||
|
padding-left: 5em !important;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.form-control {
|
||||||
|
width: 6em;
|
||||||
|
}
|
||||||
|
</style>
|
135
components/TeamForm.vue
Normal file
135
components/TeamForm.vue
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
<template>
|
||||||
|
<div class="sign-up__form">
|
||||||
|
<div class="sign-up__form-inputs">
|
||||||
|
<div class="sign-up__row sign-up__simple-input">
|
||||||
|
<div class="form-group position-relative">
|
||||||
|
<label for="">عنوان:</label>
|
||||||
|
<input
|
||||||
|
class="form-control elem__placeholder-gray"
|
||||||
|
v-model.trim="value.title"
|
||||||
|
type="text"
|
||||||
|
placeholder="عنوان"
|
||||||
|
autocomplete="on"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sign-up__row sign-up__simple-input">
|
||||||
|
<div class="form-group position-relative">
|
||||||
|
<label for="">سازمان:</label>
|
||||||
|
<input
|
||||||
|
class="form-control elem__placeholder-gray"
|
||||||
|
v-model.trim="value.organ"
|
||||||
|
type="text"
|
||||||
|
placeholder="سازمان"
|
||||||
|
autocomplete="on"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<div class="sign-up__btn-container ms-3">
|
||||||
|
<a @click="closeForm()" class="btn">انصراف</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-primary" @click="submit()">
|
||||||
|
<the-button-loading v-if="loading"></the-button-loading>
|
||||||
|
<template v-if="value.id">
|
||||||
|
{{ $t("Update") }}
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{ $t("Save") }}
|
||||||
|
</template>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// import taskApi from "@apis/taskApi";
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService( this.taskMicroServiceName
|
||||||
|
);
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
parentLoading: false,
|
||||||
|
teamData: {
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
id: undefined,
|
||||||
|
organ: null,
|
||||||
|
title: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
teamData(newValu) {
|
||||||
|
this.value = newValu;
|
||||||
|
},
|
||||||
|
parentLoading(newVal) {
|
||||||
|
this.loading = newVal;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.value = this.teamData;
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// organ: "",
|
||||||
|
// title: "",
|
||||||
|
loading: this.parentLoading,
|
||||||
|
value: {
|
||||||
|
id: undefined,
|
||||||
|
organ: null,
|
||||||
|
title: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
taskMicroServiceName() {
|
||||||
|
return process.env.VUE_APP_TASK;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit() {
|
||||||
|
this.loading = true;
|
||||||
|
this.$emit("on-pass-by-emit", this.value);
|
||||||
|
},
|
||||||
|
// addTeams() {
|
||||||
|
// this.$emit("add-teams");
|
||||||
|
// },
|
||||||
|
closeForm() {
|
||||||
|
this.$emit("close-form");
|
||||||
|
},
|
||||||
|
// getGroups() {
|
||||||
|
// this.$emit("get-groups");
|
||||||
|
// },
|
||||||
|
// addTeams() {
|
||||||
|
// let url = taskApi.taskTeams.add;
|
||||||
|
// let payload = {
|
||||||
|
// title: this.value.title,
|
||||||
|
// organ: this.value.organ,
|
||||||
|
// };
|
||||||
|
// this.httpService
|
||||||
|
// .postRequest(url, payload)
|
||||||
|
// .then((res) => {
|
||||||
|
// this.mySwalToast({
|
||||||
|
// html: res.message,
|
||||||
|
// });
|
||||||
|
// })
|
||||||
|
// .finally(() => {
|
||||||
|
// this.getGroups();
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
// input::placeholder {
|
||||||
|
// color: #d7d7d7;
|
||||||
|
// }
|
||||||
|
</style>
|
46
json/menu.json
Normal file
46
json/menu.json
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"color": 5,
|
||||||
|
"icon": "Home-21",
|
||||||
|
"link": "defaultRoute",
|
||||||
|
"title": "پیشخوان",
|
||||||
|
"translateKey": "Dashboard"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": 5,
|
||||||
|
"icon": "projects",
|
||||||
|
"link": "taskDashboard",
|
||||||
|
"title": "پیشخوان مدیریت وظایف",
|
||||||
|
"translateKey": "TaskDashboard"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": 5,
|
||||||
|
"icon": "task-list",
|
||||||
|
"link": "taskTimes",
|
||||||
|
"title": "ساعات",
|
||||||
|
"translateKey": "TaskTimes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": 5,
|
||||||
|
"icon": "task-time",
|
||||||
|
"link": "taskList",
|
||||||
|
"title": "وظایف",
|
||||||
|
"translateKey": "TaskList"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": 5,
|
||||||
|
"icon": "groups",
|
||||||
|
"link": "teams",
|
||||||
|
"title": "تیم ها",
|
||||||
|
"translateKey": "Teams"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": 5,
|
||||||
|
"icon": "portal-roles",
|
||||||
|
"link": "taskReport",
|
||||||
|
"title": "گزارش وظایف",
|
||||||
|
"translateKey": "taskReport"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
56
json/teamListTableAction.json
Normal file
56
json/teamListTableAction.json
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
[
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"showOutside": false,
|
||||||
|
|
||||||
|
"show": true,
|
||||||
|
"icon": "Component-242--1",
|
||||||
|
"title": "ویرایش",
|
||||||
|
"to": {
|
||||||
|
"name": "undefined"
|
||||||
|
},
|
||||||
|
"selected": false,
|
||||||
|
"disabled": false,
|
||||||
|
"howToOpen": "",
|
||||||
|
"href": "",
|
||||||
|
"class": "edit-btn",
|
||||||
|
"action": "edit-table-item",
|
||||||
|
"can": "forms_edit"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"showOutside": false,
|
||||||
|
|
||||||
|
"show": true,
|
||||||
|
"icon": "Component-295--1",
|
||||||
|
"title": "حذف",
|
||||||
|
"to": {
|
||||||
|
"name": "undefined"
|
||||||
|
},
|
||||||
|
"selected": false,
|
||||||
|
"disabled": false,
|
||||||
|
"howToOpen": "",
|
||||||
|
"href": "",
|
||||||
|
"class": "delete-btn",
|
||||||
|
"action": "delete-table-item",
|
||||||
|
"can": "forms_delete"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"showOutside": false,
|
||||||
|
|
||||||
|
"show": true,
|
||||||
|
"icon": "groups",
|
||||||
|
"title": "اعضا",
|
||||||
|
"to": {
|
||||||
|
"name": "undefined"
|
||||||
|
},
|
||||||
|
"selected": false,
|
||||||
|
"disabled": false,
|
||||||
|
"howToOpen": "",
|
||||||
|
"href": "",
|
||||||
|
"class": "",
|
||||||
|
"action": "select-list-columns",
|
||||||
|
"can": "form_select-list-columns"
|
||||||
|
}
|
||||||
|
]
|
162
pages/Task.vue
Normal file
162
pages/Task.vue
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
<template>
|
||||||
|
<section>
|
||||||
|
<Navbar class="task-navbar"> </Navbar>
|
||||||
|
|
||||||
|
<the-sidebar2
|
||||||
|
:showUserAvatar="true"
|
||||||
|
:menu="menu"
|
||||||
|
@statusPage="statusPage"
|
||||||
|
></the-sidebar2>
|
||||||
|
|
||||||
|
<main class="main-page__content" :class="{ expanded: !isSidebarCollapsed }">
|
||||||
|
<right-section
|
||||||
|
ref="chat-list-panel"
|
||||||
|
@select-day="selectDay"
|
||||||
|
:show-header="statusPagHedear"
|
||||||
|
:key="render"
|
||||||
|
id="group"
|
||||||
|
></right-section>
|
||||||
|
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<div class="position-relative d-flex justify-content-center"></div>
|
||||||
|
<template>
|
||||||
|
<MainSection
|
||||||
|
ref="mainsection"
|
||||||
|
:key="render"
|
||||||
|
></MainSection>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="right-section-mobile"></div>
|
||||||
|
|
||||||
|
<!-- <mobile-footer></mobile-footer> -->
|
||||||
|
</main>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters, mapMutations, mapActions } from "vuex";
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
import menu from "@task/json/menu.json";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService();
|
||||||
|
this.getSchemas();
|
||||||
|
},
|
||||||
|
|
||||||
|
// mixins: [commentMixin],
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.TOGGLE_PANEL(false);
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
getPanelStatus(status) {
|
||||||
|
if (status) this.openForm();
|
||||||
|
else this.closeModal();
|
||||||
|
},
|
||||||
|
$route: {
|
||||||
|
handler: function () {
|
||||||
|
this.sidebarCollapsedSetter(true);
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
nomber: 0,
|
||||||
|
statusPagHedear: 1,
|
||||||
|
render: 1,
|
||||||
|
showListPanel: false,
|
||||||
|
menu: menu,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters([
|
||||||
|
"getPanelStatus",
|
||||||
|
"isSidebarCollapsed",
|
||||||
|
"organNameGetter",
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations([
|
||||||
|
"TOGGLE_PANEL",
|
||||||
|
"sidebarCollapsedSetter",
|
||||||
|
"taskSchemaSetter",
|
||||||
|
]),
|
||||||
|
...mapActions(["checkPermissions"]),
|
||||||
|
getSchemas() {
|
||||||
|
let url = this.repoMicroServiceName + "schema";
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, {
|
||||||
|
organ: this.organNameGetter,
|
||||||
|
system: "task",
|
||||||
|
build_state: this.buildState,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
this.taskSchemaSetter(response.data.task[0]);
|
||||||
|
this.render++;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
selectedListBackTitle(name) {
|
||||||
|
if (name == "groups") return "دانشتو با بقیه به اشتراک بزار.";
|
||||||
|
if (name == "privates") return "به هر کی دوست داری، پیام بده.";
|
||||||
|
if (name == "lobbies") return "به تالار گفتگو خوش اومدی";
|
||||||
|
},
|
||||||
|
|
||||||
|
// showSearch() {
|
||||||
|
// search in current group, not all groups.
|
||||||
|
// this.$refs["chat-list-panel"].showSearchs(true);
|
||||||
|
// },
|
||||||
|
|
||||||
|
// #region mehdi
|
||||||
|
statusPage($event) {
|
||||||
|
const number = $event;
|
||||||
|
|
||||||
|
if (number == 1) {
|
||||||
|
if (this.$refs["chat-list-panel"].showMainpag == false) {
|
||||||
|
this.$refs["chat-list-panel"].showMainpag = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.$refs["chat-list-panel"].showMainpag == false) {
|
||||||
|
this.$refs["chat-list-panel"].showMainpag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
toggleSidebarMenu() {
|
||||||
|
this.TOGGLE_SIDEBAR_MENU();
|
||||||
|
},
|
||||||
|
showToggleListPanel() {
|
||||||
|
this.showListPanel = !this.showListPanel;
|
||||||
|
this.$refs["chat-list-panel"].showMainpag = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// #region mehdi
|
||||||
|
openPagGrup(data) {
|
||||||
|
this.enablePanelToggling = data;
|
||||||
|
if (this.enablePanelToggling == 1) {
|
||||||
|
this.showToggleListPanel();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectDay(date) {
|
||||||
|
this.$refs.mainsection.setCurrentDate(date);
|
||||||
|
},
|
||||||
|
// #endregion
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
MainSection: () => import("@task/components/MainSection"),
|
||||||
|
RightSection: () => import("@task/components/RightSection"),
|
||||||
|
Navbar: () => import("@task/components/Navbar"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
289
pages/TaskDashboard.vue
Normal file
289
pages/TaskDashboard.vue
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
<template>
|
||||||
|
<section>
|
||||||
|
<Navbar class="task-navbar"> </Navbar>
|
||||||
|
<the-sidebar2
|
||||||
|
:showUserAvatar="true"
|
||||||
|
:menu="menu"
|
||||||
|
@statusPage="statusPage"
|
||||||
|
></the-sidebar2>
|
||||||
|
|
||||||
|
<main
|
||||||
|
class="task-dashboard main-page__content"
|
||||||
|
:class="{ expanded: !isSidebarCollapsed }"
|
||||||
|
>
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<div class="position-relative d-flex justify-content-center"></div>
|
||||||
|
<section class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-6 mt-3">
|
||||||
|
<div class="my-card DonutChart">
|
||||||
|
<!-- <h2 class="title">Tasks by status</h2> -->
|
||||||
|
<pie-donut
|
||||||
|
:dataPie="dataPie"
|
||||||
|
:PieOptions="PieOptions"
|
||||||
|
width="90%"
|
||||||
|
height="300px"
|
||||||
|
ref="donutchart"
|
||||||
|
></pie-donut>
|
||||||
|
<div class="content"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3 mt-3">
|
||||||
|
<div class="my-card">
|
||||||
|
<h2 class="title">Completed tasks</h2>
|
||||||
|
<div class="content">
|
||||||
|
<span class="value">28</span
|
||||||
|
><span class="subtitle">tasks completed</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3 mt-3">
|
||||||
|
<div class="my-card">
|
||||||
|
<h2 class="title">Incomplete tasks</h2>
|
||||||
|
<div class="content">
|
||||||
|
<span class="value">14</span
|
||||||
|
><span class="subtitle">to be done</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-4">
|
||||||
|
<div class="my-card total-tasks">
|
||||||
|
<h2 class="title">Total tasks by assignee</h2>
|
||||||
|
<div class="content"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-8">
|
||||||
|
<div class="my-card Gantt">
|
||||||
|
<h2 class="title">Timeline</h2>
|
||||||
|
<div class="content">
|
||||||
|
<Gantt class="Gantt"></Gantt>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="my-card">
|
||||||
|
<h2 class="title">Cumulative flow</h2>
|
||||||
|
<div class="content"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// import commentMixin from "@mixins/commentMixin";
|
||||||
|
// import apis from "@apis/listApi";
|
||||||
|
import { mapGetters, mapMutations, mapActions } from "vuex";
|
||||||
|
// import { handleErrors } from "@utilities/utilities";
|
||||||
|
// import HttpService from "@services/httpService";
|
||||||
|
import menu from "@task/json/menu.json";
|
||||||
|
import taskApi from "@apis/taskApi";
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
export default {
|
||||||
|
beforeMount() {
|
||||||
|
// const headers = {
|
||||||
|
// "app-id": process.env.VUE_APP_APP_ID,
|
||||||
|
// // "lang": process.env.VUE_APP_LANG,
|
||||||
|
// // "app-version-code": process.env.VUE_APP_APP_VERSION,
|
||||||
|
// };
|
||||||
|
// this.httpService = new HttpService(this.repoMicroServiceName);
|
||||||
|
},
|
||||||
|
// mixins: [commentMixin],
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService( this.taskMicroServiceName
|
||||||
|
);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.TOGGLE_PANEL(false);
|
||||||
|
this.getvalueChartDonut();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
getPanelStatus(status) {
|
||||||
|
if (status) this.openForm();
|
||||||
|
else this.closeModal();
|
||||||
|
},
|
||||||
|
$route: {
|
||||||
|
handler: function () {
|
||||||
|
this.sidebarCollapsedSetter(true);
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
// listIdGetter(newId) {
|
||||||
|
// this.filterBy(this.selectedFilter);
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
PieOptions: {
|
||||||
|
radius: ["40%", "70%"],
|
||||||
|
selectedMode: "single",
|
||||||
|
},
|
||||||
|
// #region mehdi
|
||||||
|
nomber: 0,
|
||||||
|
statusPagHedear: 1,
|
||||||
|
dataPie: [],
|
||||||
|
// #endregion
|
||||||
|
rerenderChatList: 1,
|
||||||
|
showListPanel: false,
|
||||||
|
menu: menu,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters([
|
||||||
|
"getPanelStatus",
|
||||||
|
"isSidebarCollapsed",
|
||||||
|
"sidebarListStatusGetter",
|
||||||
|
]),
|
||||||
|
...mapGetters("list", [
|
||||||
|
"listComponentNameGetter",
|
||||||
|
"selectedProjectGetter",
|
||||||
|
"listIdGetter",
|
||||||
|
"selectedItemGetter",
|
||||||
|
"listGetter",
|
||||||
|
]),
|
||||||
|
taskMicroServiceName() {
|
||||||
|
return process.env.VUE_APP_TASK;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations([
|
||||||
|
"TOGGLE_PANEL",
|
||||||
|
"sidebarCollapsedSetter",
|
||||||
|
"SET_SIDEBAR_LIST_STATUS",
|
||||||
|
]),
|
||||||
|
...mapMutations("list", [
|
||||||
|
"SET_LIST_COMPONENT_NAME",
|
||||||
|
"SET_SELECTED_ITEM",
|
||||||
|
"SET_SELECTED_PROJECT",
|
||||||
|
"SET_LIST_ID",
|
||||||
|
"SET_LIST",
|
||||||
|
"SET_LIST_ID",
|
||||||
|
]),
|
||||||
|
...mapActions(["checkPermissions", "storeState", "getState"]),
|
||||||
|
selectedListBackTitle(name) {
|
||||||
|
if (name == "groups") return "دانشتو با بقیه به اشتراک بزار.";
|
||||||
|
if (name == "privates") return "به هر کی دوست داری، پیام بده.";
|
||||||
|
if (name == "lobbies") return "به تالار گفتگو خوش اومدی";
|
||||||
|
},
|
||||||
|
// showSearch() {
|
||||||
|
// search in current group, not all groups.
|
||||||
|
// this.$refs["chat-list-panel"].showSearchs(true);
|
||||||
|
// },
|
||||||
|
|
||||||
|
// #region mehdi
|
||||||
|
statusPage($event) {
|
||||||
|
const number = $event;
|
||||||
|
|
||||||
|
if (number == 1) {
|
||||||
|
if (this.$refs["chat-list-panel"].showMainpag == false) {
|
||||||
|
this.$refs["chat-list-panel"].showMainpag = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.$refs["chat-list-panel"].showMainpag == false) {
|
||||||
|
this.$refs["chat-list-panel"].showMainpag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
toggleSidebarMenu() {
|
||||||
|
this.TOGGLE_SIDEBAR_MENU();
|
||||||
|
},
|
||||||
|
showToggleListPanel() {
|
||||||
|
this.showListPanel = !this.showListPanel;
|
||||||
|
this.$refs["chat-list-panel"].showMainpag = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// #region mehdi
|
||||||
|
openPagGrup(data) {
|
||||||
|
this.enablePanelToggling = data;
|
||||||
|
if (this.enablePanelToggling == 1) {
|
||||||
|
this.showToggleListPanel();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #endregion
|
||||||
|
getvalueChartDonut() {
|
||||||
|
let payload = {
|
||||||
|
user_id: this.$store.getters.currentUser.user_id,
|
||||||
|
};
|
||||||
|
let url = taskApi.taskChart.donut;
|
||||||
|
var vm = this;
|
||||||
|
this.httpService.postRequest(url, payload).then((res) => {
|
||||||
|
vm.dataPie = [];
|
||||||
|
res.data.forEach((element) => {
|
||||||
|
vm.dataPie.push({
|
||||||
|
y: element.Percent,
|
||||||
|
name: element.category,
|
||||||
|
// color: colors[5],
|
||||||
|
drilldown: {
|
||||||
|
categories: [element.category],
|
||||||
|
data: [element.Total],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
MainSection: () => import("@task/components/MainSection"),
|
||||||
|
RightSection: () => import("@task/components/RightSection"),
|
||||||
|
Navbar: () => import("@task/components/Navbar"),
|
||||||
|
Gantt: () => import("@components/charts/Gantt.vue"),
|
||||||
|
PieDonut: () => import("@components/charts/PieDonut.vue"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.task-dashboard {
|
||||||
|
.row {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
.my-card {
|
||||||
|
// &.DonutChart{
|
||||||
|
// width: 54em;
|
||||||
|
// }
|
||||||
|
// &.Gantt{
|
||||||
|
// width: 72.5em;
|
||||||
|
// }
|
||||||
|
// &.total-tasks{
|
||||||
|
// width: unset;
|
||||||
|
// }
|
||||||
|
// &.ComparetasksChart{
|
||||||
|
// width: 100%;
|
||||||
|
// }
|
||||||
|
// width: 26em;
|
||||||
|
height: 18em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 1em;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 0.4688rem 2.1875rem rgba(4, 9, 20, 0.03),
|
||||||
|
0 0.9375rem 1.4063rem rgba(4, 9, 20, 0.03),
|
||||||
|
0 0.25rem 0.5313rem rgba(4, 9, 20, 0.03),
|
||||||
|
0 0.125rem 0.1875rem rgba(4, 9, 20, 0.03);
|
||||||
|
.title {
|
||||||
|
font-size: 1.2em;
|
||||||
|
text-align: left;
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
142
pages/TaskReport.vue
Normal file
142
pages/TaskReport.vue
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<the-sidebar2
|
||||||
|
:class="buildName"
|
||||||
|
:menu="menu"
|
||||||
|
:showUserAvatar="true"
|
||||||
|
></the-sidebar2>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<div class="col">
|
||||||
|
<div
|
||||||
|
class="main-page__content navbar row align-items-center p-0"
|
||||||
|
:class="{ expanded: !isSidebarCollapsed }"
|
||||||
|
>
|
||||||
|
<div class="col col-lg-auto order-1 breadcrumbs">
|
||||||
|
<Breadcrumbs />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-lg order-3 order-lg-2">
|
||||||
|
<div
|
||||||
|
class="nav-tabs-container nav-tabs d-flex justify-content-center"
|
||||||
|
>
|
||||||
|
<ul class="nav">
|
||||||
|
<li
|
||||||
|
class="nav-item desktop"
|
||||||
|
v-for="(navItem, index) in navList"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
:title="navItem.title"
|
||||||
|
type="button"
|
||||||
|
class="btn nav-link"
|
||||||
|
@click.prevent="setActiveTab(navItem)"
|
||||||
|
:class="{
|
||||||
|
active: activeTabGetter?.key == navItem.key,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ navItem.title }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto col-lg-auto order-2 order-lg-3 d-flex">
|
||||||
|
<user-avatar-dropdown
|
||||||
|
style="position: static"
|
||||||
|
class="user-avatar-component"
|
||||||
|
></user-avatar-dropdown>
|
||||||
|
<select-language-dropdown></select-language-dropdown>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="main-page__content"
|
||||||
|
:class="{ expanded: !isSidebarCollapsed }"
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
v-if="mainComponentName"
|
||||||
|
:is="mainComponentName"
|
||||||
|
></component>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
import menu from "@task/json/menu.json";
|
||||||
|
import { mapGetters, mapMutations } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService(this.taskMicroServiceName);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.setActiveTab(this.navList[0]);
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
httpService: undefined,
|
||||||
|
menu: menu,
|
||||||
|
mainComponentName: "TaskUserReport",
|
||||||
|
navList: [
|
||||||
|
{
|
||||||
|
title: "کاربران",
|
||||||
|
key: "users",
|
||||||
|
},
|
||||||
|
{ title: "گروه ها", key: "group" },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters("entity", ["activeTabGetter"]),
|
||||||
|
...mapGetters(["isSidebarCollapsed"]),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations("entity", ["activeTabSetter"]),
|
||||||
|
setActiveTab(tab) {
|
||||||
|
this.activeTabSetter(tab);
|
||||||
|
if (tab.key == "group") {
|
||||||
|
this.mainComponentName = "TaskGroupReport";
|
||||||
|
} else {
|
||||||
|
this.mainComponentName = "TaskUserReport";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
TaskUserReport: () => import("@task/components/TaskUserReport.vue"),
|
||||||
|
TaskGroupReport: () => import("@task/components/TaskGroupReport.vue"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
// .breadcrumbs {
|
||||||
|
// margin-right: 7.5em !important;
|
||||||
|
// }
|
||||||
|
// .expanded {
|
||||||
|
// margin-right: 3em;
|
||||||
|
// }
|
||||||
|
.nav-item {
|
||||||
|
.nav-tabs .nav-link:hover,
|
||||||
|
.nav-tabs .nav-link:focus {
|
||||||
|
color: var(--primary-color);
|
||||||
|
border-color: transparent;
|
||||||
|
transition: background-color 0.3s ease, color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
padding: 0.5rem 2.5rem !important;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navbar {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
.nav-tabs {
|
||||||
|
border-bottom: unset;
|
||||||
|
}
|
||||||
|
</style>
|
598
pages/TaskTeams.vue
Normal file
598
pages/TaskTeams.vue
Normal file
|
@ -0,0 +1,598 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class=" container-fluid">
|
||||||
|
<header>
|
||||||
|
<the-navbar></the-navbar>
|
||||||
|
</header>
|
||||||
|
<the-sidebar2 :menu="menu" :showUserAvatar="true"></the-sidebar2>
|
||||||
|
<main
|
||||||
|
class="pages-content-container main-page__content"
|
||||||
|
:class="{ expanded: !isSidebarCollapsed }"
|
||||||
|
>
|
||||||
|
<div class="pages-content mt-4 mt-lg-0 col-12">
|
||||||
|
<div class="" :class="{ 'd-flex': showPanel || showPanelTeams }">
|
||||||
|
<template v-if="canView">
|
||||||
|
<my-table
|
||||||
|
:tableActions="tableActions"
|
||||||
|
height="auto"
|
||||||
|
:hasSearch="true"
|
||||||
|
minHeight="25em"
|
||||||
|
maxHeight="calc(100dvh - 5em)"
|
||||||
|
:paginationInfo="pagination"
|
||||||
|
:sortingInfo="sorting"
|
||||||
|
:items="groupLists"
|
||||||
|
:fetchingData="fetchingData"
|
||||||
|
:tableColumns="tableColumns"
|
||||||
|
:totalPages="pagination.pages"
|
||||||
|
@search="searchGroups"
|
||||||
|
@reset-form="searchGroups"
|
||||||
|
@delete-table-item="deleteItem"
|
||||||
|
@edit-table-item="toggleUsersPanel"
|
||||||
|
@page-changed="pageChanged"
|
||||||
|
@page-limit-changed="pageLimitChanged"
|
||||||
|
@sort-changed="sortChanged"
|
||||||
|
@on-linked-title-click="onLinkedTitleClick"
|
||||||
|
>
|
||||||
|
<template v-slot:tableHeaderActions>
|
||||||
|
<div class="d-flex">
|
||||||
|
<!-- <div class="dropdown">
|
||||||
|
<button
|
||||||
|
class="btn dropdown-toggle"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
{{ groupsTranslation[searchType] }}
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu text-end">
|
||||||
|
<button
|
||||||
|
class="dropdown-item"
|
||||||
|
type="button"
|
||||||
|
@click.prevent="setSearchType('getGroupsWithoutAdmin')"
|
||||||
|
:class="{
|
||||||
|
active: searchType == 'getGroupsWithoutAdmin',
|
||||||
|
}"
|
||||||
|
value="getGroupsWithoutAdmin"
|
||||||
|
>
|
||||||
|
{{ groupsTranslation["getGroupsWithoutAdmin"] }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="dropdown-item"
|
||||||
|
type="button"
|
||||||
|
@click.prevent="setSearchType('getGroupsWithAdmin')"
|
||||||
|
:class="{ active: searchType == 'getGroupsWithAdmin' }"
|
||||||
|
value="getGroupsWithAdmin"
|
||||||
|
>
|
||||||
|
{{ groupsTranslation["getGroupsWithAdmin"] }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<button
|
||||||
|
v-if="createPanel"
|
||||||
|
@click.prevent="openCreatePanel()"
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
افزودن تیم
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</my-table>
|
||||||
|
</template>
|
||||||
|
<no-data v-else>
|
||||||
|
<the-content-loading v-if="fetchingData"></the-content-loading>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="d-flex justify-content-center align-items-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="alert alert-warning d-flex justify-content-center align-items-center"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="tavasi tavasi-warning-circle color-inherit ms-1 text__32"
|
||||||
|
></span>
|
||||||
|
عدم دسترسی
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</no-data>
|
||||||
|
<div class="side-panel" v-if="showPanel">
|
||||||
|
<div
|
||||||
|
class="side-panel-header d-flex mb-3 pb-3 border-bottom align-items-center"
|
||||||
|
>
|
||||||
|
<!-- <h5 class="m-0">اعضای تیم</h5> -->
|
||||||
|
<button
|
||||||
|
@click.prevent="addMember()"
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
افزودن عضو جدید
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click.prevent="toggleUsersPanel()"
|
||||||
|
class="btn me-auto"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<svg class="icon icon-Component-294--1">
|
||||||
|
<use xlink:href="#icon-Component-294--1"></use>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="side-panel-content">
|
||||||
|
<MembersSearch
|
||||||
|
v-if="showPanel"
|
||||||
|
:listMember="listMember"
|
||||||
|
:searchResults="users"
|
||||||
|
@on-send="searchUsers"
|
||||||
|
@delete-member="deleteMembers"
|
||||||
|
@edit-member="editMembers"
|
||||||
|
></MembersSearch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="side-panel" v-if="showPanelTeams">
|
||||||
|
<div
|
||||||
|
class="side-panel-header d-flex mb-3 pb-3 border-bottom align-items-center"
|
||||||
|
>
|
||||||
|
<h6 class="m-0">مدیریت تیم ها</h6>
|
||||||
|
|
||||||
|
<button
|
||||||
|
@click.prevent="closeShowPanelTeams()"
|
||||||
|
class="btn btn-outline-primary me-auto"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
x
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="side-panel-content">
|
||||||
|
<TeamForm
|
||||||
|
v-if="showPanelTeams"
|
||||||
|
@on-pass-by-emit="save"
|
||||||
|
@close-form="closeShowPanelTeams()"
|
||||||
|
:teamData="selectedItemClone"
|
||||||
|
></TeamForm>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<AddMemberToTeamModal
|
||||||
|
@update-member="updateMembers"
|
||||||
|
:item="[]"
|
||||||
|
v-if="showAddMember"
|
||||||
|
class="add-member"
|
||||||
|
></AddMemberToTeamModal>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters, mapActions } from "vuex";
|
||||||
|
import HttpService from "@services/httpService";
|
||||||
|
import menu from "@task/json/menu.json";
|
||||||
|
import permitApis from "@apis/permitApi";
|
||||||
|
import taskApi from "@apis/taskApi";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
beforeMount() {
|
||||||
|
this.httpService = new HttpService(this.taskMicroServiceName);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.checkPermisionBeforGetList();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
groupsId: "",
|
||||||
|
showAddMember: false,
|
||||||
|
listMember: [],
|
||||||
|
users: [],
|
||||||
|
createPanel: true,
|
||||||
|
searchType: "getGroupsWithoutAdmin",
|
||||||
|
groupLists: [],
|
||||||
|
menu: menu,
|
||||||
|
firstTimeSearching: false,
|
||||||
|
httpService: undefined,
|
||||||
|
tableActions: [
|
||||||
|
{
|
||||||
|
showOutside: true,
|
||||||
|
show: true,
|
||||||
|
icon: "Component-242--1",
|
||||||
|
title: "تعیین مدیر",
|
||||||
|
to: {
|
||||||
|
name: "undefined",
|
||||||
|
},
|
||||||
|
selected: false,
|
||||||
|
disabled: false,
|
||||||
|
howToOpen: "",
|
||||||
|
href: "",
|
||||||
|
class: "edit-btn",
|
||||||
|
action: "edit-table-item",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
showOutside: true,
|
||||||
|
show: true,
|
||||||
|
icon: "Component-295--1",
|
||||||
|
title: "حذف",
|
||||||
|
to: {
|
||||||
|
name: "undefined",
|
||||||
|
},
|
||||||
|
selected: false,
|
||||||
|
disabled: false,
|
||||||
|
howToOpen: "",
|
||||||
|
href: "",
|
||||||
|
class: "delete-btn",
|
||||||
|
action: "delete-table-item",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
canView: false,
|
||||||
|
fetchingData: false,
|
||||||
|
tableColumns: [
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "title",
|
||||||
|
title: "عنوان",
|
||||||
|
width: "4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLink: true,
|
||||||
|
key: "organ",
|
||||||
|
title: "سازمان",
|
||||||
|
width: "4",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pagination: {
|
||||||
|
page: 1,
|
||||||
|
pages: 0,
|
||||||
|
total: 0,
|
||||||
|
offset: 0,
|
||||||
|
limit: 10,
|
||||||
|
},
|
||||||
|
sorting: {
|
||||||
|
sortby: "title",
|
||||||
|
sortorder: "asc", // asc | desc | none
|
||||||
|
},
|
||||||
|
// users: [],
|
||||||
|
loading: false,
|
||||||
|
showPanel: false,
|
||||||
|
showPanelTeams: false,
|
||||||
|
selectedItemClone: undefined,
|
||||||
|
|
||||||
|
prevSelectedItemIndex: undefined,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(["isSidebarCollapsed"]),
|
||||||
|
|
||||||
|
...mapGetters("permit", ["projectGetter"]),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(["checkPermissions"]),
|
||||||
|
|
||||||
|
async getGroups() {
|
||||||
|
let url = taskApi.taskTeams.getList;
|
||||||
|
let payload = {
|
||||||
|
organ: "",
|
||||||
|
...this.sorting,
|
||||||
|
...this.pagination,
|
||||||
|
};
|
||||||
|
return await this.httpService.postRequest(url, payload).then((res) => {
|
||||||
|
this.groupLists = res.data;
|
||||||
|
// this.pagination.pages = res.pagination.pages;
|
||||||
|
this.pagination = { ...this.pagination, ...res.pagination };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
checkPermisionBeforGetList() {
|
||||||
|
if (this.fetchingData) return;
|
||||||
|
this.fetchingData = true;
|
||||||
|
|
||||||
|
this.checkPermissions({ _this: this, permission: "teams_list" })
|
||||||
|
.then(() => {
|
||||||
|
this.getGroups()
|
||||||
|
.then(() => {
|
||||||
|
this.canView = true;
|
||||||
|
this.fetchingData = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.canView = false;
|
||||||
|
this.fetchingData = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.canView = false;
|
||||||
|
this.fetchingData = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateUrl(url, query = "") {
|
||||||
|
url = url.replace("@offset", this.pagination.offset);
|
||||||
|
url = url.replace("@limit", this.pagination.limit);
|
||||||
|
url = url.replace("@sortby", this.sorting.sortby);
|
||||||
|
url = url.replace("@sortorder", this.sorting.sortorder);
|
||||||
|
|
||||||
|
// for searching groups.
|
||||||
|
if (query?.length) url = url.replace("@query", query);
|
||||||
|
else url = url.replace("/@query", query);
|
||||||
|
return url;
|
||||||
|
},
|
||||||
|
save(formData = undefined) {
|
||||||
|
if (this.loading) return;
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
const url = formData.id ? taskApi.taskTeams.edit : taskApi.taskTeams.add;
|
||||||
|
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, formData)
|
||||||
|
.then((res) => {
|
||||||
|
this.getGroups().then(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mySwalToast({
|
||||||
|
html: res.message,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.showPanel = false;
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
this.createPanel = true;
|
||||||
|
|
||||||
|
this.resetForm();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteItem(index) {
|
||||||
|
// if (this.loading) return;
|
||||||
|
this.loading = true;
|
||||||
|
let groupId = this.groupLists[index].id;
|
||||||
|
const payload = {
|
||||||
|
id: groupId,
|
||||||
|
};
|
||||||
|
let url = taskApi.taskTeams.delete;
|
||||||
|
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار",
|
||||||
|
html: "از حذف این مورد مطمئن هستید؟",
|
||||||
|
icon: "warning",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.httpService.postRequest(url, payload).then((res) => {
|
||||||
|
this.getGroups().then(() => {
|
||||||
|
this.loading = false;
|
||||||
|
// this.showPanel = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mySwalToast({
|
||||||
|
html: res.message,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
openCreatePanel() {
|
||||||
|
this.selectedItemClone = undefined;
|
||||||
|
|
||||||
|
if (this.showPanelTeams) {
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
} else {
|
||||||
|
this.showPanelTeams = true;
|
||||||
|
this.showPanel = false;
|
||||||
|
this.createPanel = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleUsersPanel(index = undefined) {
|
||||||
|
if (index !== undefined) {
|
||||||
|
if (this.prevSelectedItemIndex !== undefined)
|
||||||
|
this.groupLists[this.prevSelectedItemIndex].active = false;
|
||||||
|
|
||||||
|
this.prevSelectedItemIndex = index;
|
||||||
|
this.$set(this.groupLists[index], "active", true);
|
||||||
|
|
||||||
|
this.selectedItemClone = structuredClone(this.groupLists[index]);
|
||||||
|
|
||||||
|
this.showPanel = false;
|
||||||
|
this.showPanelTeams = true;
|
||||||
|
this.createPanel = false;
|
||||||
|
} else {
|
||||||
|
this.resetForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeShowPanelTeams() {
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
this.createPanel = true;
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
this.selectedItemClone = undefined;
|
||||||
|
this.showPanel = false;
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
},
|
||||||
|
// pagination and sorting
|
||||||
|
resetPagination() {
|
||||||
|
this.pagination = {
|
||||||
|
pages: 0,
|
||||||
|
total: 0,
|
||||||
|
page: 1,
|
||||||
|
offset: 0,
|
||||||
|
limit: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
pageLimitChanged(paging) {
|
||||||
|
this.resetPagination();
|
||||||
|
this.pagination.limit = paging.limit;
|
||||||
|
|
||||||
|
this.getGroups();
|
||||||
|
},
|
||||||
|
pageChanged(paging) {
|
||||||
|
let page = paging.pageNumber;
|
||||||
|
page -= 1;
|
||||||
|
this.pagination.offset = page * paging.limit;
|
||||||
|
this.pagination.limit = paging.limit;
|
||||||
|
this.pagination.page = paging.pageNumber;
|
||||||
|
|
||||||
|
this.getGroups();
|
||||||
|
},
|
||||||
|
sortChanged(sorting) {
|
||||||
|
this.pagination.page = this.pagination.offset = 0;
|
||||||
|
this.sorting = sorting;
|
||||||
|
|
||||||
|
this.getGroups();
|
||||||
|
},
|
||||||
|
searchGroups(query) {
|
||||||
|
this.resetPagination();
|
||||||
|
this[this.searchType](query);
|
||||||
|
},
|
||||||
|
async searchUsers(query = "") {
|
||||||
|
// this.resetPagination();
|
||||||
|
|
||||||
|
let url = this.loginMicroServiceName + permitApis.users.search;
|
||||||
|
url = url.replace("{{offset}}", 0);
|
||||||
|
url = url.replace("{{limit}}", 50);
|
||||||
|
url = url.replace("{{sortby}}", "username");
|
||||||
|
url = url.replace("{{sortorder}}", "desc");
|
||||||
|
|
||||||
|
// removing '/' before query if query is empty.
|
||||||
|
if (query) url = url.replace("{{query}}", query);
|
||||||
|
else url = url.replace("/{{query}}", query);
|
||||||
|
|
||||||
|
return await this.httpService.getRequest(url).then((res) => {
|
||||||
|
this.users = res.data;
|
||||||
|
// this.pagination = { ...this.pagination, ...res.pagination };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onLinkedTitleClick(index) {
|
||||||
|
this.showPanelTeams = false;
|
||||||
|
this.showPanel = true;
|
||||||
|
this.groupsId = index.index;
|
||||||
|
this.getMembers();
|
||||||
|
// if (this.showPanel) {
|
||||||
|
// this.showPanel = false;
|
||||||
|
// } else {
|
||||||
|
// this.showPanelTeams = false;
|
||||||
|
// this.showPanel = true;
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
getMembers() {
|
||||||
|
let payload = {
|
||||||
|
group_id: this.groupsId + 1,
|
||||||
|
offset: 0,
|
||||||
|
limit: 50,
|
||||||
|
sortby: "id",
|
||||||
|
sortorder: "asc",
|
||||||
|
};
|
||||||
|
const url = taskApi.taskTeams.members;
|
||||||
|
this.httpService.postRequest(url, payload).then((res) => {
|
||||||
|
this.listMember = res.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addMember() {
|
||||||
|
this.showAddMember = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
$("#share-modal").modal("show");
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
updateMembers(payload) {
|
||||||
|
const formData = {
|
||||||
|
...payload,
|
||||||
|
...{ group_id: this.groupsId + 1 },
|
||||||
|
};
|
||||||
|
const url = taskApi.taskTeams.addMembers;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, formData)
|
||||||
|
.then((response) => {
|
||||||
|
this.getMembers();
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: response.message,
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "خطا",
|
||||||
|
html: err.response.message ?? err.message,
|
||||||
|
icon: "error",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
$("#share-modal").modal("hide");
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showModal = true;
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteMembers(list) {
|
||||||
|
let payload = {
|
||||||
|
id: list.id,
|
||||||
|
};
|
||||||
|
const url = taskApi.taskTeams.deleteMembers;
|
||||||
|
this.httpService.postRequest(url, payload);
|
||||||
|
this.mySwalConfirm({
|
||||||
|
title: "هشدار!!!",
|
||||||
|
html: "از حذف این مورد مطمئن هستید؟",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.getMembers();
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: "مورد با موفقیت حذف شد",
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
editMembers(payload) {
|
||||||
|
// console.log(this.listMember.id)
|
||||||
|
const formData = {
|
||||||
|
...payload,
|
||||||
|
...{ project_id: this.projectId },
|
||||||
|
};
|
||||||
|
const url = taskApi.taskTeams.editMembers;
|
||||||
|
this.httpService
|
||||||
|
.postRequest(url, formData)
|
||||||
|
.then((response) => {
|
||||||
|
this.getMembers();
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "تبریک",
|
||||||
|
html: response.message,
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.mySwalToast({
|
||||||
|
title: "خطا",
|
||||||
|
html: err.response.message ?? err.message,
|
||||||
|
icon: "error",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
$("#share-modal").modal("hide");
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showModal = true;
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
MembersSearch: () => import("@task/components/MembersSearch"),
|
||||||
|
TeamForm: () => import("@task/components/TeamForm"),
|
||||||
|
AddMemberToTeamModal: () => import("@task/components/AddMemberToTeamModal"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.side-panel {
|
||||||
|
padding: 1em;
|
||||||
|
width: 30em;
|
||||||
|
max-width: 100%;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
}
|
||||||
|
// .pages-content-container {
|
||||||
|
// margin-right: 8em;
|
||||||
|
// margin-left: 2em;
|
||||||
|
// }
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user