Added functionality to User Manager

This commit is contained in:
Nicola Carminati
2019-03-18 17:18:16 +01:00
parent 3225276560
commit e96010e8e6
25 changed files with 2011 additions and 1878 deletions
+15 -8
View File
@@ -132,14 +132,21 @@ namespace Step.Controllers.WebApi
public IHttpActionResult UpdateUserData(int userId, [FromBody] DTONewUserModel userData)
{
using (UsersController usersController = new UsersController())
{
if (usersController.FindByUsername(userData.Username) != null)
return BadRequest();
// Update database with new user data
var user = usersController.UpdateUserData(userId, userData);
return Ok(user);
{
UserModel user = usersController.FindById(userId);
if (user == null)
return NotFound();
else
{
if (user.Username != userData.Username)
{
if (usersController.FindByUsername(userData.Username) != null)
return BadRequest();
}
return Ok(usersController.UpdateUserData(userId, userData));
}
}
}
@@ -83,6 +83,12 @@ button.btn, .button.btn {
&.dark-blue:active {
background-color: @color-darkish-blue-two !important;
}
&.pressed{
background-image: linear-gradient(to bottom, @color-silver, @color-white2);
border: none !important;
box-shadow: inset @button-shadow !important;
}
}
+2 -2
View File
@@ -42,7 +42,7 @@ sans-serif;
width: 100%;
}
input.invalid:not([readonly]), input[aria-invalid="true"]:not([readonly]) {
box-shadow: inset 0px 0px 0px 1px @color-scarlet;
box-shadow: inset 0px 0px 0px 1px @color-scarlet !important;
}
small.error {
text-align: left;
@@ -69,7 +69,7 @@ sans-serif;
}
input.invalid:not([readonly]), input[aria-invalid="true"]:not([readonly]) {
box-shadow: inset 0px 0px 0px 1px @color-scarlet;
box-shadow: inset 0px 0px 0px 1px @color-scarlet !important;
}
textarea{
+114 -18
View File
@@ -2704,32 +2704,128 @@
.rows{
display: flex;
flex-flow: row;
.avatarContainer{
width: 288px;
height: 288px;
max-height: 418px;
overflow-y: auto;
.sx{
display: flex;
.profile{
margin: auto;
background-color: #1177bb;
font-size: 128px;
justify-content: center;
flex-flow: column;
width: 288px;
.error{
color: #a10518;
font-size: 22px;
font-weight: bold;
text-align: center;
}
.avatarContainer{
width: 288px;
height: 288px;
display: flex;
box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.4);
align-items: center;
border-radius: 72px;
border: none;
height: 144px;
width: 144px;
cursor: pointer;
color: #000;
z-index: 1;
flex-flow: column;
.profile{
margin: auto;
background-color: #1177bb;
font-size: 128px;
justify-content: center;
display: flex;
box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.4);
align-items: center;
border-radius: 72px;
border: none;
height: 144px;
width: 144px;
cursor: pointer;
color: #000;
z-index: 1;
}
}
}
.divider{
width: 100%;
height: 20px;
}
.content-btn{
width: 440px;
box-shadow: 0 0px 3px 0 rgba(0, 0, 0, 0.4);
margin-top: 17px;
font-size: 18px;
height: 52px;
cursor: pointer;
display: flex;
align-items: center;
&:hover{
outline: 5px #1791ff auto;
}
[type="radio"]:checked,
[type="radio"]:not(:checked) {
visibility: hidden;
}
[type="radio"]:checked + label,
[type="radio"]:not(:checked) + label {
position: relative;
padding-left: 45px;
cursor: pointer;
line-height: 25px;
display: inline-block;
color: @color-cyan-blue;
}
[type="radio"]:checked + label:before,
[type="radio"]:not(:checked) + label:before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 24px;
height: 24px;
border: 1px solid #ddd;
border-radius: 100%;
background: #fff;
}
[type="radio"][disabled]:checked + label,
[type="radio"][disabled]:not(:checked) + label {
cursor: not-allowed;
}
[type="radio"]:checked + label:after,
[type="radio"]:not(:checked) + label:after {
content: "";
width: 18px;
height: 18px;
background-image: linear-gradient(to bottom, #1756ad, #002680);
position: absolute;
top: 4px;
left: 4px;
border-radius: 100%;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
}
[type="radio"][disabled]:checked + label:after,
[type="radio"][disabled]:not(:checked) + label:after {
background: @color-gunmetal;
}
[type="radio"]:checked + label {
font-weight: 600;
}
[type="radio"]:not(:checked) + label:after {
opacity: 0;
-webkit-transform: scale(0);
transform: scale(0);
}
[type="radio"]:checked + label:after {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
}
}
.typology {
display: flex;
+8 -15
View File
@@ -166,36 +166,29 @@
tr:nth-child(odd) {background: #FFF}
th:nth-child(1), td:nth-child(1){
width:50px;
max-width: 50px;
text-align: right;
padding-left: 5px;
}
th:nth-child(2), td:nth-child(2){
width:150px;
max-width:150px;
}
th:nth-child(2), td:nth-child(2){
width:250px;
max-width:250px;
text-align: left;
}
th:nth-child(3), td:nth-child(3){
width:250px;
max-width:250px;
text-align: left;
}
th:nth-child(4), td:nth-child(4){
th:nth-child(4),td:nth-child(4){
width:250px;
max-width:250px;
text-align: left;
}
th:nth-child(5),td:nth-child(5){
width:250px;
max-width:250px;
text-align: left;
}
th:nth-child(6), td:nth-child(6){
th:nth-child(5), td:nth-child(5){
width:150px;
max-width: 150px;
}
th:nth-child(7), td:nth-child(7){
th:nth-child(6), td:nth-child(6){
text-align: left;
}
th, td{
+103 -406
View File
@@ -2723,13 +2723,27 @@
.modal.create-user .rows {
display: flex;
flex-flow: row;
max-height: 418px;
overflow-y: auto;
}
.modal.create-user .rows .avatarContainer {
.modal.create-user .rows .sx {
display: flex;
flex-flow: column;
width: 288px;
}
.modal.create-user .rows .sx .error {
color: #a10518;
font-size: 22px;
font-weight: bold;
text-align: center;
}
.modal.create-user .rows .sx .avatarContainer {
width: 288px;
height: 288px;
display: flex;
flex-flow: column;
}
.modal.create-user .rows .avatarContainer .profile {
.modal.create-user .rows .sx .avatarContainer .profile {
margin: auto;
background-color: #1177bb;
font-size: 128px;
@@ -2749,6 +2763,78 @@
width: 100%;
height: 20px;
}
.modal.create-user .rows .content-btn {
width: 440px;
box-shadow: 0 0px 3px 0 rgba(0, 0, 0, 0.4);
margin-top: 17px;
font-size: 18px;
height: 52px;
cursor: pointer;
display: flex;
align-items: center;
}
.modal.create-user .rows .content-btn:hover {
outline: 5px #1791ff auto;
}
.modal.create-user .rows .content-btn [type="radio"]:checked,
.modal.create-user .rows .content-btn [type="radio"]:not(:checked) {
visibility: hidden;
}
.modal.create-user .rows .content-btn [type="radio"]:checked + label,
.modal.create-user .rows .content-btn [type="radio"]:not(:checked) + label {
position: relative;
padding-left: 45px;
cursor: pointer;
line-height: 25px;
display: inline-block;
color: #002e6e;
}
.modal.create-user .rows .content-btn [type="radio"]:checked + label:before,
.modal.create-user .rows .content-btn [type="radio"]:not(:checked) + label:before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 24px;
height: 24px;
border: 1px solid #ddd;
border-radius: 100%;
background: #fff;
}
.modal.create-user .rows .content-btn [type="radio"][disabled]:checked + label,
.modal.create-user .rows .content-btn [type="radio"][disabled]:not(:checked) + label {
cursor: not-allowed;
}
.modal.create-user .rows .content-btn [type="radio"]:checked + label:after,
.modal.create-user .rows .content-btn [type="radio"]:not(:checked) + label:after {
content: "";
width: 18px;
height: 18px;
background-image: linear-gradient(to bottom, #1756ad, #002680);
position: absolute;
top: 4px;
left: 4px;
border-radius: 100%;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
}
.modal.create-user .rows .content-btn [type="radio"][disabled]:checked + label:after,
.modal.create-user .rows .content-btn [type="radio"][disabled]:not(:checked) + label:after {
background: #4e585e;
}
.modal.create-user .rows .content-btn [type="radio"]:checked + label {
font-weight: 600;
}
.modal.create-user .rows .content-btn [type="radio"]:not(:checked) + label:after {
opacity: 0;
-webkit-transform: scale(0);
transform: scale(0);
}
.modal.create-user .rows .content-btn [type="radio"]:checked + label:after {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
.modal.create-user .typology {
display: flex;
flex-flow: column;
@@ -2996,7 +3082,7 @@
}
.form-group input.invalid:not([readonly]),
.form-group input[aria-invalid="true"]:not([readonly]) {
box-shadow: inset 0px 0px 0px 1px #d0021b;
box-shadow: inset 0px 0px 0px 1px #d0021b !important;
}
.form-group small.error {
text-align: left;
@@ -3019,7 +3105,7 @@
}
input.invalid:not([readonly]),
input[aria-invalid="true"]:not([readonly]) {
box-shadow: inset 0px 0px 0px 1px #d0021b;
box-shadow: inset 0px 0px 0px 1px #d0021b !important;
}
textarea {
font-family: 'Work Sans', sans-serif;
@@ -3102,6 +3188,12 @@ button.btn.dark-blue:active,
.button.btn.dark-blue:active {
background-color: #004990 !important;
}
button.btn.pressed,
.button.btn.pressed {
background-image: linear-gradient(to bottom, #bbbcbc, #f1f1f1);
border: none !important;
box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.4) !important;
}
button.btn.btn-success {
background-image: linear-gradient(to bottom, #1756ad, #002680);
color: white;
@@ -19295,15 +19387,14 @@ footer .container button.big:before {
}
.users-container .users-box .users-body .users-table th:nth-child(1),
.users-container .users-box .users-body .users-table td:nth-child(1) {
width: 50px;
max-width: 50px;
text-align: right;
padding-left: 5px;
width: 150px;
max-width: 150px;
}
.users-container .users-box .users-body .users-table th:nth-child(2),
.users-container .users-box .users-body .users-table td:nth-child(2) {
width: 150px;
max-width: 150px;
width: 250px;
max-width: 250px;
text-align: left;
}
.users-container .users-box .users-body .users-table th:nth-child(3),
.users-container .users-box .users-body .users-table td:nth-child(3) {
@@ -19319,17 +19410,11 @@ footer .container button.big:before {
}
.users-container .users-box .users-body .users-table th:nth-child(5),
.users-container .users-box .users-body .users-table td:nth-child(5) {
width: 250px;
max-width: 250px;
text-align: left;
}
.users-container .users-box .users-body .users-table th:nth-child(6),
.users-container .users-box .users-body .users-table td:nth-child(6) {
width: 150px;
max-width: 150px;
}
.users-container .users-box .users-body .users-table th:nth-child(7),
.users-container .users-box .users-body .users-table td:nth-child(7) {
.users-container .users-box .users-body .users-table th:nth-child(6),
.users-container .users-box .users-body .users-table td:nth-child(6) {
text-align: left;
}
.users-container .users-box .users-body .users-table th,
@@ -19420,394 +19505,6 @@ footer .container button.big:before {
width: 100%;
display: table;
}
.tooltip {
display: block !important;
z-index: 10000;
}
.tooltip .wrapper {
width: 100%;
height: 100%;
border: solid 2px #1791ff;
background-color: #fff;
border-radius: 2px;
}
.tooltip .wrapper .tooltip-arrow {
width: 0;
height: 0;
border-style: solid;
position: absolute;
margin: 5px;
border-color: #1791ff;
z-index: 1;
}
.tooltip .wrapper .tooltip-inner {
color: #878787;
padding: 5px 10px 4px;
}
.tooltip[x-placement^="top"] {
margin-bottom: 5px;
}
.tooltip[x-placement^="top"] .tooltip-arrow {
border-width: 18px 18px 0 18px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
bottom: -16px;
left: calc(45%);
margin-top: 0;
margin-bottom: 0;
}
.tooltip[x-placement^="top"] .tooltip-arrow::before {
border-color: #f1f1f1 !important;
border-width: 15px 14px 0 14px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
bottom: 3px;
left: -14px;
margin-top: 0;
margin-bottom: 0;
}
.tooltip[x-placement^="bottom"] {
margin-top: 5px;
}
.tooltip[x-placement^="bottom"] .tooltip-arrow {
border-width: 0 18px 18px 18px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-top-color: transparent !important;
top: -16px;
left: calc(45%);
margin-top: 0;
margin-bottom: 0;
}
.tooltip[x-placement^="bottom"] .tooltip-arrow::before {
border-width: 0 14px 15px 14px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-top-color: transparent !important;
top: 3px;
left: -14px;
margin-top: 0;
margin-bottom: 0;
}
.tooltip.popover .wrapper {
width: 100%;
height: 100%;
border: solid 2px #1791ff;
background-color: #fff;
border-radius: 2px;
}
.tooltip.popover .wrapper .popover-arrow {
border-color: #1791ff;
}
.tooltip.popover .wrapper .popover-arrow::before {
content: '';
width: 0;
height: 0;
border-style: solid;
position: absolute;
border-color: #fff;
z-index: 1;
}
.tooltip.popover .wrapper .popover-inner {
background: #fff;
color: #878787;
padding: 0;
}
.tooltip.popover .wrapper .popover-inner .header {
height: 63px;
display: flex;
align-items: center;
padding-left: 16px;
font-size: 20px;
font-size: 16px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: normal;
letter-spacing: normal;
text-align: left;
color: #002680;
}
.tooltip.popover .wrapper .popover-inner .header label {
width: 234px;
}
.tooltip.popover .wrapper .popover-inner .header button.close {
display: flex;
width: 28px;
height: 28px;
border-radius: 50%;
border: none;
background-color: #002680;
color: #fff;
font-size: 16px;
float: right;
cursor: pointer;
z-index: 1000;
}
.tooltip.popover .wrapper .popover-inner .header button.close .fa {
display: flex;
margin-left: auto;
margin-right: auto;
}
.tooltip.popover .wrapper .popover-inner .header button.close:active {
background-color: #1791ff;
color: #fff;
}
.tooltip.popover .wrapper .popover-inner .body {
color: #878787;
border-top: 2px solid #d8d8d8;
}
.tooltip.popover .wrapper .popover-inner .body .date {
display: flex;
flex-flow: row;
padding: 15px 0px;
color: #878787;
}
.tooltip.popover .wrapper .popover-inner .body .date .column {
display: flex;
flex-flow: column;
flex: 1 1 auto;
width: 50%;
align-items: center;
justify-content: center;
}
.tooltip.popover .wrapper .popover-inner .body .date .column span.title {
display: block;
font-size: 12px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: normal;
letter-spacing: normal;
text-align: center;
color: #878787;
}
.tooltip.popover .wrapper .popover-inner .body .date .column span.value {
display: block;
font-size: 14px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: 1.43;
letter-spacing: normal;
text-align: left;
color: #4b4b4b;
}
.tooltip.popover .wrapper .popover-inner .body .footer {
padding: 15px 0px;
display: flex;
flex-flow: row;
background-color: #f1f1f1;
color: #878787;
}
.tooltip.popover .wrapper .popover-inner .body .footer .column {
display: flex;
flex-flow: column;
flex: 1 1 auto;
width: 50%;
align-items: center;
justify-content: center;
}
.tooltip.popover .wrapper .popover-inner .body .footer .column span.title {
display: block;
font-size: 12px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: normal;
letter-spacing: normal;
text-align: center;
color: #878787;
}
.tooltip.popover .wrapper .popover-inner .body .footer .column span.value {
display: block;
font-size: 20px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: 0.9;
letter-spacing: normal;
text-align: center;
color: #4b4b4b;
}
.tooltip[aria-hidden='true'] {
visibility: hidden;
opacity: 0;
transition: opacity .15s, visibility .15s;
}
.tooltip[aria-hidden='false'] {
visibility: visible;
opacity: 1;
transition: opacity .15s;
}
/**START - TOOLTIP COLUMN CHART PRODUZIONE**/
.card-report-tooltip-top {
opacity: 1;
position: absolute;
width: 288px;
border: solid 2px #1791ff;
border-radius: 2px;
background-color: #fff;
z-index: 100;
}
.card-report-tooltip-top:before {
content: '';
display: block;
position: absolute;
left: 138px;
bottom: 100%;
width: 4px;
height: 0px;
border: 14px solid transparent;
border-bottom-color: #1791ff;
}
.card-report-tooltip-top:after {
content: '';
display: block;
position: absolute;
left: 141px;
bottom: 100%;
width: 0;
height: 0;
border: 13px solid transparent;
border-bottom-color: white;
}
.card-report-tooltip-bottom {
opacity: 1;
position: absolute;
width: 288px;
border: solid 2px #1791ff;
border-radius: 2px;
background-color: #fff;
z-index: 100;
}
.card-report-tooltip-bottom:before {
content: '';
display: block;
position: absolute;
left: 132px;
top: 100%;
width: 4px;
height: 0px;
border: 14px solid transparent;
border-top-color: #1791ff;
}
.card-report-tooltip-bottom:after {
content: '';
display: block;
position: absolute;
left: 135px;
top: 100%;
width: 0;
height: 0;
border: 13px solid transparent;
border-top-color: #f1f1f1;
}
.card-report-tooltip-bottom,
.card-report-tooltip-top {
pointer-events: all !important;
background: #fff;
color: #878787;
padding: 0;
}
.card-report-tooltip-bottom.hidden,
.card-report-tooltip-top.hidden {
visibility: hidden;
}
.card-report-tooltip-bottom .header,
.card-report-tooltip-top .header {
height: 63px;
display: flex;
align-items: center;
padding-left: 16px;
font-size: 20px;
font-size: 16px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: normal;
letter-spacing: normal;
text-align: left;
color: #002680;
}
.card-report-tooltip-bottom .header label,
.card-report-tooltip-top .header label {
width: 234px;
}
.card-report-tooltip-bottom .header button.close,
.card-report-tooltip-top .header button.close {
display: flex;
width: 28px;
height: 28px;
border-radius: 50%;
border: none;
background-color: #002680;
color: #fff;
font-size: 16px;
float: right;
cursor: pointer;
z-index: 1000;
}
.card-report-tooltip-bottom .header button.close .fa,
.card-report-tooltip-top .header button.close .fa {
display: flex;
margin-left: auto;
margin-right: auto;
}
.card-report-tooltip-bottom .header button.close:active,
.card-report-tooltip-top .header button.close:active {
background-color: #1791ff;
color: #fff;
}
.card-report-tooltip-bottom .body,
.card-report-tooltip-top .body {
color: #878787;
border-top: 2px solid #d8d8d8;
}
.card-report-tooltip-bottom .body .footer,
.card-report-tooltip-top .body .footer {
padding: 15px 0px;
display: flex;
flex-flow: row;
background-color: #f1f1f1;
color: #878787;
}
.card-report-tooltip-bottom .body .footer .column,
.card-report-tooltip-top .body .footer .column {
display: flex;
flex-flow: column;
flex: 1 1 auto;
width: 50%;
align-items: center;
justify-content: center;
}
.card-report-tooltip-bottom .body .footer .column span.title,
.card-report-tooltip-top .body .footer .column span.title {
display: block;
font-size: 12px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: normal;
letter-spacing: normal;
text-align: center;
color: #878787;
}
.card-report-tooltip-bottom .body .footer .column span.value,
.card-report-tooltip-top .body .footer .column span.value {
display: block;
font-size: 20px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: 0.9;
letter-spacing: normal;
text-align: center;
color: #4b4b4b;
}
/**END - TOOLTIP COLUMN CHART PRODUZIONE**/
a,
a:visited,
a:hover,
+1400 -1400
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,6 +1,6 @@
import Factory from "./factoryService";
import { MessageService } from "./messageService";
import { UUID } from "./utils";
import { UUID,Utilities } from "./utils";
export function awaiter(promise) {
@@ -16,4 +16,4 @@ export function awaiter(promise) {
}
export { Factory, MessageService, UUID };
export { Factory, MessageService, UUID, Utilities };
+2 -1
View File
@@ -1,4 +1,4 @@
export default class Utilities {
export class Utilities {
static debounce(func: any, wait: any, immediate: boolean = false) {
var timeout;
return function () {
@@ -10,6 +10,7 @@ export default class Utilities {
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
+5 -1
View File
@@ -30,6 +30,8 @@ import ModalJobAddParameter from "./modules/base-components/modal-job-add-parame
import ModalEditJob from "./modules/base-components/modal-edit-job.vue";
import ModalAddOffsetTool from "./modules/base-components/modal-add-offset-tool.vue";
import ModalCreateUser from "./modules/base-components/modal-create-user.vue";
import ModalPasswordUser from "./modules/base-components/modal-password-user.vue";
import ModalRoleUser from "./modules/base-components/modal-role-user.vue";
import ModalMissingTools from "./modules/base-components/modal-missing-tools.vue";
import ProgramManagement from "./modules/program-management.vue";
import ZoomImage from './modules/base-components/zoom-image.vue';
@@ -63,7 +65,9 @@ export {
SoftKeysPrefered,
CreateQueue,
ZoomImage,
ModalCreateUser
ModalCreateUser,
ModalPasswordUser,
ModalRoleUser
}
@@ -299,7 +299,6 @@ export default class toolingEquipment extends Vue {
public addTool() {
let newTool = {};
console.log("entro")
if(!this.isSiemens){
this.selectedTool = Object.assign({}, newTool)
@@ -5,7 +5,7 @@ import { getColorFromName,isDarkColor } from "src/_base/utils";
import { usersService } from "src/services";
import { awaiter } from "src/_base";
import { ModalHelper } from "src/components/modals";
import { ModalCreateUser } from "src/modules/base-components";
import { ModalCreateUser, ModalPasswordUser, ModalRoleUser } from "src/modules/base-components";
import { Watch } from "vue-property-decorator";
import { store } from "src/store";
@@ -20,12 +20,11 @@ export default class Users extends Vue {
public selectedUser: any = null;
public users: any = [];
public currentFilter: string = "";
public isLoading: boolean = false;
get Users() {
get Users() {
if(this.selectedUser)
this.selectUser((this.$store.state as AppModel).users.users.find(X=>X.id == this.selectedUser.id))
return (this.$store.state as AppModel).users.users;
}
@@ -45,6 +44,11 @@ export default class Users extends Vue {
else
return this.selectedUser.id == u.id;
}
//if is logged update info
isUserLogged(id){
return (store.state as AppModel).currentUser.id == id;
}
selectUser(u){
this.selectedUser = u;
@@ -60,11 +64,23 @@ export default class Users extends Vue {
ModalHelper.ShowModal(ModalCreateUser);
}
editPswSelectedUser(){
ModalHelper.userModal.currentUser = Object.assign({}, this.selectedUser);
ModalHelper.ShowModal(ModalPasswordUser);
}
editRoleSelectedUser(){
ModalHelper.userModal.currentUser = Object.assign({}, this.selectedUser);
ModalHelper.ShowModal(ModalRoleUser);
}
deleteSelectedUser(){
ModalHelper.AskConfirm(this.$options.filters.localize("modal_confirm_title", "Richiesta di conferma"),
this.$options.filters.localize("modal_confirm_delete_user", "Confermi la cancellazione dell'utente?"),
() => {
awaiter (usersService.deleteUser(this.selectedUser));
}, null);
}
@@ -76,6 +92,14 @@ export default class Users extends Vue {
}
async mounted() {
this.isLoading = true;
await awaiter (usersService.getUsers());
this.isLoading = false;
}
async reloadUsers() {
await awaiter (usersService.getUsers());
}
}
@@ -12,11 +12,17 @@
<div>
<label>{{'users_header_label_procedure' | localize("Ricerca utente per username")}}</label>
<input class="custom users-input-procedure" v-model="searchText" type="text" @focus="extendSelectState = false" :placeholder="'users_header_label_procedure_placeholder' | localize('Username dell\'utente ...')">
</div>
<div>
<label>&nbsp;</label>
<button class="btn" @click="reloadUsers()"><i class="fa fa-refresh"></i></button>
</div>
<div class="group-button">
<button class="btn" :disabled="!canEdit" @click="editRoleSelectedUser"><i class="fa fa-industry"></i></button>
<button class="btn" :disabled="!canEdit" @click="editPswSelectedUser"><i class="fa fa-key"></i></button>
<button class="btn" :disabled="!canEdit" @click="editSelectedUser"><i class="fa fa-pencil-square-o"></i></button>
<button class="btn" :disabled="!canEdit" @click="deleteSelectedUser"><i class="fa fa-trash"></i></button>
<button class="btn" :disabled="!canEdit || isUserLogged(this.selectedUser.id)" @click="deleteSelectedUser"><i class="fa fa-trash"></i></button>
</div>
</div>
@@ -25,7 +31,6 @@
<table>
<thead>
<tr>
<th>{{'users_table_header_id' | localize("Id")}}</th>
<th>{{'users_table_header_avatar' | localize("Avatar")}}</th>
<th>{{'users_table_header_username' | localize("Username")}}</th>
<th>{{'users_table_header_firstname' | localize("Nome")}}</th>
@@ -36,7 +41,6 @@
</thead>
<tbody class="scrollable">
<tr v-for="m in Users.filter(t => t.username && t.username.toLowerCase().indexOf(this.currentFilter) >=0)" :key="m.id" :class="{selected: isUserSelected(m)}" @click="selectUser(m)" >
<td colspan="1"><div>{{m.id}}</div></td>
<td colspan="1">
<div class="profile"
:class="{'colorWhite':isDarkColor(getColor(m.lastName,m.firstName))}"
@@ -12,6 +12,8 @@ import MaintenanceProgress from "./maintenance-progress.vue";
import CreateMaintenance from "../create-maintenance.vue";
import ModalCreateUser from "./modal-create-user.vue";
import ModalPasswordUser from "./modal-password-user.vue";
import ModalRoleUser from "./modal-role-user.vue";
import ModalIframe from "./modal-iframe.vue";
import ModalImage from "./modal-image.vue";
import ModalAddOffsetTool from "./modal-add-offset-tool.vue";
@@ -35,6 +37,8 @@ export {
CreateMaintenance,
ModalCreateUser,
ModalPasswordUser,
ModalRoleUser,
ModalIframe,
ModalImage,
ModalAddOffsetTool,
@@ -4,6 +4,8 @@ import Component from "vue-class-component";
import { ModalHelper, Modal } from "src/components/modals";
import { getColorFromName,isDarkColor } from "src/_base/utils";
import { usersService } from "src/services";
import { Watch } from "vue-property-decorator";
import { AppModel } from "src/store";
@Component({
components: { modal: Modal },
@@ -11,18 +13,47 @@ import { usersService } from "src/services";
export default class modalCreateUser extends Vue {
newUser: any = {id:0,username:"",lastName:"",firstName:"",password:""};
mountedUsername: string;
usernameAllowed: Boolean = true;
timeout: any;
fakePassword: string = "XXXXXXXXX";
get Users() {
return (this.$store.state as AppModel).users.users;
}
beforeMount() {
if(!this.isNewUser())
this.newUser = ModalHelper.userModal.currentUser;
this.mountedUsername = this.newUser.username;
Factory.Get(MessageService).subscribeToChannel("esc_pressed", args => {
this.close();
});
}
@Watch("newUser.username")
userChange(){
//Debounce
if(this.timeout)
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
if(this.mountedUsername.toLowerCase() == this.newUser.username.toLowerCase()){
this.usernameAllowed = true;
}
else{
if(this.Users.find(X=>X.username.toLowerCase() == this.newUser.username.toLowerCase())==null)
this.usernameAllowed = true;
else
this.usernameAllowed = false;
}
}, 300);
}
getColor(nome,cognome){
return getColorFromName(nome,cognome);
}
@@ -1,21 +1,23 @@
<template>
<modal type="create-user" :title="'create_user_lbl_title_window' | localize('Creazione utente')">
<modal type="create-user" :title="'create_user_lbl_title_window' | localize('User Editor')">
<button class="close" slot="header-buttons" @click="close()"><i class="fa fa-remove"></i></button>
<div class="rows">
<div class="avatarContainer">
<div class="profile"
:class="{'colorWhite':isDarkColor(getColor(newUser.lastName,newUser.firstName))}"
:style="{'background-color':getColor(newUser.lastName,newUser.firstName) }"
>
<i class="fa fa-user"></i>
</div>
</div>
<div class="sx">
<div class="avatarContainer">
<div class="profile"
:class="{'colorWhite':isDarkColor(getColor(newUser.lastName,newUser.firstName))}"
:style="{'background-color':getColor(newUser.lastName,newUser.firstName) }"
>
<i class="fa fa-user"></i>
</div>
</div>
<div v-if="!usernameAllowed" class="error">{{'create_user_username_not_allowed' | localize("Username not allowed")}}</div>
</div>
<div>
<div class="title">
<label class="title_lbl">{{'create_user_lbl_username' | localize("Username")}}</label>
<input type="text" v-validate.initial="{required: true}" v-model="newUser.username">
<input type="text" v-validate.initial="{required: true}" v-model="newUser.username" :class="{invalid:!usernameAllowed}">
</div>
<div class="title" v-if="isNewUser()">
<label class="title_lbl">{{'create_user_lbl_password' | localize("Password")}}</label>
@@ -39,8 +41,8 @@
<footer>
<div class="pull-right">
<button class="btn" @click="close()">{{'create_user_btn_cancel' | localize("Annulla")}}</button>
<button class="btn btn-success" v-if="isNewUser()" :disabled="!isValid" @click="newUser.id > 0 ? modify(newUser) : create(newUser)">{{'create_user_btn_add_confirm' | localize("Conferma")}}</button>
<button class="btn btn-success" v-if="!isNewUser()" :disabled="!isValid" @click="newUser.id > 0 ? modify(newUser) : create(newUser)">{{'create_user_btn_edit_confirm' | localize("Modifica")}}</button>
<button class="btn btn-success" v-if="isNewUser()" :disabled="!isValid || !usernameAllowed" @click="create(newUser)">{{'create_user_btn_add_confirm' | localize("Conferma")}}</button>
<button class="btn btn-success" v-if="!isNewUser()" :disabled="!isValid || !usernameAllowed" @click="modify(newUser)">{{'create_user_btn_edit_confirm' | localize("Modifica")}}</button>
</div>
</footer>
</modal>
@@ -0,0 +1,76 @@
import Vue from "vue";
import { Factory, MessageService,awaiter } from 'src/_base';
import Component from "vue-class-component";
import { ModalHelper, Modal } from "src/components/modals";
import { getColorFromName,isDarkColor } from "src/_base/utils";
import { usersService } from "src/services";
import { Watch } from "vue-property-decorator";
import { AppModel } from "src/store";
@Component({
components: { modal: Modal },
})
export default class modalPasswordUser extends Vue {
newUser: any = {id:0,username:"",lastName:"",firstName:"",password:"",newPassword:""};
pswOk: boolean= false;
pswVisible:string="password";
get Users() {
return (this.$store.state as AppModel).users.users;
}
beforeMount() {
this.newUser = ModalHelper.userModal.currentUser;
Factory.Get(MessageService).subscribeToChannel("esc_pressed", args => {
this.close();
});
}
@Watch("newUser.password")
@Watch("newUser.newPassword")
userChange(){
this.pswOk = this.newUser.password == this.newUser.newPassword;
}
getColor(nome,cognome){
return getColorFromName(nome,cognome);
}
isDarkColor(color){
return isDarkColor(color);
}
beforeDestroy() {
Factory.Get(MessageService).deleteChannel("esc_pressed");
}
close() {
Factory.Get(MessageService).deleteChannel("esc_pressed");
ModalHelper.HideModal();
}
togglePswVisible() {
if(this.pswVisible=="text")
this.pswVisible="password";
else
this.pswVisible="text";
}
get isPswVisible() {
return this.pswVisible=="text";
}
async modify(user) {
alert("ToDo");
this.close();
//awaiter(usersService.editUser(user).then(response => {
// this.close();
//}));
}
}
@@ -0,0 +1,48 @@
<template>
<modal type="create-user" :title="'password_user_lbl_title_window' | localize('Password Editor: %s',newUser.username)">
<button class="close" slot="header-buttons" @click="close()"><i class="fa fa-remove"></i></button>
<div class="rows">
<div class="sx">
<div class="avatarContainer">
<div class="profile"
:class="{'colorWhite':isDarkColor(getColor(newUser.lastName,newUser.firstName))}"
:style="{'background-color':getColor(newUser.lastName,newUser.firstName) }"
>
<i class="fa fa-user"></i>
</div>
</div>
<div v-if="!pswOk" class="error">{{'create_user_psw_not_equals' | localize("Passwords must be the same")}}</div>
</div>
<div>
<div class="title">
<label class="title_lbl">{{'create_user_lbl_firstname' | localize("First Name")}}</label>
<input type="text" v-model="newUser.firstName" disabled="disabled">
</div>
<div class="title">
<label class="title_lbl">{{'create_user_lbl_lastname' | localize("Last Name")}}</label>
<input type="text" v-model="newUser.lastName" disabled="disabled">
</div>
<div class="divider">&nbsp;</div>
<div class="title">
<label class="title_lbl">{{'password_user_lbl_password' | localize("Password attuale")}}</label>
<input :type="pswVisible" v-validate.initial="{required: true}" v-model="newUser.password">
</div>
<div class="title" >
<label class="title_lbl">{{'password_user_lbl_password' | localize("Password nuova")}}</label>
<input :type="pswVisible" v-validate.initial="{required: true}" v-model="newUser.newPassword">
</div>
</div>
</div>
<footer>
<div class="pull-left">
<button class="btn" :class="{pressed:isPswVisible}" @click="togglePswVisible()"><i class="fa fa-eye"></i></button>
</div>
<div class="pull-right">
<button class="btn" @click="close()">{{'create_user_btn_cancel' | localize("Annulla")}}</button>
<button class="btn btn-success" :disabled="!isValid || !pswOk" @click="modify(newUser)">{{'create_user_btn_add_confirm' | localize("Conferma")}}</button>
</div>
</footer>
</modal>
</template>
<script src="./modal-password-user.ts" lang="ts"></script>
@@ -0,0 +1,68 @@
import Vue from "vue";
import { Factory, MessageService,awaiter } from 'src/_base';
import Component from "vue-class-component";
import { ModalHelper, Modal } from "src/components/modals";
import { getColorFromName,isDarkColor } from "src/_base/utils";
import { usersService } from "src/services";
import { Watch } from "vue-property-decorator";
import { AppModel } from "src/store";
@Component({
components: { modal: Modal },
})
export default class modalRoleUser extends Vue {
newUser: any = {id:0,username:"",lastName:"",firstName:"",password:"",newPassword:""};
roles: any = [];
selectedRole: number = -1;
beforeMount() {
this.newUser = ModalHelper.userModal.currentUser;
this.selectedRole = this.newUser.role.id;
Factory.Get(MessageService).subscribeToChannel("esc_pressed", args => {
this.close();
});
}
async mounted(){
this.roles = await awaiter (usersService.getRoles());
}
ischecked(id){
return id==this.selectedRole;
}
select(id){
this.selectedRole = id;
}
get selectOk(){
return this.selectedRole>0;
}
getColor(nome,cognome){
return getColorFromName(nome,cognome);
}
isDarkColor(color){
return isDarkColor(color);
}
beforeDestroy() {
Factory.Get(MessageService).deleteChannel("esc_pressed");
}
close() {
Factory.Get(MessageService).deleteChannel("esc_pressed");
ModalHelper.HideModal();
}
async modify(user) {
awaiter(usersService.editRole(user,this.selectedRole).then(response => {
this.close();
}));
}
}
@@ -0,0 +1,31 @@
<template>
<modal type="create-user" :title="'role_user_lbl_title_window' | localize('Role Editor: %s',newUser.username)">
<button class="close" slot="header-buttons" @click="close()"><i class="fa fa-remove"></i></button>
<div class="rows scrollable">
<div class="sx">
<div class="avatarContainer">
<div class="profile"
:class="{'colorWhite':isDarkColor(getColor(newUser.lastName,newUser.firstName))}"
:style="{'background-color':getColor(newUser.lastName,newUser.firstName) }"
>
<i class="fa fa-user"></i>
</div>
</div>
</div>
<div>
<div class="content-btn" v-for="(t) in roles" :key="'role_'+t.id" @click="select(t.id)">
<input type="radio" name="radio-group" :checked="ischecked(t.id)" >
<label for="datefixed">{{t.name}}</label>
</div>
</div>
</div>
<footer>
<div class="pull-right">
<button class="btn" @click="close()">{{'create_user_btn_cancel' | localize("Annulla")}}</button>
<button class="btn btn-success" :disabled="!selectOk" @click="modify(newUser)">{{'create_user_btn_add_confirm' | localize("Conferma")}}</button>
</div>
</footer>
</modal>
</template>
<script src="./modal-role-user.ts" lang="ts"></script>
+1 -1
View File
@@ -37,7 +37,7 @@ export class DataService extends baseRestService {
public async setActiveScreenOnHMI(screen) {
let result = await this.put("/api/nc/active_screen/"+ screen,null, true);
if(typeof cmsClient != "undefined"){}
if(typeof cmsClient != "undefined")
cmsClient.forceNcFocus();
return result;
}
+5
View File
@@ -400,6 +400,11 @@ export class Hub {
public ncSoftKeyClick(id: number) {
this._hub.server.ncSoftKeyClick(id);
if(typeof cmsClient != "undefined"){
if(cmsClient.getNcWindowState() == 1)
cmsClient.forceNcFocus();
}
}
public headOverrideMinus(id: number) {
@@ -32,7 +32,6 @@ export class LoginService extends baseRestService {
async getAllUsers(): Promise<any> {
let result = await this.Get<any>("api/user/list",true);
console.log(result);
return result;
}
+30
View File
@@ -2,6 +2,7 @@ import { baseRestService } from "src/_base/baseRestService";
import { usersActions } from "../store/users.store";
import Factory from "src/_base/factoryService";
import { store, AppModel } from "../store";
import { LoginService } from "src/app.modules";
export class UsersService extends baseRestService {
@@ -11,6 +12,11 @@ export class UsersService extends baseRestService {
return result;
}
async getRoles(): Promise<any> {
let result = await this.Get<any>("api/user/manager/role/list",true);
return result;
}
async createUser(model: any){
var result = await this.Post<any>("api/user/manager/user/", model,true);
usersActions.updateUser(store, result);
@@ -20,8 +26,32 @@ export class UsersService extends baseRestService {
async editUser(model: any){
var result = await this.Put<any>("api/user/manager/user/" + model.id , model,true);
usersActions.updateUser(store, result);
//if is logged update info
if((store.state as AppModel).currentUser.id == model.id){
await Factory.Get(LoginService).getUserInfo();
}
return result;
}
async deleteUser(model: any){
var result = await this.Delete<any>("api/user/manager/user/" + model.id ,true);
usersActions.deleteUser(store, model.id);
return result;
}
async editRole(model: any,roleId:number){
var result = await this.Put<any>("api/user/manager/user/" + model.id +"/role/" + roleId , null,true);
usersActions.updateUser(store, result);
//if is logged update info
if((store.state as AppModel).currentUser.id == model.id){
await Factory.Get(LoginService).getUserInfo();
}
return result;
}
}
Factory.Register(UsersService);
+8
View File
@@ -5,6 +5,7 @@ export interface UsersStoreModel {
export interface UsersActions {
updateUsers(context, model:server.userModel[]);
updateUser(context, model:server.userModel);
deleteUser(context, id:number);
}
export const usersStore = {
@@ -30,6 +31,10 @@ export interface UsersStoreModel {
updateUser(store, model:server.userModel) {
store._users.set(model.id, model);
store.users = Array.from(store._users.values());
},
deleteUser(store, id:number) {
store._users.delete(id)
store.users = Array.from(store._users.values());
}
},
actions: {
@@ -38,6 +43,9 @@ export interface UsersStoreModel {
},
updateUser(context, model:server.userModel) {
context.commit("updateUser", model);
},
deleteUser(context, id:number) {
context.commit("deleteUser", id);
}
}as UsersActions
}