mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-04-28 18:38:24 -05:00
fix(frontend): add horizontal overflow handling to tables on mobile
Wraps all tables that were missing overflow handling in a `has-horizontal-overflow` div to prevent horizontal overflow on mobile viewports. Affected components: - Sessions.vue - ApiTokens.vue - ProjectSettingsWebhooks.vue - LinkSharing.vue - UserTeam.vue - EditTeam.vue - ProjectSettingsViews.vue Fixes https://github.com/go-vikunja/vikunja/issues/2331
This commit is contained in:
@@ -67,108 +67,110 @@
|
||||
</XButton>
|
||||
</div>
|
||||
|
||||
<table
|
||||
<div
|
||||
v-if="linkShares.length > 0"
|
||||
class="table has-actions is-striped is-hoverable is-fullwidth"
|
||||
class="has-horizontal-overflow"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th />
|
||||
<th v-if="availableViews.length > 0">
|
||||
{{ $t('project.share.links.view') }}
|
||||
</th>
|
||||
<th>{{ $t('project.share.attributes.delete') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="s in linkShares"
|
||||
:key="s.id"
|
||||
>
|
||||
<td>
|
||||
<p
|
||||
v-if="s.name !== ''"
|
||||
class="mbe-2 is-italic"
|
||||
>
|
||||
{{ s.name }}
|
||||
</p>
|
||||
|
||||
<p class="mbe-2">
|
||||
<i18n-t
|
||||
keypath="project.share.links.sharedBy"
|
||||
scope="global"
|
||||
<table class="table has-actions is-striped is-hoverable is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th />
|
||||
<th v-if="availableViews.length > 0">
|
||||
{{ $t('project.share.links.view') }}
|
||||
</th>
|
||||
<th>{{ $t('project.share.attributes.delete') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="s in linkShares"
|
||||
:key="s.id"
|
||||
>
|
||||
<td>
|
||||
<p
|
||||
v-if="s.name !== ''"
|
||||
class="mbe-2 is-italic"
|
||||
>
|
||||
<strong>{{ getDisplayName(s.sharedBy) }}</strong>
|
||||
</i18n-t>
|
||||
</p>
|
||||
{{ s.name }}
|
||||
</p>
|
||||
|
||||
<p class="mbe-2">
|
||||
<template v-if="s.permission === PERMISSIONS.ADMIN">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="lock" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.admin') }}
|
||||
</template>
|
||||
<template v-else-if="s.permission === PERMISSIONS.READ_WRITE">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="pen" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.readWrite') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="icon is-small">
|
||||
<Icon icon="users" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.read') }}
|
||||
</template>
|
||||
</p>
|
||||
<p class="mbe-2">
|
||||
<i18n-t
|
||||
keypath="project.share.links.sharedBy"
|
||||
scope="global"
|
||||
>
|
||||
<strong>{{ getDisplayName(s.sharedBy) }}</strong>
|
||||
</i18n-t>
|
||||
</p>
|
||||
|
||||
<p class="mbe-2">
|
||||
<template v-if="s.permission === PERMISSIONS.ADMIN">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="lock" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.admin') }}
|
||||
</template>
|
||||
<template v-else-if="s.permission === PERMISSIONS.READ_WRITE">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="pen" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.readWrite') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="icon is-small">
|
||||
<Icon icon="users" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.read') }}
|
||||
</template>
|
||||
</p>
|
||||
|
||||
<FormField
|
||||
:model-value="shareLinks[s.id]"
|
||||
readonly
|
||||
type="text"
|
||||
>
|
||||
<template #addon>
|
||||
<XButton
|
||||
v-tooltip="$t('misc.copy')"
|
||||
:shadow="false"
|
||||
@click="copy(shareLinks[s.id])"
|
||||
>
|
||||
<span class="icon">
|
||||
<Icon icon="paste" />
|
||||
</span>
|
||||
</XButton>
|
||||
</template>
|
||||
</FormField>
|
||||
</td>
|
||||
<td v-if="availableViews.length > 0">
|
||||
<div class="select">
|
||||
<select v-model="selectedViews[s.id]">
|
||||
<option
|
||||
v-for="(view) in availableViews"
|
||||
:key="view.id"
|
||||
:value="view.id"
|
||||
>
|
||||
{{ view.title }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td class="actions">
|
||||
<XButton
|
||||
danger
|
||||
icon="trash-alt"
|
||||
@click="
|
||||
() => {
|
||||
linkIdToDelete = s.id
|
||||
showDeleteModal = true
|
||||
}
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<FormField
|
||||
:model-value="shareLinks[s.id]"
|
||||
readonly
|
||||
type="text"
|
||||
>
|
||||
<template #addon>
|
||||
<XButton
|
||||
v-tooltip="$t('misc.copy')"
|
||||
:shadow="false"
|
||||
@click="copy(shareLinks[s.id])"
|
||||
>
|
||||
<span class="icon">
|
||||
<Icon icon="paste" />
|
||||
</span>
|
||||
</XButton>
|
||||
</template>
|
||||
</FormField>
|
||||
</td>
|
||||
<td v-if="availableViews.length > 0">
|
||||
<div class="select">
|
||||
<select v-model="selectedViews[s.id]">
|
||||
<option
|
||||
v-for="(view) in availableViews"
|
||||
:key="view.id"
|
||||
:value="view.id"
|
||||
>
|
||||
{{ view.title }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td class="actions">
|
||||
<XButton
|
||||
danger
|
||||
icon="trash-alt"
|
||||
@click="
|
||||
() => {
|
||||
linkIdToDelete = s.id
|
||||
showDeleteModal = true
|
||||
}
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
|
||||
@@ -41,99 +41,101 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table
|
||||
<div
|
||||
v-if="sharables.length > 0"
|
||||
class="table has-actions is-striped is-hoverable is-fullwidth mbe-4"
|
||||
class="has-horizontal-overflow mbe-4"
|
||||
>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="s in sharables"
|
||||
:key="s.id"
|
||||
>
|
||||
<template v-if="shareType === 'user'">
|
||||
<td>{{ getDisplayName(s) }}</td>
|
||||
<td>
|
||||
<template v-if="s.id === userInfo.id">
|
||||
<b class="is-success">{{ $t('project.share.userTeam.you') }}</b>
|
||||
<table class="table has-actions is-striped is-hoverable is-fullwidth">
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="s in sharables"
|
||||
:key="s.id"
|
||||
>
|
||||
<template v-if="shareType === 'user'">
|
||||
<td>{{ getDisplayName(s) }}</td>
|
||||
<td>
|
||||
<template v-if="s.id === userInfo.id">
|
||||
<b class="is-success">{{ $t('project.share.userTeam.you') }}</b>
|
||||
</template>
|
||||
</td>
|
||||
</template>
|
||||
<template v-if="shareType === 'team'">
|
||||
<td>
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'teams.edit',
|
||||
params: { id: s.id },
|
||||
}"
|
||||
>
|
||||
{{ s.name }}
|
||||
</RouterLink>
|
||||
</td>
|
||||
</template>
|
||||
<td class="type">
|
||||
<template v-if="s.permission === PERMISSIONS.ADMIN">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="lock" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.admin') }}
|
||||
</template>
|
||||
<template v-else-if="s.permission === PERMISSIONS.READ_WRITE">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="pen" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.readWrite') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="icon is-small">
|
||||
<Icon icon="users" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.read') }}
|
||||
</template>
|
||||
</td>
|
||||
</template>
|
||||
<template v-if="shareType === 'team'">
|
||||
<td>
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'teams.edit',
|
||||
params: { id: s.id },
|
||||
}"
|
||||
>
|
||||
{{ s.name }}
|
||||
</RouterLink>
|
||||
<td
|
||||
v-if="userIsAdmin"
|
||||
class="actions"
|
||||
>
|
||||
<div class="select">
|
||||
<select
|
||||
v-model="selectedPermission[s.id]"
|
||||
class="mie-2"
|
||||
@change="toggleType(s)"
|
||||
>
|
||||
<option
|
||||
:selected="s.permission === PERMISSIONS.READ"
|
||||
:value="PERMISSIONS.READ"
|
||||
>
|
||||
{{ $t('project.share.permission.read') }}
|
||||
</option>
|
||||
<option
|
||||
:selected="s.permission === PERMISSIONS.READ_WRITE"
|
||||
:value="PERMISSIONS.READ_WRITE"
|
||||
>
|
||||
{{ $t('project.share.permission.readWrite') }}
|
||||
</option>
|
||||
<option
|
||||
:selected="s.permission === PERMISSIONS.ADMIN"
|
||||
:value="PERMISSIONS.ADMIN"
|
||||
>
|
||||
{{ $t('project.share.permission.admin') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<XButton
|
||||
danger
|
||||
icon="trash-alt"
|
||||
@click="
|
||||
() => {
|
||||
sharable = s
|
||||
showDeleteModal = true
|
||||
}
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</template>
|
||||
<td class="type">
|
||||
<template v-if="s.permission === PERMISSIONS.ADMIN">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="lock" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.admin') }}
|
||||
</template>
|
||||
<template v-else-if="s.permission === PERMISSIONS.READ_WRITE">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="pen" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.readWrite') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="icon is-small">
|
||||
<Icon icon="users" />
|
||||
</span>
|
||||
{{ $t('project.share.permission.read') }}
|
||||
</template>
|
||||
</td>
|
||||
<td
|
||||
v-if="userIsAdmin"
|
||||
class="actions"
|
||||
>
|
||||
<div class="select">
|
||||
<select
|
||||
v-model="selectedPermission[s.id]"
|
||||
class="mie-2"
|
||||
@change="toggleType(s)"
|
||||
>
|
||||
<option
|
||||
:selected="s.permission === PERMISSIONS.READ"
|
||||
:value="PERMISSIONS.READ"
|
||||
>
|
||||
{{ $t('project.share.permission.read') }}
|
||||
</option>
|
||||
<option
|
||||
:selected="s.permission === PERMISSIONS.READ_WRITE"
|
||||
:value="PERMISSIONS.READ_WRITE"
|
||||
>
|
||||
{{ $t('project.share.permission.readWrite') }}
|
||||
</option>
|
||||
<option
|
||||
:selected="s.permission === PERMISSIONS.ADMIN"
|
||||
:value="PERMISSIONS.ADMIN"
|
||||
>
|
||||
{{ $t('project.share.permission.admin') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<XButton
|
||||
danger
|
||||
icon="trash-alt"
|
||||
@click="
|
||||
() => {
|
||||
sharable = s
|
||||
showDeleteModal = true
|
||||
}
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<Nothing v-else>
|
||||
{{ $t('project.share.userTeam.notShared', {type: shareTypeNames}) }}
|
||||
|
||||
@@ -151,68 +151,70 @@ async function saveViewPosition(e) {
|
||||
{{ $t('project.views.onlyAdminsCanEdit') }}
|
||||
</Message>
|
||||
|
||||
<table
|
||||
<div
|
||||
v-if="views?.length > 0"
|
||||
class="table has-actions is-striped is-hoverable is-fullwidth"
|
||||
class="has-horizontal-overflow"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('project.views.title') }}</th>
|
||||
<th>{{ $t('project.views.kind') }}</th>
|
||||
<th class="has-text-end">
|
||||
{{ $t('project.views.actions') }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<draggable
|
||||
v-model="views"
|
||||
tag="tbody"
|
||||
item-key="id"
|
||||
handle=".handle"
|
||||
:animation="100"
|
||||
@end="saveViewPosition"
|
||||
>
|
||||
<template #item="{element: v}">
|
||||
<table class="table has-actions is-striped is-hoverable is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<template v-if="viewToEdit !== null && viewToEdit.id === v.id">
|
||||
<td colspan="3">
|
||||
<ViewEditForm
|
||||
v-model="viewToEdit"
|
||||
class="mbe-4"
|
||||
:loading="projectViewService.loading"
|
||||
:show-save-buttons="true"
|
||||
@cancel="viewToEdit = null"
|
||||
@update:modelValue="saveView(viewToEdit)"
|
||||
/>
|
||||
</td>
|
||||
</template>
|
||||
<template v-else>
|
||||
<td>{{ v.title }}</td>
|
||||
<td>{{ v.viewKind }}</td>
|
||||
<td class="has-text-end actions">
|
||||
<XButton
|
||||
v-if="isAdmin"
|
||||
class="is-danger mie-2"
|
||||
icon="trash-alt"
|
||||
@click="() => {
|
||||
viewIdToDelete = v.id
|
||||
showDeleteModal = true
|
||||
}"
|
||||
/>
|
||||
<XButton
|
||||
v-if="isAdmin"
|
||||
icon="pen"
|
||||
@click="viewToEdit = {...v}"
|
||||
/>
|
||||
<span class="icon handle">
|
||||
<Icon icon="grip-lines" />
|
||||
</span>
|
||||
</td>
|
||||
</template>
|
||||
<th>{{ $t('project.views.title') }}</th>
|
||||
<th>{{ $t('project.views.kind') }}</th>
|
||||
<th class="has-text-end">
|
||||
{{ $t('project.views.actions') }}
|
||||
</th>
|
||||
</tr>
|
||||
</template>
|
||||
</draggable>
|
||||
</table>
|
||||
</thead>
|
||||
<draggable
|
||||
v-model="views"
|
||||
tag="tbody"
|
||||
item-key="id"
|
||||
handle=".handle"
|
||||
:animation="100"
|
||||
@end="saveViewPosition"
|
||||
>
|
||||
<template #item="{element: v}">
|
||||
<tr>
|
||||
<template v-if="viewToEdit !== null && viewToEdit.id === v.id">
|
||||
<td colspan="3">
|
||||
<ViewEditForm
|
||||
v-model="viewToEdit"
|
||||
class="mbe-4"
|
||||
:loading="projectViewService.loading"
|
||||
:show-save-buttons="true"
|
||||
@cancel="viewToEdit = null"
|
||||
@update:modelValue="saveView(viewToEdit)"
|
||||
/>
|
||||
</td>
|
||||
</template>
|
||||
<template v-else>
|
||||
<td>{{ v.title }}</td>
|
||||
<td>{{ v.viewKind }}</td>
|
||||
<td class="has-text-end actions">
|
||||
<XButton
|
||||
v-if="isAdmin"
|
||||
class="is-danger mie-2"
|
||||
icon="trash-alt"
|
||||
@click="() => {
|
||||
viewIdToDelete = v.id
|
||||
showDeleteModal = true
|
||||
}"
|
||||
/>
|
||||
<XButton
|
||||
v-if="isAdmin"
|
||||
icon="pen"
|
||||
@click="viewToEdit = {...v}"
|
||||
/>
|
||||
<span class="icon handle">
|
||||
<Icon icon="grip-lines" />
|
||||
</span>
|
||||
</td>
|
||||
</template>
|
||||
</tr>
|
||||
</template>
|
||||
</draggable>
|
||||
</table>
|
||||
</div>
|
||||
</CreateEdit>
|
||||
|
||||
<Modal
|
||||
|
||||
@@ -246,44 +246,46 @@ function validateSelectedEvents() {
|
||||
</XButton>
|
||||
</div>
|
||||
|
||||
<table
|
||||
<div
|
||||
v-if="webhooks?.length > 0"
|
||||
class="table has-actions is-striped is-hoverable is-fullwidth"
|
||||
class="has-horizontal-overflow"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('project.webhooks.targetUrl') }}</th>
|
||||
<th>{{ $t('project.webhooks.events') }}</th>
|
||||
<th>{{ $t('misc.created') }}</th>
|
||||
<th>{{ $t('misc.createdBy') }}</th>
|
||||
<th />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="w in webhooks"
|
||||
:key="w.id"
|
||||
>
|
||||
<td>{{ w.targetUrl }}</td>
|
||||
<td>{{ w.events.join(', ') }}</td>
|
||||
<td>{{ formatDateShort(w.created) }}</td>
|
||||
<td>
|
||||
<User
|
||||
:avatar-size="25"
|
||||
:user="w.createdBy"
|
||||
/>
|
||||
</td>
|
||||
<table class="table has-actions is-striped is-hoverable is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('project.webhooks.targetUrl') }}</th>
|
||||
<th>{{ $t('project.webhooks.events') }}</th>
|
||||
<th>{{ $t('misc.created') }}</th>
|
||||
<th>{{ $t('misc.createdBy') }}</th>
|
||||
<th />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="w in webhooks"
|
||||
:key="w.id"
|
||||
>
|
||||
<td>{{ w.targetUrl }}</td>
|
||||
<td>{{ w.events.join(', ') }}</td>
|
||||
<td>{{ formatDateShort(w.created) }}</td>
|
||||
<td>
|
||||
<User
|
||||
:avatar-size="25"
|
||||
:user="w.createdBy"
|
||||
/>
|
||||
</td>
|
||||
|
||||
<td class="actions">
|
||||
<XButton
|
||||
danger
|
||||
icon="trash-alt"
|
||||
@click="() => {showDeleteModal = true;webhookIdToDelete = w.id}"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<td class="actions">
|
||||
<XButton
|
||||
danger
|
||||
icon="trash-alt"
|
||||
@click="() => {showDeleteModal = true;webhookIdToDelete = w.id}"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
:enabled="showDeleteModal"
|
||||
|
||||
@@ -109,61 +109,63 @@
|
||||
{{ $t('team.edit.mustSelectUser') }}
|
||||
</p>
|
||||
</form>
|
||||
<table class="table has-actions is-striped is-hoverable is-fullwidth">
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="m in team?.members"
|
||||
:key="m.id"
|
||||
>
|
||||
<td>
|
||||
<User
|
||||
:avatar-size="24"
|
||||
:user="m"
|
||||
class="m-0"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<template v-if="m.id === userInfo.id">
|
||||
<b class="is-success">You</b>
|
||||
</template>
|
||||
</td>
|
||||
<td class="type">
|
||||
<template v-if="m.admin">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="lock" />
|
||||
</span>
|
||||
{{ $t('team.attributes.admin') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="icon is-small">
|
||||
<Icon icon="user" />
|
||||
</span>
|
||||
{{ $t('team.attributes.member') }}
|
||||
</template>
|
||||
</td>
|
||||
<td
|
||||
v-if="userIsAdmin"
|
||||
class="actions"
|
||||
<div class="has-horizontal-overflow">
|
||||
<table class="table has-actions is-striped is-hoverable is-fullwidth">
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="m in team?.members"
|
||||
:key="m.id"
|
||||
>
|
||||
<XButton
|
||||
v-if="m.id !== userInfo.id"
|
||||
:loading="teamMemberService.loading"
|
||||
class="mie-2"
|
||||
@click="() => toggleUserType(m)"
|
||||
<td>
|
||||
<User
|
||||
:avatar-size="24"
|
||||
:user="m"
|
||||
class="m-0"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<template v-if="m.id === userInfo.id">
|
||||
<b class="is-success">You</b>
|
||||
</template>
|
||||
</td>
|
||||
<td class="type">
|
||||
<template v-if="m.admin">
|
||||
<span class="icon is-small">
|
||||
<Icon icon="lock" />
|
||||
</span>
|
||||
{{ $t('team.attributes.admin') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="icon is-small">
|
||||
<Icon icon="user" />
|
||||
</span>
|
||||
{{ $t('team.attributes.member') }}
|
||||
</template>
|
||||
</td>
|
||||
<td
|
||||
v-if="userIsAdmin"
|
||||
class="actions"
|
||||
>
|
||||
{{ m.admin ? $t('team.edit.makeMember') : $t('team.edit.makeAdmin') }}
|
||||
</XButton>
|
||||
<XButton
|
||||
v-if="m.id !== userInfo.id"
|
||||
:loading="teamMemberService.loading"
|
||||
danger
|
||||
icon="trash-alt"
|
||||
@click="() => {memberToDelete = m; showUserDeleteModal = true}"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<XButton
|
||||
v-if="m.id !== userInfo.id"
|
||||
:loading="teamMemberService.loading"
|
||||
class="mie-2"
|
||||
@click="() => toggleUserType(m)"
|
||||
>
|
||||
{{ m.admin ? $t('team.edit.makeMember') : $t('team.edit.makeAdmin') }}
|
||||
</XButton>
|
||||
<XButton
|
||||
v-if="m.id !== userInfo.id"
|
||||
:loading="teamMemberService.loading"
|
||||
danger
|
||||
icon="trash-alt"
|
||||
@click="() => {memberToDelete = m; showUserDeleteModal = true}"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<XButton
|
||||
|
||||
@@ -217,60 +217,62 @@ function toggleGroupPermissionsFromChild(group: string, checked: boolean) {
|
||||
.
|
||||
</p>
|
||||
|
||||
<table
|
||||
<div
|
||||
v-if="tokens.length > 0"
|
||||
class="table"
|
||||
class="has-horizontal-overflow"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('misc.id') }}</th>
|
||||
<th>{{ $t('user.settings.apiTokens.attributes.title') }}</th>
|
||||
<th>{{ $t('user.settings.apiTokens.attributes.permissions') }}</th>
|
||||
<th>{{ $t('user.settings.apiTokens.attributes.expiresAt') }}</th>
|
||||
<th>{{ $t('misc.created') }}</th>
|
||||
<th class="has-text-end">
|
||||
{{ $t('misc.actions') }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="tk in tokens"
|
||||
:key="tk.id"
|
||||
>
|
||||
<td>{{ tk.id }}</td>
|
||||
<td>{{ tk.title }}</td>
|
||||
<td class="is-capitalized">
|
||||
<template
|
||||
v-for="(v, p) in tk.permissions"
|
||||
:key="'permission-' + p"
|
||||
>
|
||||
<strong>{{ formatPermissionTitle(p) }}:</strong>
|
||||
{{ v.map(formatPermissionTitle).join(', ') }}
|
||||
<br>
|
||||
</template>
|
||||
</td>
|
||||
<td>
|
||||
{{ formatDisplayDate(tk.expiresAt) }}
|
||||
<p
|
||||
v-if="tk.expiresAt < new Date()"
|
||||
class="has-text-danger"
|
||||
>
|
||||
{{ $t('user.settings.apiTokens.expired', {ago: formatDateSince(tk.expiresAt)}) }}
|
||||
</p>
|
||||
</td>
|
||||
<td>{{ formatDisplayDate(tk.created) }}</td>
|
||||
<td class="has-text-end">
|
||||
<XButton
|
||||
variant="secondary"
|
||||
@click="() => {tokenToDelete = tk; showDeleteModal = true}"
|
||||
>
|
||||
{{ $t('misc.delete') }}
|
||||
</XButton>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('misc.id') }}</th>
|
||||
<th>{{ $t('user.settings.apiTokens.attributes.title') }}</th>
|
||||
<th>{{ $t('user.settings.apiTokens.attributes.permissions') }}</th>
|
||||
<th>{{ $t('user.settings.apiTokens.attributes.expiresAt') }}</th>
|
||||
<th>{{ $t('misc.created') }}</th>
|
||||
<th class="has-text-end">
|
||||
{{ $t('misc.actions') }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="tk in tokens"
|
||||
:key="tk.id"
|
||||
>
|
||||
<td>{{ tk.id }}</td>
|
||||
<td>{{ tk.title }}</td>
|
||||
<td class="is-capitalized">
|
||||
<template
|
||||
v-for="(v, p) in tk.permissions"
|
||||
:key="'permission-' + p"
|
||||
>
|
||||
<strong>{{ formatPermissionTitle(p) }}:</strong>
|
||||
{{ v.map(formatPermissionTitle).join(', ') }}
|
||||
<br>
|
||||
</template>
|
||||
</td>
|
||||
<td>
|
||||
{{ formatDisplayDate(tk.expiresAt) }}
|
||||
<p
|
||||
v-if="tk.expiresAt < new Date()"
|
||||
class="has-text-danger"
|
||||
>
|
||||
{{ $t('user.settings.apiTokens.expired', {ago: formatDateSince(tk.expiresAt)}) }}
|
||||
</p>
|
||||
</td>
|
||||
<td>{{ formatDisplayDate(tk.created) }}</td>
|
||||
<td class="has-text-end">
|
||||
<XButton
|
||||
variant="secondary"
|
||||
@click="() => {tokenToDelete = tk; showDeleteModal = true}"
|
||||
>
|
||||
{{ $t('misc.delete') }}
|
||||
</XButton>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<form
|
||||
v-if="showCreateForm"
|
||||
|
||||
@@ -45,48 +45,50 @@ async function deleteSession() {
|
||||
{{ $t('user.settings.sessions.description') }}
|
||||
</p>
|
||||
|
||||
<table
|
||||
<div
|
||||
v-if="sessions.length > 0"
|
||||
class="table"
|
||||
class="has-horizontal-overflow"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('user.settings.sessions.deviceInfo') }}</th>
|
||||
<th>{{ $t('user.settings.sessions.ipAddress') }}</th>
|
||||
<th>{{ $t('user.settings.sessions.lastActive') }}</th>
|
||||
<th class="has-text-end">
|
||||
{{ $t('misc.actions') }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="session in sessions"
|
||||
:key="session.id"
|
||||
>
|
||||
<td>
|
||||
{{ session.deviceInfo }}
|
||||
<span
|
||||
v-if="session.id === authStore.currentSessionId"
|
||||
class="tag is-primary mis-2"
|
||||
>
|
||||
{{ $t('user.settings.sessions.current') }}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ session.ipAddress }}</td>
|
||||
<td>{{ formatDateSince(session.lastActive) }}</td>
|
||||
<td class="has-text-end">
|
||||
<XButton
|
||||
v-if="session.id !== authStore.currentSessionId"
|
||||
variant="secondary"
|
||||
@click="confirmDelete(session)"
|
||||
>
|
||||
{{ $t('misc.delete') }}
|
||||
</XButton>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('user.settings.sessions.deviceInfo') }}</th>
|
||||
<th>{{ $t('user.settings.sessions.ipAddress') }}</th>
|
||||
<th>{{ $t('user.settings.sessions.lastActive') }}</th>
|
||||
<th class="has-text-end">
|
||||
{{ $t('misc.actions') }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="session in sessions"
|
||||
:key="session.id"
|
||||
>
|
||||
<td>
|
||||
{{ session.deviceInfo }}
|
||||
<span
|
||||
v-if="session.id === authStore.currentSessionId"
|
||||
class="tag is-primary mis-2"
|
||||
>
|
||||
{{ $t('user.settings.sessions.current') }}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ session.ipAddress }}</td>
|
||||
<td>{{ formatDateSince(session.lastActive) }}</td>
|
||||
<td class="has-text-end">
|
||||
<XButton
|
||||
v-if="session.id !== authStore.currentSessionId"
|
||||
variant="secondary"
|
||||
@click="confirmDelete(session)"
|
||||
>
|
||||
{{ $t('misc.delete') }}
|
||||
</XButton>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p v-else>
|
||||
{{ $t('user.settings.sessions.noOtherSessions') }}
|
||||
|
||||
Reference in New Issue
Block a user