diff --git a/ui/src/views/UserListView.vue b/ui/src/views/UserListView.vue
index 6bb84b0..03e9081 100644
--- a/ui/src/views/UserListView.vue
+++ b/ui/src/views/UserListView.vue
@@ -51,12 +51,34 @@
mdi-lock-open-variant
-
- mdi-pencil
-
-
- mdi-delete
-
+
+
+
+
+ mdi-cog
+
+
+
+
+
+
+
+
+
+
+
@@ -85,6 +107,21 @@
+
+
+
+
+ {{ t('user.' + actionType) }}
+ {{ t('user.' + actionType + 'Confirm', { id: actionTarget?.id }) }}
+
+
+ {{ t('common.cancel') }}
+ {{ t('common.confirm') }}
+
+
+
@@ -120,6 +157,12 @@ const deleteTarget = ref(null)
const deleting = ref(false)
const bulkDeleteDialog = ref(false)
+// Row gear-menu action state (lock/unlock, isolate/restore, reset).
+const actionDialog = ref(false)
+const actionType = ref('')
+const actionTarget = ref(null)
+const actionLoading = ref(false)
+
const headers = computed(() => [
{ title: t('user.login'), key: 'id', sortable: true },
{ title: t('user.firstName'), key: 'firstName', sortable: true },
@@ -180,6 +223,36 @@ async function confirmBulkDelete() {
dt.load({ page: 1, itemsPerPage: itemsPerPage.value })
}
+function startUserAction(item, type) {
+ actionTarget.value = item
+ actionType.value = type
+ actionDialog.value = true
+}
+
+async function confirmUserAction() {
+ if (dt.demoMode.value) {
+ errorStore.push({ message: t('user.demoAction'), status: 0 })
+ actionDialog.value = false
+ return
+ }
+ actionLoading.value = true
+ const id = actionTarget.value.id
+ const actions = {
+ lock: () => api.del(`rest/service/id/user/${id}/lock`),
+ unlock: () => api.put(`rest/service/id/user/${id}/unlock`),
+ isolate: () => api.del(`rest/service/id/user/${id}/isolate`),
+ restore: () => api.put(`rest/service/id/user/${id}/restore`),
+ resetPassword: () => api.put(`rest/service/id/user/${id}/reset`),
+ }
+ await actions[actionType.value]()
+ actionLoading.value = false
+ actionDialog.value = false
+ actionTarget.value = null
+ // Reload the current page so the status icon and the contextual
+ // lock/isolate menu labels reflect the new state.
+ dt.load(lastOptions)
+}
+
onMounted(() => {
appStore.setBreadcrumbs(
[