Move most all table views to new action menu pattern
This commit is contained in:
@@ -5,7 +5,7 @@ const i18n = useI18n();
|
||||
const t = i18n.t;
|
||||
|
||||
import { ref, onMounted, useTemplateRef } from 'vue';
|
||||
import { Button, TableView, Dialog } from '@cloudron/pankow';
|
||||
import { Button, Menu, TableView, Dialog } from '@cloudron/pankow';
|
||||
import { eachLimit } from 'async';
|
||||
import Section from '../components/Section.vue';
|
||||
import MailinglistDialog from '../components/MailinglistDialog.vue';
|
||||
@@ -29,6 +29,24 @@ const columns = {
|
||||
actions: {}
|
||||
};
|
||||
|
||||
const actionMenuModel = ref([]);
|
||||
const actionMenuElement = useTemplateRef('actionMenuElement');
|
||||
function onActionMenu(mailinglist, event) {
|
||||
actionMenuModel.value = [{
|
||||
icon: 'fa-solid fa-pencil-alt',
|
||||
label: t('main.action.edit'),
|
||||
action: onAddOrEdit.bind(null, mailinglist),
|
||||
}, {
|
||||
separator: true,
|
||||
}, {
|
||||
icon: 'fa-solid fa-trash-alt',
|
||||
label: t('main.action.remove'),
|
||||
action: onRemove.bind(null, mailinglist),
|
||||
}];
|
||||
|
||||
actionMenuElement.value.open(event, event.currentTarget);
|
||||
}
|
||||
|
||||
const busy = ref(true);
|
||||
const mailinglists = ref([]);
|
||||
const domains = ref([]);
|
||||
@@ -108,6 +126,7 @@ onMounted(async () => {
|
||||
|
||||
<template>
|
||||
<div class="content">
|
||||
<Menu ref="actionMenuElement" :model="actionMenuModel" />
|
||||
<Dialog ref="removeDialog"
|
||||
:title="$t('email.deleteMailinglistDialog.title', { name: removeMailinglist.name, domain: removeMailinglist.domain })"
|
||||
:confirm-label="$t('email.deleteMailinglistDialog.deleteAction')"
|
||||
@@ -139,9 +158,8 @@ onMounted(async () => {
|
||||
{{ mailinglist.members.join(', ') }}
|
||||
</template>
|
||||
<template #actions="mailinglist">
|
||||
<div class="table-actions">
|
||||
<Button tool secondary small icon="fa fa-pencil-alt" @click.stop="onAddOrEdit(mailinglist)"></Button>
|
||||
<Button tool danger small icon="fa-solid fa-trash-alt" @click.stop="onRemove(mailinglist)"></Button>
|
||||
<div style="text-align: right;">
|
||||
<Button tool plain secondary @click.capture="onActionMenu(mailinglist, $event)" icon="fa-solid fa-ellipsis" />
|
||||
</div>
|
||||
</template>
|
||||
</TableView>
|
||||
|
||||
@@ -5,7 +5,7 @@ const i18n = useI18n();
|
||||
const t = i18n.t;
|
||||
|
||||
import { computed, reactive, onMounted, ref, useTemplateRef } from 'vue';
|
||||
import { Button, TableView, ProgressBar, ButtonGroup, FormGroup, Checkbox, Dialog } from '@cloudron/pankow';
|
||||
import { Button, Menu, TableView, ProgressBar, FormGroup, Checkbox, Dialog } from '@cloudron/pankow';
|
||||
import { prettyBinarySize } from '@cloudron/pankow/utils';
|
||||
import { each } from 'async';
|
||||
import Section from '../components/Section.vue';
|
||||
@@ -37,6 +37,30 @@ const columns = {
|
||||
actions: {}
|
||||
};
|
||||
|
||||
const actionMenuModel = ref([]);
|
||||
const actionMenuElement = useTemplateRef('actionMenuElement');
|
||||
function onActionMenu(service, event) {
|
||||
actionMenuModel.value = [{
|
||||
icon: 'fa-solid fa-pencil-alt',
|
||||
label: t('main.action.edit'),
|
||||
visible: service.status !== 'disabled' && service.memoryLimit,
|
||||
action: onEdit.bind(null, service),
|
||||
}, {
|
||||
icon: 'fa-solid fa-sync-alt',
|
||||
label: t('services.restartActionTooltip'),
|
||||
visible: service.id !== 'box',
|
||||
disabled: (service.status === 'starting' && !service.config.recoveryMode),
|
||||
action: onRestart.bind(null, service.id),
|
||||
}, {
|
||||
icon: 'fa-solid fa-fw fa-file-alt',
|
||||
label: t('logs.title'),
|
||||
target: '_blank',
|
||||
href: `/logs.html?id=${service.id}`,
|
||||
}];
|
||||
|
||||
actionMenuElement.value.open(event, event.currentTarget);
|
||||
}
|
||||
|
||||
const services = reactive({
|
||||
box: {
|
||||
name: 'cloudron',
|
||||
@@ -178,6 +202,7 @@ onMounted(async () => {
|
||||
|
||||
<template>
|
||||
<div class="content">
|
||||
<Menu ref="actionMenuElement" :model="actionMenuModel" />
|
||||
<Dialog ref="dialog"
|
||||
:title="$t('services.configure.title', { name: editService.name })"
|
||||
:confirm-busy="editBusy"
|
||||
@@ -220,12 +245,8 @@ onMounted(async () => {
|
||||
<span v-show="service.memoryLimit">{{ prettyBinarySize(service.memoryLimit) }}</span>
|
||||
</template>
|
||||
<template #actions="service">
|
||||
<div class="table-actions">
|
||||
<ButtonGroup>
|
||||
<Button small tool secondary v-if="service.status !== 'disabled' && service.config.memoryLimit" @click="onEdit(service)" v-tooltip="$t('services.configureActionTooltip')" icon="fa-solid fa fa-pencil-alt"/>
|
||||
<Button small tool secondary v-if="service.id !== 'box'" @click="onRestart(service.id)" :loading="service.status === 'starting' && !service.config.recoveryMode" v-tooltip="$t('services.restartActionTooltip')" icon="fa-solid fa-sync-alt"/>
|
||||
<Button tool small secondary :href="`/logs.html?id=${service.id}`" target="_blank" v-tooltip="$t('logs.title')" icon="fa-solid fa-file-alt" />
|
||||
</ButtonGroup>
|
||||
<div style="text-align: right;">
|
||||
<Button tool plain secondary @click.capture="onActionMenu(service, $event)" icon="fa-solid fa-ellipsis" />
|
||||
</div>
|
||||
</template>
|
||||
</TableView>
|
||||
|
||||
@@ -5,7 +5,7 @@ const i18n = useI18n();
|
||||
const t = i18n.t;
|
||||
|
||||
import { ref, onMounted, useTemplateRef, computed } from 'vue';
|
||||
import { Button, Dialog, TableView, FormGroup, TextInput, InputGroup, InputDialog } from '@cloudron/pankow';
|
||||
import { Button, Menu, Dialog, TableView, FormGroup, TextInput, InputGroup, InputDialog } from '@cloudron/pankow';
|
||||
import { copyToClipboard } from '@cloudron/pankow/utils';
|
||||
import Section from '../components/Section.vue';
|
||||
import DashboardModel from '../models/DashboardModel.js';
|
||||
@@ -19,6 +19,24 @@ const columns = {
|
||||
actions: {}
|
||||
};
|
||||
|
||||
const actionMenuModel = ref([]);
|
||||
const actionMenuElement = useTemplateRef('actionMenuElement');
|
||||
function onActionMenu(client, event) {
|
||||
actionMenuModel.value = [{
|
||||
icon: 'fa-solid fa-pencil-alt',
|
||||
label: t('main.action.edit'),
|
||||
action: onEdit.bind(null, client),
|
||||
}, {
|
||||
separator: true,
|
||||
}, {
|
||||
icon: 'fa-solid fa-trash-alt',
|
||||
label: t('main.action.remove'),
|
||||
action: onRemove.bind(null, client),
|
||||
}];
|
||||
|
||||
actionMenuElement.value.open(event, event.currentTarget);
|
||||
}
|
||||
|
||||
const inputDialog = useTemplateRef('inputDialog');
|
||||
const editDialog = useTemplateRef('editDialog');
|
||||
|
||||
@@ -83,7 +101,8 @@ async function onSubmit() {
|
||||
|
||||
async function onRemove(client) {
|
||||
const yes = await inputDialog.value.confirm({
|
||||
message: t('oidc.deleteClientDialog.title', { client: client.name }) + ' ' + t('oidc.deleteClientDialog.description'),
|
||||
title: t('oidc.deleteClientDialog.title', { client: client.name }),
|
||||
message: t('oidc.deleteClientDialog.description'),
|
||||
confirmStyle: 'danger',
|
||||
confirmLabel: t('main.dialog.delete'),
|
||||
rejectLabel: t('main.dialog.cancel')
|
||||
@@ -119,6 +138,7 @@ onMounted(async () => {
|
||||
|
||||
<template>
|
||||
<div class="content">
|
||||
<Menu ref="actionMenuElement" :model="actionMenuModel" />
|
||||
<InputDialog ref="inputDialog" />
|
||||
<Dialog ref="editDialog"
|
||||
:title="clientId ? $t('oidc.editClientDialog.title', { client: clientName }) : $t('oidc.newClientDialog.title')"
|
||||
@@ -184,9 +204,8 @@ onMounted(async () => {
|
||||
|
||||
<TableView :columns="columns" :model="clients" :placeholder="$t('oidc.clients.empty')">
|
||||
<template #actions="client">
|
||||
<div class="table-actions">
|
||||
<Button tool secondary small icon="fa-solid fa-pencil-alt" @click.stop="onEdit(client)"></Button>
|
||||
<Button tool danger small icon="fa-solid fa-trash-alt" @click.stop="onRemove(client)"></Button>
|
||||
<div style="text-align: right;">
|
||||
<Button tool plain secondary @click.capture="onActionMenu(client, $event)" icon="fa-solid fa-ellipsis" />
|
||||
</div>
|
||||
</template>
|
||||
</TableView>
|
||||
|
||||
@@ -5,7 +5,7 @@ const i18n = useI18n();
|
||||
const t = i18n.t;
|
||||
|
||||
import { ref, onMounted, computed, useTemplateRef, inject } from 'vue';
|
||||
import { Button, ButtonGroup, TextInput, SingleSelect, TableView, InputDialog } from '@cloudron/pankow';
|
||||
import { Button, Menu, TextInput, SingleSelect, TableView, InputDialog } from '@cloudron/pankow';
|
||||
import { ROLES } from '../constants.js';
|
||||
import Section from '../components/Section.vue';
|
||||
import UserDialog from '../components/UserDialog.vue';
|
||||
@@ -37,6 +37,43 @@ const usersColumns = {
|
||||
actions: {}
|
||||
};
|
||||
|
||||
const actionMenuModel = ref([]);
|
||||
const actionMenuElement = useTemplateRef('actionMenuElement');
|
||||
function onUserActionMenu(user, event) {
|
||||
actionMenuModel.value = [{
|
||||
icon: 'fa-solid fa-paper-plane',
|
||||
label: t('users.users.invitationTooltip'),
|
||||
visible: !user.inviteAccepted && !isMe(user) && !user.source,
|
||||
disabled: !canEdit(user),
|
||||
action: onInvitation.bind(null, user),
|
||||
}, {
|
||||
icon: 'fa-solid fa-key',
|
||||
label: t('users.users.resetPasswordTooltip'),
|
||||
visible: user.inviteAccepted && !user.source,
|
||||
disabled: !canEdit(user),
|
||||
action: onPasswordReset.bind(null, user),
|
||||
}, {
|
||||
icon: 'fa-solid fa-user-secret',
|
||||
label: t('users.users.setGhostTooltip'),
|
||||
visible: canImpersonate(user),
|
||||
action: onImpersonate.bind(null, user),
|
||||
}, {
|
||||
icon: 'fa fa-pencil-alt',
|
||||
label: t('main.action.edit'),
|
||||
disabled: !canEdit(user),
|
||||
action: onEditOrAddUser.bind(null, user),
|
||||
}, {
|
||||
separator: true,
|
||||
}, {
|
||||
icon: 'fa-solid fa-trash-alt',
|
||||
label: t('main.action.remove'),
|
||||
disabled: !canEdit(user),
|
||||
action: onRemoveUser.bind(null, user),
|
||||
}];
|
||||
|
||||
actionMenuElement.value.open(event, event.currentTarget);
|
||||
}
|
||||
|
||||
const groupsColumns = {
|
||||
name: {
|
||||
label: t('users.groups.name'),
|
||||
@@ -50,6 +87,22 @@ const groupsColumns = {
|
||||
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([
|
||||
@@ -221,6 +274,7 @@ onMounted(async () => {
|
||||
|
||||
<template>
|
||||
<div class="content">
|
||||
<Menu ref="actionMenuElement" :model="actionMenuModel" />
|
||||
<InputDialog ref="inputDialog" />
|
||||
<UserDialog ref="userDialog" @success="refreshUsers()"/>
|
||||
<GroupDialog ref="groupDialog" @success="refreshGroups()"/>
|
||||
@@ -255,14 +309,8 @@ onMounted(async () => {
|
||||
</span>
|
||||
</template>
|
||||
<template #actions="user">
|
||||
<div class="table-actions">
|
||||
<ButtonGroup>
|
||||
<Button small tool secondary :disabled="!canEdit(user)" v-if="!user.inviteAccepted && !isMe(user) && !user.source" @click.stop="onInvitation(user)" v-tooltip="$t('users.users.invitationTooltip')" icon="fa-solid fa-paper-plane" />
|
||||
<Button small tool secondary :disabled="!canEdit(user)" v-if="user.inviteAccepted && !user.source" @click.stop="onPasswordReset(user)" v-tooltip="$t('users.users.resetPasswordTooltip')" icon="fa-solid fa-key" />
|
||||
<Button small tool secondary v-if="canImpersonate(user)" @click.stop="onImpersonate(user)" v-tooltip="$t('users.users.setGhostTooltip')" icon="fa-solid fa-user-secret" />
|
||||
<Button small tool secondary :disabled="!canEdit(user)" @click.stop="onEditOrAddUser(user)" v-tooltip="$t('users.users.editUserTooltip')" icon="fa fa-pencil-alt" />
|
||||
</ButtonGroup>
|
||||
<Button small tool danger :disabled="!canEdit(user) || isMe(user)" @click.stop="onRemoveUser(user)" v-tooltip="$t('users.users.removeUserTooltip')" icon="far fa-trash-alt" />
|
||||
<div style="text-align: right;">
|
||||
<Button tool plain secondary @click.capture="onUserActionMenu(user, $event)" icon="fa-solid fa-ellipsis" />
|
||||
</div>
|
||||
</template>
|
||||
</TableView>
|
||||
@@ -283,11 +331,8 @@ onMounted(async () => {
|
||||
{{ groupMembers(group) }}
|
||||
</template>
|
||||
<template #actions="group">
|
||||
<div class="table-actions">
|
||||
<ButtonGroup>
|
||||
<Button tool small secondary @click.stop="onEditOrAddGroup(group)" v-tooltip="'Edit Group'" icon="fa fa-pencil-alt" />
|
||||
</ButtonGroup>
|
||||
<Button tool small danger @click.stop="onRemoveGroup(group)" v-tooltip="'Remove Group'" icon="far fa-trash-alt" />
|
||||
<div style="text-align: right;">
|
||||
<Button tool plain secondary @click.capture="onGroupActionMenu(group, $event)" icon="fa-solid fa-ellipsis" />
|
||||
</div>
|
||||
</template>
|
||||
</TableView>
|
||||
|
||||
@@ -5,7 +5,7 @@ const i18n = useI18n();
|
||||
const t = i18n.t;
|
||||
|
||||
import { computed, ref, useTemplateRef, onMounted } from 'vue';
|
||||
import { Button, ButtonGroup, Checkbox, Dialog, SingleSelect, FormGroup, InputDialog, NumberInput, PasswordInput, TableView, TextInput } from '@cloudron/pankow';
|
||||
import { Button, Menu, Checkbox, Dialog, SingleSelect, FormGroup, InputDialog, NumberInput, PasswordInput, TableView, TextInput } from '@cloudron/pankow';
|
||||
import Section from '../components/Section.vue';
|
||||
import StateLED from '../components/StateLED.vue';
|
||||
import VolumesModel from '../models/VolumesModel.js';
|
||||
@@ -31,6 +31,35 @@ const columns = {
|
||||
actions: {}
|
||||
};
|
||||
|
||||
const actionMenuModel = ref([]);
|
||||
const actionMenuElement = useTemplateRef('actionMenuElement');
|
||||
function onActionMenu(volume, event) {
|
||||
actionMenuModel.value = [{
|
||||
icon: 'fa-solid fa-sync-alt',
|
||||
label: t('volumes.remountActionTooltip'),
|
||||
visible: volume.mountType === 'sshfs' || volume.mountType === 'cifs' || volume.mountType === 'nfs' || volume.mountType === 'ext4' || volume.mountType === 'xfs',
|
||||
action: remount.bind(null, volume),
|
||||
}, {
|
||||
icon: 'fa-solid fa-pencil-alt',
|
||||
label: t('main.action.edit'),
|
||||
visible: volume.mountType === 'sshfs' || volume.mountType === 'cifs' || volume.mountType === 'nfs',
|
||||
action: openVolumeDialog.bind(null, volume),
|
||||
}, {
|
||||
icon: 'fa-solid fa-folder',
|
||||
label: t('volumes.openFileManagerActionTooltip'),
|
||||
target: '_blank',
|
||||
href: '/filemanager.html#/home/volume/' + volume.id,
|
||||
}, {
|
||||
separator: true,
|
||||
}, {
|
||||
icon: 'fa-solid fa-trash-alt',
|
||||
label: t('main.action.remove'),
|
||||
action: onRemove.bind(null, volume),
|
||||
}];
|
||||
|
||||
actionMenuElement.value.open(event, event.currentTarget);
|
||||
}
|
||||
|
||||
const busy = ref(true);
|
||||
const volumes = ref([]);
|
||||
const volumeDialogData = ref({
|
||||
@@ -202,6 +231,7 @@ onMounted(async () =>{
|
||||
|
||||
<template>
|
||||
<div class="content">
|
||||
<Menu ref="actionMenuElement" :model="actionMenuModel" />
|
||||
<InputDialog ref="inputDialog" />
|
||||
|
||||
<Dialog ref="volumeDialog"
|
||||
@@ -298,13 +328,8 @@ onMounted(async () =>{
|
||||
</div>
|
||||
</template>
|
||||
<template #actions="volume">
|
||||
<div class="table-actions">
|
||||
<ButtonGroup>
|
||||
<Button tool secondary small icon="fa fa-sync-alt" v-if="volume.mountType === 'sshfs' || volume.mountType === 'cifs' || volume.mountType === 'nfs' || volume.mountType === 'ext4' || volume.mountType === 'xfs'" v-tooltip="$t('volumes.remountActionTooltip')" @click="remount(volume)"></Button>
|
||||
<Button tool secondary small icon="fa fa-pencil-alt" v-if="volume.mountType === 'sshfs' || volume.mountType === 'cifs' || volume.mountType === 'nfs'" v-tooltip="$t('volumes.editActionTooltip')" @click="openVolumeDialog(volume)"></Button>
|
||||
<Button tool secondary small icon="fas fa-folder" v-tooltip="$t('volumes.openFileManagerActionTooltip')" :href="'/filemanager.html#/home/volume/' + volume.id" target="_blank"></Button>
|
||||
</ButtonGroup>
|
||||
<Button tool danger small icon="fa-solid fa-trash-alt" v-tooltip="$t('volumes.removeVolumeActionTooltip')" @click="onRemove(volume)"></Button>
|
||||
<div style="text-align: right;">
|
||||
<Button tool plain secondary @click.capture="onActionMenu(volume, $event)" icon="fa-solid fa-ellipsis" />
|
||||
</div>
|
||||
</template>
|
||||
</TableView>
|
||||
|
||||
Reference in New Issue
Block a user