fix: streamline admin UI with common save actions

pull/663/head
Nicolas Giard 6 years ago
parent ed7d3ab540
commit 5066167163

@ -20,6 +20,9 @@
v-list-tile(to='/pages') v-list-tile(to='/pages')
v-list-tile-avatar: v-icon insert_drive_file v-list-tile-avatar: v-icon insert_drive_file
v-list-tile-title {{ $t('admin:pages.title') }} v-list-tile-title {{ $t('admin:pages.title') }}
v-list-tile-action
v-chip(small, disabled, color='grey lighten-4')
.caption.grey--text 123
v-list-tile(to='/theme') v-list-tile(to='/theme')
v-list-tile-avatar: v-icon palette v-list-tile-avatar: v-icon palette
v-list-tile-title {{ $t('admin:theme.title') }} v-list-tile-title {{ $t('admin:theme.title') }}
@ -32,9 +35,8 @@
v-list-tile-avatar: v-icon perm_identity v-list-tile-avatar: v-icon perm_identity
v-list-tile-title {{ $t('admin:users.title') }} v-list-tile-title {{ $t('admin:users.title') }}
v-list-tile-action v-list-tile-action
.justify-end v-chip(small, disabled, color='grey lighten-4')
v-chip(small, disabled, color='grey lighten-4') .caption.grey--text 1
.caption.grey--text 1
v-divider.my-2 v-divider.my-2
v-subheader.pl-4 {{ $t('admin:nav.modules') }} v-subheader.pl-4 {{ $t('admin:nav.modules') }}
v-list-tile(to='/auth') v-list-tile(to='/auth')
@ -158,11 +160,14 @@ export default {
} }
} }
.admin-header-icon { .admin-header {
position: absolute; display: flex;
top: 1rem; justify-content: flex-start;
right: 1rem; align-items: center;
&-title {
margin-left: 1rem;
}
} }
</style> </style>

@ -1,65 +1,66 @@
<template lang='pug'> <template lang='pug'>
v-card(flat) v-container(fluid, grid-list-lg)
v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') call_split v-flex(xs12)
.headline.blue--text.text--darken-2 API .admin-header
.subheading.grey--text Manage keys to access the API v-icon(size='80', color='grey lighten-2') call_split
v-card .admin-header-title
v-card-title .headline.blue--text.text--darken-2 API
v-btn(color='green', dark) .subheading.grey--text Manage keys to access the API
v-icon(left) power_settings_new v-spacer
| Enable API v-btn(outline, color='grey', large)
v-btn(color='primary', dark) v-icon refresh
v-icon(left) add v-btn(color='green', dark, depressed, large)
| New API Key v-icon(left) power_settings_new
v-btn(icon) | Enable API
v-icon.grey--text refresh v-btn(color='primary', depressed, large)
v-spacer v-icon(left) add
v-text-field(append-icon='search', label='Search', single-line, hide-details, v-model='search') | New API Key
v-data-table( v-card.mt-3
v-model='selected' v-data-table(
:items='items', v-model='selected'
:headers='headers', :items='items',
:search='search', :headers='headers',
:pagination.sync='pagination', :search='search',
:rows-per-page-items='[15]' :pagination.sync='pagination',
select-all, :rows-per-page-items='[15]'
hide-actions, select-all,
disable-initial-sort hide-actions,
) disable-initial-sort
template(slot='headers', slot-scope='props') )
tr template(slot='headers', slot-scope='props')
th(width='50') tr
th.text-xs-right( th(width='50')
width='80' th.text-xs-right(
:class='[`column sortable`, pagination.descending ? `desc` : `asc`, pagination.sortBy === `id` ? `active` : ``]' width='80'
@click='changeSort(`id`)' :class='[`column sortable`, pagination.descending ? `desc` : `asc`, pagination.sortBy === `id` ? `active` : ``]'
) @click='changeSort(`id`)'
v-icon(small) arrow_upward )
| ID v-icon(small) arrow_upward
th.text-xs-left( | ID
v-for='header in props.headers' th.text-xs-left(
:key='header.text' v-for='header in props.headers'
:width='header.width' :key='header.text'
:class='[`column sortable`, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]' :width='header.width'
@click='changeSort(header.value)' :class='[`column sortable`, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]'
) @click='changeSort(header.value)'
| {{ header.text }} )
v-icon(small) arrow_upward | {{ header.text }}
template(slot='items', slot-scope='props') v-icon(small) arrow_upward
tr(:active='props.selected') template(slot='items', slot-scope='props')
td tr(:active='props.selected')
v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected') td
td.text-xs-right {{ props.item.id }} v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected')
td {{ props.item.name }} td.text-xs-right {{ props.item.id }}
td {{ props.item.key }} td {{ props.item.name }}
td {{ props.item.createdOn }} td {{ props.item.key }}
td {{ props.item.updatedOn }} td {{ props.item.createdOn }}
td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz td {{ props.item.updatedOn }}
template(slot='no-data') td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz
v-alert(icon='warning', :value='true') No users to display! template(slot='no-data')
.text-xs-center.py-2 v-alert(icon='warning', :value='true') No users to display!
v-pagination(v-model='pagination.page', :length='pages') .text-xs-center.py-2
v-pagination(v-model='pagination.page', :length='pages')
</template> </template>
<script> <script>

@ -1,122 +1,124 @@
<template lang='pug'> <template lang='pug'>
v-card(tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"') v-container(fluid, grid-list-lg)
.pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') lock_outline v-flex(xs12)
.headline.primary--text Authentication .admin-header
.subheading.grey--text Configure the authentication settings of your wiki v-icon(size='80', color='grey lighten-2') lock_outline
v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows) .admin-header-title
v-tab(key='settings'): v-icon settings .headline.primary--text Authentication
v-tab(v-for='strategy in activeStrategies', :key='strategy.key') {{ strategy.title }} .subheading.grey--text Configure the authentication settings of your wiki
v-spacer
v-btn(outline, color='grey', @click='refresh', large)
v-icon refresh
v-btn(color='primary', @click='save', depressed, large)
v-icon(left) chevron_right
span Apply Configuration
v-tab-item(key='settings', :transition='false', :reverse-transition='false') v-card.mt-3
v-card.pa-3(flat, tile) v-tabs(color='grey darken-2', fixed-tabs, slider-color='white', show-arrows, dark)
.body-2.grey--text.text--darken-1 Select which authentication strategies to enable: v-tab(key='settings'): v-icon settings
.caption.grey--text.pb-2 Some strategies require additional configuration in their dedicated tab (when selected). v-tab(v-for='strategy in activeStrategies', :key='strategy.key') {{ strategy.title }}
v-form
v-checkbox.my-0(
v-for='strategy in strategies'
v-model='strategy.isEnabled'
:key='strategy.key'
:label='strategy.title'
color='primary'
:disabled='strategy.key === `local`'
hide-details
)
v-tab-item(v-for='(strategy, n) in activeStrategies', :key='strategy.key', :transition='false', :reverse-transition='false') v-tab-item(key='settings', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile) v-card.pa-3(flat, tile)
v-form .body-2.grey--text.text--darken-1 Select which authentication strategies to enable:
.authlogo .caption.grey--text.pb-2 Some strategies require additional configuration in their dedicated tab (when selected).
img(:src='strategy.logo', :alt='strategy.title') v-form
v-subheader.pl-0 {{strategy.title}} v-checkbox.my-0(
.caption {{strategy.description}} v-for='strategy in strategies'
.caption: a(:href='strategy.website') {{strategy.website}} v-model='strategy.isEnabled'
v-divider.mt-3 :key='strategy.key'
v-subheader.pl-0 Strategy Configuration :label='strategy.title'
.body-1.ml-3(v-if='!strategy.config || strategy.config.length < 1') This strategy has no configuration options you can modify. color='primary'
template(v-else, v-for='cfg in strategy.config') :disabled='strategy.key === `local`'
v-select( hide-details
v-if='cfg.value.type === "string" && cfg.value.enum' )
outline
background-color='grey lighten-2'
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch.mb-3(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
)
v-text-field(
v-else
outline
background-color='grey lighten-2'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-divider.mt-3
v-subheader.pl-0 Registration
.pr-3
v-switch.ml-3(
v-model='strategy.selfRegistration'
label='Allow self-registration'
color='primary'
hint='Allow any user successfully authorized by the strategy to access the wiki.'
persistent-hint
)
v-combobox.ml-3.mt-3(
label='Limit to specific email domains'
v-model='strategy.domainWhitelist'
prepend-icon='mail_outline'
outline
background-color='grey lighten-2'
persistent-hint
deletable-chips
clearable
multiple
chips
)
v-autocomplete.ml-3(
outline
background-color='grey lighten-2'
:items='groups'
item-text='name'
item-value='id'
label='Assign to group'
v-model='strategy.autoEnrollGroups'
prepend-icon='people'
hint='Automatically assign new users to these groups.'
persistent-hint
deletable-chips
clearable
multiple
chips
)
v-card-chin
v-btn(color='primary', @click='save')
v-icon(left) chevron_right
span Apply Configuration
v-spacer
v-btn(icon, @click='refresh')
v-icon.grey--text refresh
v-tab-item(v-for='(strategy, n) in activeStrategies', :key='strategy.key', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile)
v-form
.authlogo
img(:src='strategy.logo', :alt='strategy.title')
v-subheader.pl-0 {{strategy.title}}
.caption {{strategy.description}}
.caption: a(:href='strategy.website') {{strategy.website}}
v-divider.mt-3
v-subheader.pl-0 Strategy Configuration
.body-1.ml-3(v-if='!strategy.config || strategy.config.length < 1') This strategy has no configuration options you can modify.
template(v-else, v-for='cfg in strategy.config')
v-select(
v-if='cfg.value.type === "string" && cfg.value.enum'
outline
background-color='grey lighten-2'
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch.mb-3(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
)
v-text-field(
v-else
outline
background-color='grey lighten-2'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-divider.mt-3
v-subheader.pl-0 Registration
.pr-3
v-switch.ml-3(
v-model='strategy.selfRegistration'
label='Allow self-registration'
color='primary'
hint='Allow any user successfully authorized by the strategy to access the wiki.'
persistent-hint
)
v-combobox.ml-3.mt-3(
label='Limit to specific email domains'
v-model='strategy.domainWhitelist'
prepend-icon='mail_outline'
outline
background-color='grey lighten-2'
persistent-hint
deletable-chips
clearable
multiple
chips
)
v-autocomplete.ml-3(
outline
background-color='grey lighten-2'
:items='groups'
item-text='name'
item-value='id'
label='Assign to group'
v-model='strategy.autoEnrollGroups'
prepend-icon='people'
hint='Automatically assign new users to these groups.'
persistent-hint
deletable-chips
clearable
multiple
chips
)
</template> </template>
<script> <script>

@ -1,84 +1,94 @@
<template lang='pug'> <template lang='pug'>
v-card(flat) v-container(fluid, grid-list-lg)
v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') favorite v-flex(xs12)
.headline.primary--text {{ $t('admin:contribute.title') }} .admin-header
.subheading.grey--text {{ $t('admin:contribute.subtitle') }} v-icon(size='80', color='grey lighten-2') favorite
v-card.pa-3 .admin-header-title
i18next.body-1.pl-3(path='admin:contribute.openSource', tag='div') .headline.primary--text {{ $t('admin:contribute.title') }}
v-icon(color='red') favorite .subheading.grey--text {{ $t('admin:contribute.subtitle') }}
a(href='https://requarks.io', target='_blank') requarks.io v-spacer
a(href='https://github.com/Requarks/wiki/graphs/contributors', target='_blank') {{ $t('admin:contribute.openSourceContributors') }} v-btn(depressed, color='primary', href='https://opencollective.com/wikijs', large)
.body-1.pt-3.pl-3 {{ $t('admin:contribute.needYourHelp') }} v-icon(left) local_atm
v-divider.mt-3 span {{ $t('admin:contribute.makeADonation') }}
v-subheader {{ $t('admin:contribute.fundOurWork') }} v-card.mt-3
.body-1.pl-3 {{ $t('admin:contribute.openCollective') }} v-card-text
v-card-actions.ml-2 i18next.body-1.pl-3(path='admin:contribute.openSource', tag='div')
v-btn(depressed, color='primary', href='https://opencollective.com/wikijs') v-icon(color='red') favorite
v-icon(left) local_atm a(href='https://requarks.io', target='_blank') requarks.io
span {{ $t('admin:contribute.makeADonation') }} a(href='https://github.com/Requarks/wiki/graphs/contributors', target='_blank') {{ $t('admin:contribute.openSourceContributors') }}
.body-1.mt-3.pl-3 {{ $t('admin:contribute.tshirts') }} .body-1.pt-3.pl-3 {{ $t('admin:contribute.needYourHelp') }}
v-card-actions.ml-2 v-divider.mt-3
v-btn(outline, color='primary', href='https://wikijs.threadless.com') v-subheader {{ $t('admin:contribute.fundOurWork') }}
v-icon(left) shopping_cart .body-1.pl-3 {{ $t('admin:contribute.openCollective') }}
span {{ $t('admin:contribute.shop') }} v-card-actions.ml-2
v-divider.mt-3 v-btn(outline, color='primary', href='https://opencollective.com/wikijs')
v-subheader {{ $t('admin:contribute.contribute') }} v-icon(left) local_atm
.body-1.pl-3 span {{ $t('admin:contribute.makeADonation') }}
ul .body-1.mt-3.pl-3 {{ $t('admin:contribute.tshirts') }}
i18next(path='admin:contribute.submitAnIdea', tag='li') v-card-actions.ml-2
a(href='https://requests.requarks.io/wiki', target='_blank') {{ $t('admin:contribute.submitAnIdeaLink') }} v-btn(outline, color='primary', href='https://wikijs.threadless.com')
i18next(path='admin:contribute.foundABug', tag='li') v-icon(left) shopping_cart
a(href='https://github.com/Requarks/wiki/issues', target='_blank') Github span {{ $t('admin:contribute.shop') }}
i18next(path='admin:contribute.helpTranslate', tag='li') v-divider.mt-3
a(href='https://gitter.im/Requarks/wiki', target='_blank') Gitter v-subheader {{ $t('admin:contribute.contribute') }}
v-divider.mt-3 .body-1.pl-3
v-subheader {{ $t('admin:contribute.spreadTheWord') }} ul
.body-1.pl-3 i18next(path='admin:contribute.submitAnIdea', tag='li')
ul a(href='https://requests.requarks.io/wiki', target='_blank') {{ $t('admin:contribute.submitAnIdeaLink') }}
li {{ $t('admin:contribute.talkToFriends') }} i18next(path='admin:contribute.foundABug', tag='li')
i18next(path='admin:contribute.followUsOnTwitter', tag='li') a(href='https://github.com/Requarks/wiki/issues', target='_blank') Github
a(href='https://twitter.com/requarks', target='_blank') Twitter i18next(path='admin:contribute.helpTranslate', tag='li')
v-card a(href='https://gitter.im/Requarks/wiki', target='_blank') Gitter
v-toolbar(color='teal', dense, dark) v-divider.mt-3
.subheading Sponsors v-subheader {{ $t('admin:contribute.spreadTheWord') }}
v-list(two-line, dense) .body-1.pl-3
template(v-for='(sponsor, idx) in sponsors') ul
v-list-tile(:key='sponsor.id') li {{ $t('admin:contribute.talkToFriends') }}
v-list-tile-avatar i18next(path='admin:contribute.followUsOnTwitter', tag='li')
img(v-if='sponsor.image', :src='sponsor.image') a(href='https://twitter.com/requarks', target='_blank') Twitter
v-avatar(v-else, color='teal', size='40') v-toolbar(color='teal', dense, dark)
span.white--text.subheading {{sponsor.name[0].toUpperCase()}} .subheading Sponsors
v-list-tile-content v-spacer
v-list-tile-title {{sponsor.name}} v-btn(outline, small, href='https://opencollective.com/wikijs/order/1273') Become a Sponsor
v-list-tile-sub-title {{sponsor.description}} v-list(two-line, dense)
v-list-tile-action(v-if='sponsor.twitter') template(v-for='(sponsor, idx) in sponsors')
v-btn(icon, :href='sponsor.twitter', target='_blank') v-list-tile(:key='sponsor.id')
icon-twitter(fillColor='#9e9e9e') v-list-tile-avatar
v-list-tile-action(v-if='sponsor.website') img(v-if='sponsor.image', :src='sponsor.image')
v-btn(icon, :href='sponsor.website', target='_blank') v-avatar(v-else, color='teal', size='40')
v-icon(color='grey') public span.white--text.subheading {{sponsor.name[0].toUpperCase()}}
v-divider(v-if='idx < sponsors.length - 1') v-list-tile-content
v-card v-list-tile-title {{sponsor.name}}
v-toolbar(color='blue-grey', dense, dark) v-list-tile-sub-title {{sponsor.description}}
.subheading Backers v-list-tile-action(v-if='sponsor.twitter')
v-list(two-line, dense) v-btn(icon, :href='sponsor.twitter', target='_blank')
template(v-for='(backer, idx) in backers') icon-twitter(fillColor='#9e9e9e')
v-list-tile(:key='backer.id') v-list-tile-action(v-if='sponsor.website')
v-list-tile-avatar v-btn(icon, :href='sponsor.website', target='_blank')
img(v-if='backer.image', :src='backer.image') v-icon(color='grey') public
v-avatar(v-else, color='blue-grey', size='40') v-divider(v-if='idx < sponsors.length - 1')
span.white--text.subheading {{backer.name[0].toUpperCase()}} v-toolbar(color='blue-grey', dense, dark)
v-list-tile-content .subheading Backers
v-list-tile-title {{backer.name}} v-spacer
v-list-tile-sub-title {{backer.description}} v-btn(outline, small, href='https://opencollective.com/wikijs/order/1272') Become a Backer
v-list-tile-action(v-if='backer.twitter') v-list(two-line, dense)
v-btn(icon, :href='backer.twitter', target='_blank') template(v-for='(backer, idx) in backers')
icon-twitter(fillColor='#9e9e9e') v-list-tile(:key='backer.id')
v-list-tile-action(v-if='backer.website') v-list-tile-avatar
v-btn(icon, :href='backer.website', target='_blank') img(v-if='backer.image', :src='backer.image')
v-icon(color='grey') public v-avatar(v-else, color='blue-grey', size='40')
v-divider(v-if='idx < backers.length - 1') span.white--text.subheading {{backer.name[0].toUpperCase()}}
v-list-tile-content
v-list-tile-title {{backer.name}}
v-list-tile-sub-title {{backer.description}}
v-list-tile-action(v-if='backer.twitter')
v-btn(icon, :href='backer.twitter', target='_blank')
icon-twitter(fillColor='#9e9e9e')
v-list-tile-action(v-if='backer.website')
v-btn(icon, :href='backer.website', target='_blank')
v-icon(color='grey') public
v-divider(v-if='idx < backers.length - 1')
</template> </template>

@ -1,90 +1,92 @@
<template lang='pug'> <template lang='pug'>
v-card(tile, flat :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"') v-container(fluid, grid-list-lg)
.pa-3.pt-4 v-layout(row, wrap)
.headline.primary--text {{ $t('admin:dashboard.title') }} v-flex(xs12)
.subheading.grey--text {{ $t('admin:dashboard.subtitle') }} .admin-header
v-container(fluid, grid-list-lg) v-icon(size='80', color='grey lighten-2') dashboard
v-layout(row, wrap) .admin-header-title
v-flex(xs12 md6 lg4 xl3 d-flex) .headline.primary--text {{ $t('admin:dashboard.title') }}
v-card.primary.dashboard-card(dark) .subheading.grey--text {{ $t('admin:dashboard.subtitle') }}
v-card-text v-flex(xs12 md6 lg4 xl3 d-flex)
v-icon.dashboard-icon insert_drive_file v-card.primary.dashboard-card(dark)
.subheading Pages v-card-text
animated-number.display-1( v-icon.dashboard-icon insert_drive_file
:value='info.pagesTotal' .subheading Pages
:duration='2000' animated-number.display-1(
:formatValue='round' :value='info.pagesTotal'
easing='easeOutQuint' :duration='2000'
) :formatValue='round'
v-flex(xs12 md6 lg4 xl3 d-flex) easing='easeOutQuint'
v-card.indigo.lighten-1.dashboard-card(dark) )
v-card-text v-flex(xs12 md6 lg4 xl3 d-flex)
v-icon.dashboard-icon person v-card.indigo.lighten-1.dashboard-card(dark)
.subheading Users v-card-text
animated-number.display-1( v-icon.dashboard-icon person
:value='info.usersTotal' .subheading Users
:duration='2000' animated-number.display-1(
:formatValue='round' :value='info.usersTotal'
easing='easeOutQuint' :duration='2000'
) :formatValue='round'
v-flex(xs12 md6 lg4 xl3 d-flex) easing='easeOutQuint'
v-card.indigo.lighten-2.dashboard-card(dark)
v-card-text
v-icon.dashboard-icon people
.subheading Groups
animated-number.display-1(
:value='info.groupsTotal'
:duration='2000'
:formatValue='round'
easing='easeOutQuint'
)
v-flex(xs12 md6 lg12 xl3 d-flex)
v-card.dashboard-card(
:class='isLatestVersion ? "teal lighten-2" : "red lighten-2"'
dark
)
v-btn(fab, absolute, right, top, small, light, to='system')
v-icon(v-if='isLatestVersion', color='teal') build
v-icon(v-else, color='red darken-4') get_app
v-card-text
v-icon.dashboard-icon blur_on
.subheading Wiki.js {{info.currentVersion}}
.body-2(v-if='isLatestVersion') You are running the latest version.
.body-2(v-else) A new version is available: {{info.latestVersion}}
v-flex(xs12)
v-card
v-card-title.subheading Recent Pages
v-data-table.pb-2(
:items='recentPages'
hide-actions
hide-headers
) )
template(slot='items' slot-scope='props') v-flex(xs12 md6 lg4 xl3 d-flex)
td(width='20', style='padding-right: 0;'): v-icon insert_drive_file v-card.indigo.lighten-2.dashboard-card(dark)
td v-card-text
.body-2.primary--text {{ props.item.title }} v-icon.dashboard-icon people
.caption.grey--text.text--darken-2 {{ props.item.description }} .subheading Groups
td.caption /{{ props.item.path }} animated-number.display-1(
td.grey--text.text--darken-2(width='250') :value='info.groupsTotal'
.caption: strong Updated {{ props.item.updatedAt | moment('from') }} :duration='2000'
.caption Created {{ props.item.createdAt | moment('calendar') }} :formatValue='round'
v-flex(xs12) easing='easeOutQuint'
v-card
v-card-title.subheading Most Popular Pages
v-data-table.pb-2(
:items='popularPages'
hide-actions
hide-headers
) )
template(slot='items' slot-scope='props') v-flex(xs12 md6 lg12 xl3 d-flex)
td(width='20', style='padding-right: 0;'): v-icon insert_drive_file v-card.dashboard-card(
td :class='isLatestVersion ? "teal lighten-2" : "red lighten-2"'
.body-2.primary--text {{ props.item.title }} dark
.caption.grey--text.text--darken-2 {{ props.item.description }} )
td.caption /{{ props.item.path }} v-btn(fab, absolute, right, top, small, light, to='system')
td.grey--text.text--darken-2(width='250') v-icon(v-if='isLatestVersion', color='teal') build
.caption: strong Updated {{ props.item.updatedAt | moment('from') }} v-icon(v-else, color='red darken-4') get_app
.caption Created {{ props.item.createdAt | moment('calendar') }} v-card-text
v-icon.dashboard-icon blur_on
.subheading Wiki.js {{info.currentVersion}}
.body-2(v-if='isLatestVersion') You are running the latest version.
.body-2(v-else) A new version is available: {{info.latestVersion}}
v-flex(xs12)
v-card
v-card-title.subheading Recent Pages
v-data-table.pb-2(
:items='recentPages'
hide-actions
hide-headers
)
template(slot='items' slot-scope='props')
td(width='20', style='padding-right: 0;'): v-icon insert_drive_file
td
.body-2.primary--text {{ props.item.title }}
.caption.grey--text.text--darken-2 {{ props.item.description }}
td.caption /{{ props.item.path }}
td.grey--text.text--darken-2(width='250')
.caption: strong Updated {{ props.item.updatedAt | moment('from') }}
.caption Created {{ props.item.createdAt | moment('calendar') }}
v-flex(xs12)
v-card
v-card-title.subheading Most Popular Pages
v-data-table.pb-2(
:items='popularPages'
hide-actions
hide-headers
)
template(slot='items' slot-scope='props')
td(width='20', style='padding-right: 0;'): v-icon insert_drive_file
td
.body-2.primary--text {{ props.item.title }}
.caption.grey--text.text--darken-2 {{ props.item.description }}
td.caption /{{ props.item.path }}
td.grey--text.text--darken-2(width='250')
.caption: strong Updated {{ props.item.updatedAt | moment('from') }}
.caption Created {{ props.item.createdAt | moment('calendar') }}
</template> </template>

@ -1,25 +1,31 @@
<template lang='pug'> <template lang='pug'>
div v-container(fluid, grid-list-lg)
v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') weekend v-flex(xs12)
.headline.primary--text Developer Tools .admin-header
.subheading.grey--text ¯\_()_/¯ v-icon(size='80', color='grey lighten-2') weekend
v-tabs( .admin-header-title
v-model='selectedTab' .headline.primary--text Developer Tools
:color='$vuetify.dark ? "primary" : "grey lighten-4"' .subheading.grey--text ¯\_()_/¯
fixed-tabs
:slider-color='$vuetify.dark ? "white" : "primary"' v-card.mt-3
show-arrows v-tabs(
@input='tabChanged' v-model='selectedTab'
) color='grey darken-2'
v-tab(key='0') Graph API Playground fixed-tabs
v-tab(key='1') Graph API Map slider-color='white'
v-tabs-items(v-model='selectedTab') show-arrows
v-tab-item(key='0', :transition='false', :reverse-transition='false') dark
#graphiql @input='tabChanged'
)
v-tab(key='0') Graph API Playground
v-tab(key='1') Graph API Map
v-tabs-items(v-model='selectedTab')
v-tab-item(key='0', :transition='false', :reverse-transition='false')
#graphiql
v-tab-item(key='1', :transition='false', :reverse-transition='false') v-tab-item(key='1', :transition='false', :reverse-transition='false')
#voyager #voyager
</template> </template>

@ -1,33 +1,36 @@
<template lang='pug'> <template lang='pug'>
v-card(tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"') v-container(fluid, grid-list-lg)
.pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') transform v-flex(xs12)
.headline.primary--text Editor .admin-header
.subheading.grey--text Configure the content editor v-icon(size='80', color='grey lighten-2') transform
v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows) .admin-header-title
v-tab(key='settings'): v-icon settings .headline.primary--text Editor
v-tab(key='code') Markdown .subheading.grey--text Configure the content editor
v-spacer
v-btn(outline, color='grey', @click='refresh', large)
v-icon refresh
v-btn(color='primary', @click='save', depressed, large)
v-icon(left) chevron_right
span Apply Configuration
v-tab-item(key='settings', :transition='false', :reverse-transition='false') v-card.mt-3
v-card.pa-3(flat, tile) v-tabs(color='grey darken-2', fixed-tabs, slider-color='white', show-arrows, dark)
.body-2.grey--text.text--darken-1 Select which editors to enable: v-tab(key='settings'): v-icon settings
.caption.grey--text.pb-2 Some editors require additional configuration in their dedicated tab (when selected). v-tab(key='code') Markdown
v-form
v-radio-group(v-model='selectedEditor')
v-radio(v-for='(editor, n) in editors', :key='n', :label='editor.text', :value='editor.value', color='primary')
v-tab-item(key='code', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile)
v-form
v-subheader Editor Configuration
.body-1.ml-3 This editor has no configuration options you can modify.
v-card-chin
v-btn(color='primary', @click='save')
v-icon(left) chevron_right
span Apply Configuration
v-spacer
v-btn(icon, @click='refresh')
v-icon.grey--text refresh
v-tab-item(key='settings', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile)
.body-2.grey--text.text--darken-1 Select which editors to enable:
.caption.grey--text.pb-2 Some editors require additional configuration in their dedicated tab (when selected).
v-form
v-radio-group(v-model='selectedEditor')
v-radio(v-for='(editor, n) in editors', :key='n', :label='editor.text', :value='editor.value', color='primary')
v-tab-item(key='code', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile)
v-form
v-subheader Editor Configuration
.body-1.ml-3 This editor has no configuration options you can modify.
</template> </template>
<script> <script>

@ -1,10 +1,16 @@
<template lang='pug'> <template lang='pug'>
v-container(fluid, fill-height, grid-list-lg) v-container(fluid, grid-list-lg)
v-layout(row wrap) v-layout(row wrap)
v-flex(xs12) v-flex(xs12)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') widgets .admin-header
.headline.primary--text {{ $t('admin:general.title') }} v-icon(size='80', color='grey lighten-2') widgets
.subheading.grey--text {{ $t('admin:general.subtitle') }} .admin-header-title
.headline.primary--text {{ $t('admin:general.title') }}
.subheading.grey--text {{ $t('admin:general.subtitle') }}
v-spacer
v-btn(color='success', depressed, @click='save', large)
v-icon(left) check
span {{$t('common:actions.apply')}}
v-form.pt-3 v-form.pt-3
v-layout(row wrap) v-layout(row wrap)
v-flex(lg6 xs12) v-flex(lg6 xs12)
@ -15,17 +21,48 @@
.subheading {{ $t('admin:general.siteInfo') }} .subheading {{ $t('admin:general.siteInfo') }}
v-subheader General v-subheader General
.px-3.pb-3 .px-3.pb-3
v-text-field(label='Site Title', required, :counter='50', v-model='siteTitle', prepend-icon='public') v-text-field(
outline
background-color='grey lighten-2'
label='Site Title'
required
:counter='50'
v-model='siteTitle'
prepend-icon='public'
)
v-divider v-divider
v-subheader SEO v-subheader SEO
.px-3.pb-3 .px-3.pb-3
v-text-field(label='Site Description', :counter='255', prepend-icon='public') v-text-field(
v-text-field(label='Site Keywords', :counter='255', prepend-icon='public') outline
v-select(label='Meta Robots', chips, tags, :items='metaRobots', v-model='metaRobotsSelection', prepend-icon='public') background-color='grey lighten-2'
label='Site Description'
:counter='255'
prepend-icon='public'
)
v-text-field(
outline
background-color='grey lighten-2'
label='Site Keywords'
:counter='255'
prepend-icon='public'
)
v-select(
outline
background-color='grey lighten-2'
label='Meta Robots'
chips
tags
:items='metaRobots'
v-model='metaRobotsSelection'
prepend-icon='public'
)
v-divider v-divider
v-subheader Analytics v-subheader Analytics
.px-3.pb-3 .px-3.pb-3
v-text-field( v-text-field(
outline
background-color='grey lighten-2'
label='Google Analytics ID' label='Google Analytics ID'
:counter='255' :counter='255'
prepend-icon='public' prepend-icon='public'
@ -36,6 +73,8 @@
v-subheader Footer Copyright v-subheader Footer Copyright
.px-3.pb-3 .px-3.pb-3
v-text-field( v-text-field(
outline
background-color='grey lighten-2'
label='Company / Organization Name' label='Company / Organization Name'
v-model='company' v-model='company'
:counter='255' :counter='255'
@ -43,11 +82,6 @@
persistent-hint persistent-hint
hint='Name to use when displaying copyright notice in the footer. Leave empty to hide.' hint='Name to use when displaying copyright notice in the footer. Leave empty to hide.'
) )
v-card-chin
v-spacer
v-btn(color='primary', @click='save')
v-icon(left) chevron_right
span Save
v-flex(lg6 xs12) v-flex(lg6 xs12)
v-card v-card
v-toolbar(color='primary', dark, dense, flat) v-toolbar(color='primary', dark, dense, flat)
@ -81,11 +115,6 @@
persistent-hint persistent-hint
hint='Uncheck this box if you don\'t want Henry, Wiki.js mascot, to be displayed on client-facing pages.' hint='Uncheck this box if you don\'t want Henry, Wiki.js mascot, to be displayed on client-facing pages.'
) )
v-card-chin
v-spacer
v-btn(color='primary', @click='save')
v-icon(left) chevron_right
span Save
v-card.mt-3 v-card.mt-3
v-toolbar(color='primary', dark, dense, flat) v-toolbar(color='primary', dark, dense, flat)
@ -107,11 +136,6 @@
persistent-hint persistent-hint
hint='Allow users to have their own personal wiki.' hint='Allow users to have their own personal wiki.'
) )
v-card-chin
v-spacer
v-btn(color='primary', @click='save')
v-icon(left) chevron_right
span Save
</template> </template>

@ -1,46 +1,47 @@
<template lang='pug'> <template lang='pug'>
v-card(flat) v-container(fluid, grid-list-lg)
v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4 v-layout(row wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') people v-flex(xs12)
.headline.blue--text.text--darken-2 Groups .admin-header
.subheading.grey--text Manage groups and their permissions v-icon(size='80', color='grey lighten-2') people
v-card .admin-header-title
v-card-title .headline.blue--text.text--darken-2 Groups
v-dialog(v-model='newGroupDialog', max-width='500') .subheading.grey--text Manage groups and their permissions
v-btn(color='primary', dark, slot='activator') v-spacer
v-icon(left) add v-btn(color='grey', outline, @click='refresh', large)
| New Group v-icon refresh
v-card v-dialog(v-model='newGroupDialog', max-width='500')
.dialog-header.is-short New Group v-btn(color='primary', depressed, slot='activator', large)
v-card-text v-icon(left) add
v-text-field(v-model='newGroupName', label='Group Name', autofocus, counter='255', @keyup.enter='createGroup') span New Group
v-card-chin v-card
v-spacer .dialog-header.is-short New Group
v-btn(flat, @click='newGroupDialog = false') Cancel v-card-text
v-btn(color='primary', @click='createGroup') Create v-text-field(v-model='newGroupName', label='Group Name', autofocus, counter='255', @keyup.enter='createGroup')
v-btn(icon, @click='refresh') v-card-chin
v-icon.grey--text refresh v-spacer
v-spacer v-btn(flat, @click='newGroupDialog = false') Cancel
v-text-field(solo, append-icon='search', label='Search', single-line, hide-details, v-model='search') v-btn(color='primary', @click='createGroup') Create
v-data-table( v-card.mt-3
:items='groups' v-data-table(
:headers='headers' :items='groups'
:search='search' :headers='headers'
:pagination.sync='pagination' :search='search'
:rows-per-page-items='[15]' :pagination.sync='pagination'
hide-actions :rows-per-page-items='[15]'
) hide-actions
template(slot='items', slot-scope='props') )
tr.is-clickable(:active='props.selected', @click='$router.push("/groups/" + props.item.id)') template(slot='items', slot-scope='props')
td.text-xs-right {{ props.item.id }} tr.is-clickable(:active='props.selected', @click='$router.push("/groups/" + props.item.id)')
td {{ props.item.name }} td.text-xs-right {{ props.item.id }}
td {{ props.item.userCount }} td {{ props.item.name }}
td {{ props.item.createdAt | moment('calendar') }} td {{ props.item.userCount }}
td {{ props.item.updatedAt | moment('calendar') }} td {{ props.item.createdAt | moment('calendar') }}
template(slot='no-data') td {{ props.item.updatedAt | moment('calendar') }}
v-alert.ma-3(icon='warning', :value='true', outline) No groups to display. template(slot='no-data')
.text-xs-center.py-2(v-if='groups.length > 15') v-alert.ma-3(icon='warning', :value='true', outline) No groups to display.
v-pagination(v-model='pagination.page', :length='pages') .text-xs-center.py-2(v-if='groups.length > 15')
v-pagination(v-model='pagination.page', :length='pages')
</template> </template>
<script> <script>

@ -1,10 +1,16 @@
<template lang='pug'> <template lang='pug'>
v-container(fluid, fill-height, grid-list-lg) v-container(fluid, grid-list-lg)
v-layout(row wrap) v-layout(row, wrap)
v-flex(xs12) v-flex(xs12)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') language .admin-header
.headline.primary--text {{ $t('admin:locale.title') }} v-icon(size='80', color='grey lighten-2') language
.subheading.grey--text {{ $t('admin:locale.subtitle') }} .admin-header-title
.headline.primary--text {{ $t('admin:locale.title') }}
.subheading.grey--text {{ $t('admin:locale.subtitle') }}
v-spacer
v-btn(color='success', depressed, @click='save', large, :loading='loading')
v-icon(left) check
span {{$t('common:actions.apply')}}
v-form.pt-3 v-form.pt-3
v-layout(row wrap) v-layout(row wrap)
v-flex(lg6 xs12) v-flex(lg6 xs12)
@ -14,6 +20,8 @@
.subheading {{ $t('admin:locale.settings') }} .subheading {{ $t('admin:locale.settings') }}
v-card-text v-card-text
v-select( v-select(
outline
background-color='grey lighten-2'
:items='installedLocales' :items='installedLocales'
prepend-icon='language' prepend-icon='language'
v-model='selectedLocale' v-model='selectedLocale'
@ -40,11 +48,6 @@
persistent-hint persistent-hint
:hint='namespacing ? $t("admin:locale.autoUpdate.hintWithNS") : $t("admin:locale.autoUpdate.hint")' :hint='namespacing ? $t("admin:locale.autoUpdate.hintWithNS") : $t("admin:locale.autoUpdate.hint")'
) )
v-card-chin
v-spacer
v-btn(color='primary', :loading='loading', @click='save')
v-icon(left) chevron_right
span {{ $t('common:actions.save') }}
v-card.mt-3 v-card.mt-3
v-toolbar(color='primary', dark, dense, flat) v-toolbar(color='primary', dark, dense, flat)
@ -92,11 +95,6 @@
v-list-tile-sub-title(v-html='data.item.nativeName') v-list-tile-sub-title(v-html='data.item.nativeName')
v-list-tile-action v-list-tile-action
v-checkbox(:input-value='data.tile.props.value', color='primary', value) v-checkbox(:input-value='data.tile.props.value', color='primary', value)
v-card-chin
v-spacer
v-btn(color='primary', :loading='loading', @click='save')
v-icon(left) chevron_right
span {{ $t('common:actions.save') }}
v-flex(lg6 xs12) v-flex(lg6 xs12)
v-card v-card
v-toolbar(color='teal', dark, dense, flat) v-toolbar(color='teal', dark, dense, flat)

@ -1,105 +1,105 @@
<template lang='pug'> <template lang='pug'>
v-card(tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"') v-container(fluid, grid-list-lg)
.pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') graphic_eq v-flex(xs12)
.headline.primary--text Logging .admin-header
.subheading.grey--text Configure the system logger(s) v-icon(size='80', color='grey lighten-2') graphic_eq
v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows) .admin-header-title
v-tab(key='settings'): v-icon settings .headline.primary--text Logging
v-tab(v-for='logger in activeLoggers', :key='logger.key') {{ logger.title }} .subheading.grey--text Configure the system logger(s)
v-spacer
v-btn(outline, color='grey', @click='refresh', large)
v-icon refresh
v-btn(color='black', dark, depressed, @click='toggleConsole', large)
v-icon(left) keyboard
span View Console
v-btn(color='primary', @click='save', depressed, large)
v-icon(left) chevron_right
span Apply Configuration
v-tab-item(key='settings', :transition='false', :reverse-transition='false') v-card.mt-3
v-card.pa-3(flat, tile) v-tabs(color='grey darken-2', fixed-tabs, slider-color='white', show-arrows, dark)
.body-2.grey--text.text--darken-1 Select which logging service to enable: v-tab(key='settings'): v-icon settings
.caption.grey--text.pb-2 Some loggers require additional configuration in their dedicated tab (when selected). v-tab(v-for='logger in activeLoggers', :key='logger.key') {{ logger.title }}
v-form
v-checkbox.my-0(
v-for='(logger, n) in loggers'
v-model='logger.isEnabled'
:key='logger.key'
:label='logger.title'
color='primary'
hide-details
)
v-tab-item(v-for='(logger, n) in activeLoggers', :key='logger.key', :transition='false', :reverse-transition='false') v-tab-item(key='settings', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile) v-card.pa-3(flat, tile)
v-form .body-2.grey--text.text--darken-1 Select which logging service to enable:
.loggerlogo .caption.grey--text.pb-2 Some loggers require additional configuration in their dedicated tab (when selected).
img(:src='logger.logo', :alt='logger.title') v-form
v-subheader.pl-0 {{logger.title}} v-checkbox.my-0(
.caption {{logger.description}} v-for='(logger, n) in loggers'
.caption: a(:href='logger.website') {{logger.website}} v-model='logger.isEnabled'
v-divider.mt-3 :key='logger.key'
v-subheader.pl-0 Logger Configuration :label='logger.title'
.body-1.ml-3(v-if='!logger.config || logger.config.length < 1') This logger has no configuration options you can modify. color='primary'
template(v-else, v-for='cfg in logger.config') hide-details
v-select(
v-if='cfg.value.type === "string" && cfg.value.enum'
outline
background-color='grey lighten-2'
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
)
v-text-field(
v-else
outline
background-color='grey lighten-2'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-divider.mt-3
v-subheader.pl-0 Log Level
.body-1.ml-3 Select the minimum error level that will be reported to this logger.
v-layout(row)
v-flex(xs12, md6, lg4)
.pt-3
v-select(
single-line
outline
background-color='grey lighten-2'
:items='levels'
label='Level'
v-model='logger.level'
prepend-icon='graphic_eq'
hint='Default: warn'
persistent-hint
) )
v-card-chin v-tab-item(v-for='(logger, n) in activeLoggers', :key='logger.key', :transition='false', :reverse-transition='false')
v-btn(color='primary', @click='save') v-card.pa-3(flat, tile)
v-icon(left) chevron_right v-form
span Apply Configuration .loggerlogo
v-btn(color='black', dark, @click='toggleConsole') img(:src='logger.logo', :alt='logger.title')
v-icon(left) keyboard v-subheader.pl-0 {{logger.title}}
span View Console .caption {{logger.description}}
v-btn(color='black', dark) .caption: a(:href='logger.website') {{logger.website}}
v-icon(left) layers_clear v-divider.mt-3
span Purge Logs v-subheader.pl-0 Logger Configuration
v-spacer .body-1.ml-3(v-if='!logger.config || logger.config.length < 1') This logger has no configuration options you can modify.
v-btn(icon, @click='refresh') template(v-else, v-for='cfg in logger.config')
v-icon.grey--text refresh v-select(
v-if='cfg.value.type === "string" && cfg.value.enum'
outline
background-color='grey lighten-2'
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
)
v-text-field(
v-else
outline
background-color='grey lighten-2'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-divider.mt-3
v-subheader.pl-0 Log Level
.body-1.ml-3 Select the minimum error level that will be reported to this logger.
v-layout(row)
v-flex(xs12, md6, lg4)
.pt-3
v-select(
single-line
outline
background-color='grey lighten-2'
:items='levels'
label='Level'
v-model='logger.level'
prepend-icon='graphic_eq'
hint='Default: warn'
persistent-hint
)
logging-console(v-model='showConsole') logging-console(v-model='showConsole')
</template> </template>

@ -1,15 +1,25 @@
<template lang='pug'> <template lang='pug'>
v-container(fluid, fill-height) v-container(fluid, grid-list-lg)
v-layout(row wrap) v-layout(row wrap)
v-flex(xs12) v-flex(xs12)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') near_me .admin-header
.headline.primary--text {{$t('navigation.title')}} v-icon(size='80', color='grey lighten-2') near_me
.subheading.grey--text {{$t('navigation.subtitle')}} .admin-header-title
.headline.primary--text {{$t('navigation.title')}}
.subheading.grey--text {{$t('navigation.subtitle')}}
v-spacer
v-btn(color='success', depressed, @click='save', large)
v-icon(left) check
span {{$t('common:actions.apply')}}
v-container.pa-0.mt-3(fluid, grid-list-lg) v-container.pa-0.mt-3(fluid, grid-list-lg)
v-layout(row) v-layout(row)
v-flex(style='flex: 0 0 350px;') v-flex(style='flex: 0 0 350px;')
v-card v-card
v-list.primary.py-2(dense, dark) v-list.py-2(dense, dark, :class='navTree.length < 1 ? "grey lighten-4" : "primary"')
v-list-tile(v-if='navTree.length < 1')
v-list-tile-avatar: v-icon(color='grey') explore_off
v-list-tile-content
.caption.grey--text {{$t('navigation.emptyList')}}
draggable(v-model='navTree') draggable(v-model='navTree')
template(v-for='navItem in navTree') template(v-for='navItem in navTree')
v-list-tile( v-list-tile(
@ -48,9 +58,6 @@
v-list-tile(@click='addItem("divider")') v-list-tile(@click='addItem("divider")')
v-list-tile-avatar: v-icon power_input v-list-tile-avatar: v-icon power_input
v-list-tile-title {{$t('navigation.divider')}} v-list-tile-title {{$t('navigation.divider')}}
v-btn.ml-2(color='success', depressed, block, @click='save')
v-icon(left) check
span {{$t('common:actions.save')}}
v-flex v-flex
v-card(v-if='current.kind === "link"') v-card(v-if='current.kind === "link"')
v-toolbar(dense, color='blue', flat, dark) v-toolbar(dense, color='blue', flat, dark)
@ -112,8 +119,8 @@
v-icon(left) delete v-icon(left) delete
span {{$t('navigation.delete', { kind: $t('navigation.divider') })}} span {{$t('navigation.delete', { kind: $t('navigation.divider') })}}
v-card(v-else) v-card(v-else)
v-card-text.grey--text {{$t('navigation.noSelectionText')}} v-card-text.grey--text(v-if='navTree.length > 0') {{$t('navigation.noSelectionText')}}
v-card-text.grey--text(v-else) {{$t('navigation.noItemsText')}}
</template> </template>
<script> <script>

@ -1,37 +1,38 @@
<template lang='pug'> <template lang='pug'>
v-card(flat) v-container(fluid, grid-list-lg)
v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4 v-layout(row wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') insert_drive_file v-flex(xs12)
.headline.blue--text.text--darken-2 Pages .admin-header
.subheading.grey--text Manage pages v-icon(size='80', color='grey lighten-2') insert_drive_file
v-card .admin-header-title
v-card-title .headline.blue--text.text--darken-2 Pages
v-btn(color='primary', dark, slot='activator') .subheading.grey--text Manage pages
v-icon(left) add v-spacer
| New Page v-btn(color='grey', outline, @click='refresh', large)
v-btn(icon, @click='refresh') v-icon.grey--text refresh
v-icon.grey--text refresh v-btn(color='primary', depressed, @click='save', large)
v-spacer v-icon(left) add
v-text-field(solo, append-icon='search', label='Search', single-line, hide-details, v-model='search') span New Page
v-data-table( v-card.mt-3
:items='groups' v-data-table(
:headers='headers' :items='groups'
:search='search' :headers='headers'
:pagination.sync='pagination' :search='search'
:rows-per-page-items='[15]' :pagination.sync='pagination'
hide-actions :rows-per-page-items='[15]'
) hide-actions
template(slot='items', slot-scope='props') )
tr.is-clickable(:active='props.selected', @click='$router.push("/e/" + props.item.id)') template(slot='items', slot-scope='props')
td.text-xs-right {{ props.item.id }} tr.is-clickable(:active='props.selected', @click='$router.push("/e/" + props.item.id)')
td {{ props.item.name }} td.text-xs-right {{ props.item.id }}
td {{ props.item.userCount }} td {{ props.item.name }}
td {{ props.item.createdAt | moment('calendar') }} td {{ props.item.userCount }}
td {{ props.item.updatedAt | moment('calendar') }} td {{ props.item.createdAt | moment('calendar') }}
template(slot='no-data') td {{ props.item.updatedAt | moment('calendar') }}
v-alert.ma-3(icon='warning', :value='true', outline) No pages to display. template(slot='no-data')
.text-xs-center.py-2(v-if='groups.length > 15') v-alert.ma-3(icon='warning', :value='true', outline) No pages to display.
v-pagination(v-model='pagination.page', :length='pages') .text-xs-center.py-2(v-if='groups.length > 15')
v-pagination(v-model='pagination.page', :length='pages')
</template> </template>
<script> <script>

@ -1,119 +1,122 @@
<template lang='pug'> <template lang='pug'>
v-container(fluid, fill-height, grid-list-lg) v-container(fluid, grid-list-lg)
v-layout(row wrap) v-layout(row, wrap)
v-flex(xs12) v-flex(xs12)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') system_update_alt .admin-header
.headline.primary--text Rendering v-icon(size='80', color='grey lighten-2') system_update_alt
.subheading.grey--text Configure how content is rendered .admin-header-title
v-layout.mt-3(row wrap) .headline.primary--text Rendering
v-flex(lg3 xs12) .subheading.grey--text Configure how content is rendered
v-spacer
v-btn(outline, color='grey', @click='refresh', large)
v-icon refresh
v-btn(color='primary', @click='save', depressed, large)
v-icon(left) chevron_right
span Apply Configuration
v-flex(lg3, xs12)
v-toolbar(
color='primary'
dense
flat
dark
)
v-icon.mr-2 line_weight
.subheading Pipeline
v-expansion-panel.adm-rendering-pipeline(v-model='selectedCore')
v-expansion-panel-content(
hide-actions
v-for='core in renderers'
:key='core.key'
)
v-toolbar( v-toolbar(
color='primary' slot='header'
color='blue'
dense dense
flat
dark dark
flat
) )
v-icon.mr-2 line_weight v-spacer
.subheading Pipeline .body-2 {{core.input}}
v-expansion-panel.adm-rendering-pipeline(v-model='selectedCore') v-icon.mx-2 arrow_forward
v-expansion-panel-content( .caption {{core.output}}
hide-actions v-spacer
v-for='core in renderers' v-list.py-0(two-line, dense)
:key='core.key' template(v-for='(rdr, n) in core.children')
) v-list-tile(
v-toolbar( avatar
slot='header' :key='rdr.key'
color='blue' @click='selectRenderer(rdr.key)'
dense :class='currentRenderer.key === rdr.key ? "blue lighten-5" : ""'
dark
flat
) )
v-spacer v-list-tile-avatar
.body-2 {{core.input}} v-icon(:color='currentRenderer.key === rdr.key ? "primary" : "grey"') {{rdr.icon}}
v-icon.mx-2 arrow_forward v-list-tile-content
.caption {{core.output}} v-list-tile-title {{rdr.title}}
v-spacer v-list-tile-sub-title {{rdr.description}}
v-list.py-0(two-line, dense) v-list-tile-avatar
template(v-for='(rdr, n) in core.children') status-indicator(v-if='rdr.isEnabled', positive, pulse)
v-list-tile( status-indicator(v-else, negative, pulse)
avatar v-divider.my-0(v-if='n < core.children.length - 1')
:key='rdr.key'
@click='selectRenderer(rdr.key)'
:class='currentRenderer.key === rdr.key ? "blue lighten-5" : ""'
)
v-list-tile-avatar
v-icon(:color='currentRenderer.key === rdr.key ? "primary" : "grey"') {{rdr.icon}}
v-list-tile-content
v-list-tile-title {{rdr.title}}
v-list-tile-sub-title {{rdr.description}}
v-list-tile-avatar
status-indicator(v-if='rdr.isEnabled', positive, pulse)
status-indicator(v-else, negative, pulse)
v-divider.my-0(v-if='n < core.children.length - 1')
v-flex(lg9 xs12) v-flex(lg9, xs12)
v-card v-card
v-toolbar( v-toolbar(
color='grey darken-1' color='grey darken-1'
dark
flat
dense
)
v-icon.mr-2 {{currentRenderer.icon}}
.subheading {{currentRenderer.title}}
v-spacer
.pt-3.mt-1
v-switch(
dark dark
flat color='white'
dense label='Enabled'
v-model='currentRenderer.isEnabled'
) )
v-icon.mr-2 {{currentRenderer.icon}} v-card-text.pb-4.pt-2.pl-4
.subheading {{currentRenderer.title}} v-subheader.pl-0 Rendering Module Configuration
v-spacer .body-1.ml-3(v-if='!currentRenderer.config || currentRenderer.config.length < 1') This rendering module has no configuration options you can modify.
.pt-3.mt-1 template(v-else, v-for='(cfg, idx) in currentRenderer.config')
v-switch( v-select(
dark v-if='cfg.value.type === "string" && cfg.value.enum'
color='white' outline
label='Enabled' background-color='grey lighten-2'
v-model='currentRenderer.isEnabled' :items='cfg.value.enum'
) :key='cfg.key'
v-card-text.pb-4.pt-2.pl-4 :label='cfg.value.title'
v-subheader.pl-0 Rendering Module Configuration v-model='cfg.value.value'
.body-1.ml-3(v-if='!currentRenderer.config || currentRenderer.config.length < 1') This rendering module has no configuration options you can modify. :hint='cfg.value.hint ? cfg.value.hint : ""'
template(v-else, v-for='(cfg, idx) in currentRenderer.config') persistent-hint
v-select( :class='cfg.value.hint ? "mb-2" : ""'
v-if='cfg.value.type === "string" && cfg.value.enum' )
outline v-switch(
background-color='grey lighten-2' v-else-if='cfg.value.type === "boolean"'
:items='cfg.value.enum' :key='cfg.key'
:key='cfg.key' :label='cfg.value.title'
:label='cfg.value.title' v-model='cfg.value.value'
v-model='cfg.value.value' color='primary'
:hint='cfg.value.hint ? cfg.value.hint : ""' :hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint persistent-hint
:class='cfg.value.hint ? "mb-2" : ""' )
) v-text-field(
v-switch( v-else
v-else-if='cfg.value.type === "boolean"' outline
:key='cfg.key' background-color='grey lighten-2'
:label='cfg.value.title' :key='cfg.key'
v-model='cfg.value.value' :label='cfg.value.title'
color='primary' v-model='cfg.value.value'
:hint='cfg.value.hint ? cfg.value.hint : ""' :hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint persistent-hint
) :class='cfg.value.hint ? "mb-2" : ""'
v-text-field( )
v-else v-divider.my-3(v-if='idx < currentRenderer.config.length - 1')
outline v-card-chin
background-color='grey lighten-2' v-spacer
:key='cfg.key' .caption.pr-3.grey--text Module: {{ currentRenderer.key }}
:label='cfg.value.title'
v-model='cfg.value.value'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-divider.my-3(v-if='idx < currentRenderer.config.length - 1')
v-card-chin
v-btn(
color='primary'
)
v-icon(left) check
span Apply Configuration
v-spacer
.caption.pr-3.grey--text Module: {{ currentRenderer.key }}
</template> </template>
<script> <script>

@ -1,87 +1,89 @@
<template lang='pug'> <template lang='pug'>
v-card(tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"') v-container(fluid, grid-list-lg)
.pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') search v-flex(xs12)
.headline.primary--text Search Engine .admin-header
.subheading.grey--text Configure the search capabilities of your wiki v-icon(size='80', color='grey lighten-2') search
v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows) .admin-header-title
v-tab(key='settings'): v-icon settings .headline.primary--text Search Engine
v-tab(v-for='engine in activeEngines', :key='engine.key') {{ engine.title }} .subheading.grey--text Configure the search capabilities of your wiki
v-spacer
v-btn(outline, color='grey', @click='refresh', large)
v-icon refresh
v-btn(color='black', dark, large, depressed)
v-icon(left) cached
span Rebuild Index
v-btn(color='primary', @click='save', depressed, large)
v-icon(left) chevron_right
span Apply Configuration
v-tab-item(key='settings', :transition='false', :reverse-transition='false') v-card.mt-3
v-card.pa-3(flat, tile) v-tabs(color='grey darken-2', fixed-tabs, slider-color='white', show-arrows, dark)
.body-2.grey--text.text--darken-1 Select which search engine to enable: v-tab(key='settings'): v-icon settings
.caption.grey--text.pb-2 Some search engines require additional configuration in their dedicated tab (when selected). v-tab(v-for='engine in activeEngines', :key='engine.key') {{ engine.title }}
v-form
v-radio-group(v-model='selectedEngine')
v-radio.my-1(
v-for='(engine, n) in engines'
:key='engine.key'
:label='engine.title'
:value='engine.key'
color='primary'
hide-details
)
v-tab-item(v-for='(engine, n) in activeEngines', :key='engine.key', :transition='false', :reverse-transition='false') v-tab-item(key='settings', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile) v-card.pa-3(flat, tile)
v-form .body-2.grey--text.text--darken-1 Select which search engine to enable:
.enginelogo .caption.grey--text.pb-2 Some search engines require additional configuration in their dedicated tab (when selected).
img(:src='engine.logo', :alt='engine.title') v-form
v-subheader.pl-0 {{engine.title}} v-radio-group(v-model='selectedEngine')
.caption {{engine.description}} v-radio.my-1(
.caption: a(:href='engine.website') {{engine.website}} v-for='(engine, n) in engines'
v-divider.mt-3 :key='engine.key'
v-subheader.pl-0 Engine Configuration :label='engine.title'
.body-1.ml-3(v-if='!engine.config || engine.config.length < 1') This engine has no configuration options you can modify. :value='engine.key'
template(v-else, v-for='cfg in logger.config') color='primary'
v-select( hide-details
v-if='cfg.value.type === "string" && cfg.value.enum' )
outline
background-color='grey lighten-2'
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
)
v-text-field(
v-else
outline
background-color='grey lighten-2'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-card-chin
v-btn(color='primary', @click='save')
v-icon(left) chevron_right
span Apply Configuration
v-btn(color='black', dark)
v-icon(left) refresh
| Rebuild Index
v-spacer
v-btn(icon, @click='refresh')
v-icon.grey--text refresh
v-tab-item(v-for='(engine, n) in activeEngines', :key='engine.key', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile)
v-form
.enginelogo
img(:src='engine.logo', :alt='engine.title')
v-subheader.pl-0 {{engine.title}}
.caption {{engine.description}}
.caption: a(:href='engine.website') {{engine.website}}
v-divider.mt-3
v-subheader.pl-0 Engine Configuration
.body-1.ml-3(v-if='!engine.config || engine.config.length < 1') This engine has no configuration options you can modify.
template(v-else, v-for='cfg in logger.config')
v-select(
v-if='cfg.value.type === "string" && cfg.value.enum'
outline
background-color='grey lighten-2'
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
)
v-text-field(
v-else
outline
background-color='grey lighten-2'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
</template> </template>
<script> <script>

@ -1,110 +1,112 @@
<template lang='pug'> <template lang='pug'>
v-card(tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"') v-container(fluid, grid-list-lg)
.pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') storage v-flex(xs12)
.headline.primary--text Storage .admin-header
.subheading.grey--text Set backup and sync targets for your content v-icon(size='80', color='grey lighten-2') storage
v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows) .admin-header-title
v-tab(key='settings'): v-icon settings .headline.primary--text Storage
v-tab(v-for='tgt in activeTargets', :key='tgt.key') {{ tgt.title }} .subheading.grey--text Set backup and sync targets for your content
v-spacer
v-btn(outline, color='grey', @click='refresh', large)
v-icon refresh
v-btn(color='primary', @click='save', depressed, large)
v-icon(left) chevron_right
span Apply Configuration
v-tab-item(key='settings', :transition='false', :reverse-transition='false') v-card.mt-3
v-card.pa-3(flat, tile) v-tabs(color='grey darken-2', fixed-tabs, slider-color='white', show-arrows, dark)
.body-2.grey--text.text--darken-1 Select which storage targets to enable: v-tab(key='settings'): v-icon settings
.caption.grey--text.pb-2 Some storage targets require additional configuration in their dedicated tab (when selected). v-tab(v-for='tgt in activeTargets', :key='tgt.key') {{ tgt.title }}
v-form
v-checkbox.my-0(
v-for='tgt in targets'
v-model='tgt.isEnabled'
:key='tgt.key'
:label='tgt.title'
color='primary'
hide-details
)
v-tab-item(v-for='(tgt, n) in activeTargets', :key='tgt.key', :transition='false', :reverse-transition='false') v-tab-item(key='settings', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile) v-card.pa-3(flat, tile)
v-form .body-2.grey--text.text--darken-1 Select which storage targets to enable:
.targetlogo .caption.grey--text.pb-2 Some storage targets require additional configuration in their dedicated tab (when selected).
img(:src='tgt.logo', :alt='tgt.title') v-form
v-subheader.pl-0 {{tgt.title}} v-checkbox.my-0(
.caption {{tgt.description}} v-for='tgt in targets'
.caption: a(:href='tgt.website') {{tgt.website}} v-model='tgt.isEnabled'
v-divider.mt-3 :key='tgt.key'
v-subheader.pl-0 Target Configuration :label='tgt.title'
.body-1.ml-3(v-if='!tgt.config || tgt.config.length < 1') This storage target has no configuration options you can modify. color='primary'
template(v-else, v-for='cfg in tgt.config') hide-details
v-select( )
v-if='cfg.value.type === "string" && cfg.value.enum'
outline
background-color='grey lighten-2'
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
)
v-text-field(
v-else
outline
background-color='grey lighten-2'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-divider.mt-3
v-subheader.pl-0 Sync Direction
.body-1.ml-3 Choose how content synchronization is handled for this storage target.
.pr-3.pt-3
v-radio-group.ml-3.py-0(v-model='tgt.mode')
v-radio(
label='Bi-directional'
color='primary'
value='sync'
)
v-radio(
label='Push to target'
color='primary'
value='push'
)
v-radio(
label='Pull from target'
color='primary'
value='pull'
)
.body-1.ml-3
strong Bi-directional
.pb-3 In bi-directional mode, content is first pulled from the storage target. Any newer content overwrites local content. New content since last sync is then pushed to the storage target, overwriting any content on target if present.
strong Push to target
.pb-3 Content is always pushed to the storage target, overwriting any existing content. This is the default and safest choice for backup scenarios.
strong Pull from target
.pb-3 Content is always pulled from the storage target, overwriting any local content which already exists. This choice is usually reserved for single-use content import. Caution with this option as any local content will always be overwritten!
v-card-chin
v-btn(color='primary', @click='save')
v-icon(left) chevron_right
span Apply Configuration
v-spacer
v-btn(icon, @click='refresh')
v-icon.grey--text refresh
v-tab-item(v-for='(tgt, n) in activeTargets', :key='tgt.key', :transition='false', :reverse-transition='false')
v-card.pa-3(flat, tile)
v-form
.targetlogo
img(:src='tgt.logo', :alt='tgt.title')
v-subheader.pl-0 {{tgt.title}}
.caption {{tgt.description}}
.caption: a(:href='tgt.website') {{tgt.website}}
v-divider.mt-3
v-subheader.pl-0 Target Configuration
.body-1.ml-3(v-if='!tgt.config || tgt.config.length < 1') This storage target has no configuration options you can modify.
template(v-else, v-for='cfg in tgt.config')
v-select(
v-if='cfg.value.type === "string" && cfg.value.enum'
outline
background-color='grey lighten-2'
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
)
v-text-field(
v-else
outline
background-color='grey lighten-2'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='settings_applications'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-divider.mt-3
v-subheader.pl-0 Sync Direction
.body-1.ml-3 Choose how content synchronization is handled for this storage target.
.pr-3.pt-3
v-radio-group.ml-3.py-0(v-model='tgt.mode')
v-radio(
label='Bi-directional'
color='primary'
value='sync'
)
v-radio(
label='Push to target'
color='primary'
value='push'
)
v-radio(
label='Pull from target'
color='primary'
value='pull'
)
.body-1.ml-3
strong Bi-directional
.pb-3 In bi-directional mode, content is first pulled from the storage target. Any newer content overwrites local content. New content since last sync is then pushed to the storage target, overwriting any content on target if present.
strong Push to target
.pb-3 Content is always pushed to the storage target, overwriting any existing content. This is the default and safest choice for backup scenarios.
strong Pull from target
.pb-3 Content is always pulled from the storage target, overwriting any local content which already exists. This choice is usually reserved for single-use content import. Caution with this option as any local content will always be overwritten!
</template> </template>
<script> <script>

@ -1,10 +1,12 @@
<template lang='pug'> <template lang='pug'>
v-container(fluid, fill-height, grid-list-lg) v-container(fluid, grid-list-lg)
v-layout(row, wrap) v-layout(row, wrap)
v-flex(xs12) v-flex(xs12)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') tune .admin-header
.headline.primary--text {{ $t('admin:system.title') }} v-icon(size='80', color='grey lighten-2') tune
.subheading.grey--text {{ $t('admin:system.subtitle') }} .admin-header-title
.headline.primary--text {{ $t('admin:system.title') }}
.subheading.grey--text {{ $t('admin:system.subtitle') }}
v-layout.mt-3(row wrap) v-layout.mt-3(row wrap)
v-flex(lg6 xs12) v-flex(lg6 xs12)
v-card v-card

@ -1,10 +1,16 @@
<template lang='pug'> <template lang='pug'>
v-container(fluid, fill-height, grid-list-lg) v-container(fluid, grid-list-lg)
v-layout(row wrap) v-layout(row wrap)
v-flex(xs12) v-flex(xs12)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') palette .admin-header
.headline.primary--text Theme v-icon(size='80', color='grey lighten-2') palette
.subheading.grey--text Modify the look &amp; feel of your wiki .admin-header-title
.headline.primary--text Theme
.subheading.grey--text Modify the look &amp; feel of your wiki
v-spacer
v-btn(color='success', depressed, @click='save', large, :loading='loading')
v-icon(left) check
span {{$t('common:actions.apply')}}
v-form.pt-3 v-form.pt-3
v-layout(row wrap) v-layout(row wrap)
v-flex(lg6 xs12) v-flex(lg6 xs12)
@ -15,6 +21,8 @@
v-card-text v-card-text
v-select( v-select(
:items='themes' :items='themes'
outline
background-color='grey lighten-2'
prepend-icon='palette' prepend-icon='palette'
v-model='selectedTheme' v-model='selectedTheme'
label='Site Theme' label='Site Theme'
@ -35,11 +43,6 @@
persistent-hint persistent-hint
hint='Not recommended for accessibility. May not be supported by all themes.' hint='Not recommended for accessibility. May not be supported by all themes.'
) )
v-card-chin
v-spacer
v-btn(color='primary', :loading='loading', @click='save')
v-icon(left) chevron_right
span Save
v-card.mt-3 v-card.mt-3
v-toolbar(color='primary', dark, dense, flat) v-toolbar(color='primary', dark, dense, flat)
v-toolbar-title v-toolbar-title
@ -57,7 +60,7 @@
) )
v-textarea.mt-2( v-textarea.mt-2(
v-model='injectHeader' v-model='injectHeader'
label='Site Header' label='Head HTML Injection'
outline outline
background-color='grey lighten-1' background-color='grey lighten-1'
color='primary' color='primary'
@ -67,7 +70,7 @@
) )
v-textarea.mt-2( v-textarea.mt-2(
v-model='injectFooter' v-model='injectFooter'
label='Site Footer' label='Body HTML Injection'
outline outline
background-color='grey lighten-1' background-color='grey lighten-1'
color='primary' color='primary'
@ -75,11 +78,6 @@
hint='HTML code to be injected just before the closing body tag' hint='HTML code to be injected just before the closing body tag'
auto-grow auto-grow
) )
v-card-chin
v-spacer
v-btn(color='primary', :loading='loading', @click='save')
v-icon(left) chevron_right
span Save
v-flex(lg6 xs12) v-flex(lg6 xs12)
v-card v-card
v-toolbar(color='teal', dark, dense, flat) v-toolbar(color='teal', dark, dense, flat)

@ -1,66 +1,67 @@
<template lang='pug'> <template lang='pug'>
v-card(flat) v-container(fluid, grid-list-lg)
v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') perm_identity v-flex(xs12)
.headline.blue--text.text--darken-2 Users .admin-header
.subheading.grey--text Manage users v-icon(size='80', color='grey lighten-2') perm_identity
v-card .admin-header-title
v-card-title .headline.blue--text.text--darken-2 Users
v-btn(color='primary', dark) .subheading.grey--text Manage users
v-icon(left) add v-spacer
| New User v-btn(outline, color='grey', large)
v-btn(color='primary', dark) v-icon refresh
v-icon(left) lock_outline v-btn(color='primary', large, depressed)
| Authorize User v-icon(left) lock_outline
v-btn(icon) span Authorize User
v-icon.grey--text refresh v-btn(color='primary', large, depressed)
v-spacer v-icon(left) add
v-text-field(append-icon='search', label='Search', single-line, hide-details, v-model='search') span New User
v-data-table( v-card.mt-3
v-model='selected' v-data-table(
:items='items', v-model='selected'
:headers='headers', :items='items',
:search='search', :headers='headers',
:pagination.sync='pagination', :search='search',
:rows-per-page-items='[15]' :pagination.sync='pagination',
select-all, :rows-per-page-items='[15]'
hide-actions, select-all,
disable-initial-sort hide-actions,
) disable-initial-sort
template(slot='headers', slot-scope='props') )
tr template(slot='headers', slot-scope='props')
th(width='50') tr
th.text-xs-right( th(width='50')
width='80' th.text-xs-right(
:class='[`column sortable`, pagination.descending ? `desc` : `asc`, pagination.sortBy === `id` ? `active` : ``]' width='80'
@click='changeSort(`id`)' :class='[`column sortable`, pagination.descending ? `desc` : `asc`, pagination.sortBy === `id` ? `active` : ``]'
) @click='changeSort(`id`)'
v-icon(small) arrow_upward )
| ID v-icon(small) arrow_upward
th.text-xs-left( | ID
v-for='header in props.headers' th.text-xs-left(
:key='header.text' v-for='header in props.headers'
:width='header.width' :key='header.text'
:class='[`column sortable`, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]' :width='header.width'
@click='changeSort(header.value)' :class='[`column sortable`, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]'
) @click='changeSort(header.value)'
| {{ header.text }} )
v-icon(small) arrow_upward | {{ header.text }}
template(slot='items', slot-scope='props') v-icon(small) arrow_upward
tr(:active='props.selected') template(slot='items', slot-scope='props')
td tr(:active='props.selected')
v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected') td
td.text-xs-right {{ props.item.id }} v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected')
td {{ props.item.email }} td.text-xs-right {{ props.item.id }}
td {{ props.item.name }} td {{ props.item.email }}
td {{ props.item.provider }} td {{ props.item.name }}
td {{ props.item.createdOn }} td {{ props.item.provider }}
td {{ props.item.updatedOn }} td {{ props.item.createdOn }}
td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz td {{ props.item.updatedOn }}
template(slot='no-data') td: v-btn(icon): v-icon.grey--text.text--darken-1 more_horiz
v-alert(icon='warning', :value='true') No users to display! template(slot='no-data')
.text-xs-center.py-2 v-alert(icon='warning', :value='true') No users to display!
v-pagination(v-model='pagination.page', :length='pages') .text-xs-center.py-2
v-pagination(v-model='pagination.page', :length='pages')
</template> </template>
<script> <script>

@ -1,142 +1,147 @@
<template lang='pug'> <template lang='pug'>
div v-container(fluid, grid-list-lg)
v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4 v-layout(row, wrap)
.admin-header-icon: v-icon(size='80', color='grey lighten-2') build v-flex(xs12)
.headline.primary--text Utilities .admin-header
.subheading.grey--text Maintenance and troubleshooting tools v-icon(size='80', color='grey lighten-2') build
v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows) .admin-header-title
v-tab(key='tools') Tools .headline.primary--text Utilities
v-tab(key='cache') Cache .subheading.grey--text Maintenance and troubleshooting tools
v-tab(key='telemetry') Telemetry
v-tab(key='support') Support
v-tab-item(key='tools', :transition='false', :reverse-transition='false') v-card.mt-3
v-container(fluid, grid-list-lg, :class='$vuetify.dark ? "" : "grey lighten-5"') v-tabs(color='grey darken-2', fixed-tabs, slider-color='white', show-arrows, dark)
v-layout(row, wrap) v-tab(key='tools') Tools
v-flex(xs12, sm6) v-tab(key='cache') Cache
v-card v-tab(key='telemetry') Telemetry
v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat) v-tab(key='support') Support
v-toolbar-title
.subheading Authentication
v-subheader Flush User Sessions
v-card-text.pt-0.pl-4
.body-1 This will cause all users to be logged out. You will need to log back in after the operation.
v-btn(depressed).ml-0
v-icon(left, color='grey') build
span Proceed
v-divider.my-0
v-subheader Reset Guest User
v-card-text.pt-0.pl-4
.body-1 This will reset the guest user to its default parameters and permissions.
v-btn(depressed).ml-0
v-icon(left, color='grey') build
span Proceed
v-card.mt-3
v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
v-toolbar-title
.subheading Modules
v-subheader Rescan Modules
v-card-text.pt-0.pl-4
.body-1 Look for new modules on disk. Existing configurations will be merged.
v-select.mt-3(
v-model='rescanModuleType'
:items='moduleTypes'
label='Modules Type'
outline
background-color='grey lighten-1'
hide-details
dense
)
v-btn.ml-0(color='primary', depressed, dark)
v-icon(left) chevron_right
span Rescan
v-flex(xs12, sm6)
v-card
v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
v-toolbar-title
.subheading Maintenance Mode
v-card-text
.body-1 Maintenance mode restrict access to the site to administrators only, regarless of current permissions.
v-btn.mt-3.ml-0(color='orange darken-2', depressed, dark)
icon-home-alert.mr-2(fillColor='#FFFFFF')
| Turn On Maintenance Mode
v-card.mt-3
v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
v-toolbar-title
.subheading Graph Endpoint
v-card-text
.body-1 The Graph API Endpoint from which remote resources like locales, themes and plugins are fetched.
.caption.red--text Do not change unless you know what you're doing!
v-text-field.my-2(outline, hide-details, background-color='grey lighten-1', label='Graph Endpoint', value='https://graph.requarks.io')
v-btn.ml-0(color='primary', depressed, dark)
v-icon(left) chevron_right
span Save
v-tab-item(key='telemetry', :transition='false', :reverse-transition='false') v-tab-item(key='tools', :transition='false', :reverse-transition='false')
v-card v-container.pa-2(fluid, grid-list-sm, :class='$vuetify.dark ? "" : "grey lighten-5"')
v-form v-layout(row, wrap)
v-card-text v-flex(xs12, sm6)
v-subheader What is telemetry? v-card
.body-1.pl-3 Telemetry allows the developers of Wiki.js to improve the software by collecting basic anonymized data about its usage and the host info. #[br] This is entirely optional and #[strong absolutely no] private data (such as content or personal data) is collected. v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
.body-1.pt-3.pl-3 For maximum privacy, a random client ID is generated every time Wiki.js is started. This ID is used to group requests together while keeping complete anonymity. v-toolbar-title
v-divider.my-3 .subheading Authentication
v-subheader What is collected? v-subheader Flush User Sessions
.body-1.pl-3 When telemetry is enabled, only the following data is transmitted: v-card-text.pt-0.pl-4
v-list(dense) .body-1 This will cause all users to be logged out. You will need to log back in after the operation.
v-list-tile v-btn(depressed).ml-0
v-list-tile-avatar: v-icon info_outline v-icon(left, color='grey') build
v-list-tile-content: v-list-tile-title.caption Version of Wiki.js installed span Proceed
v-list-tile v-divider.my-0
v-list-tile-avatar: v-icon info_outline v-subheader Reset Guest User
v-list-tile-content: v-list-tile-title.caption Basic OS information (version, CPU cores, RAM available) v-card-text.pt-0.pl-4
v-list-tile .body-1 This will reset the guest user to its default parameters and permissions.
v-list-tile-avatar: v-icon info_outline v-btn(depressed).ml-0
v-list-tile-content: v-list-tile-title.caption Crash debug data v-icon(left, color='grey') build
v-list-tile span Proceed
v-list-tile-avatar: v-icon info_outline v-card.mt-3
v-list-tile-content: v-list-tile-title.caption Setup analytics (step reached) v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
.body-2.pl-3 v-toolbar-title
v-divider.my-3 .subheading Modules
v-subheader Settings v-subheader Rescan Modules
.pl-3 v-card-text.pt-0.pl-4
v-switch.mt-0( .body-1 Look for new modules on disk. Existing configurations will be merged.
v-model='telemetry', v-select.mt-3(
label='Enable Telemetry', v-model='rescanModuleType'
:value='true', :items='moduleTypes'
color='primary', label='Modules Type'
hint='Allow Wiki.js to transmit telemetry data.', outline
persistent-hint background-color='grey lighten-1'
) hide-details
.subheading.mt-3.grey--text.text--darken-1 Client ID dense
.body-1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx )
v-card-chin v-btn.ml-0(color='primary', depressed, dark)
v-btn(color='primary') v-icon(left) chevron_right
v-icon(left) chevron_right span Rescan
| Save Changes v-flex(xs12, sm6)
v-spacer v-card
v-btn(outline, color='grey') v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
v-icon(left) autorenew v-toolbar-title
span Reset Client ID .subheading Maintenance Mode
v-card-text
.body-1 Maintenance mode restrict access to the site to administrators only, regarless of current permissions.
v-btn.mt-3.ml-0(color='orange darken-2', depressed, dark)
icon-home-alert.mr-2(fillColor='#FFFFFF')
| Turn On Maintenance Mode
v-card.mt-3
v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
v-toolbar-title
.subheading Graph Endpoint
v-card-text
.body-1 The Graph API Endpoint from which remote resources like locales, themes and plugins are fetched.
.caption.red--text Do not change unless you know what you're doing!
v-text-field.my-2(outline, hide-details, background-color='grey lighten-1', label='Graph Endpoint', value='https://graph.requarks.io')
v-btn.ml-0(color='primary', depressed, dark)
v-icon(left) chevron_right
span Save
v-tab-item(key='telemetry', :transition='false', :reverse-transition='false')
v-card
v-form
v-card-text
v-subheader What is telemetry?
.body-1.pl-3 Telemetry allows the developers of Wiki.js to improve the software by collecting basic anonymized data about its usage and the host info. #[br] This is entirely optional and #[strong absolutely no] private data (such as content or personal data) is collected.
.body-1.pt-3.pl-3 For maximum privacy, a random client ID is generated every time Wiki.js is started. This ID is used to group requests together while keeping complete anonymity.
v-divider.my-3
v-subheader What is collected?
.body-1.pl-3 When telemetry is enabled, only the following data is transmitted:
v-list(dense)
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Version of Wiki.js installed
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Basic OS information (version, CPU cores, RAM available)
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Crash debug data
v-list-tile
v-list-tile-avatar: v-icon info_outline
v-list-tile-content: v-list-tile-title.caption Setup analytics (step reached)
.body-2.pl-3
v-divider.my-3
v-subheader Settings
.pl-3
v-switch.mt-0(
v-model='telemetry',
label='Enable Telemetry',
:value='true',
color='primary',
hint='Allow Wiki.js to transmit telemetry data.',
persistent-hint
)
.subheading.mt-3.grey--text.text--darken-1 Client ID
.body-1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
v-card-chin
v-btn(color='primary')
v-icon(left) chevron_right
| Save Changes
v-spacer
v-btn(outline, color='grey')
v-icon(left) autorenew
span Reset Client ID
v-tab-item(key='support', :transition='false', :reverse-transition='false') v-tab-item(key='support', :transition='false', :reverse-transition='false')
v-card.pa-3 v-card.pa-3
v-subheader Report a bug v-subheader Report a bug
.body-1.pl-3 Bugs can be reported using GitHub issues on the project repository page. .body-1.pl-3 Bugs can be reported using GitHub issues on the project repository page.
v-btn.ml-3.mt-3(depressed, dark, color='grey darken-2', href='https://github.com/Requarks/wiki/issues', target='_blank') v-btn.ml-3.mt-3(depressed, dark, color='grey darken-2', href='https://github.com/Requarks/wiki/issues', target='_blank')
icon-github-circle.mr-3(fillColor='#FFFFFF') icon-github-circle.mr-3(fillColor='#FFFFFF')
span Submit an issue span Submit an issue
v-divider.my-3 v-divider.my-3
v-subheader Suggest a New Feature / Enhancement v-subheader Suggest a New Feature / Enhancement
.body-1.pl-3 Have an idea for a new feature or something that could be improved? .body-1.pl-3 Have an idea for a new feature or something that could be improved?
v-btn.ml-3.mt-3(depressed, dark, color='indigo', href='https://requests.requarks.io/wiki', target='_blank') v-btn.ml-3.mt-3(depressed, dark, color='indigo', href='https://requests.requarks.io/wiki', target='_blank')
v-icon(left) lightbulb_outline v-icon(left) lightbulb_outline
span Submit an idea span Submit an idea
v-divider.my-3 v-divider.my-3
v-subheader Questions / Comments v-subheader Questions / Comments
.body-1.pl-3 Join our gitter channel. We are very active and friendly! .body-1.pl-3 Join our gitter channel. We are very active and friendly!
v-btn.ml-3.mt-3(depressed, dark, color='pink', href='https://gitter.im/Requarks/wiki', target='_blank') v-btn.ml-3.mt-3(depressed, dark, color='pink', href='https://gitter.im/Requarks/wiki', target='_blank')
v-icon(left) chat v-icon(left) chat
span Launch Gitter span Launch Gitter
</template> </template>

Loading…
Cancel
Save