From 6c0afa965110ab232cedc251806bbf21caa7c895 Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Mon, 19 Oct 2020 13:31:44 -0400 Subject: [PATCH] Add userName util function to render user's name --- .../database/seeds/02-rows/03-presets.yaml | 2 +- app/src/displays/user/user.vue | 9 ++--- app/src/interfaces/user/user.vue | 34 ++++--------------- app/src/lang/en-US/index.json | 2 ++ app/src/modules/activity/routes/item.vue | 6 +++- .../components/file-info-sidebar-detail.vue | 17 +++++----- .../routes/data-model/new-collection.vue | 2 -- .../routes/presets/collection/collection.vue | 6 ++-- .../modules/settings/routes/presets/item.vue | 5 +-- app/src/modules/users/routes/item.vue | 8 +++-- .../components/continue-as/continue-as.vue | 5 +-- app/src/stores/user.ts | 3 +- app/src/utils/user-name.ts | 18 ++++++++++ .../comment-item-header.vue | 11 +++--- .../comments-sidebar-detail.vue | 1 + .../comments-sidebar-detail/types.ts | 9 ++--- .../revisions-drawer-detail/revision-item.vue | 7 ++-- .../revisions-drawer-detail.vue | 1 + .../revisions-drawer-picker.vue | 5 +-- .../revisions-drawer-detail/types.ts | 5 +-- .../components/user-popover/user-popover.vue | 7 ++-- 21 files changed, 83 insertions(+), 80 deletions(-) create mode 100644 app/src/utils/user-name.ts diff --git a/api/src/database/seeds/02-rows/03-presets.yaml b/api/src/database/seeds/02-rows/03-presets.yaml index ccb7b53382..df9e909390 100644 --- a/api/src/database/seeds/02-rows/03-presets.yaml +++ b/api/src/database/seeds/02-rows/03-presets.yaml @@ -31,7 +31,7 @@ data: cards: icon: account_circle title: '{{ first_name }} {{ last_name }}' - subtitle: '{{ title }}' + subtitle: '{{ email }}' size: 4 - collection: directus_activity diff --git a/app/src/displays/user/user.vue b/app/src/displays/user/user.vue index 69f9ce67b2..5e2b46d8ae 100644 --- a/app/src/displays/user/user.vue +++ b/app/src/displays/user/user.vue @@ -5,17 +5,17 @@ v-if="(display === 'avatar' || display === 'both') && src" :src="src" role="presentation" - :alt="value && `${value.first_name} ${value.last_name}`" + :alt="value && userName(value)" :class="{ circle }" /> - {{ value.first_name }} {{ value.last_name }} + {{ userName(value) }} @@ -23,6 +23,7 @@ diff --git a/app/src/interfaces/user/user.vue b/app/src/interfaces/user/user.vue index a8da9f1a2d..28c7744fd7 100644 --- a/app/src/interfaces/user/user.vue +++ b/app/src/interfaces/user/user.vue @@ -12,11 +12,7 @@ > @@ -65,7 +61,7 @@ @click="setCurrent(item)" > - + {{ userName(currentUser) }} @@ -105,10 +101,6 @@ export default defineComponent({ type: String, default: null, }, - template: { - type: String, - default: null, - }, selectMode: { type: String as PropType<'auto' | 'dropdown' | 'modal'>, default: 'auto', @@ -122,7 +114,7 @@ export default defineComponent({ const { usesMenu, menuActive } = useMenu(); const { info: collectionInfo } = useCollection(ref('directus_users')); const { selection, stageSelection, selectModalActive } = useSelection(); - const { displayTemplate, onPreviewClick, requiredFields } = usePreview(); + const { onPreviewClick } = usePreview(); const { totalCount, loading: usersLoading, fetchUsers, users } = useUsers(); const { setCurrent, currentUser, loading: loadingCurrent, currentPrimaryKey } = useCurrent(); @@ -134,7 +126,6 @@ export default defineComponent({ return { collectionInfo, currentUser, - displayTemplate, users, usersLoading, loadingCurrent, @@ -192,16 +183,10 @@ export default defineComponent({ async function fetchCurrent() { loading.value = true; - const fields = requiredFields; - - if (fields.includes('id') === false) { - fields.push('id'); - } - try { const response = await api.get(`/users/${props.value}`, { params: { - fields: fields, + fields: ['id', 'email', 'first_name', 'last_name'], }, }); @@ -231,11 +216,7 @@ export default defineComponent({ loading.value = true; - const fields = requiredFields; - - if (fields.includes('id') === false) { - fields.push('id'); - } + const fields = ['id', 'email', 'first_name', 'last_name']; try { const response = await api.get(`/users`, { @@ -280,10 +261,7 @@ export default defineComponent({ } function usePreview() { - const displayTemplate = '{{ first_name }} {{ last_name }}'; - const requiredFields = ['first_name', 'last_name']; - - return { onPreviewClick, displayTemplate, requiredFields }; + return { onPreviewClick }; function onPreviewClick() { if (props.disabled) return; diff --git a/app/src/lang/en-US/index.json b/app/src/lang/en-US/index.json index fad743f221..ef5137abfc 100644 --- a/app/src/lang/en-US/index.json +++ b/app/src/lang/en-US/index.json @@ -901,6 +901,8 @@ "statuses_not_configured": "Status mapping configured incorrectly", "status_mapping": "Status Mapping", + "unknown_user": "Unknown User", + "creating_in": "Creating Item in {collection}", "editing_in": "Editing Item in {collection}", "editing_in_batch": "Batch Editing {count} Items", diff --git a/app/src/modules/activity/routes/item.vue b/app/src/modules/activity/routes/item.vue index dbe60c6285..7ac8308826 100644 --- a/app/src/modules/activity/routes/item.vue +++ b/app/src/modules/activity/routes/item.vue @@ -12,7 +12,7 @@

User:

- {{ item.user.first_name }} {{ item.user.last_name }} + {{ userName(item.user) }}

Action:

@@ -51,6 +51,7 @@ import { defineComponent, computed, toRefs, ref, watch } from '@vue/composition- import { i18n } from '@/lang'; import router from '@/router'; import api from '@/api'; +import { userName } from '@/utils/user-name'; type Values = { [field: string]: any; @@ -58,6 +59,7 @@ type Values = { type ActivityRecord = { user: { + email: string; first_name: string; last_name: string; } | null; @@ -97,6 +99,7 @@ export default defineComponent({ error, close, openItemLink, + userName, }; async function loadActivity() { @@ -107,6 +110,7 @@ export default defineComponent({ params: { fields: [ 'user.id', + 'user.email', 'user.first_name', 'user.last_name', 'action', diff --git a/app/src/modules/files/components/file-info-sidebar-detail.vue b/app/src/modules/files/components/file-info-sidebar-detail.vue index 18081a21b1..31e9d24930 100644 --- a/app/src/modules/files/components/file-info-sidebar-detail.vue +++ b/app/src/modules/files/components/file-info-sidebar-detail.vue @@ -115,6 +115,7 @@ import i18n from '@/lang'; import marked from 'marked'; import localizedFormat from '@/utils/localized-format'; import api from '@/api'; +import { userName } from '@/utils/user-name'; export default defineComponent({ inheritAttrs: false, @@ -194,31 +195,31 @@ export default defineComponent({ try { const response = await api.get(`/users/${props.file.uploaded_by}`, { params: { - fields: ['id', 'first_name', 'last_name', 'role'], + fields: ['id', 'email', 'first_name', 'last_name', 'role'], }, }); - const { id, first_name, last_name, role } = response.data.data; + const user = response.data.data; userCreated.value = { id: props.file.uploaded_by, - name: first_name + ' ' + last_name, - link: `/users/${id}`, + name: userName(user), + link: `/users/${user.id}`, }; if (props.file.modified_by) { const response = await api.get(`/users/${props.file.modified_by}`, { params: { - fields: ['id', 'first_name', 'last_name', 'role'], + fields: ['id', 'email', 'first_name', 'last_name', 'role'], }, }); - const { id, first_name, last_name, role } = response.data.data; + const user = response.data.data; userModified.value = { id: props.file.modified_by, - name: first_name + ' ' + last_name, - link: `/users/${id}`, + name: userName(user), + link: `/users/${user.id}`, }; } } finally { diff --git a/app/src/modules/settings/routes/data-model/new-collection.vue b/app/src/modules/settings/routes/data-model/new-collection.vue index 5edb0c38b8..ea82121add 100644 --- a/app/src/modules/settings/routes/data-model/new-collection.vue +++ b/app/src/modules/settings/routes/data-model/new-collection.vue @@ -373,7 +373,6 @@ export default defineComponent({ special: ['user-created'], interface: 'user', options: { - template: '{{first_name}} {{last_name}}', display: 'both', }, readonly: true, @@ -407,7 +406,6 @@ export default defineComponent({ special: ['user-updated'], interface: 'user', options: { - template: '{{first_name}} {{last_name}}', display: 'both', }, readonly: true, diff --git a/app/src/modules/settings/routes/presets/collection/collection.vue b/app/src/modules/settings/routes/presets/collection/collection.vue index fefa474b4e..cf823d7f36 100644 --- a/app/src/modules/settings/routes/presets/collection/collection.vue +++ b/app/src/modules/settings/routes/presets/collection/collection.vue @@ -103,11 +103,12 @@ import { TranslateResult } from 'vue-i18n'; import router from '@/router'; import ValueNull from '@/views/private/components/value-null'; import PresetsInfoSidebarDetail from './components/presets-info-sidebar-detail.vue'; +import { userName } from '@/utils/user-name'; type PresetRaw = { id: number; bookmark: null | string; - user: null | { first_name: string; last_name: string }; + user: null | { email: string; first_name: string; last_name: string }; role: null | { name: string }; collection: string; layout: string; @@ -173,7 +174,7 @@ export default defineComponent({ } if (preset.user) { - scope = `${preset.user.first_name} ${preset.user.last_name}`; + scope = userName(preset.user); } const collection = collectionsStore.getCollection(preset.collection)?.name; @@ -200,6 +201,7 @@ export default defineComponent({ fields: [ 'id', 'bookmark', + 'user.email', 'user.first_name', 'user.last_name', 'role.name', diff --git a/app/src/modules/settings/routes/presets/item.vue b/app/src/modules/settings/routes/presets/item.vue index b7047bdcff..307cafa4fe 100644 --- a/app/src/modules/settings/routes/presets/item.vue +++ b/app/src/modules/settings/routes/presets/item.vue @@ -102,6 +102,7 @@ import { useCollectionsStore, usePresetsStore } from '@/stores'; import { getLayouts } from '@/layouts'; import router from '@/router'; import marked from 'marked'; +import { userName } from '@/utils/user-name'; type User = { id: number; @@ -365,12 +366,12 @@ export default defineComponent({ try { const response = await api.get(`/users`, { params: { - fields: ['first_name', 'last_name', 'id'], + fields: ['email', 'first_name', 'last_name', 'id'], }, }); users.value = response.data.data.map((user: any) => ({ - name: user.first_name + ' ' + user.last_name, + name: userName(user), id: user.id, })); } catch (err) { diff --git a/app/src/modules/users/routes/item.vue b/app/src/modules/users/routes/item.vue index 136b560334..9c44f53655 100644 --- a/app/src/modules/users/routes/item.vue +++ b/app/src/modules/users/routes/item.vue @@ -102,7 +102,7 @@
- +
@@ -112,7 +112,7 @@ @@ -179,6 +179,7 @@ import { getRootPath } from '@/utils/get-root-path'; import useShortcut from '@/composables/use-shortcut'; import { isAllowed } from '@/utils/is-allowed'; import useCollection from '@/composables/use-collection'; +import { userName } from '@/utils/user-name'; type Values = { [field: string]: any; @@ -255,7 +256,7 @@ export default defineComponent({ if (isNew.value === false && item.value !== null) { const user = item.value as any; - return `${user.first_name} ${user.last_name}`; + return userName(user); } return i18n.t('adding_user'); @@ -334,6 +335,7 @@ export default defineComponent({ archiving, archiveTooltip, form, + userName, }; function useBreadcrumb() { diff --git a/app/src/routes/login/components/continue-as/continue-as.vue b/app/src/routes/login/components/continue-as/continue-as.vue index f5f47b5e9e..3cf12fa39a 100644 --- a/app/src/routes/login/components/continue-as/continue-as.vue +++ b/app/src/routes/login/components/continue-as/continue-as.vue @@ -17,6 +17,7 @@ import { defineComponent, computed, watch, ref } from '@vue/composition-api'; import api from '@/api'; import { hydrate } from '@/hydrate'; import router from '@/router'; +import { userName } from '@/utils/user-name'; export default defineComponent({ setup() { @@ -36,11 +37,11 @@ export default defineComponent({ try { const response = await api.get(`/users/me`, { params: { - fields: ['first_name', 'last_name', 'last_page'], + fields: ['email', 'first_name', 'last_name', 'last_page'], }, }); - name.value = response.data.data.first_name + ' ' + response.data.data.last_name; + name.value = userName(response.data.data); lastPage.value = response.data.data.last_page; } catch (err) { error.value = err; diff --git a/app/src/stores/user.ts b/app/src/stores/user.ts index 10197744a6..db10df3789 100644 --- a/app/src/stores/user.ts +++ b/app/src/stores/user.ts @@ -3,6 +3,7 @@ import api from '@/api'; import { useLatencyStore } from '@/stores'; import { User } from '@/types'; +import { userName } from '@/utils/user-name'; export const useUserStore = createStore({ id: 'userStore', @@ -14,7 +15,7 @@ export const useUserStore = createStore({ getters: { fullName(state) { if (state.currentUser === null) return null; - return state.currentUser.first_name + ' ' + state.currentUser.last_name; + return userName(state.currentUser); }, isAdmin(state) { return state.currentUser?.role.admin_access === true || false; diff --git a/app/src/utils/user-name.ts b/app/src/utils/user-name.ts new file mode 100644 index 0000000000..180c89a928 --- /dev/null +++ b/app/src/utils/user-name.ts @@ -0,0 +1,18 @@ +import { User } from '@/types'; +import { i18n } from '@/lang'; + +export function userName(user: Partial): string { + if (user.first_name && user.last_name) { + return `${user.first_name} ${user.last_name}`; + } + + if (user.first_name) { + return user.first_name; + } + + if (user.email) { + return user.email; + } + + return i18n.t('unknown_user') as string; +} diff --git a/app/src/views/private/components/comments-sidebar-detail/comment-item-header.vue b/app/src/views/private/components/comments-sidebar-detail/comment-item-header.vue index 756c11c8a5..42387b5192 100644 --- a/app/src/views/private/components/comments-sidebar-detail/comment-item-header.vue +++ b/app/src/views/private/components/comments-sidebar-detail/comment-item-header.vue @@ -1,11 +1,7 @@