Page MenuHomePhorge

D3544.1775500355.diff
No OneTemporary

Authored By
Unknown
Size
23 KB
Referenced Files
None
Subscribers
None

D3544.1775500355.diff

diff --git a/src/resources/lang/en/ui.php b/src/resources/lang/en/ui.php
--- a/src/resources/lang/en/ui.php
+++ b/src/resources/lang/en/ui.php
@@ -47,7 +47,7 @@
'paired' => "Paired devices",
'pairing-instructions' => "Pair a new device using the following QR-Code:",
'deviceid' => "Device ID",
- 'nodevices' => "There are currently no devices",
+ 'list-empty' => "There are currently no devices",
'delete' => "Remove devices",
'remove-devices' => "Remove Devices",
'remove-devices-text' => "Do you really want to remove all devices permanently?"
@@ -187,7 +187,7 @@
'create-title' => "Invite for a signup",
'create-email' => "Enter an email address of the person you want to invite.",
'create-csv' => "To send multiple invitations at once, provide a CSV (comma separated) file, or alternatively a plain-text file, containing one email address per line.",
- 'empty-list' => "There are no invitations in the database.",
+ 'list-empty' => "There are no invitations in the database.",
'title' => "Signup invitations",
'search' => "Email address or domain",
'send' => "Send invite(s)",
diff --git a/src/resources/lang/fr/ui.php b/src/resources/lang/fr/ui.php
--- a/src/resources/lang/fr/ui.php
+++ b/src/resources/lang/fr/ui.php
@@ -149,7 +149,7 @@
'create-title' => "Invitation à une inscription",
'create-email' => "Saisissez l'adresse électronique de la personne que vous souhaitez inviter.",
'create-csv' => "Pour envoyer plusieurs invitations à la fois, fournissez un fichier CSV (séparé par des virgules) ou un fichier en texte brut, contenant une adresse e-mail par ligne.",
- 'empty-list' => "Il y a aucune invitation dans la mémoire de données.",
+ 'list-empty' => "Il y a aucune invitation dans la mémoire de données.",
'title' => "Invitation d'inscription",
'search' => "Adresse E-mail ou domaine",
'send' => "Envoyer invitation(s)",
diff --git a/src/resources/themes/app.scss b/src/resources/themes/app.scss
--- a/src/resources/themes/app.scss
+++ b/src/resources/themes/app.scss
@@ -170,13 +170,6 @@
padding: 0;
}
- td {
- & > svg + a,
- & > svg + span {
- margin-left: .4em;
- }
- }
-
&.files {
table-layout: fixed;
diff --git a/src/resources/vue/Admin/SharedFolder.vue b/src/resources/vue/Admin/SharedFolder.vue
--- a/src/resources/vue/Admin/SharedFolder.vue
+++ b/src/resources/vue/Admin/SharedFolder.vue
@@ -74,23 +74,7 @@
<div class="tab-pane" id="folder-aliases" role="tabpanel" aria-labelledby="tab-aliases">
<div class="card-body">
<div class="card-text">
- <table class="table table-sm table-hover mb-0">
- <thead>
- <tr>
- <th scope="col">{{ $t('form.email') }}</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(alias, index) in folder.aliases" :id="'alias' + index" :key="index">
- <td>{{ alias }}</td>
- </tr>
- </tbody>
- <tfoot class="table-fake-body">
- <tr>
- <td>{{ $t('shf.aliases-none') }}</td>
- </tr>
- </tfoot>
- </table>
+ <list-table :list="folder.aliases" :setup="aliasesListSetup" class="mb-0"></list-table>
</div>
</div>
</div>
@@ -99,9 +83,23 @@
</template>
<script>
+ import { ListTable } from '../Widgets/ListTools'
+
export default {
+ components: {
+ ListTable
+ },
data() {
return {
+ aliasesListSetup: {
+ columns: [
+ {
+ prop: 'email',
+ content: item => item
+ },
+ ],
+ footLabel: 'shf.aliases-none'
+ },
folder: { config: {}, aliases: [] }
}
},
diff --git a/src/resources/vue/Admin/User.vue b/src/resources/vue/Admin/User.vue
--- a/src/resources/vue/Admin/User.vue
+++ b/src/resources/vue/Admin/User.vue
@@ -184,48 +184,14 @@
<div class="tab-pane" id="user-aliases" role="tabpanel" aria-labelledby="tab-aliases">
<div class="card-body">
<div class="card-text">
- <table class="table table-sm table-hover mb-0">
- <thead>
- <tr>
- <th scope="col">{{ $t('form.email') }}</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(alias, index) in user.aliases" :id="'alias' + index" :key="index">
- <td>{{ alias }}</td>
- </tr>
- </tbody>
- <tfoot class="table-fake-body">
- <tr>
- <td>{{ $t('user.aliases-none') }}</td>
- </tr>
- </tfoot>
- </table>
+ <list-table :list="user.aliases" :setup="aliasesListSetup" class="mb-0"></list-table>
</div>
</div>
</div>
<div class="tab-pane" id="user-subscriptions" role="tabpanel" aria-labelledby="tab-subscriptions">
<div class="card-body">
<div class="card-text">
- <table class="table table-sm table-hover mb-0">
- <thead>
- <tr>
- <th scope="col">{{ $t('user.subscription') }}</th>
- <th scope="col">{{ $t('user.price') }}</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(sku, sku_id) in skus" :id="'sku' + sku.id" :key="sku_id">
- <td>{{ sku.name }}</td>
- <td class="price">{{ sku.price }}</td>
- </tr>
- </tbody>
- <tfoot class="table-fake-body">
- <tr>
- <td colspan="2">{{ $t('user.subscriptions-none') }}</td>
- </tr>
- </tfoot>
- </table>
+ <list-table :list="skus" :setup="skusListSetup" class="mb-0"></list-table>
<small v-if="discount > 0" class="hint">
<hr class="m-0">
&sup1; {{ $t('user.discount-hint') }}: {{ discount }}% - {{ discount_description }}
@@ -268,7 +234,7 @@
<div class="tab-pane" id="user-shared-folders" role="tabpanel" aria-labelledby="tab-shared-folders">
<div class="card-body">
<div class="card-text">
- <shared-folder-list :list="folders" :email="true" class="mb-0"></shared-folder-list>
+ <shared-folder-list :list="folders" :with-email="true" class="mb-0"></shared-folder-list>
</div>
</div>
</div>
@@ -388,6 +354,7 @@
<script>
import { Modal } from 'bootstrap'
import TransactionLog from '../Widgets/TransactionLog'
+ import { ListTable } from '../Widgets/ListTools'
import { default as DistlistList } from '../Distlist/ListWidget'
import { default as DomainList } from '../Domain/ListWidget'
import { default as ResourceList } from '../Resource/ListWidget'
@@ -407,6 +374,7 @@
components: {
DistlistList,
DomainList,
+ ListTable,
ResourceList,
SharedFolderList,
TransactionLog,
@@ -421,6 +389,15 @@
},
data() {
return {
+ aliasesListSetup: {
+ columns: [
+ {
+ prop: 'email',
+ content: item => item
+ },
+ ],
+ footLabel: 'user.aliases-none'
+ },
oneoff_amount: '',
oneoff_description: '',
oneoff_negative: false,
@@ -436,8 +413,23 @@
distlists: [],
domains: [],
resources: [],
- skus: [],
sku2FA: null,
+ skus: [],
+ skusListSetup: {
+ columns: [
+ {
+ prop: 'name',
+ label: 'user.subscription'
+ },
+ {
+ prop: 'price',
+ className: 'price',
+ label: 'user.price'
+ }
+ ],
+ footLabel: 'user.subscriptions-none',
+ model: 'sku'
+ },
users: [],
user: {
aliases: [],
diff --git a/src/resources/vue/Distlist/ListWidget.vue b/src/resources/vue/Distlist/ListWidget.vue
--- a/src/resources/vue/Distlist/ListWidget.vue
+++ b/src/resources/vue/Distlist/ListWidget.vue
@@ -21,13 +21,15 @@
return {
setup: {
model: 'distlist',
- cols: [
+ columns: [
{
prop: 'name',
- icon: 'users'
+ icon: 'users',
+ link: true
},
{
prop: 'email',
+ link: true
}
]
}
diff --git a/src/resources/vue/Domain/ListWidget.vue b/src/resources/vue/Domain/ListWidget.vue
--- a/src/resources/vue/Domain/ListWidget.vue
+++ b/src/resources/vue/Domain/ListWidget.vue
@@ -21,10 +21,11 @@
return {
setup: {
model: 'domain',
- cols: [
+ columns: [
{
prop: 'namespace',
- icon: 'globe'
+ icon: 'globe',
+ link: true
}
]
}
diff --git a/src/resources/vue/Reseller/Invitations.vue b/src/resources/vue/Reseller/Invitations.vue
--- a/src/resources/vue/Reseller/Invitations.vue
+++ b/src/resources/vue/Reseller/Invitations.vue
@@ -11,35 +11,20 @@
<btn class="btn-success create-invite ms-1" @click="inviteUserDialog" icon="envelope-open-text">{{ $t('invitation.create') }}</btn>
</div>
- <table id="invitations-list" class="table table-sm table-hover">
- <thead>
- <tr>
- <th scope="col">{{ $t('user.ext-email') }}</th>
- <th scope="col">{{ $t('form.created') }}</th>
- <th scope="col"></th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="inv in invitations" :id="'i' + inv.id" :key="inv.id">
- <td class="email">
- <svg-icon icon="envelope-open-text" :class="statusClass(inv)" :title="$t('invitation.status-' + statusLabel(inv))"></svg-icon>
- <span>{{ inv.email }}</span>
- </td>
- <td class="datetime">
- {{ inv.created }}
- </td>
- <td class="buttons">
- <btn class="text-danger button-delete p-0 ms-1" @click="deleteInvite(inv.id)" icon="trash-can">
- <span class="btn-label">{{ $t('btn.delete') }}</span>
- </btn>
- <btn class="button-resend p-0 ms-1" :disabled="inv.isNew || inv.isCompleted" @click="resendInvite(inv.id)" icon="redo">
- <span class="btn-label">{{ $t('btn.resend') }}</span>
- </btn>
- </td>
- </tr>
- </tbody>
- <list-foot :text="$t('invitation.empty-list')" colspan="3"></list-foot>
- </table>
+ <list-table id="invitations-list" :list="invitations" :setup="setup">
+ <template #email="{ item }">
+ <svg-icon icon="envelope-open-text" :class="statusClass(item)" :title="$t('invitation.status-' + statusLabel(item))"></svg-icon>
+ &nbsp;<span>{{ item.email }}</span>
+ </template>
+ <template #buttons="{ item }">
+ <btn class="text-danger button-delete p-0 ms-1" @click="deleteInvite(item.id)" icon="trash-can">
+ <span class="btn-label">{{ $t('btn.delete') }}</span>
+ </btn>
+ <btn class="button-resend p-0 ms-1" :disabled="item.isNew || item.isCompleted" @click="resendInvite(item.id)" icon="rotate-left">
+ <span class="btn-label">{{ $t('btn.resend') }}</span>
+ </btn>
+ </template>
+ </list-table>
<list-more v-if="hasMore" :on-click="loadInvitations"></list-more>
</div>
</div>
@@ -84,14 +69,30 @@
library.add(
require('@fortawesome/free-solid-svg-icons/faEnvelopeOpenText').definition,
require('@fortawesome/free-solid-svg-icons/faPaperPlane').definition,
- require('@fortawesome/free-solid-svg-icons/faRedo').definition,
+ require('@fortawesome/free-solid-svg-icons/faRotateLeft').definition,
)
export default {
mixins: [ ListTools ],
data() {
return {
- invitations: []
+ invitations: [],
+ setup: {
+ buttons: true,
+ model: 'invitation',
+ columns: [
+ {
+ prop: 'email',
+ label: 'user.ext-email',
+ className: 'email',
+ contentSlot: 'email'
+ },
+ {
+ prop: 'created',
+ className: 'datetime'
+ }
+ ]
+ }
}
},
mounted() {
diff --git a/src/resources/vue/Resource/ListWidget.vue b/src/resources/vue/Resource/ListWidget.vue
--- a/src/resources/vue/Resource/ListWidget.vue
+++ b/src/resources/vue/Resource/ListWidget.vue
@@ -21,13 +21,15 @@
return {
setup: {
model: 'resource',
- cols: [
+ columns: [
{
prop: 'name',
- icon: 'gear'
+ icon: 'gear',
+ link: true
},
{
prop: 'email',
+ link: true
}
]
}
diff --git a/src/resources/vue/SharedFolder/ListWidget.vue b/src/resources/vue/SharedFolder/ListWidget.vue
--- a/src/resources/vue/SharedFolder/ListWidget.vue
+++ b/src/resources/vue/SharedFolder/ListWidget.vue
@@ -15,30 +15,29 @@
ListTable
},
props: {
- email: { type: Boolean, default: () => false },
+ withEmail: { type: Boolean, default: () => false },
list: { type: Array, default: () => [] }
},
computed: {
setup() {
- let cols = [
+ let columns = [
{
prop: 'name',
- icon: 'folder-open'
+ icon: 'folder-open',
+ link: true
},
{
prop: 'type',
- contentLabel: (item) => {
- return 'shf.type-' + item.type
- }
+ contentLabel: item => 'shf.type-' + item.type
}
]
- if (this.email) {
- cols.push({ prop: 'email' })
+ if (this.withEmail) {
+ columns.push({ prop: 'email', link: true })
}
return {
- cols,
+ columns,
model: 'shared-folder',
prefix: 'shf'
}
diff --git a/src/resources/vue/User/ListWidget.vue b/src/resources/vue/User/ListWidget.vue
--- a/src/resources/vue/User/ListWidget.vue
+++ b/src/resources/vue/User/ListWidget.vue
@@ -17,11 +17,12 @@
return {
setup: {
model: 'user',
- cols: [
+ columns: [
{
prop: 'email',
icon: 'user',
- label: 'form.primary-email'
+ label: 'form.primary-email',
+ link: true
}
]
}
diff --git a/src/resources/vue/Widgets/CompanionappList.vue b/src/resources/vue/Widgets/CompanionappList.vue
--- a/src/resources/vue/Widgets/CompanionappList.vue
+++ b/src/resources/vue/Widgets/CompanionappList.vue
@@ -3,21 +3,7 @@
<btn icon="trash-can" class="btn-outline-danger button-delete float-end" @click="showDeleteConfirmation()">
{{ $t('companion.delete') }}
</btn>
- <table class="table table-sm m-0 entries">
- <thead>
- <tr>
- <th scope="col">{{ $t('companion.name') }}</th>
- <th scope="col">{{ $t('companion.deviceid') }}</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="entry in entries" :id="'entry' + entry.id" :key="entry.id">
- <td class="description">{{ entry.name }}</td>
- <td class="description">{{ entry.device_id }}</td>
- </tr>
- </tbody>
- <list-foot :text="$t('companion.nodevices')" :colspan="2"></list-foot>
- </table>
+ <list-table class="m-0" :list="entries" :setup="setup"></list-table>
<list-more v-if="hasMore" :on-click="loadMore"></list-more>
<div id="delete-warning" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
@@ -45,11 +31,22 @@
export default {
mixins: [ ListTools ],
- props: {
- },
data() {
return {
- entries: []
+ entries: [],
+ setup: {
+ model: 'companion',
+ columns: [
+ {
+ prop: 'name'
+ },
+ {
+ prop: 'device_id',
+ label: 'companion.deviceid'
+ }
+ ]
+ }
+
}
},
mounted() {
diff --git a/src/resources/vue/Widgets/ListTools.vue b/src/resources/vue/Widgets/ListTools.vue
--- a/src/resources/vue/Widgets/ListTools.vue
+++ b/src/resources/vue/Widgets/ListTools.vue
@@ -47,6 +47,15 @@
setup: { type: Object, default: () => {} },
},
methods: {
+ content(column, item) {
+ if (column.contentLabel) {
+ return this.$t(column.contentLabel(item))
+ }
+ if (column.content) {
+ return column.content(item)
+ }
+ return item[column.prop]
+ },
label(label) {
let l = `${this.setup.prefix || this.setup.model}${label}`
return this.$te(l) ? l : `form${label}`
@@ -59,20 +68,24 @@
`<table class="table table-sm table-hover">
<thead>
<tr>
- <th v-for="col in setup.cols" scope="col">{{ $t(col.label || label('.' + col.prop)) }}</th>
+ <th v-for="column in setup.columns" scope="col">{{ $t(column.label || label('.' + column.prop)) }}</th>
+ <th v-if="setup.buttons" scope="col"></th>
</tr>
</thead>
<tbody>
- <tr v-for="item in list" :key="item.id" @click="$root.clickRecord">
- <td v-for="col in setup.cols" :key="col.prop + item.id">
- <svg-icon v-if="col.icon" :icon="col.icon" :class="$root.statusClass(item)" :title="$root.statusText(item)"></svg-icon>
- <span v-if="col.contentLabel" >{{ $t(col.contentLabel(item)) }}</span>
- <router-link v-else-if="!current || current.id != item.id" :to="url(item)">{{ item[col.prop] }}</router-link>
- <span v-else>{{ item[col.prop] }}</span>
+ <tr v-for="(item, index) in list" :key="item.id || index" :id="setup.model ? (setup.model + (item.id || index)) : null" @click="$root.clickRecord">
+ <td v-for="column in setup.columns" :key="column.prop + (item.id || index)" :class="column.className">
+ <svg-icon v-if="column.icon" :icon="column.icon" :class="$root.statusClass(item)" :title="$root.statusText(item)"></svg-icon>
+ <router-link v-if="column.link && (!current || current.id != item.id)" :to="url(item)">{{ content(column, item) }}</router-link>
+ <slot v-else-if="column.contentSlot" :name="column.contentSlot" v-bind:item="item"></slot>
+ <span v-else>{{ content(column, item) }}</span>
+ </td>
+ <td v-if="setup.buttons" class="buttons">
+ <slot name="buttons" v-bind:item="item"></slot>
</td>
</tr>
</tbody>
- <list-foot :text="$t(label('.list-empty'))" :colspan="setup.cols.length"></list-foot>
+ <list-foot :text="$t(setup.footLabel || label('.list-empty'))" :colspan="setup.columns.length + (setup.buttons ? 1 : 0)"></list-foot>
</table>`
}

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 6, 6:32 PM (2 h, 30 s ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18833876
Default Alt Text
D3544.1775500355.diff (23 KB)

Event Timeline