Make Groups a separate view

This commit is contained in:
Girish Ramakrishnan
2025-09-16 12:53:43 +02:00
parent 405302e2f0
commit 496ada3647
14 changed files with 203 additions and 95 deletions
-80
View File
@@ -9,7 +9,6 @@ import { Button, Menu, TextInput, SingleSelect, TableView, InputDialog } from '@
import { ROLES } from '../constants.js';
import Section from '../components/Section.vue';
import UserDialog from '../components/UserDialog.vue';
import GroupDialog from '../components/GroupDialog.vue';
import ImpersonateDialog from '../components/ImpersonateDialog.vue';
import InvitationDialog from '../components/InvitationDialog.vue';
import PasswordResetDialog from '../components/PasswordResetDialog.vue';
@@ -76,35 +75,6 @@ function onUserActionMenu(user, event) {
actionMenuElement.value.open(event, event.currentTarget);
}
const groupsColumns = {
name: {
label: t('users.groups.name'),
sort: true
},
users: {
label: t('users.groups.users'),
sort: true,
hideMobile: true,
},
actions: {}
};
function onGroupActionMenu(group, event) {
actionMenuModel.value = [{
icon: 'fa-solid fa-pencil-alt',
label: t('main.action.edit'),
action: onEditOrAddGroup.bind(null, group),
}, {
separator: true,
}, {
icon: 'fa-solid fa-trash-alt',
label: t('main.action.remove'),
action: onRemoveGroup.bind(null, group),
}];
actionMenuElement.value.open(event, event.currentTarget);
}
const profile = ref({});
const busy = ref(true);
const filterOptions = ref([
@@ -125,7 +95,6 @@ const subscriptionRequiredDialog = inject('subscriptionRequiredDialog');
const inputDialog = useTemplateRef('inputDialog');
const userDialog = useTemplateRef('userDialog');
const groupDialog = useTemplateRef('groupDialog');
const impersonateDialog = useTemplateRef('impersonateDialog');
const passwordResetDialog = useTemplateRef('passwordResetDialog');
@@ -190,10 +159,6 @@ function isMe(user) {
return user.username === profile.value.username;
}
function groupMembers(group) {
return group.userIds.filter(function (uid) { return !!usersById.value[uid]; }).map(function (uid) { return usersById.value[uid].username || usersById.value[uid].email; }).join(' ');
}
function onImpersonate(user) {
impersonateDialog.value.open(user);
}
@@ -212,28 +177,6 @@ function onInvitation(user) {
invitationDialog.value.open(user);
}
function onEditOrAddGroup(group = null) {
if (group || features.value.userGroups) groupDialog.value.open(group);
else subscriptionRequiredDialog.value.open();
}
async function onRemoveGroup(group) {
const yes = await inputDialog.value.confirm({
title: t('users.deleteGroupDialog.title', { name: group.name }),
message: t('users.deleteGroupDialog.description', { memberCount: group.userIds.length }),
confirmStyle: 'danger',
confirmLabel: t('users.deleteGroupDialog.deleteAction'),
rejectLabel: t('main.dialog.cancel')
});
if (!yes) return;
const [error] = await groupsModel.remove(group.id);
if (error) console.error(error);
await refreshGroups();
}
async function onRemoveUser(user) {
const yes = await inputDialog.value.confirm({
title: t('users.deleteUserDialog.title', { username: (user.username || user.email) }),
@@ -279,7 +222,6 @@ onMounted(async () => {
<Menu ref="actionMenuElement" :model="actionMenuModel" />
<InputDialog ref="inputDialog" />
<UserDialog ref="userDialog" @success="refreshUsers()"/>
<GroupDialog ref="groupDialog" @success="refreshGroups()"/>
<ImpersonateDialog ref="impersonateDialog" />
<PasswordResetDialog ref="passwordResetDialog" />
<InvitationDialog ref="invitationDialog" @refresh-required="refreshUsers()" />
@@ -320,28 +262,6 @@ onMounted(async () => {
</template>
</TableView>
</Section>
<Section :title="$t('users.groups.title')" :title-badge="!features.userGroups ? 'Upgrade' : ''">
<template #header-buttons>
<Button icon="fa-solid fa-plus" @click="onEditOrAddGroup()">{{ $t('users.groups.newGroupAction') }}</Button>
</template>
<TableView :columns="groupsColumns" :model="groups" :busy="busy" style="max-height: 400px;" :placeholder="$t('users.groups.emptyPlaceholder')">
<template #name="group">
{{ group.name }} &nbsp; <i v-if="group.source" class="far fa-address-book" v-tooltip="$t('users.groups.externalLdapTooltip')"></i>
</template>
<template #users="group">
{{ groupMembers(group) }}
</template>
<template #actions="group">
<div style="text-align: right;">
<Button tool plain secondary @click.capture="onGroupActionMenu(group, $event)" icon="fa-solid fa-ellipsis" />
</div>
</template>
</TableView>
<br/>
<div>{{ $t('users.groups.count', { count: groups.length }) }}</div>
</Section>
</div>
</template>