Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added select and chips to beautify users/groups #3853

Merged
merged 1 commit into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 44 additions & 26 deletions opal-ui/src/components/admin/AddUserDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,17 @@
>
</q-input>
</template>

<!-- TODO: create a comp with q-input and q-chip -->
<q-input
v-model="userGroups"
dense
type="text"
:label="$t('groups')"
<q-select
v-model="newUser.groups"
use-input
use-chips
multiple
input-debounce="0"
:hint="$t('groups_hint')"
class="q-mb-md"
lazy-rules
>
</q-input>
@new-value="addGroup"
:options="groupFilters"
@filter="filterGroups"
></q-select>
</q-form>
</q-card-section>

Expand All @@ -99,6 +98,7 @@ interface DialogProps {

const { t } = useI18n();
const usersStore = useUsersStore();
const groupsStore = useGroupsStore();
const formRef = ref();
const props = defineProps<DialogProps>();
const emit = defineEmits(['update:modelValue']);
Expand All @@ -112,20 +112,9 @@ const newUser = ref<SubjectCredentialsDto>({
} as SubjectCredentialsDto);

const confirmPassword = ref('');
const groups = ref('');
const certificate = ref('');

const userGroups = computed({
get() {
return groups.value;
},
set(value) {
if (!!value && value.trim().length > 0) {
groups.value = value;
newUser.value.groups = value.split(',').map((g) => g.trim());
}
},
});
let groupFilterOptions = Array<string>();
const groupFilters = ref(Array<string>());

const userCertificate = computed({
get() {
Expand All @@ -143,6 +132,33 @@ const editMode = computed(() => !!props.user && !!props.user.name);
const submitCaption = computed(() => (editMode.value ? t('update') : t('add')));
const dialogTitle = computed(() => (editMode.value ? t('user_edit') : t('user_add')));

function filterGroups(val: string, update: any) {
update(() => {
if (val.trim().length === 0) {
groupFilters.value = [...groupFilterOptions];
} else {
const needle = val.toLowerCase();
groupFilters.value = groupFilters.value.filter((v) => v.toLowerCase().indexOf(needle) > -1);
}
});
}

function addGroup(val: string, done: any) {
if (val.trim().length > 0) {
const modelValue = newUser.value.groups.slice();
if (groupFilterOptions.includes(val) === false) {
groupFilterOptions.push(val);
groupFilters.value = [...groupFilterOptions];
}
if (modelValue.includes(val) === false) {
modelValue.push(val);
}

done(null);
newUser.value.groups = modelValue;
}
}

// Validation rules
const validateRequiredName = (val: string) => (val && val.trim().length > 0) || t('validation.user.name_required');
const validateRequiredCertificate = (val: string) =>
Expand Down Expand Up @@ -175,7 +191,8 @@ watch(
} as SubjectCredentialsDto;
}

userGroups.value = newUser.value.groups ? newUser.value.groups.join(', ') : '';
groupFilterOptions = groupsStore.groups.map((g) => g.name) || [];
groupFilters.value = [...groupFilterOptions];
showDialog.value = value;
}
}
Expand All @@ -199,7 +216,8 @@ async function onAddUser() {
(editMode.value ? usersStore.updateUser(newUser.value) : usersStore.addUser(newUser.value))
.then(() => {
confirmPassword.value = '';
groups.value = '';
groupFilterOptions = [];
groupFilters.value = [];
certificate.value = '';
showDialog.value = false;
})
Expand Down
8 changes: 5 additions & 3 deletions opal-ui/src/components/admin/GroupsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
>
<template v-slot:body-cell-users="props">
<q-td :props="props" @mouseover="onOverRow(props.row)" @mouseleave="onLeaveRow(props.row)">
<span>{{ props.col.format(props.row.subjectCredentials) }}</span>
<q-chip class="q-ml-none" v-for="user in props.col.format(props.row.subjectCredentials)" :key="user.name">
{{ user }}
</q-chip>
<div class="float-right">
<q-btn
rounded
Expand Down Expand Up @@ -70,14 +72,14 @@ const columns = [
field: 'name',
format: (val: string) => val,
sortable: true,
style: 'width: 25%',
style: 'width: 15%',
},
{
name: 'users',
label: t('users'),
align: 'left',
field: 'subjectCredentials',
format: (val: string[]) => (val || []).join(', '),
format: (val: string[]) => (val || []).filter((val) => !!val && val.length > 0),
},
];

Expand Down
7 changes: 5 additions & 2 deletions opal-ui/src/components/admin/UsersList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@
</template>
<template v-slot:body-cell-groups="props">
<q-td :props="props" @mouseover="onOverRow(props.row)" @mouseleave="onLeaveRow(props.row)">
<span>{{ props.col.format(props.row.groups) }}</span>
<q-chip class="q-ml-none" v-for="group in props.col.format(props.row.groups)" :key="group.name">
{{ group }}
</q-chip>
<div class="float-right">
<q-btn
rounded
Expand Down Expand Up @@ -144,13 +146,14 @@ const columns = [
field: 'name',
format: (val: string) => val,
sortable: true,
style: 'width: 15%',
},
{
name: 'groups',
label: t('groups'),
align: 'left',
field: 'groups',
format: (val: string[]) => (val || []).join(', '),
format: (val: string[]) => (val || []).filter((val) => !!val && val.length > 0),
style: 'width: 50%',
},
{
Expand Down
2 changes: 1 addition & 1 deletion opal-ui/src/i18n/en/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export default {
users_filter_placeholder: 'Filter users by name, group or authentication type...',
groups: 'Groups',
groups_info: 'Groups can only be defined through users. Removing a group removes users from this group.',
groups_hint: "Press comma (',') to add a group that is not in the suggestion list.",
groups_hint: 'Select a group or type a new name and press \'Enter\'.',
delete_group_confirm: "Are you sure you want to delete group '{group}'?",
enable: 'Enable',
enabled: 'Enabled',
Expand Down
2 changes: 1 addition & 1 deletion opal-ui/src/i18n/fr/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export default {
users_filter_placeholder: "Filtrer les utilisateurs par nom, groupe ou type d'authentification...",
groups: 'Groupes',
groups_info: "Les groupes ne peuvent être définis que par l'intermédiaire des utilisateurs. La suppression d'un groupe supprime les utilisateurs de ce groupe.",
groups_hint: "Appuyez sur la virgule (',') pour ajouter un groupe qui ne figure pas dans la liste des suggestions.",
groups_hint: 'Sélectionnez un groupe ou saisissez un nouveau nom et appuyez sur \'Entrée\'.',
enable: 'Activer',
enabled: 'Activé',
disable: 'Désactiver',
Expand Down