ソースを参照

feat: admin dark mode

NGPixel 7 年 前
コミット
1d2d1c66c1

+ 1 - 0
client/app.js

@@ -80,6 +80,7 @@ Vue.component('login', () => import(/* webpackMode: "eager" */ './components/log
 Vue.component('nav-header', () => import(/* webpackMode: "eager" */ './components/nav-header.vue'))
 Vue.component('profile', () => import(/* webpackChunkName: "profile" */ './components/profile.vue'))
 Vue.component('setup', () => import(/* webpackChunkName: "setup" */ './components/setup.vue'))
+Vue.component('v-card-chin', () => import(/* webpackMode: "eager" */ './components/common/v-card-chin.vue'))
 
 let bootstrap = () => {
   // ====================================

+ 35 - 22
client/components/admin.vue

@@ -1,77 +1,81 @@
 <template lang='pug'>
-  v-app.admin
+  v-app(:dark='darkMode').admin
     nav-header
     v-navigation-drawer.pb-0(v-model='adminDrawerShown', app, fixed, clipped, left, permanent)
       v-list(dense)
         v-list-tile.pt-2(to='/dashboard')
-          v-list-tile-action: v-icon dashboard
+          v-list-tile-avatar: v-icon dashboard
           v-list-tile-title Dashboard
         v-divider.my-2
         v-subheader Site
         v-list-tile(to='/general')
-          v-list-tile-action: v-icon widgets
+          v-list-tile-avatar: v-icon widgets
           v-list-tile-title General
         v-list-tile(to='/locale')
-          v-list-tile-action: v-icon language
+          v-list-tile-avatar: v-icon language
           v-list-tile-title Locale
         v-list-tile(to='/stats')
-          v-list-tile-action: v-icon show_chart
+          v-list-tile-avatar: v-icon show_chart
           v-list-tile-title Statistics
         v-list-tile(to='/theme')
-          v-list-tile-action: v-icon palette
+          v-list-tile-avatar: v-icon palette
           v-list-tile-title Theme
         v-divider.my-2
         v-subheader Users
         v-list-tile(to='/groups')
-          v-list-tile-action: v-icon people
+          v-list-tile-avatar: v-icon people
           v-list-tile-title Groups
         v-list-tile(to='/users')
-          v-list-tile-action: v-icon perm_identity
+          v-list-tile-avatar: v-icon perm_identity
           v-list-tile-title Users
+          v-list-tile-action
+            .justify-end
+              v-chip(small, disabled, color='grey lighten-4')
+                .caption.grey--text 1
         v-divider.my-2
         v-subheader Modules
         v-list-tile(to='/auth')
-          v-list-tile-action: v-icon lock_outline
+          v-list-tile-avatar: v-icon lock_outline
           v-list-tile-title Authentication
         v-list-tile(to='/rendering')
-          v-list-tile-action: v-icon system_update_alt
+          v-list-tile-avatar: v-icon system_update_alt
           v-list-tile-title Content Rendering
         v-list-tile(to='/editor')
-          v-list-tile-action: v-icon transform
+          v-list-tile-avatar: v-icon transform
           v-list-tile-title Editor
         v-list-tile(to='/logging')
-          v-list-tile-action: v-icon graphic_eq
+          v-list-tile-avatar: v-icon graphic_eq
           v-list-tile-title Logging
         v-list-tile(to='/search')
-          v-list-tile-action: v-icon search
+          v-list-tile-avatar: v-icon search
           v-list-tile-title Search Engine
         v-list-tile(to='/storage')
-          v-list-tile-action: v-icon storage
+          v-list-tile-avatar: v-icon storage
           v-list-tile-title Storage
         v-divider.my-2
         v-subheader System
         v-list-tile(to='/api')
-          v-list-tile-action: v-icon call_split
+          v-list-tile-avatar: v-icon call_split
           v-list-tile-title API Access
         v-list-tile(to='/system')
-          v-list-tile-action: v-icon tune
+          v-list-tile-avatar: v-icon tune
           v-list-tile-title System Info
         v-list-tile(to='/utilities')
-          v-list-tile-action: v-icon build
+          v-list-tile-avatar: v-icon build
           v-list-tile-title Utilities
         v-list-tile(to='/dev')
-          v-list-tile-action: v-icon weekend
+          v-list-tile-avatar: v-icon weekend
           v-list-tile-title Developer Tools
         v-divider.my-2
         v-list-tile(to='/contribute')
-          v-list-tile-action: v-icon favorite
+          v-list-tile-avatar: v-icon favorite
           v-list-tile-title Contribute to Wiki.js
 
     v-content
       transition(name='admin-router')
         router-view
 
-    v-footer.py-2.justify-center(app, absolute, color='grey lighten-3', inset, height='auto')
+    v-footer.py-2.justify-center(app, absolute, :color='darkMode ? "" : "grey lighten-3"', inset, height='auto')
       .caption.grey--text.text--darken-1 Powered by Wiki.js
 
     v-snackbar(
@@ -90,6 +94,12 @@
 import VueRouter from 'vue-router'
 import { mapState } from 'vuex'
 
+import adminStore from '@/store/admin'
+
+/* global WIKI */
+
+WIKI.$store.registerModule('admin', adminStore)
+
 const router = new VueRouter({
   mode: 'history',
   base: '/a',
@@ -113,7 +123,7 @@ const router = new VueRouter({
     { path: '/system', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-system.vue') },
     { path: '/utilities', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-utilities.vue') },
     { path: '/dev', component: () => import(/* webpackChunkName: "admin-dev" */ './admin/admin-dev.vue') },
-    { path: '/contribute', component: () => import(/* webpackChunkName: "admin-dev" */ './admin/admin-contribute.vue') }
+    { path: '/contribute', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-contribute.vue') }
   ]
 })
 
@@ -124,7 +134,10 @@ export default {
     }
   },
   computed: {
-    ...mapState(['notification']),
+    ...mapState({
+      notification: state => state.notification,
+      darkMode: state => state.admin.theme.dark
+    }),
     notificationState: {
       get() { return this.notification.isActive },
       set(newState) { this.$store.commit('updateNotificationState', newState) }

+ 1 - 1
client/components/admin/admin-api.vue

@@ -1,6 +1,6 @@
 <template lang='pug'>
   v-card(flat)
-    v-card(flat, color='grey lighten-5').pa-3.pt-4
+    v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
       .headline.blue--text.text--darken-2 API
       .subheading.grey--text Manage keys to access the API
     v-card

+ 3 - 4
client/components/admin/admin-auth.vue

@@ -1,9 +1,9 @@
 <template lang='pug'>
-  v-card(tile, color='grey lighten-5')
+  v-card(tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"')
     .pa-3.pt-4
       .headline.primary--text Authentication
       .subheading.grey--text Configure the authentication settings of your wiki
-    v-tabs(color='grey lighten-4', fixed-tabs, slider-color='primary', show-arrows)
+    v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows)
       v-tab(key='settings'): v-icon settings
       v-tab(v-for='strategy in activeStrategies', :key='strategy.key') {{ strategy.title }}
 
@@ -41,8 +41,7 @@
             v-text-field.ml-3(label='Limit to specific email domains', prepend-icon='mail_outline')
             v-text-field.ml-3(label='Assign to group', prepend-icon='people')
 
-    v-divider.my-0
-    v-card-actions.grey.lighten-4
+    v-card-chin
       v-btn(color='primary')
         v-icon(left) chevron_right
         span Save

+ 26 - 28
client/components/admin/admin-contribute.vue

@@ -1,33 +1,31 @@
 <template lang='pug'>
   v-card(flat)
-    v-card(color='grey lighten-5')
-      .pa-3.pt-4
-        .headline.primary--text Contribute
-        .subheading.grey--text Help support Wiki.js development and operations
-
-      v-card.pa-3
-        .body-1.pl-3 Wiki.js is a #[strong free and open-source software] brought to you with #[v-icon(color='red') favorite] by #[a(href='https://requarks.io', target='_blank') requarks.io] and #[a(href='https://github.com/Requarks/wiki/graphs/contributors', target='_blank') contributors].
-        .body-1.pt-3.pl-3 We need your help to keep improving the software and run the various associated services (e.g. hosting and networking).
-        v-divider
-        v-subheader Fund our work
-        .body-1.pl-3 Wiki.js is part of the Open Collective initiative. You can contribute financially by making a monthly or one-time donation:
-        v-card-actions.mt-3.ml-2
-          v-btn(depressed, color='primary', href='https://opencollective.com/wikijs')
-            v-icon(left) local_atm
-            | Make a donation
-        v-divider
-        v-subheader Contribute
-        .body-1.pl-3
-          ul
-            li Submit an idea or vote on a proposed one on the #[a(href='https://requests.requarks.io/wiki', target='_blank') feature requests board].
-            li Found a bug? Submit an issue on #[a(href='https://github.com/Requarks/wiki/issues', target='_blank') Github].
-            li Help translate Wiki.js in your language. Let us know on #[a(href='https://gitter.im/Requarks/wiki', target='_blank') Gitter].
-        v-divider
-        v-subheader Spread the word
-        .body-1.pl-3
-          ul
-            li Talk to your friends and colleagues about how awesome Wiki.js is!
-            li Follow us on #[a(href='https://twitter.com/requarks', target='_blank') Twitter].
+    v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
+      .headline.primary--text Contribute
+      .subheading.grey--text Help support Wiki.js development and operations
+    v-card.pa-3
+      .body-1.pl-3 Wiki.js is a #[strong free and open-source software] brought to you with #[v-icon(color='red') favorite] by #[a(href='https://requarks.io', target='_blank') requarks.io] and #[a(href='https://github.com/Requarks/wiki/graphs/contributors', target='_blank') contributors].
+      .body-1.pt-3.pl-3 We need your help to keep improving the software and run the various associated services (e.g. hosting and networking).
+      v-divider
+      v-subheader Fund our work
+      .body-1.pl-3 Wiki.js is part of the Open Collective initiative. You can contribute financially by making a monthly or one-time donation:
+      v-card-actions.mt-3.ml-2
+        v-btn(depressed, color='primary', href='https://opencollective.com/wikijs')
+          v-icon(left) local_atm
+          | Make a donation
+      v-divider
+      v-subheader Contribute
+      .body-1.pl-3
+        ul
+          li Submit an idea or vote on a proposed one on the #[a(href='https://requests.requarks.io/wiki', target='_blank') feature requests board].
+          li Found a bug? Submit an issue on #[a(href='https://github.com/Requarks/wiki/issues', target='_blank') Github].
+          li Help translate Wiki.js in your language. Let us know on #[a(href='https://gitter.im/Requarks/wiki', target='_blank') Gitter].
+      v-divider
+      v-subheader Spread the word
+      .body-1.pl-3
+        ul
+          li Talk to your friends and colleagues about how awesome Wiki.js is!
+          li Follow us on #[a(href='https://twitter.com/requarks', target='_blank') Twitter].
 
 </template>
 

+ 19 - 13
client/components/admin/admin-dev.vue

@@ -1,18 +1,24 @@
 <template lang='pug'>
-  v-card(flat)
-    v-card(color='grey lighten-5')
-      .pa-3.pt-4
-        .headline.primary--text Developer Tools
-        .subheading.grey--text ¯\_(ツ)_/¯
-      v-tabs(v-model='selectedTab', color='grey lighten-4', fixed-tabs, slider-color='primary', show-arrows, @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
+  div
+    v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
+      .headline.primary--text Developer Tools
+      .subheading.grey--text ¯\_(ツ)_/¯
+    v-tabs(
+      v-model='selectedTab'
+      :color='$vuetify.dark ? "primary" : "grey lighten-4"'
+      fixed-tabs
+      :slider-color='$vuetify.dark ? "white" : "primary"'
+      show-arrows
+      @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')
-          #voyager
+      v-tab-item(key='1', :transition='false', :reverse-transition='false')
+        #voyager
 
 </template>
 

+ 22 - 23
client/components/admin/admin-editor.vue

@@ -1,29 +1,28 @@
 <template lang='pug'>
   v-card(flat)
-    v-card(color='grey lighten-5')
-      .pa-3.pt-4
-        .headline.primary--text Editor
-        .subheading.grey--text Configure the content editor
-      v-tabs(color='grey lighten-4', fixed-tabs, slider-color='primary', show-arrows)
-        v-tab(key='settings'): v-icon settings
-        v-tab(key='code') Markdown
+    v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
+      .headline.primary--text Editor
+      .subheading.grey--text Configure the content editor
+    v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows)
+      v-tab(key='settings'): v-icon settings
+      v-tab(key='code') Markdown
 
-        v-tab-item(key='settings', :transition='false', :reverse-transition='false')
-          v-card.pa-3
-            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-divider
-              v-btn(color='primary')
-                v-icon(left) chevron_right
-                | Set Editor
-              v-btn(icon)
-                v-icon.grey--text refresh
-        v-tab-item(key='code', :transition='false', :reverse-transition='false')
-          v-card.pa-3
-            v-form
-              v-subheader Editor Configuration
-              .body-1 This editor has no configuration options you can modify.
+      v-tab-item(key='settings', :transition='false', :reverse-transition='false')
+        v-card.pa-3
+          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-divider
+            v-btn(color='primary')
+              v-icon(left) chevron_right
+              | Set Editor
+            v-btn(icon)
+              v-icon.grey--text refresh
+      v-tab-item(key='code', :transition='false', :reverse-transition='false')
+        v-card.pa-3
+          v-form
+            v-subheader Editor Configuration
+            .body-1 This editor has no configuration options you can modify.
 
 </template>
 

+ 1 - 2
client/components/admin/admin-general.vue

@@ -21,8 +21,7 @@
                     v-text-field(label='Site Description', :counter='255', prepend-icon='public')
                     v-text-field(label='Site Keywords', :counter='255', prepend-icon='public')
                     v-select(label='Meta Robots', chips, tags, :items='metaRobots', v-model='metaRobotsSelection', prepend-icon='public')
-                  v-divider.my-0
-                  v-card-actions.grey.lighten-4
+                  v-card-chin
                     v-spacer
                     v-btn(color='primary')
                       v-icon(left) chevron_right

+ 2 - 2
client/components/admin/admin-groups-edit.vue

@@ -1,10 +1,10 @@
 <template lang='pug'>
   v-card
-    v-card(flat, color='grey lighten-5').pa-3.pt-4
+    v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
       .headline.blue--text.text--darken-2 Edit Group
       .subheading.grey--text {{name}}
       v-btn(color='primary', fab, absolute, bottom, right, small, to='/groups'): v-icon arrow_upward
-    v-tabs(v-model='tab', color='grey lighten-4', fixed-tabs, slider-color='primary', show-arrows)
+    v-tabs(v-model='tab', :color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows)
       v-tab(key='properties') Properties
       v-tab(key='rights') Permissions
       v-tab(key='users') Users

+ 1 - 1
client/components/admin/admin-groups.vue

@@ -1,6 +1,6 @@
 <template lang='pug'>
   v-card(flat)
-    v-card(flat, color='grey lighten-5').pa-3.pt-4
+    v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
       .headline.blue--text.text--darken-2 Groups
       .subheading.grey--text Manage groups and their permissions
     v-card

+ 2 - 4
client/components/admin/admin-locale.vue

@@ -39,8 +39,7 @@
                     persistent-hint
                     :hint='namespacing ? "Automatically download updates to all namespaced locales enabled below." : "Automatically download updates to this locale as they become available."'
                   )
-                v-divider.my-0
-                v-card-actions.grey.lighten-4
+                v-card-chin
                   v-spacer
                   v-btn(color='primary', :loading='loading', @click='save')
                     v-icon(left) chevron_right
@@ -92,8 +91,7 @@
                           v-list-tile-sub-title(v-html='data.item.nativeName')
                         v-list-tile-action
                           v-checkbox(:input-value='data.tile.props.value', color='primary', value)
-                v-divider.my-0
-                v-card-actions.grey.lighten-4
+                v-card-chin
                   v-spacer
                   v-btn(color='primary', :loading='loading', @click='save')
                     v-icon(left) chevron_right

+ 42 - 43
client/components/admin/admin-logging.vue

@@ -1,50 +1,49 @@
 <template lang='pug'>
   v-card(flat)
-    v-card(color='grey lighten-5')
-      .pa-3.pt-4
-        .headline.primary--text Logging
-        .subheading.grey--text Configure the system logger(s)
-      v-tabs(color='grey lighten-4', fixed-tabs, slider-color='primary', show-arrows)
-        v-tab(key='settings'): v-icon settings
-        v-tab(v-for='svc in activeServices', :key='svc.key') {{ svc.title }}
+    v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
+      .headline.primary--text Logging
+      .subheading.grey--text Configure the system logger(s)
+    v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows)
+      v-tab(key='settings'): v-icon settings
+      v-tab(v-for='svc in activeServices', :key='svc.key') {{ svc.title }}
 
-        v-tab-item(key='settings', :transition='false', :reverse-transition='false')
-          v-card.pa-3
-            .body-2.pb-2 Select which logging service to enable:
-            v-form
-              v-checkbox(
-                v-for='(svc, n) in services',
-                v-model='selectedServices',
-                :key='svc.key',
-                :label='svc.title',
-                :value='svc.key',
-                color='primary',
-                :disabled='svc.key === `console`'
-                hide-details
-              )
-              v-divider
-              v-btn(color='primary')
-                v-icon(left) chevron_right
-                | Set Services
-              v-btn(color='black', dark)
-                v-icon(left) keyboard
-                | View Console
-              v-btn(color='black', dark)
-                v-icon(left) layers_clear
-                | Purge Logs
-              v-btn(icon, @click='refresh')
-                v-icon.grey--text refresh
+      v-tab-item(key='settings', :transition='false', :reverse-transition='false')
+        v-card.pa-3
+          .body-2.pb-2 Select which logging service to enable:
+          v-form
+            v-checkbox(
+              v-for='(svc, n) in services',
+              v-model='selectedServices',
+              :key='svc.key',
+              :label='svc.title',
+              :value='svc.key',
+              color='primary',
+              :disabled='svc.key === `console`'
+              hide-details
+            )
+            v-divider
+            v-btn(color='primary')
+              v-icon(left) chevron_right
+              | Set Services
+            v-btn(color='black', dark)
+              v-icon(left) keyboard
+              | View Console
+            v-btn(color='black', dark)
+              v-icon(left) layers_clear
+              | Purge Logs
+            v-btn(icon, @click='refresh')
+              v-icon.grey--text refresh
 
-        v-tab-item(v-for='(svc, n) in activeServices', :key='svc.key', :transition='false', :reverse-transition='false')
-          v-card.pa-3
-            v-form
-              v-subheader Service Configuration
-              .body-1(v-if='!svc.props || svc.props.length < 1') This logging service has no configuration options you can modify.
-              v-text-field(v-else, v-for='prop in svc.props', :key='prop', :label='prop', prepend-icon='mode_edit')
-              v-divider
-              v-btn(color='primary')
-                v-icon(left) chevron_right
-                | Save Configuration
+      v-tab-item(v-for='(svc, n) in activeServices', :key='svc.key', :transition='false', :reverse-transition='false')
+        v-card.pa-3
+          v-form
+            v-subheader Service Configuration
+            .body-1(v-if='!svc.props || svc.props.length < 1') This logging service has no configuration options you can modify.
+            v-text-field(v-else, v-for='prop in svc.props', :key='prop', :label='prop', prepend-icon='mode_edit')
+            v-divider
+            v-btn(color='primary')
+              v-icon(left) chevron_right
+              | Save Configuration
 
     v-snackbar(
       color='success'

+ 29 - 30
client/components/admin/admin-search.vue

@@ -1,36 +1,35 @@
 <template lang='pug'>
   v-card(flat)
-    v-card(color='grey lighten-5')
-      .pa-3.pt-4
-        .headline.primary--text Search Engine
-        .subheading.grey--text Configure the search capabilities of your wiki
-      v-tabs(color='grey lighten-4', fixed-tabs, slider-color='primary', show-arrows)
-        v-tab(key='settings'): v-icon settings
-        v-tab(key='db') Database
-        v-tab(key='algolia') Algolia
-        v-tab(key='elasticsearch') Elasticsearch
-        v-tab(key='solr') Solr
+    v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
+      .headline.primary--text Search Engine
+      .subheading.grey--text Configure the search capabilities of your wiki
+    v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows)
+      v-tab(key='settings'): v-icon settings
+      v-tab(key='db') Database
+      v-tab(key='algolia') Algolia
+      v-tab(key='elasticsearch') Elasticsearch
+      v-tab(key='solr') Solr
 
-        v-tab-item(key='settings')
-          v-card.pa-3
-            v-form
-              v-radio-group(v-model='selectedEngine')
-                v-radio(v-for='(engine, n) in engines', :key='n', :label='engine.text', :value='engine.value', color='primary')
-              v-divider
-              v-btn(color='primary')
-                v-icon(left) chevron_right
-                | Set Engine
-              v-btn(color='black', dark)
-                v-icon(left) refresh
-                | Rebuild Index
-        v-tab-item(key='db')
-          v-card.pa-3 TODO
-        v-tab-item(key='algolia')
-          v-card.pa-3 TODO
-        v-tab-item(key='elasticsearch')
-          v-card.pa-3 TODO
-        v-tab-item(key='solr')
-          v-card.pa-3 TODO
+      v-tab-item(key='settings')
+        v-card.pa-3
+          v-form
+            v-radio-group(v-model='selectedEngine')
+              v-radio(v-for='(engine, n) in engines', :key='n', :label='engine.text', :value='engine.value', color='primary')
+            v-divider
+            v-btn(color='primary')
+              v-icon(left) chevron_right
+              | Set Engine
+            v-btn(color='black', dark)
+              v-icon(left) refresh
+              | Rebuild Index
+      v-tab-item(key='db')
+        v-card.pa-3 TODO
+      v-tab-item(key='algolia')
+        v-card.pa-3 TODO
+      v-tab-item(key='elasticsearch')
+        v-card.pa-3 TODO
+      v-tab-item(key='solr')
+        v-card.pa-3 TODO
 
 </template>
 

+ 30 - 31
client/components/admin/admin-storage.vue

@@ -1,37 +1,36 @@
 <template lang='pug'>
   v-card(flat)
-    v-card(color='grey lighten-5')
-      .pa-3.pt-4
-        .headline.primary--text Storage
-        .subheading.grey--text Set backup and sync targets for your content
-      v-tabs(color='grey lighten-4', fixed-tabs, slider-color='primary', show-arrows)
-        v-tab(key='settings'): v-icon settings
-        v-tab(key='local') Local FS
-        v-tab(key='git') Git
-        v-tab(key='s3') Amazon S3
-        v-tab(key='azure') Azure Blob Storage
-        v-tab(key='digitalocean') DigitalOcean Spaces
-        v-tab(key='dropbox') Dropbox
-        v-tab(key='gdrive') Google Drive
-        v-tab(key='onedrive') OneDrive
-        v-tab(key='scp') SCP (SSH)
+    v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
+      .headline.primary--text Storage
+      .subheading.grey--text Set backup and sync targets for your content
+    v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows)
+      v-tab(key='settings'): v-icon settings
+      v-tab(key='local') Local FS
+      v-tab(key='git') Git
+      v-tab(key='s3') Amazon S3
+      v-tab(key='azure') Azure Blob Storage
+      v-tab(key='digitalocean') DigitalOcean Spaces
+      v-tab(key='dropbox') Dropbox
+      v-tab(key='gdrive') Google Drive
+      v-tab(key='onedrive') OneDrive
+      v-tab(key='scp') SCP (SSH)
 
-        v-tab-item(key='settings')
-          v-card.pa-3
-            v-form
-              v-checkbox(
-                v-for='(target, n) in targets',
-                v-model='auths',
-                :key='n',
-                :label='target.text',
-                :value='target.value',
-                color='primary',
-                hide-details
-              )
-              v-divider
-              v-btn(color='primary')
-                v-icon(left) chevron_right
-                | Set Backup Targets
+      v-tab-item(key='settings')
+        v-card.pa-3
+          v-form
+            v-checkbox(
+              v-for='(target, n) in targets',
+              v-model='auths',
+              :key='n',
+              :label='target.text',
+              :value='target.value',
+              color='primary',
+              hide-details
+            )
+            v-divider
+            v-btn(color='primary')
+              v-icon(left) chevron_right
+              | Set Backup Targets
 
 </template>
 

+ 7 - 2
client/components/admin/admin-theme.vue

@@ -21,8 +21,7 @@
                         v-list-tile-sub-title(v-html='data.item.author')
                   v-divider
                   v-switch(v-model='darkMode', label='Dark Mode', color='primary', persistent-hint, hint='Not recommended for accessibility.')
-                v-divider.my-0
-                v-card-actions.grey.lighten-4
+                v-card-chin
                   v-spacer
                   v-btn(color='primary', :loading='loading', @click='save')
                     v-icon(left) chevron_right
@@ -45,6 +44,12 @@ export default {
       selectedTheme: 'default',
       darkMode: false
     }
+  },
+  watch: {
+    darkMode(newValue, oldValue) {
+      this.$store.commit('admin/setThemeDarkMode', newValue)
+      console.info(this.$vuetify.dark)
+    }
   }
 }
 </script>

+ 1 - 1
client/components/admin/admin-users.vue

@@ -1,6 +1,6 @@
 <template lang='pug'>
   v-card(flat)
-    v-card(flat, color='grey lighten-5').pa-3.pt-4
+    v-card(flat, tile, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
       .headline.blue--text.text--darken-2 Users
       .subheading.grey--text Manage users
     v-card

+ 9 - 10
client/components/admin/admin-utilities.vue

@@ -1,20 +1,19 @@
 <template lang='pug'>
-  v-card(flat)
-    v-card(color='grey lighten-5')
-      .pa-3.pt-4
-        .headline.primary--text Utilities
-        .subheading.grey--text Maintenance and troubleshooting tools
-    v-tabs(v-model='tab', color='grey lighten-4', fixed-tabs, slider-color='primary', show-arrows)
+  div
+    v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
+      .headline.primary--text Utilities
+      .subheading.grey--text Maintenance and troubleshooting tools
+    v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows)
       v-tab(key='tools') Tools
       v-tab(key='telemetry') Telemetry
       v-tab(key='telemetry') Support
 
       v-tab-item(key='tools', :transition='false', :reverse-transition='false')
-        v-container.grey.lighten-5(fluid, grid-list-lg)
+        v-container(fluid, grid-list-lg, :class='$vuetify.dark ? "" : "grey lighten-5"')
           v-layout(row, wrap)
             v-flex(xs12, sm6)
               v-card
-                v-toolbar(color='grey darken-3', dark, dense, flat)
+                v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
                   v-toolbar-title
                     .subheading Authentication
                 v-subheader Flush User Sessions
@@ -31,7 +30,7 @@
                     span Proceed
             v-flex(xs12, sm6)
               v-card
-                v-toolbar(color='grey darken-3', dark, dense, flat)
+                v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
                   v-toolbar-title
                     .subheading Maintenance Mode
                 v-card-text
@@ -40,7 +39,7 @@
                     icon-home-alert.mr-2(fillColor='#FFFFFF')
                     | Turn On Maintenance Mode
               v-card.mt-3
-                v-toolbar(color='grey darken-3', dark, dense, flat)
+                v-toolbar(:color='$vuetify.dark ? "" : "grey darken-3"', dark, dense, flat)
                   v-toolbar-title
                     .subheading Graph Endpoint
                 v-card-text

+ 14 - 0
client/components/common/v-card-chin.vue

@@ -0,0 +1,14 @@
+<template lang='pug'>
+  div
+    v-divider.my-0
+    v-card-actions(:class='dark ? "" : "grey lighten-4"')
+      slot
+</template>
+
+<script>
+export default {
+  computed: {
+    dark() { return this.$vuetify.dark }
+  }
+}
+</script>

+ 13 - 0
client/store/admin.js

@@ -0,0 +1,13 @@
+export default {
+  namespaced: true,
+  state: {
+    theme: {
+      dark: false
+    }
+  },
+  mutations: {
+    setThemeDarkMode(state, payload) {
+      state.theme.dark = payload
+    }
+  }
+}

+ 1 - 0
client/store/index.js

@@ -5,6 +5,7 @@ import Vuex from 'vuex'
 Vue.use(Vuex)
 
 export default new Vuex.Store({
+  strict: process.env.NODE_ENV !== 'production',
   state: {
     loadingStack: [],
     notification: {