add posibility user can change own password close #16
This commit is contained in:
85
src/vueLib/login/ChangePassword.vue
Normal file
85
src/vueLib/login/ChangePassword.vue
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<DialogFrame
|
||||||
|
ref="dialog"
|
||||||
|
:header-title="$t('changePassword') + ' ' + $t('user') + ' ' + localUser.user"
|
||||||
|
:height="510"
|
||||||
|
:width="500"
|
||||||
|
:inner-padding="48"
|
||||||
|
>
|
||||||
|
<q-form ref="form">
|
||||||
|
<div class="row justify-center q-gutter-md">
|
||||||
|
<q-input
|
||||||
|
class="col-6 required"
|
||||||
|
filled
|
||||||
|
autocomplete="current-password"
|
||||||
|
:type="showPassword ? 'text' : 'password'"
|
||||||
|
:label="$t('currentPassword')"
|
||||||
|
v-model="localUser.password"
|
||||||
|
:rules="[(val) => !!val || $t('currentPassword') + ' ' + $t('isRequired')]"
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
:icon="showPassword ? 'visibility_off' : 'visibility'"
|
||||||
|
@mousedown.prevent="showPassword = true"
|
||||||
|
@mouseup.prevent="showPassword = false"
|
||||||
|
@mouseleave.prevent="showPassword = false"
|
||||||
|
@touchstart.prevent="showPassword = true"
|
||||||
|
@touchend.prevent="showPassword = false"
|
||||||
|
@touchcancel.prevent="showPassword = false"
|
||||||
|
></q-btn>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
<div class="col-6">
|
||||||
|
<EnterNewPassword v-model:password="localUser.newPassword!" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-form>
|
||||||
|
<div class="row justify-center">
|
||||||
|
<q-btn class="q-ma-md" color="primary" no-caps @click="save">{{ $t('save') }}</q-btn>
|
||||||
|
</div>
|
||||||
|
</DialogFrame>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import DialogFrame from '../dialog/DialogFrame.vue';
|
||||||
|
import type { User } from 'src/vueLib/models/users';
|
||||||
|
import { i18n } from 'src/boot/lang';
|
||||||
|
import { useNotify } from '../general/useNotify';
|
||||||
|
import { validateQForm } from '../utils/validation';
|
||||||
|
import EnterNewPassword from './EnterNewPassword.vue';
|
||||||
|
|
||||||
|
const { NotifyResponse } = useNotify();
|
||||||
|
const dialog = ref();
|
||||||
|
const showPassword = ref(false);
|
||||||
|
const form = ref();
|
||||||
|
const localUser = ref<User>({
|
||||||
|
user: '',
|
||||||
|
email: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const open = (user: User) => {
|
||||||
|
localUser.value = user;
|
||||||
|
localUser.value.password = '';
|
||||||
|
localUser.value.newPassword = '';
|
||||||
|
dialog.value?.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
dialog.value?.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:password']);
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
if (!(await validateQForm(form.value))) {
|
||||||
|
NotifyResponse(i18n.global.t('notAllRequiredFieldsFilled'), 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit('update:password', localUser.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open, close });
|
||||||
|
</script>
|
||||||
129
src/vueLib/login/EnterNewPassword.vue
Normal file
129
src/vueLib/login/EnterNewPassword.vue
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-input
|
||||||
|
class="col-5 required"
|
||||||
|
:label="$t('password')"
|
||||||
|
autocomplete="new-password"
|
||||||
|
filled
|
||||||
|
:lazy-rules="false"
|
||||||
|
:rules="[validatePassword]"
|
||||||
|
v-model="password"
|
||||||
|
@update:model-value="checkStrength"
|
||||||
|
:type="showPassword1 ? 'text' : 'password'"
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
:icon="showPassword1 ? 'visibility_off' : 'visibility'"
|
||||||
|
@mousedown.prevent="showPassword1 = true"
|
||||||
|
@mouseup.prevent="showPassword1 = false"
|
||||||
|
@mouseleave.prevent="showPassword1 = false"
|
||||||
|
@touchstart.prevent="showPassword1 = true"
|
||||||
|
@touchend.prevent="showPassword1 = false"
|
||||||
|
@touchcancel.prevent="showPassword1 = false"
|
||||||
|
></q-btn>
|
||||||
|
<q-icon :name="strengthIcon" :color="strengthColor"></q-icon>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
|
||||||
|
<div class="q-mt-md q-px-xl">
|
||||||
|
<q-linear-progress :value="strengthValue" :color="strengthColor" size="8px" rounded />
|
||||||
|
<div class="text-caption text-center q-mt-xs">
|
||||||
|
{{ strengthLabel }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-input
|
||||||
|
ref="pwdForm2"
|
||||||
|
class="col-5 required"
|
||||||
|
:label="$t('password')"
|
||||||
|
autocomplete="new-password"
|
||||||
|
filled
|
||||||
|
:type="showPassword2 ? 'text' : 'password'"
|
||||||
|
:rules="[checkSamePassword]"
|
||||||
|
v-model="passwordCheck"
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
:icon="showPassword2 ? 'visibility_off' : 'visibility'"
|
||||||
|
@mousedown.prevent="showPassword2 = true"
|
||||||
|
@mouseup.prevent="showPassword2 = false"
|
||||||
|
@mouseleave.prevent="showPassword2 = false"
|
||||||
|
@touchstart.prevent="showPassword2 = true"
|
||||||
|
@touchend.prevent="showPassword2 = false"
|
||||||
|
@touchcancel.prevent="showPassword2 = false"
|
||||||
|
></q-btn>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import zxcvbn from 'zxcvbn';
|
||||||
|
import { i18n } from 'src/boot/lang';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
password: { type: String },
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:password']);
|
||||||
|
|
||||||
|
const pwdForm2 = ref();
|
||||||
|
const showPassword1 = ref(false);
|
||||||
|
const showPassword2 = ref(false);
|
||||||
|
const passwordCheck = ref('');
|
||||||
|
const strengthValue = ref(0);
|
||||||
|
const strengthLabel = ref('Enter a password');
|
||||||
|
const strengthColor = ref('grey');
|
||||||
|
const strengthIcon = ref('lock');
|
||||||
|
|
||||||
|
function checkStrength() {
|
||||||
|
const result = zxcvbn(password.value || '');
|
||||||
|
strengthValue.value = (result.score + 1) / 5;
|
||||||
|
const levels = [
|
||||||
|
i18n.global.t('veryWeak'),
|
||||||
|
i18n.global.t('weak'),
|
||||||
|
i18n.global.t('fair'),
|
||||||
|
i18n.global.t('good'),
|
||||||
|
i18n.global.t('strong'),
|
||||||
|
];
|
||||||
|
const colors = ['red', 'orange', 'yellow', 'light-green', 'green'];
|
||||||
|
const icon = ['lock', 'warning', 'error_outline', 'check_circle_outline', 'verified_user'];
|
||||||
|
|
||||||
|
strengthLabel.value = levels[result.score] || i18n.global.t('veryWeak');
|
||||||
|
strengthColor.value = colors[result.score] || 'grey';
|
||||||
|
strengthIcon.value = icon[result.score] || 'lock';
|
||||||
|
}
|
||||||
|
|
||||||
|
function validatePassword(): string | boolean {
|
||||||
|
pwdForm2.value?.validate();
|
||||||
|
|
||||||
|
if (!password.value) return i18n.global.t('passwordIsRequired');
|
||||||
|
|
||||||
|
if (password.value.length < 8) {
|
||||||
|
return i18n.global.t('passwordTooShort');
|
||||||
|
} else if (!/[A-Z]/.test(password.value)) {
|
||||||
|
return i18n.global.t('passwordNeedsUppercase');
|
||||||
|
} else if (!/[a-z]/.test(password.value)) {
|
||||||
|
return i18n.global.t('passwordNeedsLowercase');
|
||||||
|
} else if (!/[0-9]/.test(password.value)) {
|
||||||
|
return i18n.global.t('passwordNeedsNumber');
|
||||||
|
} else if (!/[!@#$%^&*(),.?":{}|<>]/.test(password.value)) {
|
||||||
|
return i18n.global.t('passwordNeedsSpecial');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkSamePassword(): string | boolean {
|
||||||
|
if (password.value === passwordCheck.value) return true;
|
||||||
|
return i18n.global.t('passwordDoNotMatch');
|
||||||
|
}
|
||||||
|
|
||||||
|
const password = computed({
|
||||||
|
get: () => props.password,
|
||||||
|
set: (v) => emit('update:password', v),
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
|
import type { Role } from './roles';
|
||||||
import type { Settings } from './settings';
|
import type { Settings } from './settings';
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
id?: number;
|
id?: number;
|
||||||
user: string;
|
user: string;
|
||||||
email: string;
|
email: string;
|
||||||
role: string;
|
role?: Role;
|
||||||
expiration?: string;
|
expiration?: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
|
newPassword?: string;
|
||||||
settings?: Settings;
|
settings?: Settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ export function useUserTable() {
|
|||||||
field: 'email',
|
field: 'email',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'newPassword',
|
||||||
|
align: 'left' as const,
|
||||||
|
label: '',
|
||||||
|
field: 'newPassword',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'role',
|
name: 'role',
|
||||||
align: 'left' as const,
|
align: 'left' as const,
|
||||||
|
|||||||
@@ -1,133 +1,148 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="q-pa-md">
|
<q-table
|
||||||
<q-table
|
flat
|
||||||
flat
|
bordered
|
||||||
bordered
|
ref="tableRef"
|
||||||
ref="tableRef"
|
title="Users"
|
||||||
title="Users"
|
title-class="text-bold text-blue-9"
|
||||||
title-class="text-bold text-blue-9"
|
:no-data-label="$t('noDataAvailable')"
|
||||||
:no-data-label="$t('noDataAvailable')"
|
:loading-label="$t('loading')"
|
||||||
:loading-label="$t('loading')"
|
:rows-per-page-label="$t('recordsPerPage')"
|
||||||
:rows-per-page-label="$t('recordsPerPage')"
|
:selected-rows-label="(val) => val + ' ' + $t('recordSelected')"
|
||||||
:selected-rows-label="(val) => val + ' ' + $t('recordSelected')"
|
:rows="users"
|
||||||
:rows="users"
|
:columns="columns"
|
||||||
:columns="columns"
|
row-key="id"
|
||||||
row-key="id"
|
v-model:pagination="pagination"
|
||||||
v-model:pagination="pagination"
|
:loading="loading"
|
||||||
:loading="loading"
|
:filter="filter"
|
||||||
:filter="filter"
|
:selection="selectOption ? 'multiple' : 'none'"
|
||||||
:selection="selectOption ? 'multiple' : 'none'"
|
v-model:selected="selected"
|
||||||
v-model:selected="selected"
|
binary-state-sort
|
||||||
binary-state-sort
|
dense
|
||||||
class="bigger-table-text"
|
class="bigger-table-text"
|
||||||
>
|
>
|
||||||
<template v-slot:top-left>
|
<template v-slot:top-left>
|
||||||
<q-btn-group push flat style="color: grey">
|
<q-btn-group push flat style="color: grey">
|
||||||
<q-btn
|
<q-btn
|
||||||
v-if="user.isPermittedTo('userSettings', 'write')"
|
v-if="user.isPermittedTo('userSettings', 'write')"
|
||||||
dense
|
dense
|
||||||
flat
|
flat
|
||||||
icon="add"
|
icon="add"
|
||||||
@click="openAllValueDialog(null)"
|
@click="openAllValueDialog(null)"
|
||||||
>
|
|
||||||
<q-tooltip>{{ $t('addNewUser') }}</q-tooltip>
|
|
||||||
</q-btn>
|
|
||||||
<q-btn
|
|
||||||
v-if="user.isPermittedTo('userSettings', 'write')"
|
|
||||||
dense
|
|
||||||
flat
|
|
||||||
style="color: grey"
|
|
||||||
:icon="selectOption ? 'check_box' : 'check_box_outline_blank'"
|
|
||||||
@click="selectOption = !selectOption"
|
|
||||||
>
|
|
||||||
<q-tooltip>{{ $t('selectUserOptions') }}</q-tooltip>
|
|
||||||
</q-btn>
|
|
||||||
</q-btn-group>
|
|
||||||
<div v-if="selectOption && selected.length > 0">
|
|
||||||
<q-btn flat dense icon="more_vert" @click="openSubmenu = true" />
|
|
||||||
<q-menu v-if="openSubmenu" anchor="bottom middle" self="top middle">
|
|
||||||
<q-item
|
|
||||||
clickable
|
|
||||||
v-close-popup
|
|
||||||
@click="openRemoveDialog(...selected)"
|
|
||||||
class="text-negative"
|
|
||||||
>{{ $t('delete') }}</q-item
|
|
||||||
>
|
|
||||||
</q-menu>
|
|
||||||
</div>
|
|
||||||
<div v-if="selectOption && selected.length > 0" class="q-ml-md text-weight-bold">
|
|
||||||
{{ $t('selected') }}: {{ selected.length }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-slot:top-right>
|
|
||||||
<q-input filled dense debounce="300" v-model="filter" :placeholder="$t('search')">
|
|
||||||
<template v-slot:append>
|
|
||||||
<q-icon name="search" />
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
</template>
|
|
||||||
<template v-slot:body-cell="props">
|
|
||||||
<q-td
|
|
||||||
:props="props"
|
|
||||||
:style="
|
|
||||||
autorized(props.row) && user.isPermittedTo('userSettings', 'write')
|
|
||||||
? 'cursor: pointer'
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
@click="
|
|
||||||
autorized(props.row) && user.isPermittedTo('userSettings', 'write')
|
|
||||||
? openSingleValueDialog(props.col.label, props.col.name, props.row)
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{{ props.value }}
|
<q-tooltip>{{ $t('addNewUser') }}</q-tooltip>
|
||||||
</q-td>
|
</q-btn>
|
||||||
</template>
|
<q-btn
|
||||||
<template v-slot:body-cell-role="props">
|
v-if="user.isPermittedTo('userSettings', 'write')"
|
||||||
<q-td :props="props">
|
dense
|
||||||
<q-select
|
flat
|
||||||
:readonly="!user.isPermittedTo('userSettings', 'write') || !autorized(props.row)"
|
style="color: grey"
|
||||||
dense
|
:icon="selectOption ? 'check_box' : 'check_box_outline_blank'"
|
||||||
v-model="props.row.role"
|
@click="selectOption = !selectOption"
|
||||||
:options="localRoles"
|
|
||||||
@update:model-value="updateUser(props.row)"
|
|
||||||
></q-select>
|
|
||||||
</q-td>
|
|
||||||
</template>
|
|
||||||
<template v-slot:body-cell-expiration="props">
|
|
||||||
<q-td
|
|
||||||
:props="props"
|
|
||||||
:style="
|
|
||||||
autorized(props.row) && user.isPermittedTo('userSettings', 'write')
|
|
||||||
? 'cursor: pointer'
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
@click="
|
|
||||||
autorized(props.row) && user.isPermittedTo('userSettings', 'write')
|
|
||||||
? openSingleValueDialog(props.col.label, props.col.name, props.row)
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{{ props.value === 'never' ? $t('never') : props.value }}
|
<q-tooltip>{{ $t('selectUserOptions') }}</q-tooltip>
|
||||||
</q-td>
|
</q-btn>
|
||||||
</template>
|
</q-btn-group>
|
||||||
<template v-slot:body-cell-option="props">
|
<div v-if="selectOption && selected.length > 0">
|
||||||
<q-td :props="props">
|
<q-btn flat dense icon="more_vert" @click="openSubmenu = true" />
|
||||||
<q-btn
|
<q-menu v-if="openSubmenu" anchor="bottom middle" self="top middle">
|
||||||
v-if="user.isPermittedTo('userSettings', 'delete')"
|
<q-item
|
||||||
:disable="!autorized(props.row)"
|
clickable
|
||||||
flat
|
v-close-popup
|
||||||
dense
|
@click="openRemoveDialog(...selected)"
|
||||||
icon="delete"
|
class="text-negative"
|
||||||
color="negative"
|
>{{ $t('delete') }}</q-item
|
||||||
@click="openRemoveDialog(props.row)"
|
|
||||||
>
|
>
|
||||||
<q-tooltip> {{ $t('delete') }} </q-tooltip>
|
</q-menu>
|
||||||
</q-btn>
|
</div>
|
||||||
</q-td>
|
<div v-if="selectOption && selected.length > 0" class="q-ml-md text-weight-bold">
|
||||||
</template>
|
{{ $t('selected') }}: {{ selected.length }}
|
||||||
</q-table>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
|
||||||
|
<!-- top right of table-->
|
||||||
|
|
||||||
|
<template v-slot:top-right>
|
||||||
|
<SearchableInput v-model="filter" :placeholder="$t('search')" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- table body content-->
|
||||||
|
|
||||||
|
<template v-slot:body-cell="props">
|
||||||
|
<q-td
|
||||||
|
:props="props"
|
||||||
|
:style="
|
||||||
|
autorized(props.row) && user.isPermittedTo('userSettings', 'write')
|
||||||
|
? 'cursor: pointer'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
@click="
|
||||||
|
autorized(props.row) && user.isPermittedTo('userSettings', 'write')
|
||||||
|
? openSingleValueDialog(props.col.label, props.col.name, props.row)
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ props.value }}
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
<template v-slot:body-cell-newPassword="props">
|
||||||
|
<q-td :props="props">
|
||||||
|
<q-btn
|
||||||
|
v-if="autorized(props.row) && currentUser.id === props.row.id"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
no-caps
|
||||||
|
color="primary"
|
||||||
|
:label="$t('changePassword')"
|
||||||
|
@click="openPwdDialog(props.row)"
|
||||||
|
></q-btn>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
<template v-slot:body-cell-role="props">
|
||||||
|
<q-td :props="props">
|
||||||
|
<q-select
|
||||||
|
:readonly="!user.isPermittedTo('userSettings', 'write') || !autorized(props.row)"
|
||||||
|
dense
|
||||||
|
v-model="props.row.role"
|
||||||
|
:options="localRoles"
|
||||||
|
option-label="role"
|
||||||
|
@update:model-value="updateUser(props.row)"
|
||||||
|
></q-select>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
<template v-slot:body-cell-expiration="props">
|
||||||
|
<q-td
|
||||||
|
:props="props"
|
||||||
|
:style="
|
||||||
|
autorized(props.row) && user.isPermittedTo('userSettings', 'write')
|
||||||
|
? 'cursor: pointer'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
@click="
|
||||||
|
autorized(props.row) && user.isPermittedTo('userSettings', 'write')
|
||||||
|
? openSingleValueDialog(props.col.label, props.col.name, props.row)
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ props.value === 'never' ? $t('never') : props.value }}
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
<template v-slot:body-cell-option="props">
|
||||||
|
<q-td :props="props">
|
||||||
|
<q-btn
|
||||||
|
v-if="user.isPermittedTo('userSettings', 'delete')"
|
||||||
|
:disable="!autorized(props.row)"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
icon="delete"
|
||||||
|
color="negative"
|
||||||
|
@click="openRemoveDialog(props.row)"
|
||||||
|
>
|
||||||
|
<q-tooltip> {{ $t('delete') }} </q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
<EditOneDialog
|
<EditOneDialog
|
||||||
ref="editOneDialog"
|
ref="editOneDialog"
|
||||||
query-id
|
query-id
|
||||||
@@ -145,6 +160,7 @@
|
|||||||
button-ok-color="red"
|
button-ok-color="red"
|
||||||
v-on:update-confirm="(val) => removeUser(...val)"
|
v-on:update-confirm="(val) => removeUser(...val)"
|
||||||
></OkDialog>
|
></OkDialog>
|
||||||
|
<ChangePassword ref="changePwdDialog" v-on:update:password="changePassword" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -159,6 +175,8 @@ import { useUserTable } from './UserTable';
|
|||||||
import { roles, useRoleTable } from '../roles/RoleTable';
|
import { roles, useRoleTable } from '../roles/RoleTable';
|
||||||
import { i18n } from 'src/boot/lang';
|
import { i18n } from 'src/boot/lang';
|
||||||
import { useUserStore } from 'src/vueLib/login/userStore';
|
import { useUserStore } from 'src/vueLib/login/userStore';
|
||||||
|
import ChangePassword from 'src/vueLib/login/ChangePassword.vue';
|
||||||
|
import SearchableInput from '../components/SearchableInput.vue';
|
||||||
|
|
||||||
const { NotifyResponse } = useNotify();
|
const { NotifyResponse } = useNotify();
|
||||||
const editOneDialog = ref();
|
const editOneDialog = ref();
|
||||||
@@ -176,6 +194,7 @@ const currentUser = ref();
|
|||||||
const { users, pagination, loading, columns, updateUsers } = useUserTable();
|
const { users, pagination, loading, columns, updateUsers } = useUserTable();
|
||||||
const { updateRoles } = useRoleTable();
|
const { updateRoles } = useRoleTable();
|
||||||
const user = useUserStore();
|
const user = useUserStore();
|
||||||
|
const changePwdDialog = ref();
|
||||||
|
|
||||||
//load on mounting page
|
//load on mounting page
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -201,6 +220,26 @@ function openAllValueDialog(user: User | null) {
|
|||||||
editAllDialog.value?.open(user);
|
editAllDialog.value?.open(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//opens password change dialog
|
||||||
|
function openPwdDialog(user: User) {
|
||||||
|
changePwdDialog.value.open(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
//change password api request
|
||||||
|
async function changePassword(user: User) {
|
||||||
|
console.log(8, user);
|
||||||
|
if (user.password == user.newPassword) {
|
||||||
|
NotifyResponse(i18n.global.t('samePasswordEntered'), 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await appApi
|
||||||
|
.post('/users/new/password', user)
|
||||||
|
.then((resp) => console.log(67, resp))
|
||||||
|
.catch((err) => console.error(err));
|
||||||
|
changePwdDialog.value.close();
|
||||||
|
}
|
||||||
|
|
||||||
//opens remove dialog
|
//opens remove dialog
|
||||||
function openRemoveDialog(...users: Users) {
|
function openRemoveDialog(...users: Users) {
|
||||||
if (users.length === 1) {
|
if (users.length === 1) {
|
||||||
@@ -245,20 +284,6 @@ function updateUser(user: User) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@keyframes blink-yellow {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
background-color: yellow;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.blink-yellow {
|
|
||||||
animation: blink-yellow 1.5s step-start 6 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bigger-table-text .q-table__middle td {
|
.bigger-table-text .q-table__middle td {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user