From 17244a0cb3bd72af08d0ccb2017ec856c29e9079 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sat, 15 Dec 2018 17:15:13 -0500 Subject: [PATCH] feat: user edit UI + admin UI improvements + fixes --- client/components/admin.vue | 34 +- client/components/admin/admin-api.vue | 2 +- client/components/admin/admin-auth.vue | 2 +- client/components/admin/admin-contribute.vue | 2 +- client/components/admin/admin-dashboard.vue | 25 +- client/components/admin/admin-dev.vue | 2 +- client/components/admin/admin-editor.vue | 2 +- client/components/admin/admin-general.vue | 6 +- client/components/admin/admin-groups-edit.vue | 8 +- client/components/admin/admin-groups.vue | 2 +- client/components/admin/admin-locale.vue | 2 +- client/components/admin/admin-logging.vue | 2 +- client/components/admin/admin-navigation.vue | 2 +- client/components/admin/admin-pages.vue | 2 +- client/components/admin/admin-rendering.vue | 2 +- client/components/admin/admin-search.vue | 2 +- client/components/admin/admin-storage.vue | 2 +- client/components/admin/admin-system.vue | 2 +- client/components/admin/admin-theme.vue | 2 +- client/components/admin/admin-users-edit.vue | 291 ++++++++++-------- client/components/admin/admin-users.vue | 22 +- client/components/admin/admin-utilities.vue | 2 +- client/components/common/nav-header.vue | 5 +- client/components/common/page-selector.vue | 50 ++- client/components/common/v-card-chin.vue | 2 +- client/components/editor.vue | 24 +- .../editor/editor-modal-properties.vue | 12 +- client/graph/admin/users/users-query-list.gql | 1 + .../graph/admin/users/users-query-single.gql | 21 ++ client/scss/components/v-dialog.scss | 6 + client/scss/pages/_new.scss | 4 +- client/static/img/icon-browse.png | Bin 0 -> 3106 bytes client/static/img/icon-people.png | Bin 0 -> 5006 bytes client/static/img/icon-unlock.png | Bin 0 -> 4343 bytes client/static/svg/icon-browse-page.svg | 57 ++++ client/static/svg/icon-categorize.svg | 57 ++++ client/static/svg/icon-close-window.svg | 52 ++++ client/static/svg/icon-cloud-storage.svg | 29 ++ client/static/svg/icon-console.svg | 47 +++ client/static/svg/icon-customer.svg | 27 ++ client/static/svg/icon-file.svg | 1 + client/static/svg/icon-gear-outline.svg | 37 +++ client/static/svg/icon-globe-earth.svg | 27 ++ client/static/svg/icon-heart-health.svg | 22 ++ client/static/svg/icon-maintenance.svg | 27 ++ client/static/svg/icon-male-user.svg | 27 ++ client/static/svg/icon-markdown.svg | 27 ++ client/static/svg/icon-open-in-browser.svg | 67 ++++ client/static/svg/icon-paint-palette.svg | 37 +++ client/static/svg/icon-people.svg | 32 ++ client/static/svg/icon-process.svg | 37 +++ client/static/svg/icon-registry-editor.svg | 52 ++++ client/static/svg/icon-rest-api.svg | 17 + client/static/svg/icon-search.svg | 1 + client/static/svg/icon-settings.svg | 27 ++ client/static/svg/icon-social-group.svg | 32 ++ client/static/svg/icon-source-code.svg | 42 +++ client/static/svg/icon-triangle-arrow.svg | 17 + client/static/svg/icon-tune.svg | 42 +++ client/static/svg/icon-unlock.svg | 17 + client/static/svg/icon-web-design.svg | 42 +++ client/store/admin.js | 8 +- dev/docker/docker-compose.yml | 11 + server/app/data.yml | 3 + server/db/migrations/2.0.0.js | 1 + server/graph/resolvers/user.js | 8 +- server/graph/schemas/user.graphql | 20 +- server/models/users.js | 1 + server/setup.js | 5 +- server/views/new.pug | 4 +- 70 files changed, 1272 insertions(+), 231 deletions(-) create mode 100644 client/graph/admin/users/users-query-single.gql create mode 100644 client/static/img/icon-browse.png create mode 100644 client/static/img/icon-people.png create mode 100644 client/static/img/icon-unlock.png create mode 100644 client/static/svg/icon-browse-page.svg create mode 100644 client/static/svg/icon-categorize.svg create mode 100644 client/static/svg/icon-close-window.svg create mode 100644 client/static/svg/icon-cloud-storage.svg create mode 100644 client/static/svg/icon-console.svg create mode 100644 client/static/svg/icon-customer.svg create mode 100644 client/static/svg/icon-file.svg create mode 100644 client/static/svg/icon-gear-outline.svg create mode 100644 client/static/svg/icon-globe-earth.svg create mode 100644 client/static/svg/icon-heart-health.svg create mode 100644 client/static/svg/icon-maintenance.svg create mode 100644 client/static/svg/icon-male-user.svg create mode 100644 client/static/svg/icon-markdown.svg create mode 100644 client/static/svg/icon-open-in-browser.svg create mode 100644 client/static/svg/icon-paint-palette.svg create mode 100644 client/static/svg/icon-people.svg create mode 100644 client/static/svg/icon-process.svg create mode 100644 client/static/svg/icon-registry-editor.svg create mode 100644 client/static/svg/icon-rest-api.svg create mode 100644 client/static/svg/icon-search.svg create mode 100644 client/static/svg/icon-settings.svg create mode 100644 client/static/svg/icon-social-group.svg create mode 100644 client/static/svg/icon-source-code.svg create mode 100644 client/static/svg/icon-triangle-arrow.svg create mode 100644 client/static/svg/icon-tune.svg create mode 100644 client/static/svg/icon-unlock.svg create mode 100644 client/static/svg/icon-web-design.svg diff --git a/client/components/admin.vue b/client/components/admin.vue index 227f8ab7..aed83164 100644 --- a/client/components/admin.vue +++ b/client/components/admin.vue @@ -23,7 +23,7 @@ v-list-tile-title {{ $t('admin:pages.title') }} v-list-tile-action v-chip(small, disabled, :color='darkMode ? `grey darken-3-d4` : `grey lighten-4`') - .caption.grey--text 123 + .caption.grey--text {{ info.pagesTotal }} v-list-tile(to='/theme') v-list-tile-avatar: v-icon palette v-list-tile-title {{ $t('admin:theme.title') }} @@ -32,12 +32,15 @@ v-list-tile(to='/groups') v-list-tile-avatar: v-icon people v-list-tile-title {{ $t('admin:groups.title') }} + v-list-tile-action + v-chip(small, disabled, :color='darkMode ? `grey darken-3-d4` : `grey lighten-4`') + .caption.grey--text {{ info.groupsTotal }} v-list-tile(to='/users') v-list-tile-avatar: v-icon perm_identity v-list-tile-title {{ $t('admin:users.title') }} v-list-tile-action v-chip(small, disabled, :color='darkMode ? `grey darken-3-d4` : `grey lighten-4`') - .caption.grey--text 1 + .caption.grey--text {{ info.usersTotal }} v-divider.my-2 v-subheader.pl-4 {{ $t('admin:nav.modules') }} v-list-tile(to='/auth') @@ -86,7 +89,15 @@ diff --git a/client/components/admin/admin-api.vue b/client/components/admin/admin-api.vue index 2c16288f..0e7d7dd3 100644 --- a/client/components/admin/admin-api.vue +++ b/client/components/admin/admin-api.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') call_split + img(src='/svg/icon-rest-api.svg', alt='API', style='width: 80px;') .admin-header-title .headline.blue--text.text--darken-2 API .subheading.grey--text Manage keys to access the API diff --git a/client/components/admin/admin-auth.vue b/client/components/admin/admin-auth.vue index 777d8966..65c2cd43 100644 --- a/client/components/admin/admin-auth.vue +++ b/client/components/admin/admin-auth.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') lock_outline + img(src='/svg/icon-unlock.svg', alt='Authentication', style='width: 80px;') .admin-header-title .headline.primary--text Authentication .subheading.grey--text Configure the authentication settings of your wiki diff --git a/client/components/admin/admin-contribute.vue b/client/components/admin/admin-contribute.vue index 7760347d..1df9813d 100644 --- a/client/components/admin/admin-contribute.vue +++ b/client/components/admin/admin-contribute.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') favorite + img(src='/svg/icon-heart-health.svg', alt='Contribute', style='width: 80px;') .admin-header-title .headline.primary--text {{ $t('admin:contribute.title') }} .subheading.grey--text {{ $t('admin:contribute.subtitle') }} diff --git a/client/components/admin/admin-dashboard.vue b/client/components/admin/admin-dashboard.vue index d70d6d61..4108f531 100644 --- a/client/components/admin/admin-dashboard.vue +++ b/client/components/admin/admin-dashboard.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') dashboard + img(src='/svg/icon-browse-page.svg', alt='Dashboard', style='width: 80px;') .admin-header-title .headline.primary--text {{ $t('admin:dashboard.title') }} .subheading.grey--text {{ $t('admin:dashboard.subtitle') }} @@ -92,8 +92,7 @@ diff --git a/client/components/admin/admin-dev.vue b/client/components/admin/admin-dev.vue index f28ec7c4..784af487 100644 --- a/client/components/admin/admin-dev.vue +++ b/client/components/admin/admin-dev.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') weekend + img(src='/svg/icon-console.svg', alt='Developer Tools', style='width: 80px;') .admin-header-title .headline.primary--text Developer Tools .subheading.grey--text ¯\_(ツ)_/¯ diff --git a/client/components/admin/admin-editor.vue b/client/components/admin/admin-editor.vue index 94a1e2cc..fa1d4ff2 100644 --- a/client/components/admin/admin-editor.vue +++ b/client/components/admin/admin-editor.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') transform + img(src='/svg/icon-web-design.svg', alt='Editor', style='width: 80px;') .admin-header-title .headline.primary--text Editor .subheading.grey--text Configure the content editor diff --git a/client/components/admin/admin-general.vue b/client/components/admin/admin-general.vue index c9cdc436..c660a2dd 100644 --- a/client/components/admin/admin-general.vue +++ b/client/components/admin/admin-general.vue @@ -3,7 +3,7 @@ v-layout(row wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') widgets + img(src='/svg/icon-categorize.svg', alt='General', style='width: 80px;') .admin-header-title .headline.primary--text {{ $t('admin:general.title') }} .subheading.grey--text {{ $t('admin:general.subtitle') }} @@ -60,7 +60,7 @@ outline label='Google Analytics ID' :counter='255' - prepend-icon='public' + prepend-icon='timeline' persistent-hint hint='Property tracking ID for Google Analytics.' ) @@ -72,7 +72,7 @@ label='Company / Organization Name' v-model='company' :counter='255' - prepend-icon='public' + prepend-icon='business' persistent-hint hint='Name to use when displaying copyright notice in the footer. Leave empty to hide.' ) diff --git a/client/components/admin/admin-groups-edit.vue b/client/components/admin/admin-groups-edit.vue index f84f1842..007aa1dc 100644 --- a/client/components/admin/admin-groups-edit.vue +++ b/client/components/admin/admin-groups-edit.vue @@ -3,11 +3,13 @@ v-layout(row wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') people + img(src='/svg/icon-social-group.svg', alt='Edit Group', style='width: 80px;') .admin-header-title .headline.blue--text.text--darken-2 Edit Group .subheading.grey--text {{name}} v-spacer + .caption.grey--text ID #[strong {{group.id}}] + v-divider.mx-3(vertical) v-btn(color='indigo', large, outline, to='/groups') v-icon arrow_back v-dialog(v-model='deleteGroupDialog', max-width='500', v-if='!group.isSystem') @@ -24,7 +26,7 @@ v-icon(left) check span Update Group v-card.mt-3 - v-tabs(v-model='tab', :color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows) + v-tabs(v-model='tab', :color='$vuetify.dark ? "primary" : "grey darken-2"', fixed-tabs, slider-color='white', show-arrows, dark) v-tab(key='properties') Properties v-tab(key='permissions') Permissions v-tab(key='rules') Page Rules @@ -41,8 +43,6 @@ counter='255' prepend-icon='people' ) - v-divider - .caption.mt-3.grey--text ID: {{group.id}} v-tab-item(key='permissions', :transition='false', :reverse-transition='false') v-container.pa-3(fluid, grid-list-md) diff --git a/client/components/admin/admin-groups.vue b/client/components/admin/admin-groups.vue index 610c0a39..7ed7399c 100644 --- a/client/components/admin/admin-groups.vue +++ b/client/components/admin/admin-groups.vue @@ -3,7 +3,7 @@ v-layout(row wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') people + img(src='/svg/icon-people.svg', alt='Groups', style='width: 80px;') .admin-header-title .headline.blue--text.text--darken-2 Groups .subheading.grey--text Manage groups and their permissions diff --git a/client/components/admin/admin-locale.vue b/client/components/admin/admin-locale.vue index 3e76f1f4..888b581f 100644 --- a/client/components/admin/admin-locale.vue +++ b/client/components/admin/admin-locale.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') language + img(src='/svg/icon-globe-earth.svg', alt='Locale', style='width: 80px;') .admin-header-title .headline.primary--text {{ $t('admin:locale.title') }} .subheading.grey--text {{ $t('admin:locale.subtitle') }} diff --git a/client/components/admin/admin-logging.vue b/client/components/admin/admin-logging.vue index 5a0be3c8..7244cd85 100644 --- a/client/components/admin/admin-logging.vue +++ b/client/components/admin/admin-logging.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') graphic_eq + img(src='/svg/icon-registry-editor.svg', alt='Logging', style='width: 80px;') .admin-header-title .headline.primary--text Logging .subheading.grey--text Configure the system logger(s) diff --git a/client/components/admin/admin-navigation.vue b/client/components/admin/admin-navigation.vue index 3762a51b..3f106ab8 100644 --- a/client/components/admin/admin-navigation.vue +++ b/client/components/admin/admin-navigation.vue @@ -3,7 +3,7 @@ v-layout(row wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') near_me + img(src='/svg/icon-triangle-arrow.svg', alt='Navigation', style='width: 80px;') .admin-header-title .headline.primary--text {{$t('navigation.title')}} .subheading.grey--text {{$t('navigation.subtitle')}} diff --git a/client/components/admin/admin-pages.vue b/client/components/admin/admin-pages.vue index 29ce64b3..1b884364 100644 --- a/client/components/admin/admin-pages.vue +++ b/client/components/admin/admin-pages.vue @@ -3,7 +3,7 @@ v-layout(row wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') insert_drive_file + img(src='/svg/icon-file.svg', alt='Page', style='width: 80px;') .admin-header-title .headline.blue--text.text--darken-2 Pages .subheading.grey--text Manage pages diff --git a/client/components/admin/admin-rendering.vue b/client/components/admin/admin-rendering.vue index 46289e7a..ef52e02a 100644 --- a/client/components/admin/admin-rendering.vue +++ b/client/components/admin/admin-rendering.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') system_update_alt + img(src='/svg/icon-process.svg', alt='Rendering', style='width: 80px;') .admin-header-title .headline.primary--text Rendering .subheading.grey--text Configure how content is rendered diff --git a/client/components/admin/admin-search.vue b/client/components/admin/admin-search.vue index 9c9979b9..c97a77c5 100644 --- a/client/components/admin/admin-search.vue +++ b/client/components/admin/admin-search.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') search + img(src='/svg/icon-search.svg', alt='Search Engine', style='width: 80px;') .admin-header-title .headline.primary--text Search Engine .subheading.grey--text Configure the search capabilities of your wiki diff --git a/client/components/admin/admin-storage.vue b/client/components/admin/admin-storage.vue index e5a85a46..c2412ccf 100644 --- a/client/components/admin/admin-storage.vue +++ b/client/components/admin/admin-storage.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') storage + img(src='/svg/icon-cloud-storage.svg', alt='Storage', style='width: 80px;') .admin-header-title .headline.primary--text Storage .subheading.grey--text Set backup and sync targets for your content diff --git a/client/components/admin/admin-system.vue b/client/components/admin/admin-system.vue index 80c15eb8..3e59b5b0 100644 --- a/client/components/admin/admin-system.vue +++ b/client/components/admin/admin-system.vue @@ -3,7 +3,7 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') tune + img(src='/svg/icon-tune.svg', alt='System Info', style='width: 80px;') .admin-header-title .headline.primary--text {{ $t('admin:system.title') }} .subheading.grey--text {{ $t('admin:system.subtitle') }} diff --git a/client/components/admin/admin-theme.vue b/client/components/admin/admin-theme.vue index 25bd9040..1428c1c3 100644 --- a/client/components/admin/admin-theme.vue +++ b/client/components/admin/admin-theme.vue @@ -3,7 +3,7 @@ v-layout(row wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') palette + img(src='/svg/icon-paint-palette.svg', alt='Theme', style='width: 80px;') .admin-header-title .headline.primary--text Theme .subheading.grey--text Modify the look & feel of your wiki diff --git a/client/components/admin/admin-users-edit.vue b/client/components/admin/admin-users-edit.vue index bef7c233..4a5b6085 100644 --- a/client/components/admin/admin-users-edit.vue +++ b/client/components/admin/admin-users-edit.vue @@ -3,148 +3,193 @@ v-layout(row, wrap) v-flex(xs12) .admin-header - v-icon(size='80', color='grey lighten-2') perm_identity + img(src='/svg/icon-male-user.svg', alt='Edit User', style='width: 80px;') .admin-header-title - .headline.blue--text.text--darken-2 Users - .subheading.grey--text Manage users + .headline.blue--text.text--darken-2 Edit User + .subheading.grey--text {{user.name}} v-spacer - v-btn(outline, color='grey', large, @click='refresh') - v-icon refresh - v-btn(color='primary', large, depressed, @click='authorizeUser') - v-icon(left) lock_outline - span Authorize Social User - v-btn(color='primary', large, depressed, @click='createUser') - v-icon(left) add - span New Local User + .caption.grey--text ID #[strong {{user.id}}] + v-divider.mx-3(vertical) + v-btn(color='indigo', large, outline, to='/users') + v-icon arrow_back + v-dialog(v-model='deleteUserDialog', max-width='500', v-if='user.id !== currentUserId && !user.isSystem') + v-btn(color='red', large, outline, slot='activator') + v-icon(color='red') delete + v-card + .dialog-header.is-red Delete User? + v-card-text Are you sure you want to delete user #[strong {{ user.name }}]? + v-card-actions + v-spacer + v-btn(flat, @click='deleteUserDialog = false') Cancel + v-btn(color='red', dark, @click='deleteUser') Delete + v-btn(color='primary', large, depressed, @click='updateUser') + v-icon(left) check + span Update User + v-flex(xs5) + v-card + v-toolbar(color='primary', dense, dark, flat) + v-icon.mr-2 directions_run + span Basic Info + v-list.py-0(two-line, dense) + v-list-tile + v-list-tile-avatar + v-icon alternate_email + v-list-tile-content + v-list-tile-title Email + v-list-tile-sub-title {{ user.email }} + v-list-tile-action + v-btn(icon, color='grey', flat) + v-icon edit + v-divider + v-list-tile + v-list-tile-avatar + v-icon person + v-list-tile-content + v-list-tile-title Display Name + v-list-tile-sub-title {{ user.name }} + v-list-tile-action + v-btn(icon, color='grey', flat) + v-icon edit v-card.mt-3 - v-data-table( - v-model='selected' - :items='users', - :headers='headers', - :search='search', - :pagination.sync='pagination', - :rows-per-page-items='[15]' - hide-actions, - disable-initial-sort - ) - template(slot='headers', slot-scope='props') - tr - th.text-xs-left( - v-for='header in props.headers' - :key='header.text' - :width='header.width' - :class='[`column`, header.sortable ? `sortable` : ``, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]' - @click='changeSort(header.value)' - ) - | {{ header.text }} - v-icon(small, v-if='header.sortable') arrow_upward - template(slot='items', slot-scope='props') - tr.is-clickable(:active='props.selected', @click='$router.push("/users/" + props.item.id)') - //- td - v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected') - td.text-xs-right {{ props.item.id }} - td: strong {{ props.item.name }} - td {{ props.item.email }} - td {{ props.item.providerKey }} - td {{ props.item.createdAt | moment('from') }} - td - v-menu(bottom, right, min-width='200') - v-btn(icon, slot='activator'): v-icon.grey--text.text--darken-1 more_horiz - v-list - v-list-tile(@click='') - v-list-tile-action - v-icon(color='primary') edit - v-list-tile-content - v-list-tile-title Edit - v-list-tile(@click='') - v-list-tile-action - v-icon(color='red') block - v-list-tile-content - v-list-tile-title Block - template(slot='no-data') - .pa-3 - v-alert(icon='warning', :value='true', outline) No users to display! - .text-xs-center.py-2 - v-pagination(v-model='pagination.page', :length='pages') + v-toolbar(color='primary', dense, dark, flat) + v-icon.mr-2 lock_outline + span Authentication + v-list.py-0(two-line, dense) + v-list-tile + v-list-tile-avatar + v-icon business + v-list-tile-content + v-list-tile-title Provider + v-list-tile-sub-title {{ user.providerKey }} + v-list-tile-action + v-img(src='https://static.requarks.io/logo/wikijs.svg', alt='') + template(v-if='user.providerKey === `local`') + v-divider + v-list-tile + v-list-tile-avatar + v-icon security + v-list-tile-content + v-list-tile-title Password + v-list-tile-sub-title ******** + v-list-tile-action + v-btn(icon, color='grey', flat) + v-icon cached + v-list-tile-action + v-btn(icon, color='grey', flat) + v-icon email + v-divider + v-list-tile + v-list-tile-avatar + v-icon screen_lock_portrait + v-list-tile-content + v-list-tile-title Two Factor Authentication (2FA) + v-list-tile-sub-title.red--text Inactive + v-list-tile-action + v-btn(icon, color='grey', flat) + v-icon power_settings_new + template(v-if='user.providerId') + v-divider + v-list-tile + v-list-tile-avatar + v-icon person + v-list-tile-content + v-list-tile-title Provider Id + v-list-tile-sub-title {{ user.providerId }} + v-card.mt-3 + v-toolbar(color='primary', dense, dark, flat) + v-icon.mr-2 people + span User Groups + v-list(dense) + template(v-for='(group, idx) in user.groups') + v-list-tile + v-list-tile-avatar + v-icon people_outline + v-list-tile-content + v-list-tile-title {{group.name}} + v-list-tile-action + v-btn(icon, color='red', flat) + v-icon clear + v-divider(v-if='idx < user.groups.length - 1') + v-card-chin + v-spacer + v-btn(small, color='primary', flat) + v-icon(left) how_to_reg + span Assign to group + v-flex(xs7) + v-card + v-toolbar(color='primary', dense, dark, flat) + v-icon.mr-2 directions_walk + span Extended Metadata + v-list.py-0(two-line, dense) + v-list-tile + v-list-tile-avatar + v-icon public + v-list-tile-content + v-list-tile-title Location + v-list-tile-sub-title {{ user.location }} + v-list-tile-action + v-btn(icon, color='grey', flat) + v-icon edit + v-divider + v-list-tile + v-list-tile-avatar + v-icon local_library + v-list-tile-content + v-list-tile-title Job Title + v-list-tile-sub-title {{ user.jobTitle }} + v-list-tile-action + v-btn(icon, color='grey', flat) + v-icon edit + v-divider + v-list-tile + v-list-tile-avatar + v-icon map + v-list-tile-content + v-list-tile-title Timezone + v-list-tile-sub-title {{ user.timezone }} + v-list-tile-action + v-btn(icon, color='grey', flat) + v-icon edit + v-card.mt-3 + v-toolbar(color='primary', dense, dark, flat) + v-icon.mr-2 insert_drive_file + span Content + v-card-text + em.caption.grey--text Coming soon - user-authorize(v-model='isAuthorizeDialogShown') - user-create(v-model='isCreateDialogShown') -