Add component for editing users

This commit is contained in:
D. Berge
2025-07-24 20:35:46 +02:00
parent f8e5b74c1a
commit ce901a03a1

View File

@@ -0,0 +1,256 @@
<template>
<v-card>
<v-card-title>
User {{ name }} <v-chip class="mx-3" small>{{id}}</v-chip>
<v-chip v-if="self.id == value.id"
small
color="primary"
>It's me!</v-chip>
</v-card-title>
<v-card-subtitle>User settings</v-card-subtitle>
<v-card-text>
<v-form>
<!--
<v-text-field
label="User ID"
hint="Unique user ID (read-only)"
persistent-hint
readonly
disabled
v-model="id"
>
</v-text-field>
-->
<v-switch
dense
label="Active"
:title="(self.id == value.id) ? 'You cannot make yourself inactive' : active ? 'Make this user inactive' : 'Make this user active'"
:disabled="self.id == value.id"
v-model="active"
></v-switch>
<label class="mr-3 pt-5">Colour
<v-menu v-model="colourMenu"
:close-on-content-click="false"
offset-y
>
<template v-slot:activator="{ on, attrs }">
<v-btn
:title="colour"
dense
small
icon
v-on="on"
><v-icon :color="colour">mdi-palette</v-icon>
</v-btn>
</template>
<v-color-picker
dot-size="25"
mode="hexa"
swatches-max-height="200"
v-model="colour"
></v-color-picker>
</v-menu>
</label>
<v-text-field
v-if="showIp || ip"
label="IP address"
hint="IP address or subnet specification for auto-login"
v-model="ip"
>
</v-text-field>
<v-text-field
v-if="showHost || host"
label="Host name"
hint="Hostname (for auto-login)"
v-model="host"
>
</v-text-field>
<v-text-field
label="Name"
hint="User name"
v-model="name"
>
</v-text-field>
<v-text-field
v-if="showPasswordField"
:type="visiblePassword ? 'text' : 'password'"
:append-icon="visiblePassword ? 'mdi-eye' : 'mdi-eye-off'"
@click:append="visiblePassword = !visiblePassword"
label="Password"
hint="User password"
v-model="password"
>
</v-text-field>
<v-text-field
label="Email"
hint="Email address"
v-model="email"
>
</v-text-field>
<v-textarea
class="mb-5"
label="Remarks"
hint="User description (visible to the user)"
auto-grow
v-model="description"
></v-textarea>
<dougal-organisations
:self="self"
:organisations.sync="organisations"
></dougal-organisations>
</v-form>
</v-card-text>
<v-card-actions>
<slot name="actions" v-bind="{ isValid, hasErrors, errors, dirty }"></slot>
</v-card-actions>
</v-card>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
import { User } from '@/lib/user';
import DougalOrganisations from './organisations'
export default {
name: "DougalUserSettings",
components: {
DougalOrganisations
},
props: {
value: Object,
self: Object, // User calling the dialogue
// The next three props determine whether the
// ip, host, and password fields are shown even
// when null / empty. If non-null, those fields
// are always shown
showIp: { type: Boolean, default: false },
showHost: { type: Boolean, default: false },
showPassword: { type: Boolean, default: false },
},
data () {
return {
colourMenu: null,
visiblePassword: false
}
},
computed: {
id () { return this.value.id },
ip: {
get () { return this.value.ip },
set (v) { this.input("ip", v) }
},
host: {
get () { return this.value.host },
set (v) { this.input("host", v) }
},
name: {
get () { return this.value.name },
set (v) { this.input("name", v) }
},
password: {
get () { return this.value.password },
set (v) { this.input("password", v) }
},
active: {
get () { return this.value.active },
set (v) { this.input("active", v) }
},
email: {
get () { return this.value.email },
set (v) { this.input("email", v) }
},
colour: {
get () { return this.value.colour },
set (v) { this.input("colour", v) }
},
description: {
get () { return this.value.description },
set (v) { this.input("description", v) }
},
organisations: {
get () { return this.value.organisations },
set (v) { this.input("organisations", v) }
},
errors () {
return this.value.errors;
},
hasErrors () {
return !this.isValid;
},
isValid () {
return this.value.isValid;
},
dirty () {
return this.value?.dirty ?? false;
},
showPasswordField () {
return this.password || (this.showPassword &&
!(this.showIp || this.ip || this.showHost || this.host));
},
...mapGetters(['user', 'loading', 'serverEvent'])
},
watch: {
validationErrors () {
this.$emit("update:errors", this.validationErrors);
}
},
methods: {
input (k, v) {
const user = new User(this.value);
user[k] = v;
this.$emit("input", user);
},
reset () {
},
save () {
},
back () {
this.$emit('close');
}
},
mounted () {
this.reset();
}
}
</script>