chore(front): refactor admin settings users
This commit is contained in:
parent
1779e66d4a
commit
606903f7e7
|
@ -5,6 +5,8 @@ import { ref, computed, reactive, watch } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import DangerousButton from '~/components/common/DangerousButton.vue'
|
import DangerousButton from '~/components/common/DangerousButton.vue'
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
|
@ -171,23 +173,23 @@ const launchAction = async () => {
|
||||||
<span v-if="needsRefresh">
|
<span v-if="needsRefresh">
|
||||||
{{ t('components.common.ActionTable.message.needsRefresh') }}
|
{{ t('components.common.ActionTable.message.needsRefresh') }}
|
||||||
</span>
|
</span>
|
||||||
<button
|
<Button
|
||||||
class="ui basic icon button"
|
tiny
|
||||||
|
icon="bi-arrow-clockwise"
|
||||||
:title="labels.refresh"
|
:title="labels.refresh"
|
||||||
:aria-label="labels.refresh"
|
:aria-label="labels.refresh"
|
||||||
@click="$emit('refresh')"
|
@click="$emit('refresh')"
|
||||||
>
|
/>
|
||||||
<i class="refresh icon" />
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<Layout
|
||||||
v-if="actionUrl && actions.length > 0"
|
v-if="actionUrl && actions.length > 0"
|
||||||
class="ui small left floated form"
|
stack
|
||||||
|
no-gap
|
||||||
|
class="ui form"
|
||||||
>
|
>
|
||||||
<div class="ui inline fields">
|
|
||||||
<div class="field">
|
|
||||||
<label for="actions-select">{{ t('components.common.ActionTable.label.actions') }}</label>
|
<label for="actions-select">{{ t('components.common.ActionTable.label.actions') }}</label>
|
||||||
|
<Layout flex>
|
||||||
<select
|
<select
|
||||||
id="actions-select"
|
id="actions-select"
|
||||||
v-model="currentActionName"
|
v-model="currentActionName"
|
||||||
|
@ -201,8 +203,6 @@ const launchAction = async () => {
|
||||||
{{ action.label }}
|
{{ action.label }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
v-if="selectAll || currentAction?.isDangerous"
|
v-if="selectAll || currentAction?.isDangerous"
|
||||||
:disabled="checked.length === 0 || undefined"
|
:disabled="checked.length === 0 || undefined"
|
||||||
|
@ -227,16 +227,17 @@ const launchAction = async () => {
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
<button
|
<Button
|
||||||
v-else
|
v-else
|
||||||
|
primary
|
||||||
:disabled="checked.length === 0"
|
:disabled="checked.length === 0"
|
||||||
:aria-label="labels.performAction"
|
:aria-label="labels.performAction"
|
||||||
:class="['ui', {disabled: checked.length === 0}, {'loading': isLoading}, 'button']"
|
:class="[{disabled: checked.length === 0}, {'loading': isLoading}]"
|
||||||
|
style="margin-top: 7px;"
|
||||||
@click="launchAction"
|
@click="launchAction"
|
||||||
>
|
>
|
||||||
{{ t('components.common.ActionTable.button.go') }}
|
{{ t('components.common.ActionTable.button.go') }}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
|
||||||
<div class="count field">
|
<div class="count field">
|
||||||
<span v-if="selectAll">
|
<span v-if="selectAll">
|
||||||
{{ t('components.common.ActionTable.button.allSelected', objectsData.count) }}
|
{{ t('components.common.ActionTable.button.allSelected', objectsData.count) }}
|
||||||
|
@ -265,11 +266,10 @@ const launchAction = async () => {
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
<div
|
<Alert
|
||||||
v-if="errors.length > 0"
|
v-if="errors.length > 0"
|
||||||
role="alert"
|
red
|
||||||
class="ui negative message"
|
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
{{ t('components.common.ActionTable.header.error') }}
|
{{ t('components.common.ActionTable.header.error') }}
|
||||||
|
@ -282,10 +282,10 @@ const launchAction = async () => {
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</Alert>
|
||||||
<div
|
<Alert
|
||||||
v-if="result"
|
v-if="result"
|
||||||
class="ui positive message"
|
green
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<span>
|
<span>
|
||||||
|
@ -297,8 +297,8 @@ const launchAction = async () => {
|
||||||
name="action-success-footer"
|
name="action-success-footer"
|
||||||
:result="result"
|
:result="result"
|
||||||
/>
|
/>
|
||||||
</div>
|
</Alert>
|
||||||
</div>
|
</Layout>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -8,6 +8,12 @@ import { useStore } from '~/store'
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
import Alert from '~/components/ui/Alert.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
|
||||||
interface Invitation {
|
interface Invitation {
|
||||||
code: string
|
code: string
|
||||||
}
|
}
|
||||||
|
@ -47,14 +53,14 @@ const getUrl = (code: string) => store.getters['instance/absoluteUrl'](router.re
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<form
|
<Layout
|
||||||
|
form
|
||||||
class="ui form"
|
class="ui form"
|
||||||
@submit.prevent="submit"
|
@submit.prevent="submit"
|
||||||
>
|
>
|
||||||
<div
|
<Alert
|
||||||
v-if="errors.length > 0"
|
v-if="errors.length > 0"
|
||||||
role="alert"
|
red
|
||||||
class="ui negative message"
|
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
{{ t('components.manage.users.InvitationForm.header.failure') }}
|
{{ t('components.manage.users.InvitationForm.header.failure') }}
|
||||||
|
@ -67,31 +73,31 @@ const getUrl = (code: string) => store.getters['instance/absoluteUrl'](router.re
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</Alert>
|
||||||
<div class="inline fields">
|
<div class="inline fields">
|
||||||
<div class="ui field">
|
<Input
|
||||||
<label for="invitation-code">{{ t('components.manage.users.InvitationForm.label.invite') }}</label>
|
|
||||||
<input
|
|
||||||
v-model="code"
|
v-model="code"
|
||||||
for="invitation-code"
|
for="invitation-code"
|
||||||
name="code"
|
name="code"
|
||||||
type="text"
|
type="text"
|
||||||
|
:label="t('components.manage.users.InvitationForm.label.invite')"
|
||||||
:placeholder="labels.placeholder"
|
:placeholder="labels.placeholder"
|
||||||
>
|
>
|
||||||
</div>
|
<template #input-right>
|
||||||
<div class="ui field">
|
<Button
|
||||||
<button
|
primary
|
||||||
:class="['ui', {loading: isLoading}, 'button']"
|
:class="[{loading: isLoading}]"
|
||||||
:disabled="isLoading"
|
:disabled="isLoading"
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
{{ t('components.manage.users.InvitationForm.button.new') }}
|
{{ t('components.manage.users.InvitationForm.button.new') }}
|
||||||
</button>
|
</Button>
|
||||||
|
</template>
|
||||||
|
</Input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</form>
|
<Spacer :size="16" />
|
||||||
<div v-if="invitations.length > 0">
|
<div v-if="invitations.length > 0">
|
||||||
<div class="ui hidden divider" />
|
|
||||||
<table class="ui ui basic table">
|
<table class="ui ui basic table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -118,12 +124,14 @@ const getUrl = (code: string) => store.getters['instance/absoluteUrl'](router.re
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<button
|
<Spacer :size="8"/>
|
||||||
class="ui basic button"
|
<Button
|
||||||
|
destructive
|
||||||
|
icon="bi-trash"
|
||||||
@click="invitations.length = 0"
|
@click="invitations.length = 0"
|
||||||
>
|
>
|
||||||
{{ t('components.manage.users.InvitationForm.button.clear') }}
|
{{ t('components.manage.users.InvitationForm.button.clear') }}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -11,7 +11,11 @@ import moment from 'moment'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import ActionTable from '~/components/common/ActionTable.vue'
|
import ActionTable from '~/components/common/ActionTable.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
|
||||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
import useOrdering from '~/composables/navigation/useOrdering'
|
import useOrdering from '~/composables/navigation/useOrdering'
|
||||||
|
@ -100,19 +104,23 @@ const labels = computed(() => ({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<Layout
|
||||||
<div class="ui inline form">
|
form
|
||||||
<div class="fields">
|
class="ui inline form"
|
||||||
|
>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="invitations-search">{{ t('components.manage.users.InvitationsTable.label.search') }}</label>
|
<label for="invitations-search">{{ t('components.manage.users.InvitationsTable.label.search') }}</label>
|
||||||
<input
|
<Input
|
||||||
id="invitations-search"
|
id="invitations-search"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
|
search
|
||||||
name="search"
|
name="search"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="labels.searchPlaceholder"
|
:placeholder="labels.searchPlaceholder"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="invitations-ordering">{{ t('components.manage.users.InvitationsTable.ordering.label') }}</label>
|
<label for="invitations-ordering">{{ t('components.manage.users.InvitationsTable.ordering.label') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -147,15 +155,12 @@ const labels = computed(() => ({
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
</Layout>
|
||||||
<div class="dimmable">
|
<div class="dimmable">
|
||||||
<div
|
<Loader
|
||||||
v-if="isLoading"
|
v-if="isLoading"
|
||||||
class="ui active inverted dimmer"
|
/>
|
||||||
>
|
|
||||||
<div class="ui loader" />
|
|
||||||
</div>
|
|
||||||
<action-table
|
<action-table
|
||||||
v-if="result"
|
v-if="result"
|
||||||
:objects-data="result"
|
:objects-data="result"
|
||||||
|
@ -224,17 +229,14 @@ const labels = computed(() => ({
|
||||||
</action-table>
|
</action-table>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<pagination
|
<Pagination
|
||||||
v-if="result && result.count > paginateBy"
|
v-if="result && result.count > paginateBy"
|
||||||
v-model:current="page"
|
v-model:current="page"
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
:paginate-by="paginateBy"
|
||||||
:total="result.count"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
<span v-if="result && result.results.length > 0">
|
||||||
{{ t('components.manage.users.InvitationsTable.pagination.results', { start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count }, result.results.length) }}
|
{{ t('components.manage.users.InvitationsTable.pagination.results', { start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count }, result.results.length) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -10,7 +10,11 @@ import { useI18n } from 'vue-i18n'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import ActionTable from '~/components/common/ActionTable.vue'
|
import ActionTable from '~/components/common/ActionTable.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
|
||||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
|
@ -102,19 +106,25 @@ const labels = computed(() => ({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<Layout
|
||||||
<div class="ui inline form">
|
form
|
||||||
|
class="ui form"
|
||||||
|
>
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="users-search">{{ t('components.manage.users.UsersTable.label.search') }}</label>
|
<Input
|
||||||
<input
|
|
||||||
id="users-search"
|
id="users-search"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
|
search
|
||||||
|
:label="t('components.manage.users.UsersTable.label.search')"
|
||||||
name="search"
|
name="search"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="labels.searchPlaceholder"
|
:placeholder="labels.searchPlaceholder"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<Spacer :size="16" />
|
||||||
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="users-ordering">{{ t('components.manage.users.UsersTable.ordering.label') }}</label>
|
<label for="users-ordering">{{ t('components.manage.users.UsersTable.ordering.label') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -146,7 +156,7 @@ const labels = computed(() => ({
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
</div>
|
||||||
<div class="dimmable">
|
<div class="dimmable">
|
||||||
<div
|
<div
|
||||||
|
@ -257,17 +267,15 @@ const labels = computed(() => ({
|
||||||
</action-table>
|
</action-table>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<pagination
|
<Pagination
|
||||||
v-if="result && result.count > paginateBy"
|
v-if="result && result.count > paginateBy"
|
||||||
v-model:current="page"
|
v-model:current="page"
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
:paginate-by="paginateBy"
|
||||||
:total="result.count"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
<span v-if="result && result.results.length > 0">
|
||||||
{{ t('components.manage.users.UsersTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}, result.results.length) }}
|
{{ t('components.manage.users.UsersTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}, result.results.length) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Tabs from '~/components/ui/Tabs.vue'
|
||||||
|
import Tab from '~/components/ui/Tab.vue'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const labels = computed(() => ({
|
const labels = computed(() => ({
|
||||||
|
@ -11,28 +15,22 @@ const labels = computed(() => ({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<Layout
|
||||||
v-title="labels.manageUsers"
|
v-title="labels.manageUsers"
|
||||||
class="main"
|
main
|
||||||
|
stack
|
||||||
>
|
>
|
||||||
<nav
|
<Tabs>
|
||||||
class="ui secondary pointing menu"
|
<Tab
|
||||||
role="navigation"
|
:title="t('views.admin.users.Base.link.users')"
|
||||||
:aria-label="labels.secondaryMenu"
|
|
||||||
>
|
|
||||||
<router-link
|
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.users.users.list'}"
|
:to="{name: 'manage.users.users.list'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.users.Base.link.users') }}
|
|
||||||
</router-link>
|
<Tab
|
||||||
<router-link
|
:title="t('views.admin.users.Base.link.invitations')"
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.users.invitations.list'}"
|
:to="{name: 'manage.users.invitations.list'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.users.Base.link.invitations') }}
|
</Tabs>
|
||||||
</router-link>
|
|
||||||
</nav>
|
|
||||||
<router-view :key="$route.fullPath" />
|
<router-view :key="$route.fullPath" />
|
||||||
</div>
|
</Layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue