Skip to content
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
5 changes: 5 additions & 0 deletions ui/src/i18n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export default {
'delegate.write': 'Write',
'delegate.adminHelp': 'With the administration security level on this resource, the receivers of this delegation can create other delegations to share this access with other valid receivers',
'delegate.writeHelp': 'With the write security level, the receivers of this delegation can modify the members of the involved groups. Without this access, this delegation grants read-only rights',
'delegate.adminGranted': 'Administration granted',
'delegate.writeGranted': 'Write access granted',
// Fragments wrapping the receiver name in bold red on the delete
// confirmation (issue #37). The host keeps the monolithic
// `delegate.deleteConfirm` key intact.
Expand All @@ -51,6 +53,7 @@ export default {
// in bold red.
'common.bulkDeleteConfirmBefore': 'Are you sure you want to delete ',
'common.bulkDeleteConfirmAfter': ' items? This cannot be undone.',
'common.edit': 'Edit',
// Chantier D2 — sensitive confirmations split in two fragments so the
// login can be wrapped in bold red between them. The monolithic
// `user.<action>Confirm` keys stay on the host side for any other
Expand All @@ -65,6 +68,8 @@ export default {
'user.restoreConfirmAfter': '?',
'user.resetPasswordConfirmBefore': 'Reset password for user ',
'user.resetPasswordConfirmAfter': '? A new password will be sent.',
'user.statusLocked': 'Locked',
'user.statusActive': 'Active',
'group.deleteConfirmBefore': 'Are you sure you want to delete ',
'group.deleteConfirmAfter': '?',
'company.deleteConfirmBefore': 'Are you sure you want to delete ',
Expand Down
5 changes: 5 additions & 0 deletions ui/src/i18n/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export default {
'delegate.write': 'Écriture',
'delegate.adminHelp': 'Avec le niveau de sécurité d\'administration sur cette ressource, les receveurs de cette délégation peuvent créer d\'autres délégations pour partager cet accès avec d\'autres receveurs valides',
'delegate.writeHelp': 'Avec le niveau de sécurité d\'écriture, les receveurs de cette délégation peuvent modifier les membres des groupes impliqués. Sans cet accès cette délégation ne donne qu\'un droit de lecture',
'delegate.adminGranted': 'Administration accordée',
'delegate.writeGranted': 'Écriture accordée',
// Fragments encadrant le nom du destinataire en gras-rouge dans la
// confirmation de suppression (issue #37). Le host garde la clé
// monolithique `delegate.deleteConfirm` intacte.
Expand All @@ -44,6 +46,7 @@ export default {
// en gras-rouge pour la suppression en masse.
'common.bulkDeleteConfirmBefore': 'Supprimer ',
'common.bulkDeleteConfirmAfter': ' éléments ? Cette action est irréversible.',
'common.edit': 'Modifier',
// Chantier D2 — confirmations sensibles découpées en deux fragments
// pour insérer l'identifiant en gras-rouge entre eux. Les clés
// monolithiques `user.<action>Confirm` restent côté host pour
Expand All @@ -58,6 +61,8 @@ export default {
'user.restoreConfirmAfter': ' ?',
'user.resetPasswordConfirmBefore': 'Réinitialiser le mot de passe de l\'utilisateur ',
'user.resetPasswordConfirmAfter': ' ? Un nouveau mot de passe lui sera envoyé.',
'user.statusLocked': 'Verrouillé',
'user.statusActive': 'Actif',
'group.deleteConfirmBefore': 'Êtes-vous certain de supprimer ',
'group.deleteConfirmAfter': ' ?',
'company.deleteConfirmBefore': 'Êtes-vous certain de supprimer ',
Expand Down
1 change: 1 addition & 0 deletions ui/src/views/CompanyEditView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
class="mb-2"
no-filter
clearable
autocomplete="off"
@update:search="onScopeSearch"
>
<template #item="{ props: itemProps, item }">
Expand Down
14 changes: 11 additions & 3 deletions ui/src/views/CompanyListView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,22 @@
v-model:items-per-page="itemsPerPage" :headers="headers" :items="dt.items.value" :items-length="dt.totalItems.value" :loading="dt.loading.value" item-value="name" show-select hover
@update:options="loadData" @click:row="(_, { item }) => router.push('/id/company/' + item.name)">
<template #item.locked="{ item }">
<v-icon v-if="item.locked" color="error" size="small">mdi-lock</v-icon>
<div class="text-center">
<v-tooltip v-if="item.locked" :text="t('user.statusLocked')" location="top">
<template #activator="{ props: tt }">
<v-icon v-bind="tt" color="error" size="small">mdi-lock</v-icon>
</template>
</v-tooltip>
</div>
</template>
<template #item.actions="{ item }">
<v-btn icon size="small" variant="text" @click.stop="router.push('/id/company/' + item.name)">
<v-icon size="small">mdi-pencil</v-icon>
<v-tooltip activator="parent" :text="t('common.edit')" location="top" />
</v-btn>
<v-btn icon size="small" variant="text" color="error" @click.stop="startDelete(item)">
<v-icon size="small">mdi-delete</v-icon>
<v-tooltip activator="parent" :text="t('common.delete')" location="top" />
</v-btn>
</template>
</LigojDataTableServer>
Expand Down Expand Up @@ -105,8 +113,8 @@ let lastOptions = {}
const headers = computed(() => [
{ title: t('common.name'), key: 'name', sortable: true },
{ title: t('group.scope'), key: 'scope', sortable: false },
{ title: t('group.members'), key: 'count', sortable: false, width: '100px' },
{ title: t('group.locked'), key: 'locked', sortable: false, width: '80px' },
{ title: t('group.members'), key: 'count', sortable: false, width: '100px', align: 'center' },
{ title: t('group.locked'), key: 'locked', sortable: false, width: '80px', align: 'center' },
{ title: '', key: 'actions', sortable: false, width: '120px', align: 'center' },
])

Expand Down
4 changes: 2 additions & 2 deletions ui/src/views/DelegateEditDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
</v-col>
<v-col cols="12" sm="7">
<v-autocomplete v-model="form.receiver" v-model:search="receiverSearch" :label="t('delegate.receiver')" :items="receiverDisplayItems" item-title="label" item-value="id"
:loading="receiverLoading" :rules="[rules.required]" no-filter clearable auto-select-first variant="outlined" class="mb-2" @update:search="onReceiverSearch"
:loading="receiverLoading" :rules="[rules.required]" no-filter clearable auto-select-first variant="outlined" class="mb-2" autocomplete="off" @update:search="onReceiverSearch"
@update:menu="onReceiverMenu" />
</v-col>
</v-row>
Expand Down Expand Up @@ -62,7 +62,7 @@
<v-text-field v-if="form.type === 'TREE'" v-model="form.name" :label="t('delegate.resource')" :rules="[rules.required]" :hint="t('delegate.resourceDnHint')" persistent-hint
variant="outlined" class="mb-2" />
<v-autocomplete v-else v-model="form.name" v-model:search="resourceSearch" :label="t('delegate.resource')" :items="resourceDisplayItems" item-title="label" item-value="id"
:loading="resourceLoading" :rules="[rules.required]" :hint="t('delegate.resourceHint')" persistent-hint no-filter clearable auto-select-first variant="outlined" class="mb-2"
:loading="resourceLoading" :rules="[rules.required]" :hint="t('delegate.resourceHint')" persistent-hint no-filter clearable auto-select-first variant="outlined" class="mb-2" autocomplete="off"
@update:search="onResourceSearch" @update:menu="onResourceMenu" />
</v-col>
</v-row>
Expand Down
33 changes: 27 additions & 6 deletions ui/src/views/DelegateListView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,47 @@
for some rows, so normalize before the TYPE_ICONS lookup —
same rationale as DelegateEditDialog.loadOnOpen(). -->
<template #item.receiver="{ item }">
<v-icon size="small" class="me-1">{{ TYPE_ICONS[item.receiverType?.toUpperCase()] || 'mdi-account' }}</v-icon>
<v-tooltip :text="t('delegate.type.' + (item.receiverType || '').toLowerCase())" location="top">
<template #activator="{ props: tt }">
<v-icon v-bind="tt" size="small" class="me-1">{{ TYPE_ICONS[item.receiverType?.toUpperCase()] || 'mdi-account' }}</v-icon>
</template>
</v-tooltip>
{{ item.receiver?.name || item.receiver?.id || item.name || '-' }}
</template>
<!-- Resource column (chantier D5+D8): fuses the former Type and
Resource columns. The kind is the leading icon (Account /
Group / Domain / File-tree); the text is the resource name
(or DN for TREE delegates). Same lowercase-normalize as above. -->
<template #item.name="{ item }">
<v-icon size="small" class="me-1">{{ TYPE_ICONS[item.type?.toUpperCase()] || '' }}</v-icon>
<v-tooltip :text="t('delegate.type.' + (item.type || '').toLowerCase())" location="top">
<template #activator="{ props: tt }">
<v-icon v-bind="tt" size="small" class="me-1">{{ TYPE_ICONS[item.type?.toUpperCase()] || '' }}</v-icon>
</template>
</v-tooltip>
{{ item.name || '-' }}
</template>
<template #item.canAdmin="{ item }">
<v-icon v-if="item.canAdmin" color="success" size="small">mdi-check</v-icon>
<div class="text-center">
<v-tooltip v-if="item.canAdmin" :text="t('delegate.adminGranted')" location="top">
<template #activator="{ props: tt }">
<v-icon v-bind="tt" color="success" size="small">mdi-check</v-icon>
</template>
</v-tooltip>
</div>
</template>
<template #item.canWrite="{ item }">
<v-icon v-if="item.canWrite" color="success" size="small">mdi-check</v-icon>
<div class="text-center">
<v-tooltip v-if="item.canWrite" :text="t('delegate.writeGranted')" location="top">
<template #activator="{ props: tt }">
<v-icon v-bind="tt" color="success" size="small">mdi-check</v-icon>
</template>
</v-tooltip>
</div>
</template>
<template #item.actions="{ item }">
<v-btn icon size="small" variant="text" @click.stop="openDialog(item.id)">
<v-icon size="small">mdi-pencil</v-icon>
<v-tooltip activator="parent" :text="t('common.edit')" location="top" />
</v-btn>
<v-btn icon size="small" variant="text" color="error" @click.stop="startDelete(item)">
<v-icon size="small">mdi-delete</v-icon>
Expand Down Expand Up @@ -133,8 +154,8 @@ const editDelegateId = ref(null)
const headers = computed(() => [
{ title: t('delegate.receiver'), key: 'receiver', sortable: true },
{ title: t('delegate.resource'), key: 'name', sortable: false },
{ title: t('delegate.admin'), key: 'canAdmin', sortable: false, width: '80px', tooltip: t('delegate.adminHelp') },
{ title: t('delegate.write'), key: 'canWrite', sortable: false, width: '80px', tooltip: t('delegate.writeHelp') },
{ title: t('delegate.admin'), key: 'canAdmin', sortable: false, width: '80px', align: 'center', tooltip: t('delegate.adminHelp') },
{ title: t('delegate.write'), key: 'canWrite', sortable: false, width: '80px', align: 'center', tooltip: t('delegate.writeHelp') },
{ title: '', key: 'actions', sortable: false, width: '120px', align: 'center' },
])

Expand Down
3 changes: 2 additions & 1 deletion ui/src/views/GroupEditView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<v-card-text>
<v-form ref="formRef" @submit.prevent="save">
<v-text-field v-model="form.name" :label="t('common.name')" :rules="[rules.required]" :disabled="isEdit" variant="outlined" class="mb-2" />
<v-autocomplete v-model="form.scope" :label="t('group.scope')" :items="availableScopes" :loading="scopesLoading" clearable variant="outlined" class="mb-2" />
<v-autocomplete v-model="form.scope" :label="t('group.scope')" :items="availableScopes" :loading="scopesLoading" clearable variant="outlined" class="mb-2" autocomplete="off" />
<!-- Parent group: lazy server-backed autosuggest. No groups are
loaded until the dropdown opens (chantier H, Fabrice review) —
the former mount-time bulk GET doesn't scale to 100k+ groups. -->
Expand All @@ -28,6 +28,7 @@
class="mb-2"
no-filter
clearable
autocomplete="off"
@update:menu="onParentMenu"
@update:search="onParentSearch"
>
Expand Down
14 changes: 11 additions & 3 deletions ui/src/views/GroupListView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,22 @@
v-model:items-per-page="itemsPerPage" :headers="headers" :items="dt.items.value" :items-length="dt.totalItems.value" :loading="dt.loading.value" item-value="name" show-select hover
@update:options="loadData" @click:row="(_, { item }) => router.push('/id/group/' + item.name)">
<template #item.locked="{ item }">
<v-icon v-if="item.locked" color="error" size="small">mdi-lock</v-icon>
<div class="text-center">
<v-tooltip v-if="item.locked" :text="t('user.statusLocked')" location="top">
<template #activator="{ props: tt }">
<v-icon v-bind="tt" color="error" size="small">mdi-lock</v-icon>
</template>
</v-tooltip>
</div>
</template>
<template #item.actions="{ item }">
<v-btn icon size="small" variant="text" @click.stop="router.push('/id/group/' + item.name)">
<v-icon size="small">mdi-pencil</v-icon>
<v-tooltip activator="parent" :text="t('common.edit')" location="top" />
</v-btn>
<v-btn icon size="small" variant="text" color="error" @click.stop="startDelete(item)">
<v-icon size="small">mdi-delete</v-icon>
<v-tooltip activator="parent" :text="t('common.delete')" location="top" />
</v-btn>
</template>
</LigojDataTableServer>
Expand Down Expand Up @@ -107,8 +115,8 @@ let lastOptions = {}
const headers = computed(() => [
{ title: t('common.name'), key: 'name', sortable: true },
{ title: t('group.scope'), key: 'scope', sortable: false },
{ title: t('group.members'), key: 'count', sortable: false, width: '100px' },
{ title: t('group.locked'), key: 'locked', sortable: false, width: '80px' },
{ title: t('group.members'), key: 'count', sortable: false, width: '100px', align: 'center' },
{ title: t('group.locked'), key: 'locked', sortable: false, width: '80px', align: 'center' },
{ title: '', key: 'actions', sortable: false, width: '120px', align: 'center' },
])

Expand Down
3 changes: 2 additions & 1 deletion ui/src/views/GroupMembersView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<v-card variant="tonal" class="mb-4">
<v-card-text class="d-flex flex-wrap align-center ga-2">
<v-autocomplete v-model="newMember" v-model:search="searchTerm" :label="t('id.group.addPlaceholder')" :items="searchResults" item-title="label" item-value="id" :loading="searching" no-filter
clearable return-object="false" variant="outlined" density="compact" hide-details style="min-width: 320px; flex: 1 1 320px" @update:search="onSearch" @update:menu="onSearchMenu" />
clearable return-object="false" variant="outlined" density="compact" hide-details autocomplete="off" style="min-width: 320px; flex: 1 1 320px" @update:search="onSearch" @update:menu="onSearchMenu" />
<v-btn color="primary" prepend-icon="mdi-account-plus" :disabled="!newMember || !groupName" :loading="adding" @click="addMember">
{{ t('id.group.add') }}
</v-btn>
Expand Down Expand Up @@ -61,6 +61,7 @@
<template #item.actions="{ item }">
<v-btn v-if="canRemove(item)" icon size="small" variant="text" color="error" :title="t('id.group.removeTitle')" @click.stop="startRemove(item)">
<v-icon size="small">mdi-account-minus</v-icon>
<v-tooltip activator="parent" :text="t('id.group.removeTitle')" location="top" />
</v-btn>
<v-tooltip v-else-if="isTransitive(item)" :text="t('id.group.transitive')" location="top">
<template #activator="{ props: tt }">
Expand Down
6 changes: 3 additions & 3 deletions ui/src/views/UserEditDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
user types (300 ms debounced). v-model stores the company name
as a string, matching the payload contract of rest/service/id/user. -->
<v-autocomplete v-model="form.company" :items="companyResults" :loading="companyLoading" :search="companySearchQuery" item-title="name" item-value="name" :label="t('user.company')"
placeholder="Rechercher une entité…" variant="outlined" class="mb-2" no-filter clearable @update:search="onCompanySearch">
placeholder="Rechercher une entité…" variant="outlined" class="mb-2" no-filter clearable autocomplete="off" @update:search="onCompanySearch">
<template #item="{ props: itemProps, item }">
<v-list-item v-bind="itemProps" :title="item?.name || ''">
<template v-if="item?.scope || item?.count !== undefined" #subtitle>
Expand All @@ -47,13 +47,13 @@
multiple + chips lets the user type any email (no
autocomplete source) and confirm with Enter or Tab;
existing emails are restored as chips at load time. -->
<v-combobox v-model="form.mails" :label="t('user.emails')" multiple chips closable-chips variant="outlined" class="mb-2" :hint="t('user.emailsHint')" persistent-hint />
<v-combobox v-model="form.mails" :label="t('user.emails')" multiple chips closable-chips variant="outlined" class="mb-2" :hint="t('user.emailsHint')" persistent-hint autocomplete="off" />
<!-- Auto-suggest for groups (multi-select). Queries
rest/service/id/group as the user types (300 ms debounced).
v-model holds an array of group **names** (strings),
matching the payload contract of rest/service/id/user. -->
<v-autocomplete v-model="groups" v-model:menu="groupMenu" :items="groupResults" :loading="groupLoading" :search="groupSearchQuery" item-title="name" item-value="name"
:label="t('user.groups')" placeholder="Ajouter un groupe…" variant="outlined" class="mb-2" multiple chips closable-chips no-filter clearable @update:search="onGroupSearch"
:label="t('user.groups')" placeholder="Ajouter un groupe…" variant="outlined" class="mb-2" multiple chips closable-chips no-filter clearable autocomplete="off" @update:search="onGroupSearch"
@update:model-value="onGroupModelUpdate">
<template #item="{ props: itemProps, item }">
<v-list-item v-bind="itemProps" :title="item?.name || ''" />
Expand Down
15 changes: 13 additions & 2 deletions ui/src/views/UserListView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,18 @@
</div>
</template>
<template #item.locked="{ item }">
<v-icon v-if="item.locked" color="error" size="small">mdi-lock</v-icon>
<v-icon v-else color="success" size="small">mdi-lock-open-variant</v-icon>
<div class="text-center">
<v-tooltip v-if="item.locked" :text="t('user.statusLocked')" location="top">
<template #activator="{ props: tt }">
<v-icon v-bind="tt" color="error" size="small">mdi-lock</v-icon>
</template>
</v-tooltip>
<v-tooltip v-else :text="t('user.statusActive')" location="top">
<template #activator="{ props: tt }">
<v-icon v-bind="tt" color="success" size="small">mdi-lock-open-variant</v-icon>
</template>
</v-tooltip>
</div>
</template>
<template #item.actions="{ item }">
<!-- Single gear button opening a menu of row actions (Fabrice
Expand All @@ -75,6 +85,7 @@
<template #activator="{ props }">
<v-btn icon size="x-small" variant="text" :aria-label="t('user.actions')" v-bind="props" @click.stop>
<v-icon size="small">mdi-cog</v-icon>
<v-tooltip activator="parent" :text="t('user.actions')" location="top" />
</v-btn>
</template>
<v-list density="compact" min-width="220">
Expand Down
Loading