mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-13 19:58:09 +00:00
Employee display name (#2717)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
7997d34d17
commit
16eec3b0a1
@ -158,6 +158,9 @@ export class TEmployee extends TPerson implements Employee {
|
||||
statuses?: number
|
||||
|
||||
mergedTo?: Ref<Employee>
|
||||
|
||||
@Prop(TypeString(), contact.string.DisplayName)
|
||||
displayName?: string | null
|
||||
}
|
||||
|
||||
@Model(contact.class.EmployeeAccount, core.class.Account)
|
||||
@ -284,7 +287,7 @@ export function createModel (builder: Builder): void {
|
||||
})
|
||||
|
||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: contact.component.EditPerson,
|
||||
editor: contact.component.EditEmployee,
|
||||
pinned: true
|
||||
})
|
||||
|
||||
|
@ -29,6 +29,7 @@ export default mergeIds(contactId, contact, {
|
||||
ContactRefPresenter: '' as AnyComponent,
|
||||
ContactPresenter: '' as AnyComponent,
|
||||
EditPerson: '' as AnyComponent,
|
||||
EditEmployee: '' as AnyComponent,
|
||||
EditOrganization: '' as AnyComponent,
|
||||
OrganizationPresenter: '' as AnyComponent,
|
||||
Contacts: '' as AnyComponent,
|
||||
|
@ -1,15 +1,19 @@
|
||||
<script lang="ts">
|
||||
import contact, { Employee, EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import core, { Ref, Space } from '@hcengineering/core'
|
||||
import { Label, Button, ActionIcon, IconClose } from '@hcengineering/ui'
|
||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import core, { IdMap, Ref, Space, toIdMap } from '@hcengineering/core'
|
||||
import { ActionIcon, Button, IconClose, Label } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { getClient } from '../utils'
|
||||
import presentation from '../plugin'
|
||||
import { createQuery, getClient } from '../utils'
|
||||
import UsersPopup from './UsersPopup.svelte'
|
||||
|
||||
export let value: Space
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
const query = createQuery()
|
||||
|
||||
let employees: IdMap<Employee> = new Map()
|
||||
query.query(contact.class.Employee, {}, (res) => (employees = toIdMap(res)))
|
||||
|
||||
let membersToAdd: EmployeeAccount[] = []
|
||||
let channelMembers: Ref<Employee>[] = []
|
||||
@ -54,8 +58,9 @@
|
||||
{#if membersToAdd.length}
|
||||
<div class="flex-row-top flex-wrap ml-6 mr-6 mt-4">
|
||||
{#each membersToAdd as m}
|
||||
{@const employee = employees.get(m.employee)}
|
||||
<div class="mr-2 p-1 item">
|
||||
{formatName(m.name)}
|
||||
{employee ? getName(employee) : ''}
|
||||
<div class="tool">
|
||||
<ActionIcon
|
||||
icon={IconClose}
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { Contact, Employee, formatName } from '@hcengineering/contact'
|
||||
import contact, { Contact, Employee, getName } from '@hcengineering/contact'
|
||||
import { Class, DocumentQuery, FindOptions, Hierarchy, Ref } from '@hcengineering/core'
|
||||
import { getEmbeddedLabel, IntlString } from '@hcengineering/platform'
|
||||
import {
|
||||
@ -33,7 +33,7 @@
|
||||
} from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import presentation, { IconPerson, UserInfo, getClient } from '..'
|
||||
import presentation, { getClient, IconPerson, UserInfo } from '..'
|
||||
import AssigneePopup from './AssigneePopup.svelte'
|
||||
|
||||
export let _class: Ref<Class<Employee>> = contact.class.Employee
|
||||
@ -76,10 +76,6 @@
|
||||
|
||||
$: updateSelected(value)
|
||||
|
||||
function getName (obj: Contact): string {
|
||||
const isPerson = client.getHierarchy().isDerived(obj._class, contact.class.Person)
|
||||
return isPerson ? formatName(obj.name) : obj.name
|
||||
}
|
||||
const mgr = getFocusManager()
|
||||
|
||||
const _click = (ev: MouseEvent): void => {
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { Contact, formatName } from '@hcengineering/contact'
|
||||
import { Contact, getName } from '@hcengineering/contact'
|
||||
import { Class, DocumentQuery, FindOptions, Hierarchy, Ref } from '@hcengineering/core'
|
||||
import { Asset, getEmbeddedLabel, IntlString } from '@hcengineering/platform'
|
||||
import {
|
||||
@ -77,10 +77,6 @@
|
||||
|
||||
$: updateSelected(value)
|
||||
|
||||
function getName (obj: Contact): string {
|
||||
const isPerson = client.getHierarchy().isDerived(obj._class, contact.class.Person)
|
||||
return isPerson ? formatName(obj.name) : obj.name
|
||||
}
|
||||
const mgr = getFocusManager()
|
||||
|
||||
const _click = (ev: MouseEvent): void => {
|
||||
|
@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import Avatar from './Avatar.svelte'
|
||||
|
||||
import { formatName, Person } from '@hcengineering/contact'
|
||||
import { getName, Person } from '@hcengineering/contact'
|
||||
import { Asset } from '@hcengineering/platform'
|
||||
import { AnySvelteComponent, IconSize } from '@hcengineering/ui'
|
||||
|
||||
@ -30,6 +30,6 @@
|
||||
<Avatar avatar={value.avatar} {size} {icon} />
|
||||
<div class="flex-col min-w-0 {size === 'tiny' || size === 'inline' ? 'ml-1' : 'ml-2'}">
|
||||
{#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if}
|
||||
<div class="content-accent-color overflow-label text-left">{formatName(value.name)}</div>
|
||||
<div class="content-accent-color overflow-label text-left">{getName(value)}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,7 +15,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { TxViewlet } from '@hcengineering/activity'
|
||||
import contact, { EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import core, { AnyAttribute, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||
import { Asset, getResource } from '@hcengineering/platform'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
@ -50,14 +50,16 @@
|
||||
|
||||
let viewlet: TxDisplayViewlet | undefined
|
||||
let props: any
|
||||
let employee: EmployeeAccount | undefined
|
||||
let account: EmployeeAccount | undefined
|
||||
let employee: Employee | undefined
|
||||
let model: AttributeModel[] = []
|
||||
let modelIcon: Asset | undefined = undefined
|
||||
|
||||
let edit = false
|
||||
|
||||
$: if (tx.tx._id !== ptx?.tx._id) {
|
||||
if (tx.tx.modifiedBy !== employee?._id) {
|
||||
if (tx.tx.modifiedBy !== account?._id) {
|
||||
account = undefined
|
||||
employee = undefined
|
||||
}
|
||||
viewlet = undefined
|
||||
@ -68,6 +70,7 @@
|
||||
|
||||
const client = getClient()
|
||||
const query = createQuery()
|
||||
const employeeQuery = createQuery()
|
||||
|
||||
function getProps (props: any, edit: boolean): any {
|
||||
return { ...props, edit, attr: tx.collectionAttribute }
|
||||
@ -85,12 +88,22 @@
|
||||
$: query.query(
|
||||
contact.class.EmployeeAccount,
|
||||
{ _id: tx.tx.modifiedBy as Ref<EmployeeAccount> },
|
||||
(account) => {
|
||||
;[employee] = account
|
||||
(res) => {
|
||||
;[account] = res
|
||||
},
|
||||
{ limit: 1 }
|
||||
)
|
||||
|
||||
$: account &&
|
||||
employeeQuery.query(
|
||||
contact.class.Employee,
|
||||
{ _id: account.employee },
|
||||
(res) => {
|
||||
;[employee] = res
|
||||
},
|
||||
{ limit: 1 }
|
||||
)
|
||||
|
||||
const showMenu = async (ev: MouseEvent): Promise<void> => {
|
||||
const actions = await getActions(client, tx.doc as Doc)
|
||||
showPopup(
|
||||
@ -167,7 +180,7 @@
|
||||
<div class="flex-row-center flex-grow label">
|
||||
<div class="bold">
|
||||
{#if employee}
|
||||
{formatName(employee.name)}
|
||||
{getName(employee)}
|
||||
{:else}
|
||||
<Label label={activity.string.System} />
|
||||
{/if}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { formatName, Person } from '@hcengineering/contact'
|
||||
import { getName, Person } from '@hcengineering/contact'
|
||||
import { Hierarchy } from '@hcengineering/core'
|
||||
import { Avatar } from '@hcengineering/presentation'
|
||||
import calendar from '../plugin'
|
||||
@ -38,7 +38,7 @@
|
||||
<div
|
||||
class="flex-presenter"
|
||||
class:inline-presenter={inline}
|
||||
use:tooltip={{ label: calendar.string.PersonsLabel, props: { name: formatName(p.name) } }}
|
||||
use:tooltip={{ label: calendar.string.PersonsLabel, props: { name: getName(p) } }}
|
||||
on:click={() => onClick(p)}
|
||||
>
|
||||
<div class="icon">
|
||||
|
@ -13,8 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { Person } from '@hcengineering/contact'
|
||||
import { formatName } from '@hcengineering/contact'
|
||||
import { getName, Person } from '@hcengineering/contact'
|
||||
import { Avatar } from '@hcengineering/presentation'
|
||||
|
||||
interface IMessage {
|
||||
@ -29,7 +28,7 @@
|
||||
<div class="flex-nowrap">
|
||||
<div class="avatar"><Avatar size={'medium'} /></div>
|
||||
<div class="flex-col-stretch message">
|
||||
<div class="header">{formatName(user.name)}<span>{message.createDate}</span></div>
|
||||
<div class="header">{getName(user)}<span>{message.createDate}</span></div>
|
||||
<div class="text">{message.text}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,10 +17,10 @@
|
||||
import { AttachmentDocList } from '@hcengineering/attachment-resources'
|
||||
import type { Comment } from '@hcengineering/chunter'
|
||||
import chunter from '@hcengineering/chunter'
|
||||
import { formatName } from '@hcengineering/contact'
|
||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import { Ref } from '@hcengineering/core'
|
||||
import { Avatar, getClient, MessageViewer } from '@hcengineering/presentation'
|
||||
import { TimeSince, ShowMore, Icon } from '@hcengineering/ui'
|
||||
import { getUser } from '../utils'
|
||||
import { Icon, ShowMore, TimeSince } from '@hcengineering/ui'
|
||||
|
||||
export let value: Comment
|
||||
export let inline: boolean = false
|
||||
@ -31,6 +31,14 @@
|
||||
const cutId = (str: string): string => {
|
||||
return str.slice(0, 4) + '...' + str.slice(-4)
|
||||
}
|
||||
|
||||
async function getEmployee (value: Comment): Promise<Employee | undefined> {
|
||||
const acc = await client.findOne(contact.class.EmployeeAccount, { _id: value.modifiedBy as Ref<EmployeeAccount> })
|
||||
if (acc !== undefined) {
|
||||
const emp = await client.findOne(contact.class.Employee, { _id: acc.employee })
|
||||
return emp
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if inline}
|
||||
@ -43,23 +51,23 @@
|
||||
<span class="content-dark-color">#{cutId(value._id.toString())}</span>
|
||||
{:else}
|
||||
<div class="flex-row-top">
|
||||
<div class="avatar">
|
||||
<Avatar size={'medium'} />
|
||||
</div>
|
||||
<div class="flex-grow flex-col select-text">
|
||||
<div class="header">
|
||||
<div class="fs-title">
|
||||
{#await getUser(client, value.modifiedBy) then user}
|
||||
{#if user}{formatName(user.name)}{/if}
|
||||
{/await}
|
||||
</div>
|
||||
<div class="content-trans-color ml-4"><TimeSince value={value.modifiedOn} /></div>
|
||||
{#await getEmployee(value) then employee}
|
||||
<div class="avatar">
|
||||
<Avatar size={'medium'} avatar={employee?.avatar} />
|
||||
</div>
|
||||
<ShowMore limit={126} fixed>
|
||||
<MessageViewer message={value.message} />
|
||||
<AttachmentDocList {value} />
|
||||
</ShowMore>
|
||||
</div>
|
||||
<div class="flex-grow flex-col select-text">
|
||||
<div class="header">
|
||||
<div class="fs-title">
|
||||
{#if employee}{getName(employee)}{/if}
|
||||
</div>
|
||||
<div class="content-trans-color ml-4"><TimeSince value={value.modifiedOn} /></div>
|
||||
</div>
|
||||
<ShowMore limit={126} fixed>
|
||||
<MessageViewer message={value.message} />
|
||||
<AttachmentDocList {value} />
|
||||
</ShowMore>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import chunter, { ChunterMessage } from '@hcengineering/chunter'
|
||||
import contact, { Employee, EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import { Ref, Space } from '@hcengineering/core'
|
||||
import { Avatar, createQuery, getClient, MessageViewer } from '@hcengineering/presentation'
|
||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import { IdMap, Ref, Space, toIdMap } from '@hcengineering/core'
|
||||
import { Avatar, createQuery, MessageViewer } from '@hcengineering/presentation'
|
||||
import { IconClose } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { UnpinMessage } from '../index'
|
||||
@ -30,38 +30,40 @@
|
||||
})
|
||||
|
||||
const employeeAccoutsQuery = createQuery()
|
||||
let employeeAcounts: EmployeeAccount[]
|
||||
let employeeAcounts: IdMap<EmployeeAccount> = new Map()
|
||||
|
||||
employeeAccoutsQuery.query(contact.class.EmployeeAccount, {}, (res) => (employeeAcounts = res))
|
||||
employeeAccoutsQuery.query(contact.class.EmployeeAccount, {}, (res) => (employeeAcounts = toIdMap(res)))
|
||||
|
||||
const employeeQuery = createQuery()
|
||||
let employees: IdMap<Employee> = new Map()
|
||||
|
||||
employeeQuery.query(contact.class.Employee, {}, (res) => (employees = toIdMap(res)))
|
||||
|
||||
const client = getClient()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
async function getEmployee (_id?: Ref<Employee>): Promise<Employee | undefined> {
|
||||
if (_id) {
|
||||
return await client.findOne(contact.class.Employee, { _id })
|
||||
function getEmployee (
|
||||
message: ChunterMessage,
|
||||
employeeAcounts: IdMap<EmployeeAccount>,
|
||||
employees: IdMap<Employee>
|
||||
): Employee | undefined {
|
||||
const acc = employeeAcounts.get(message.createBy as Ref<EmployeeAccount>)
|
||||
if (acc) {
|
||||
return employees.get(acc.employee)
|
||||
}
|
||||
}
|
||||
|
||||
function getEmployeeAccount (message: ChunterMessage): EmployeeAccount | undefined {
|
||||
return employeeAcounts?.find((e) => e._id === message.createBy)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="antiPopup vScroll popup">
|
||||
{#each pinnedMessages as message}
|
||||
{@const employee = getEmployee(message, employeeAcounts, employees)}
|
||||
<div class="message">
|
||||
<div class="header">
|
||||
{#await getEmployeeAccount(message) then employeeAccount}
|
||||
{#await getEmployee(employeeAccount?.employee) then employee}
|
||||
<div class="avatar">
|
||||
<Avatar size={'medium'} avatar={employee?.avatar} />
|
||||
</div>
|
||||
{/await}
|
||||
<span class="name">
|
||||
{formatName(employeeAccount?.name ?? '')}
|
||||
</span>
|
||||
{/await}
|
||||
<div class="avatar">
|
||||
<Avatar size={'medium'} avatar={employee?.avatar} />
|
||||
</div>
|
||||
<span class="name">
|
||||
{employee ? getName(employee) : ''}
|
||||
</span>
|
||||
<div
|
||||
class="cross"
|
||||
on:click={async () => {
|
||||
|
@ -1,24 +1,32 @@
|
||||
<script lang="ts">
|
||||
import { Account, Ref } from '@hcengineering/core'
|
||||
import contact, { EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import { Account, IdMap, Ref, toIdMap } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
|
||||
export let reactionAccounts: Ref<Account>[]
|
||||
let accounts: IdMap<EmployeeAccount> = new Map()
|
||||
let employees: IdMap<Employee> = new Map()
|
||||
|
||||
const client = getClient()
|
||||
let accountNames: string[] = []
|
||||
const query = createQuery()
|
||||
const empQ = createQuery()
|
||||
$: query.query(contact.class.EmployeeAccount, {}, (res) => {
|
||||
accounts = toIdMap(res)
|
||||
})
|
||||
|
||||
async function getAccountNames (reactionAccounts: Ref<EmployeeAccount>[]) {
|
||||
client
|
||||
.findAll(contact.class.EmployeeAccount, { _id: { $in: reactionAccounts } })
|
||||
.then((res) => (accountNames = res.map((a) => a.name)))
|
||||
empQ.query(contact.class.Employee, {}, (res) => (employees = toIdMap(res)))
|
||||
|
||||
function getAccName (acc: Ref<Account>, accounts: IdMap<EmployeeAccount>, employees: IdMap<Employee>): string {
|
||||
const account = accounts.get(acc as Ref<EmployeeAccount>)
|
||||
if (account !== undefined) {
|
||||
const emp = employees.get(account.employee)
|
||||
return emp ? getName(emp) : ''
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
$: getAccountNames(reactionAccounts as Ref<EmployeeAccount>[])
|
||||
</script>
|
||||
|
||||
{#each accountNames as name}
|
||||
{#each reactionAccounts as acc}
|
||||
<div>
|
||||
{formatName(name)}
|
||||
{getAccName(acc, accounts, employees)}
|
||||
</div>
|
||||
{/each}
|
||||
|
@ -2,8 +2,8 @@
|
||||
import attachment, { Attachment } from '@hcengineering/attachment'
|
||||
import AttachmentPreview from '@hcengineering/attachment-resources/src/components/AttachmentPreview.svelte'
|
||||
import { ChunterMessage } from '@hcengineering/chunter'
|
||||
import { EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import core, { Ref, WithLookup } from '@hcengineering/core'
|
||||
import contact, { Employee, EmployeeAccount, getName as getContactName } from '@hcengineering/contact'
|
||||
import core, { IdMap, Ref, toIdMap, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { Label, Scroller } from '@hcengineering/ui'
|
||||
import chunter from '../plugin'
|
||||
@ -16,11 +16,18 @@
|
||||
let savedMessages: WithLookup<ChunterMessage>[] = []
|
||||
let savedAttachmentsIds: Ref<Attachment>[] = []
|
||||
let savedAttachments: WithLookup<Attachment>[] = []
|
||||
let accounts: IdMap<EmployeeAccount> = new Map()
|
||||
let employees: IdMap<Employee> = new Map()
|
||||
|
||||
const messagesQuery = createQuery()
|
||||
const attachmentsQuery = createQuery()
|
||||
const savedMessagesQuery = createQuery()
|
||||
const savedAttachmentsQuery = createQuery()
|
||||
const accQ = createQuery()
|
||||
const empQ = createQuery()
|
||||
|
||||
accQ.query(contact.class.EmployeeAccount, {}, (res) => (accounts = toIdMap(res)))
|
||||
empQ.query(contact.class.Employee, {}, (res) => (employees = toIdMap(res)))
|
||||
|
||||
savedMessagesQuery.query(chunter.class.SavedMessages, {}, (res) => {
|
||||
savedMessagesIds = res.map((r) => r.attachedTo)
|
||||
@ -46,18 +53,9 @@
|
||||
)
|
||||
|
||||
$: savedAttachmentsIds &&
|
||||
attachmentsQuery.query(
|
||||
attachment.class.Attachment,
|
||||
{ _id: { $in: savedAttachmentsIds } },
|
||||
(res) => {
|
||||
savedAttachments = res
|
||||
},
|
||||
{
|
||||
lookup: {
|
||||
modifiedBy: core.class.Account
|
||||
}
|
||||
}
|
||||
)
|
||||
attachmentsQuery.query(attachment.class.Attachment, { _id: { $in: savedAttachmentsIds } }, (res) => {
|
||||
savedAttachments = res
|
||||
})
|
||||
|
||||
const pinnedQuery = createQuery()
|
||||
const pinnedIds: Ref<ChunterMessage>[] = []
|
||||
@ -82,10 +80,13 @@
|
||||
})
|
||||
}
|
||||
|
||||
function getName (a: WithLookup<Attachment>): string | undefined {
|
||||
const name = (a.$lookup?.modifiedBy as EmployeeAccount).name
|
||||
if (name !== undefined) {
|
||||
return formatName(name)
|
||||
function getName (a: Attachment): string | undefined {
|
||||
const acc = accounts.get(a.modifiedBy as Ref<EmployeeAccount>)
|
||||
if (acc !== undefined) {
|
||||
const emp = employees.get(acc?.employee)
|
||||
if (emp !== undefined) {
|
||||
return getContactName(emp)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -16,7 +16,7 @@
|
||||
import attachment, { Attachment } from '@hcengineering/attachment'
|
||||
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
|
||||
import type { ChunterSpace, Message, ThreadMessage } from '@hcengineering/chunter'
|
||||
import contact, { Employee, EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import core, {
|
||||
FindOptions,
|
||||
generateId,
|
||||
@ -124,7 +124,7 @@
|
||||
for (const account of accounts) {
|
||||
const employee = employees.get(account.employee)
|
||||
if (employee !== undefined) {
|
||||
res.push(formatName(employee.name))
|
||||
res.push(getName(employee))
|
||||
}
|
||||
}
|
||||
return res
|
||||
|
@ -1,19 +1,12 @@
|
||||
import { chunterId, ChunterMessage } from '@hcengineering/chunter'
|
||||
import contact, { EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import { Account, Class, Client, Obj, Ref, Space, getCurrentAccount, Timestamp } from '@hcengineering/core'
|
||||
import contact, { EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import { Class, Client, getCurrentAccount, Obj, Ref, Space, Timestamp } from '@hcengineering/core'
|
||||
import { Asset } from '@hcengineering/platform'
|
||||
import { getCurrentLocation, locationToUrl, navigate } from '@hcengineering/ui'
|
||||
import { writable, get } from 'svelte/store'
|
||||
import { get, writable } from 'svelte/store'
|
||||
|
||||
import chunter from './plugin'
|
||||
|
||||
export async function getUser (
|
||||
client: Client,
|
||||
user: Ref<EmployeeAccount> | Ref<Account>
|
||||
): Promise<EmployeeAccount | undefined> {
|
||||
return await client.findOne(contact.class.EmployeeAccount, { _id: user as Ref<EmployeeAccount> })
|
||||
}
|
||||
|
||||
export function getTime (time: number): string {
|
||||
let options: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: 'numeric' }
|
||||
if (!isToday(time)) {
|
||||
@ -44,13 +37,19 @@ export function classIcon (client: Client, _class: Ref<Class<Obj>>): Asset | und
|
||||
export async function getDmName (client: Client, dm: Space): Promise<string> {
|
||||
const myAccId = getCurrentAccount()._id
|
||||
|
||||
const employeeAccounts = await client.findAll(contact.class.EmployeeAccount, {
|
||||
let employeeAccounts: EmployeeAccount[] = await client.findAll(contact.class.EmployeeAccount, {
|
||||
_id: { $in: dm.members as Array<Ref<EmployeeAccount>> }
|
||||
})
|
||||
|
||||
const name = (dm.members.length > 1 ? employeeAccounts.filter((a) => a._id !== myAccId) : employeeAccounts)
|
||||
.map((a) => formatName(a.name))
|
||||
.join(', ')
|
||||
if (dm.members.length > 1) {
|
||||
employeeAccounts = employeeAccounts.filter((p) => p._id !== myAccId)
|
||||
}
|
||||
|
||||
const emloyees = await client.findAll(contact.class.Employee, {
|
||||
_id: { $in: employeeAccounts.map((p) => p.employee) }
|
||||
})
|
||||
|
||||
const name = emloyees.map((a) => getName(a)).join(', ')
|
||||
|
||||
return name
|
||||
}
|
||||
|
@ -76,6 +76,7 @@
|
||||
"Profile": "Profile",
|
||||
"ProfilePlaceholder": "Profile...",
|
||||
"CurrentEmployee": "Current employee",
|
||||
"MergeEmployee": "Merge employee"
|
||||
"MergeEmployee": "Merge employee",
|
||||
"DisplayName": "Display name"
|
||||
}
|
||||
}
|
@ -76,6 +76,7 @@
|
||||
"Profile": "Профиль",
|
||||
"ProfilePlaceholder": "Профиль...",
|
||||
"CurrentEmployee": "Текущий сотрудник",
|
||||
"MergeEmployee": "Объеденить сотрудника"
|
||||
"MergeEmployee": "Объеденить сотрудника",
|
||||
"DisplayName": "Отображаемое имя"
|
||||
}
|
||||
}
|
@ -16,8 +16,8 @@
|
||||
<script lang="ts">
|
||||
import { Contact, Employee, Organization } from '@hcengineering/contact'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Label } from '@hcengineering/ui'
|
||||
import contact from '../plugin'
|
||||
import EmployeePresenter from './EmployeePresenter.svelte'
|
||||
|
||||
import OrganizationPresenter from './OrganizationPresenter.svelte'
|
||||
import PersonPresenter from './PersonPresenter.svelte'
|
||||
@ -39,13 +39,10 @@
|
||||
const toEmployee = (contact: Contact) => contact as Employee
|
||||
</script>
|
||||
|
||||
{#if isPerson(value)}
|
||||
{#if isEmployee(value)}
|
||||
<EmployeePresenter {isInteractive} value={toEmployee(value)} />
|
||||
{:else if isPerson(value)}
|
||||
<PersonPresenter {isInteractive} {value} />
|
||||
{#if isEmployee(value) && toEmployee(value)?.active === false}
|
||||
<div class="ml-1">
|
||||
(<Label label={contact.string.Inactive} />)
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<OrganizationPresenter value={toOrg(value)} />
|
||||
{/if}
|
||||
|
197
plugins/contact-resources/src/components/EditEmployee.svelte
Normal file
197
plugins/contact-resources/src/components/EditEmployee.svelte
Normal file
@ -0,0 +1,197 @@
|
||||
<!--
|
||||
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||
// Copyright © 2021 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Employee, EmployeeAccount, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
||||
import { AccountRole, getCurrentAccount, Ref, Space } from '@hcengineering/core'
|
||||
import { changeName } from '@hcengineering/login-resources'
|
||||
import { AttributeEditor, Avatar, createQuery, EditableAvatar, getClient } from '@hcengineering/presentation'
|
||||
import setting, { IntegrationType } from '@hcengineering/setting'
|
||||
import { createFocusManager, EditBox, FocusHandler } from '@hcengineering/ui'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import contact from '../plugin'
|
||||
import ChannelsEditor from './ChannelsEditor.svelte'
|
||||
|
||||
export let object: Employee
|
||||
const client = getClient()
|
||||
|
||||
const account = getCurrentAccount() as EmployeeAccount
|
||||
|
||||
let avatarEditor: EditableAvatar
|
||||
|
||||
$: owner = account.employee === object._id
|
||||
$: editable = account.role >= AccountRole.Maintainer || owner
|
||||
let firstName = getFirstName(object.name)
|
||||
let lastName = getLastName(object.name)
|
||||
let displayName = object.displayName ?? ''
|
||||
|
||||
$: setName(object)
|
||||
|
||||
let email: string | undefined
|
||||
$: if (editable) {
|
||||
client.findOne(contact.class.EmployeeAccount, { employee: (object as Employee)._id }).then((acc) => {
|
||||
email = acc?.email
|
||||
})
|
||||
}
|
||||
|
||||
function setName (object: Person) {
|
||||
firstName = getFirstName(object.name)
|
||||
lastName = getLastName(object.name)
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
function firstNameChange () {
|
||||
changeName(firstName, getLastName(object.name))
|
||||
}
|
||||
|
||||
function lastNameChange () {
|
||||
changeName(getFirstName(object.name), lastName)
|
||||
}
|
||||
|
||||
function changeDisplayName () {
|
||||
client.update(object, {
|
||||
displayName: displayName === '' ? null : displayName
|
||||
})
|
||||
}
|
||||
|
||||
let integrations: Set<Ref<IntegrationType>> = new Set<Ref<IntegrationType>>()
|
||||
const settingsQuery = createQuery()
|
||||
$: settingsQuery.query(
|
||||
setting.class.Integration,
|
||||
{ space: account._id as string as Ref<Space>, disabled: false },
|
||||
(res) => {
|
||||
integrations = new Set(res.map((p) => p.type))
|
||||
}
|
||||
)
|
||||
|
||||
const sendOpen = () => dispatch('open', { ignoreKeys: ['comments', 'name', 'channels', 'city', 'displayName'] })
|
||||
onMount(sendOpen)
|
||||
|
||||
async function onAvatarDone () {
|
||||
if (object.avatar != null) {
|
||||
await avatarEditor.removeAvatar(object.avatar)
|
||||
}
|
||||
const avatar = await avatarEditor.createAvatar()
|
||||
await client.update(object, {
|
||||
avatar
|
||||
})
|
||||
}
|
||||
|
||||
const manager = createFocusManager()
|
||||
</script>
|
||||
|
||||
<FocusHandler {manager} />
|
||||
|
||||
{#if object !== undefined}
|
||||
<div class="flex-row-stretch flex-grow">
|
||||
<div class="mr-8">
|
||||
{#key object}
|
||||
{#if editable}
|
||||
<EditableAvatar
|
||||
avatar={object.avatar}
|
||||
{email}
|
||||
id={object._id}
|
||||
size={'x-large'}
|
||||
bind:this={avatarEditor}
|
||||
on:done={onAvatarDone}
|
||||
/>
|
||||
{:else}
|
||||
<Avatar avatar={object.avatar} size={'x-large'} />
|
||||
{/if}
|
||||
{/key}
|
||||
</div>
|
||||
<div class="flex-grow flex-col">
|
||||
<div class="flex-grow flex-col">
|
||||
<div class="name">
|
||||
{#if owner}
|
||||
<EditBox
|
||||
placeholder={contact.string.PersonFirstNamePlaceholder}
|
||||
bind:value={firstName}
|
||||
on:change={firstNameChange}
|
||||
focusIndex={1}
|
||||
/>
|
||||
{:else}
|
||||
{firstName}
|
||||
{/if}
|
||||
</div>
|
||||
<div class="name">
|
||||
{#if owner}
|
||||
<EditBox
|
||||
placeholder={contact.string.PersonLastNamePlaceholder}
|
||||
bind:value={lastName}
|
||||
on:change={lastNameChange}
|
||||
focusIndex={2}
|
||||
/>
|
||||
{:else}
|
||||
{lastName}
|
||||
{/if}
|
||||
</div>
|
||||
<div class="name">
|
||||
{#if editable}
|
||||
<EditBox
|
||||
placeholder={contact.string.DisplayName}
|
||||
bind:value={displayName}
|
||||
on:change={changeDisplayName}
|
||||
focusIndex={1}
|
||||
/>
|
||||
{:else}
|
||||
{displayName}
|
||||
{/if}
|
||||
</div>
|
||||
<div class="location">
|
||||
<AttributeEditor
|
||||
maxWidth="20rem"
|
||||
_class={contact.class.Person}
|
||||
{editable}
|
||||
{object}
|
||||
key="city"
|
||||
focusIndex={3}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="separator" />
|
||||
<div class="flex-row-center">
|
||||
<ChannelsEditor
|
||||
attachedTo={object._id}
|
||||
attachedClass={object._class}
|
||||
{editable}
|
||||
bind:integrations
|
||||
shape={'circle'}
|
||||
focusIndex={10}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
.name {
|
||||
font-weight: 500;
|
||||
font-size: 1.25rem;
|
||||
color: var(--theme-caption-color);
|
||||
}
|
||||
.location {
|
||||
margin-top: 0.25rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.separator {
|
||||
margin: 1rem 0;
|
||||
height: 1px;
|
||||
background-color: var(--divider-color);
|
||||
}
|
||||
</style>
|
@ -14,11 +14,11 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { combineName, Employee, EmployeeAccount, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
||||
import { combineName, EmployeeAccount, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
||||
import { getCurrentAccount, Ref, Space } from '@hcengineering/core'
|
||||
import { AttributeEditor, Avatar, createQuery, EditableAvatar, getClient } from '@hcengineering/presentation'
|
||||
import { AttributeEditor, createQuery, EditableAvatar, getClient } from '@hcengineering/presentation'
|
||||
import setting, { IntegrationType } from '@hcengineering/setting'
|
||||
import { EditBox, createFocusManager, FocusHandler } from '@hcengineering/ui'
|
||||
import { createFocusManager, EditBox, FocusHandler } from '@hcengineering/ui'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import contact from '../plugin'
|
||||
import ChannelsEditor from './ChannelsEditor.svelte'
|
||||
@ -26,24 +26,15 @@
|
||||
export let object: Person
|
||||
const client = getClient()
|
||||
|
||||
const hierarchy = client.getHierarchy()
|
||||
const account = getCurrentAccount() as EmployeeAccount
|
||||
|
||||
let avatarEditor: EditableAvatar
|
||||
|
||||
$: editable = !hierarchy.isDerived(object._class, contact.class.Employee)
|
||||
let firstName = getFirstName(object.name)
|
||||
let lastName = getLastName(object.name)
|
||||
|
||||
$: setName(object)
|
||||
|
||||
let email: string | undefined
|
||||
$: if (editable && hierarchy.isDerived(object._class, contact.class.Employee)) {
|
||||
client.findOne(contact.class.EmployeeAccount, { employee: (object as Employee)._id }).then((acc) => {
|
||||
email = acc?.email
|
||||
})
|
||||
}
|
||||
|
||||
function setName (object: Person) {
|
||||
firstName = getFirstName(object.name)
|
||||
lastName = getLastName(object.name)
|
||||
@ -52,13 +43,13 @@
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
function firstNameChange () {
|
||||
client.updateDoc(object._class, object.space, object._id, {
|
||||
client.update(object, {
|
||||
name: combineName(firstName, getLastName(object.name))
|
||||
})
|
||||
}
|
||||
|
||||
function lastNameChange () {
|
||||
client.updateDoc(object._class, object.space, object._id, {
|
||||
client.update(object, {
|
||||
name: combineName(getFirstName(object.name), lastName)
|
||||
})
|
||||
}
|
||||
@ -76,12 +67,12 @@
|
||||
const sendOpen = () => dispatch('open', { ignoreKeys: ['comments', 'name', 'channels', 'city'] })
|
||||
onMount(sendOpen)
|
||||
|
||||
async function onAvatarDone (e: any) {
|
||||
async function onAvatarDone () {
|
||||
if (object.avatar != null) {
|
||||
await avatarEditor.removeAvatar(object.avatar)
|
||||
}
|
||||
const avatar = await avatarEditor.createAvatar()
|
||||
await client.updateDoc(object._class, object.space, object._id, {
|
||||
await client.update(object, {
|
||||
avatar
|
||||
})
|
||||
}
|
||||
@ -95,55 +86,35 @@
|
||||
<div class="flex-row-stretch flex-grow">
|
||||
<div class="mr-8">
|
||||
{#key object}
|
||||
{#if editable}
|
||||
<EditableAvatar
|
||||
avatar={object.avatar}
|
||||
{email}
|
||||
id={object._id}
|
||||
size={'x-large'}
|
||||
bind:this={avatarEditor}
|
||||
on:done={onAvatarDone}
|
||||
/>
|
||||
{:else}
|
||||
<Avatar avatar={object.avatar} size={'x-large'} />
|
||||
{/if}
|
||||
<EditableAvatar
|
||||
avatar={object.avatar}
|
||||
id={object._id}
|
||||
size={'x-large'}
|
||||
bind:this={avatarEditor}
|
||||
on:done={onAvatarDone}
|
||||
/>
|
||||
{/key}
|
||||
</div>
|
||||
<div class="flex-grow flex-col">
|
||||
<div class="flex-grow flex-col">
|
||||
<div class="name">
|
||||
{#if editable}
|
||||
<EditBox
|
||||
placeholder={contact.string.PersonFirstNamePlaceholder}
|
||||
bind:value={firstName}
|
||||
on:change={firstNameChange}
|
||||
focusIndex={1}
|
||||
/>
|
||||
{:else}
|
||||
{firstName}
|
||||
{/if}
|
||||
<EditBox
|
||||
placeholder={contact.string.PersonFirstNamePlaceholder}
|
||||
bind:value={firstName}
|
||||
on:change={firstNameChange}
|
||||
focusIndex={1}
|
||||
/>
|
||||
</div>
|
||||
<div class="name">
|
||||
{#if editable}
|
||||
<EditBox
|
||||
placeholder={contact.string.PersonLastNamePlaceholder}
|
||||
bind:value={lastName}
|
||||
on:change={lastNameChange}
|
||||
focusIndex={2}
|
||||
/>
|
||||
{:else}
|
||||
{lastName}
|
||||
{/if}
|
||||
<EditBox
|
||||
placeholder={contact.string.PersonLastNamePlaceholder}
|
||||
bind:value={lastName}
|
||||
on:change={lastNameChange}
|
||||
focusIndex={2}
|
||||
/>
|
||||
</div>
|
||||
<div class="location">
|
||||
<AttributeEditor
|
||||
maxWidth="20rem"
|
||||
_class={contact.class.Person}
|
||||
{editable}
|
||||
{object}
|
||||
key="city"
|
||||
focusIndex={3}
|
||||
/>
|
||||
<AttributeEditor maxWidth="20rem" _class={contact.class.Person} {object} key="city" focusIndex={3} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -152,7 +123,6 @@
|
||||
<ChannelsEditor
|
||||
attachedTo={object._id}
|
||||
attachedClass={object._class}
|
||||
{editable}
|
||||
bind:integrations
|
||||
shape={'circle'}
|
||||
focusIndex={10}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Employee, EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import { Account } from '@hcengineering/core'
|
||||
import { Avatar, createQuery } from '@hcengineering/presentation'
|
||||
import { showPopup } from '@hcengineering/ui'
|
||||
@ -41,7 +41,7 @@
|
||||
<div class="flex-row-center" class:user-container={employee !== undefined} on:click={onClick}>
|
||||
{#if employee}
|
||||
<Avatar size={'x-small'} avatar={employee.avatar} />
|
||||
<div class="overflow-label user">{formatName(employee.name)}</div>
|
||||
<div class="overflow-label user">{getName(employee)}</div>
|
||||
{:else}
|
||||
<div class="overflow-label user">{value.email}</div>
|
||||
{/if}
|
||||
|
@ -2,11 +2,11 @@
|
||||
import { Employee } from '@hcengineering/contact'
|
||||
import { WithLookup } from '@hcengineering/core'
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import { showPopup } from '@hcengineering/ui'
|
||||
import { Label, showPopup } from '@hcengineering/ui'
|
||||
import { PersonLabelTooltip } from '..'
|
||||
import PersonPresenter from '../components/PersonPresenter.svelte'
|
||||
import contact from '../plugin'
|
||||
import EmployeePreviewPopup from './EmployeePreviewPopup.svelte'
|
||||
import EmployeeStatusPresenter from './EmployeeStatusPresenter.svelte'
|
||||
|
||||
export let value: WithLookup<Employee> | null | undefined
|
||||
export let tooltipLabels: PersonLabelTooltip | undefined = undefined
|
||||
@ -56,9 +56,9 @@
|
||||
{defaultName}
|
||||
/>
|
||||
</div>
|
||||
{#if value?.$lookup?.statuses?.length}
|
||||
<div class="pl-2 status content-color">
|
||||
<EmployeeStatusPresenter employee={value} />
|
||||
{#if value?.active === false}
|
||||
<div class="ml-1">
|
||||
(<Label label={contact.string.Inactive} />)
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { Employee, EmployeeAccount, formatName, Status } from '@hcengineering/contact'
|
||||
import { getCurrentAccount, Ref, Hierarchy, WithLookup } from '@hcengineering/core'
|
||||
import { Employee, EmployeeAccount, getName, Status } from '@hcengineering/contact'
|
||||
import { getCurrentAccount, Hierarchy, Ref, WithLookup } from '@hcengineering/core'
|
||||
import { Avatar, createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { Button, getPanelURI, Label, showPopup, resizeObserver } from '@hcengineering/ui'
|
||||
import EmployeeSetStatusPopup from './EmployeeSetStatusPopup.svelte'
|
||||
import { Button, getPanelURI, Label, resizeObserver, showPopup } from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import contact from '../plugin'
|
||||
import EmployeeSetStatusPopup from './EmployeeSetStatusPopup.svelte'
|
||||
import EmployeeStatusPresenter from './EmployeeStatusPresenter.svelte'
|
||||
import Edit from './icons/Edit.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import view from '@hcengineering/view'
|
||||
|
||||
export let employeeId: Ref<Employee>
|
||||
|
||||
@ -60,9 +60,9 @@
|
||||
>
|
||||
{#if employee}
|
||||
<div class="flex-col-center pb-2">
|
||||
<Avatar size="x-large" avatar={employee?.avatar} />
|
||||
<Avatar size="x-large" avatar={employee.avatar} />
|
||||
</div>
|
||||
<div class="pb-2">{formatName(employee?.name ?? '')}</div>
|
||||
<div class="pb-2">{getName(employee)}</div>
|
||||
<a href={`#${getPanelURI(view.component.EditDoc, employee._id, Hierarchy.mixinOrClass(employee), 'content')}`}
|
||||
><Label label={contact.string.ViewFullProfile} /></a
|
||||
>
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Channel, ChannelProvider, Employee, formatName } from '@hcengineering/contact'
|
||||
import { Channel, ChannelProvider, Employee, getName } from '@hcengineering/contact'
|
||||
import core, { Doc, DocumentUpdate, Mixin, Ref, TxProcessor } from '@hcengineering/core'
|
||||
import { leaveWorkspace } from '@hcengineering/login-resources'
|
||||
import { Avatar, Card, createQuery, EmployeeBox, getClient } from '@hcengineering/presentation'
|
||||
@ -217,7 +217,7 @@
|
||||
</MergeComparer>
|
||||
<MergeComparer key="name" {value} {targetEmp} onChange={select}>
|
||||
<svelte:fragment slot="item" let:item>
|
||||
{formatName(item.name)}
|
||||
{getName(item)}
|
||||
</svelte:fragment>
|
||||
</MergeComparer>
|
||||
{#each objectAttributes as attribute}
|
||||
@ -263,7 +263,7 @@
|
||||
</Grid>
|
||||
<div class="flex-col-center">
|
||||
<Avatar avatar={result.avatar} size={'large'} icon={contact.icon.Person} />
|
||||
{formatName(result.name)}
|
||||
{getName(result)}
|
||||
<DatePresenter value={result.birthday} />
|
||||
<StringEditor value={result.city} readonly placeholder={contact.string.Location} />
|
||||
<ChannelsDropdown
|
||||
|
@ -14,7 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import attachment from '@hcengineering/attachment'
|
||||
import contact, { Channel, Contact, formatName } from '@hcengineering/contact'
|
||||
import contact, { Channel, Contact, getName } from '@hcengineering/contact'
|
||||
import { Hierarchy } from '@hcengineering/core'
|
||||
import { Avatar, createQuery } from '@hcengineering/presentation'
|
||||
import { Component, Label, showPanel } from '@hcengineering/ui'
|
||||
@ -51,7 +51,7 @@
|
||||
if (!disabled) showPanel(view.component.EditDoc, object._id, Hierarchy.mixinOrClass(object), 'content')
|
||||
}}
|
||||
>
|
||||
{formatName(object.name)}
|
||||
{getName(object)}
|
||||
</div>
|
||||
<div class="description overflow-label">{object.city ?? ''}</div>
|
||||
<div class="footer flex flex-reverse flex-grow">
|
||||
|
@ -13,14 +13,14 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { formatName, Person } from '@hcengineering/contact'
|
||||
import { Employee, getName, Person } from '@hcengineering/contact'
|
||||
import { Hierarchy } from '@hcengineering/core'
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import { Avatar } from '@hcengineering/presentation'
|
||||
import { getPanelURI, Label, LabelAndProps, tooltip } from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
|
||||
export let value: Person | undefined | null
|
||||
export let value: Person | Employee | undefined | null
|
||||
export let inline: boolean = false
|
||||
export let isInteractive = true
|
||||
export let shouldShowAvatar: boolean = true
|
||||
@ -78,7 +78,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
{#if value && shouldShowName}
|
||||
<span class="eContentPresenterLabel">{formatName(value.name)}</span>
|
||||
<span class="eContentPresenterLabel">{getName(value)}</span>
|
||||
{/if}
|
||||
{#if !value && shouldShowName && defaultName}
|
||||
<div class="eContentPresenterLabel">
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { formatName, Person } from '@hcengineering/contact'
|
||||
import { getName, Person } from '@hcengineering/contact'
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import { LabelAndProps } from '@hcengineering/ui'
|
||||
@ -41,7 +41,7 @@
|
||||
? undefined
|
||||
: {
|
||||
label: presentation.string.InltPropsValue,
|
||||
props: { value: formatName(value.name) }
|
||||
props: { value: getName(value) }
|
||||
}
|
||||
}
|
||||
const component = value ? tooltipLabels.component : undefined
|
||||
@ -50,7 +50,7 @@
|
||||
? tooltipLabels.personLabel
|
||||
: presentation.string.InltPropsValue
|
||||
: undefined
|
||||
const props = tooltipLabels.props ? tooltipLabels.props : value ? { value: formatName(value.name) } : undefined
|
||||
const props = tooltipLabels.props ? tooltipLabels.props : value ? { value: getName(value) } : undefined
|
||||
return {
|
||||
component,
|
||||
label,
|
||||
|
@ -14,48 +14,49 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Channel, Contact, Employee, formatName, getGravatarUrl } from '@hcengineering/contact'
|
||||
import { Channel, Contact, Employee, getGravatarUrl, getName } from '@hcengineering/contact'
|
||||
import { Class, Client, DocumentQuery, Ref, RelatedDocument, WithLookup } from '@hcengineering/core'
|
||||
import { leaveWorkspace } from '@hcengineering/login-resources'
|
||||
import { IntlString, Resources } from '@hcengineering/platform'
|
||||
import { Avatar, getClient, MessageBox, ObjectSearchResult, UserInfo, getFileUrl } from '@hcengineering/presentation'
|
||||
import { Avatar, getClient, getFileUrl, MessageBox, ObjectSearchResult, UserInfo } from '@hcengineering/presentation'
|
||||
import { AnyComponent, AnySvelteComponent, showPopup } from '@hcengineering/ui'
|
||||
import AccountArrayEditor from './components/AccountArrayEditor.svelte'
|
||||
import AccountBox from './components/AccountBox.svelte'
|
||||
import ChannelFilter from './components/ChannelFilter.svelte'
|
||||
import Channels from './components/Channels.svelte'
|
||||
import ChannelsDropdown from './components/ChannelsDropdown.svelte'
|
||||
import ChannelsEditor from './components/ChannelsEditor.svelte'
|
||||
import ChannelsPresenter from './components/ChannelsPresenter.svelte'
|
||||
import ChannelsView from './components/ChannelsView.svelte'
|
||||
import ContactArrayEditor from './components/ContactArrayEditor.svelte'
|
||||
import ContactPresenter from './components/ContactPresenter.svelte'
|
||||
import ContactRefPresenter from './components/ContactRefPresenter.svelte'
|
||||
import Contacts from './components/Contacts.svelte'
|
||||
import ContactsTabs from './components/ContactsTabs.svelte'
|
||||
import CreateEmployee from './components/CreateEmployee.svelte'
|
||||
import CreateOrganization from './components/CreateOrganization.svelte'
|
||||
import CreatePerson from './components/CreatePerson.svelte'
|
||||
import EditEmployee from './components/EditEmployee.svelte'
|
||||
import EditMember from './components/EditMember.svelte'
|
||||
import EditOrganization from './components/EditOrganization.svelte'
|
||||
import EditPerson from './components/EditPerson.svelte'
|
||||
import EmployeeAccountPresenter from './components/EmployeeAccountPresenter.svelte'
|
||||
import EmployeeAccountRefPresenter from './components/EmployeeAccountRefPresenter.svelte'
|
||||
import EmployeeArrayEditor from './components/EmployeeArrayEditor.svelte'
|
||||
import AccountArrayEditor from './components/AccountArrayEditor.svelte'
|
||||
import EmployeeBrowser from './components/EmployeeBrowser.svelte'
|
||||
import EmployeeEditor from './components/EmployeeEditor.svelte'
|
||||
import EmployeePresenter from './components/EmployeePresenter.svelte'
|
||||
import EmployeeRefPresenter from './components/EmployeeRefPresenter.svelte'
|
||||
import MemberPresenter from './components/MemberPresenter.svelte'
|
||||
import MembersPresenter from './components/MembersPresenter.svelte'
|
||||
import Members from './components/Members.svelte'
|
||||
import MembersPresenter from './components/MembersPresenter.svelte'
|
||||
import MergeEmployee from './components/MergeEmployee.svelte'
|
||||
import OrganizationEditor from './components/OrganizationEditor.svelte'
|
||||
import OrganizationPresenter from './components/OrganizationPresenter.svelte'
|
||||
import PersonEditor from './components/PersonEditor.svelte'
|
||||
import PersonPresenter from './components/PersonPresenter.svelte'
|
||||
import SocialEditor from './components/SocialEditor.svelte'
|
||||
import ContactRefPresenter from './components/ContactRefPresenter.svelte'
|
||||
import PersonRefPresenter from './components/PersonRefPresenter.svelte'
|
||||
import EmployeeRefPresenter from './components/EmployeeRefPresenter.svelte'
|
||||
import ChannelFilter from './components/ChannelFilter.svelte'
|
||||
import AccountBox from './components/AccountBox.svelte'
|
||||
import MergeEmployee from './components/MergeEmployee.svelte'
|
||||
import ContactArrayEditor from './components/ContactArrayEditor.svelte'
|
||||
import SocialEditor from './components/SocialEditor.svelte'
|
||||
import contact from './plugin'
|
||||
import {
|
||||
employeeSort,
|
||||
@ -88,7 +89,7 @@ export {
|
||||
|
||||
const toObjectSearchResult = (e: WithLookup<Contact>): ObjectSearchResult => ({
|
||||
doc: e,
|
||||
title: formatName(e.name),
|
||||
title: getName(e),
|
||||
icon: Avatar,
|
||||
iconProps: { size: 'x-small', avatar: e.avatar },
|
||||
component: UserInfo,
|
||||
@ -167,6 +168,7 @@ export default async (): Promise<Resources> => ({
|
||||
CreatePerson,
|
||||
CreateOrganization,
|
||||
EditPerson,
|
||||
EditEmployee,
|
||||
EditOrganization,
|
||||
SocialEditor,
|
||||
Contacts,
|
||||
|
@ -61,7 +61,8 @@ export default mergeIds(contactId, contact, {
|
||||
CreateEmployee: '' as IntlString,
|
||||
Inactive: '' as IntlString,
|
||||
NotSpecified: '' as IntlString,
|
||||
MergeEmployee: '' as IntlString
|
||||
MergeEmployee: '' as IntlString,
|
||||
DisplayName: '' as IntlString
|
||||
},
|
||||
function: {
|
||||
EmployeeSort: '' as SortFunc,
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { ChannelProvider, Contact, Employee, EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import { ChannelProvider, Contact, Employee, EmployeeAccount, formatName, getName } from '@hcengineering/contact'
|
||||
import { Doc, getCurrentAccount, ObjQueryType, Ref, Timestamp, toIdMap } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { TemplateDataProvider } from '@hcengineering/templates'
|
||||
@ -61,8 +61,10 @@ export async function employeeSort (value: Array<Ref<Employee>>): Promise<Array<
|
||||
}
|
||||
|
||||
if (employeeId1 != null && employeeId2 != null) {
|
||||
const name1 = formatName(employees.get(employeeId1)?.name ?? '')
|
||||
const name2 = formatName(employees.get(employeeId2)?.name ?? '')
|
||||
const employee1 = employees.get(employeeId1)
|
||||
const employee2 = employees.get(employeeId2)
|
||||
const name1 = employee1 != null ? getName(employee1) : ''
|
||||
const name2 = employee2 != null ? getName(employee2) : ''
|
||||
|
||||
return name1.localeCompare(name2)
|
||||
}
|
||||
@ -126,7 +128,7 @@ export async function getContactName (provider: TemplateDataProvider): Promise<s
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
if (hierarchy.isDerived(value._class, contact.class.Person)) {
|
||||
return formatName(value.name)
|
||||
return getName(value)
|
||||
} else {
|
||||
return value.name
|
||||
}
|
||||
|
@ -144,6 +144,7 @@ export interface Employee extends Person {
|
||||
active: boolean
|
||||
mergedTo?: Ref<Employee>
|
||||
statuses?: number
|
||||
displayName?: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,6 +194,27 @@ export function formatName (name: string): string {
|
||||
return getLastName(name) + ' ' + getFirstName(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function getName (value: Contact): string {
|
||||
if (isEmployee(value)) {
|
||||
return value.displayName ?? formatName(value.name)
|
||||
}
|
||||
if (isPerson(value)) {
|
||||
return formatName(value.name)
|
||||
}
|
||||
return value.name
|
||||
}
|
||||
|
||||
function isEmployee (value: Contact): value is Employee {
|
||||
return value._class === contactPlugin.class.Employee
|
||||
}
|
||||
|
||||
function isPerson (value: Contact): value is Person {
|
||||
return value._class === contactPlugin.class.Person
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
|
@ -14,8 +14,14 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { Channel, Contact, EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import { Ref, SortingOrder } from '@hcengineering/core'
|
||||
import contact, {
|
||||
Channel,
|
||||
Contact,
|
||||
Employee,
|
||||
EmployeeAccount,
|
||||
getName as getContactName
|
||||
} from '@hcengineering/contact'
|
||||
import { IdMap, Ref, SortingOrder, toIdMap } from '@hcengineering/core'
|
||||
import { Message, SharedMessage } from '@hcengineering/gmail'
|
||||
import { NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
@ -33,12 +39,17 @@
|
||||
/(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/
|
||||
|
||||
let messages: Message[] = []
|
||||
let accounts: EmployeeAccount[] = []
|
||||
let accounts: IdMap<EmployeeAccount> = new Map()
|
||||
let employees: IdMap<Employee> = new Map()
|
||||
let selected: Set<Ref<SharedMessage>> = new Set<Ref<SharedMessage>>()
|
||||
let selectable = false
|
||||
|
||||
const messagesQuery = createQuery()
|
||||
const accauntsQuery = createQuery()
|
||||
const accountsQuery = createQuery()
|
||||
const employeesQuery = createQuery()
|
||||
|
||||
accountsQuery.query(contact.class.EmployeeAccount, {}, (res) => (accounts = toIdMap(res)))
|
||||
employeesQuery.query(contact.class.Employee, {}, (res) => (employees = toIdMap(res)))
|
||||
|
||||
const notificationClient = NotificationClientImpl.getClient()
|
||||
|
||||
@ -49,8 +60,6 @@
|
||||
(res) => {
|
||||
messages = res
|
||||
notificationClient.updateLastView(channelId, channel._class, undefined, true)
|
||||
const accountsIds = new Set(messages.map((p) => p.modifiedBy as Ref<EmployeeAccount>))
|
||||
updateAccountsQuery(accountsIds)
|
||||
},
|
||||
{ sort: { sendOn: SortingOrder.Descending } }
|
||||
)
|
||||
@ -58,12 +67,6 @@
|
||||
|
||||
$: updateMessagesQuery(channel._id)
|
||||
|
||||
function updateAccountsQuery (accountsIds: Set<Ref<EmployeeAccount>>): void {
|
||||
accauntsQuery.query(contact.class.EmployeeAccount, { _id: { $in: Array.from(accountsIds) } }, (result) => {
|
||||
accounts = result
|
||||
})
|
||||
}
|
||||
|
||||
const client = getClient()
|
||||
|
||||
async function share (): Promise<void> {
|
||||
@ -75,7 +78,7 @@
|
||||
object._class,
|
||||
'gmailSharedMessages',
|
||||
{
|
||||
messages: convertMessages(selectedMessages, accounts)
|
||||
messages: convertMessages(selectedMessages, accounts, employees)
|
||||
}
|
||||
)
|
||||
await notificationClient.updateLastView(channel._id, channel._class, undefined, true)
|
||||
@ -88,25 +91,36 @@
|
||||
selected = selected
|
||||
}
|
||||
|
||||
function convertMessages (messages: Message[], accounts: EmployeeAccount[]): SharedMessage[] {
|
||||
function convertMessages (
|
||||
messages: Message[],
|
||||
accounts: IdMap<EmployeeAccount>,
|
||||
employees: IdMap<Employee>
|
||||
): SharedMessage[] {
|
||||
return messages.map((m) => {
|
||||
return {
|
||||
...m,
|
||||
_id: m._id as string as Ref<SharedMessage>,
|
||||
sender: getName(m, accounts, true),
|
||||
receiver: getName(m, accounts, false)
|
||||
sender: getName(m, accounts, employees, true),
|
||||
receiver: getName(m, accounts, employees, false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getName (message: Message, accounts: EmployeeAccount[], sender: boolean): string {
|
||||
function getName (
|
||||
message: Message,
|
||||
accounts: IdMap<EmployeeAccount>,
|
||||
employees: IdMap<Employee>,
|
||||
sender: boolean
|
||||
): string {
|
||||
if (message.incoming === sender) {
|
||||
return `${formatName(object.name)} (${channel.value})`
|
||||
return `${getContactName(object)} (${channel.value})`
|
||||
} else {
|
||||
const account = accounts.find((p) => p._id === message.modifiedBy)
|
||||
const account = accounts.get(message.modifiedBy as Ref<EmployeeAccount>)
|
||||
const emp = account ? employees.get(account?.employee) : undefined
|
||||
const value = message.incoming ? message.to : message.from
|
||||
const email = value.match(EMAIL_REGEX)
|
||||
return account ? `${formatName(account.name)} (${email?.[0] ?? value})` : email?.[0] ?? value
|
||||
const emailVal = email?.[0] ?? value
|
||||
return emp ? `${getContactName(emp)} (${emailVal})` : emailVal
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -154,7 +168,7 @@
|
||||
<Scroller>
|
||||
<div class="popupPanel-body__main-content py-4 clear-mins flex-no-shrink">
|
||||
{#if messages && messages.length > 0}
|
||||
<Messages messages={convertMessages(messages, accounts)} {selectable} bind:selected on:select />
|
||||
<Messages messages={convertMessages(messages, accounts, employees)} {selectable} bind:selected on:select />
|
||||
<div class="clear-mins h-4 flex-no-shrink" />
|
||||
{:else}
|
||||
<div class="flex-col-center justify-center h-full">
|
||||
|
@ -14,8 +14,8 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { Channel, formatName } from '@hcengineering/contact'
|
||||
import { Class, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||
import contact, { Channel, Contact, getName } from '@hcengineering/contact'
|
||||
import { Class, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||
import { SharedMessage } from '@hcengineering/gmail'
|
||||
import { NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
@ -31,10 +31,11 @@
|
||||
import IntegrationSelector from './IntegrationSelector.svelte'
|
||||
import NewMessage from './NewMessage.svelte'
|
||||
|
||||
export let _id: Ref<Doc>
|
||||
export let _class: Ref<Class<Doc>>
|
||||
export let _id: Ref<Contact>
|
||||
export let _class: Ref<Class<Contact>>
|
||||
|
||||
let object: Contact
|
||||
|
||||
let object: any
|
||||
let newMessage: boolean = false
|
||||
let currentMessage: SharedMessage | undefined = undefined
|
||||
let channel: Channel | undefined = undefined
|
||||
@ -115,7 +116,7 @@
|
||||
<span class="wrapped-title">Email</span>
|
||||
<span class="wrapped-subtitle">
|
||||
<Label label={gmail.string.YouAnd} />
|
||||
<b>{formatName(object.name)}</b>
|
||||
<b>{getName(object)}</b>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import attachmentP, { Attachment } from '@hcengineering/attachment'
|
||||
import { AttachmentPresenter } from '@hcengineering/attachment-resources'
|
||||
import contact, { Channel, Contact, formatName } from '@hcengineering/contact'
|
||||
import contact, { Channel, Contact, getName } from '@hcengineering/contact'
|
||||
import { Account, Data, generateId, Ref } from '@hcengineering/core'
|
||||
import { NewMessage, SharedMessage } from '@hcengineering/gmail'
|
||||
import { NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||
@ -172,7 +172,7 @@
|
||||
/>
|
||||
<div class="flex-grow flex-col">
|
||||
<Label label={plugin.string.NewMessage} />
|
||||
<span class="content-accent-color"><b>{formatName(object.name)} ({channel.value})</b></span>
|
||||
<span class="content-accent-color"><b>{getName(object)} ({channel.value})</b></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="buttons-group small-gap">
|
||||
|
@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import attachmentP, { Attachment } from '@hcengineering/attachment'
|
||||
import { AttachmentPresenter } from '@hcengineering/attachment-resources'
|
||||
import contact, { Channel, Contact, formatName } from '@hcengineering/contact'
|
||||
import contact, { Channel, Contact, getName as getContactName } from '@hcengineering/contact'
|
||||
import { Account, generateId, getCurrentAccount, Ref, toIdMap } from '@hcengineering/core'
|
||||
import { NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||
import { getResource, setPlatformStatus, unknownError } from '@hcengineering/platform'
|
||||
@ -183,7 +183,7 @@
|
||||
function getName (channel: Channel): string {
|
||||
const contact = contactMap.get(channel.attachedTo as Ref<Contact>)
|
||||
if (contact === undefined) return channel.value
|
||||
return `${formatName(contact.name)} (${channel.value})`
|
||||
return `${getContactName(contact)} (${channel.value})`
|
||||
}
|
||||
|
||||
const settingsQuery = createQuery()
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Employee, formatName } from '@hcengineering/contact'
|
||||
import { Employee, getName } from '@hcengineering/contact'
|
||||
import { Ref, TxOperations } from '@hcengineering/core'
|
||||
import { Department, fromTzDate, Request, RequestType, Staff } from '@hcengineering/hr'
|
||||
import { MessageBox } from '@hcengineering/presentation'
|
||||
@ -30,7 +30,7 @@ export async function addMember (client: TxOperations, employee?: Employee, valu
|
||||
MessageBox,
|
||||
{
|
||||
label: hr.string.MoveStaff,
|
||||
labelProps: { name: formatName(employee.name) },
|
||||
labelProps: { name: getName(employee) },
|
||||
message: hr.string.MoveStaffDescr,
|
||||
params: {
|
||||
current: current.name,
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { formatName, Person } from '@hcengineering/contact'
|
||||
import contact, { getName, Person } from '@hcengineering/contact'
|
||||
import { Ref } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import type { Applicant } from '@hcengineering/recruit'
|
||||
@ -39,7 +39,7 @@
|
||||
{#if shortLabel}<Label label={shortLabel} />-{/if}{value.number}
|
||||
</div>
|
||||
{#if person}
|
||||
<div class="ml-1">{formatName(person.name)}</div>
|
||||
<div class="ml-1">{getName(person)}</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import attachment from '@hcengineering/attachment'
|
||||
import chunter from '@hcengineering/chunter'
|
||||
import contact, { Channel, formatName, Person } from '@hcengineering/contact'
|
||||
import contact, { Channel, getName, Person } from '@hcengineering/contact'
|
||||
import { ChannelsEditor } from '@hcengineering/contact-resources'
|
||||
import { Hierarchy } from '@hcengineering/core'
|
||||
import { Avatar, createQuery, getClient } from '@hcengineering/presentation'
|
||||
@ -58,7 +58,7 @@
|
||||
}
|
||||
}}
|
||||
>
|
||||
{formatName(candidate.name)}
|
||||
{getName(candidate)}
|
||||
</div>
|
||||
{#if client.getHierarchy().hasMixin(candidate, recruit.mixin.Candidate)}
|
||||
{@const cand = client.getHierarchy().as(candidate, recruit.mixin.Candidate)}
|
||||
|
@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import { AttachmentsPresenter } from '@hcengineering/attachment-resources'
|
||||
import { CommentsPresenter } from '@hcengineering/chunter-resources'
|
||||
import contact, { formatName } from '@hcengineering/contact'
|
||||
import contact, { getName } from '@hcengineering/contact'
|
||||
import { Hierarchy, WithLookup } from '@hcengineering/core'
|
||||
import notification from '@hcengineering/notification'
|
||||
import { Avatar } from '@hcengineering/presentation'
|
||||
@ -43,7 +43,7 @@
|
||||
<Avatar avatar={object.$lookup?.attachedTo?.avatar} size={'medium'} />
|
||||
<div class="flex-grow flex-col min-w-0 ml-2">
|
||||
<div class="fs-title over-underline lines-limit-2">
|
||||
{formatName(object.$lookup?.attachedTo?.name ?? '')}
|
||||
{object.$lookup?.attachedTo ? getName(object.$lookup.attachedTo) : ''}
|
||||
</div>
|
||||
<div class="text-sm lines-limit-2">{object.$lookup?.attachedTo?.title ?? ''}</div>
|
||||
</div>
|
||||
|
@ -15,7 +15,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import calendar from '@hcengineering/calendar'
|
||||
import { formatName, Person } from '@hcengineering/contact'
|
||||
import { getName, Person } from '@hcengineering/contact'
|
||||
import { Hierarchy } from '@hcengineering/core'
|
||||
import { Avatar } from '@hcengineering/presentation'
|
||||
import { showPanel, tooltip } from '@hcengineering/ui'
|
||||
@ -38,7 +38,7 @@
|
||||
<div
|
||||
class="flex-presenter"
|
||||
class:inline-presenter={inline}
|
||||
use:tooltip={{ label: calendar.string.PersonsLabel, props: { name: formatName(p.name) } }}
|
||||
use:tooltip={{ label: calendar.string.PersonsLabel, props: { name: getName(p) } }}
|
||||
on:click={() => onClick(p)}
|
||||
>
|
||||
<div class="icon">
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import { Ref } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Request } from '@hcengineering/request'
|
||||
@ -25,18 +25,31 @@
|
||||
|
||||
export let value: Request
|
||||
|
||||
let employee: EmployeeAccount | undefined
|
||||
let account: EmployeeAccount | undefined
|
||||
let employee: Employee | undefined
|
||||
|
||||
const query = createQuery()
|
||||
|
||||
$: query.query(
|
||||
contact.class.EmployeeAccount,
|
||||
{ _id: value.tx.modifiedBy as Ref<EmployeeAccount> },
|
||||
(account) => {
|
||||
;[employee] = account
|
||||
(res) => {
|
||||
;[account] = res
|
||||
},
|
||||
{ limit: 1 }
|
||||
)
|
||||
|
||||
const employeeQuery = createQuery()
|
||||
|
||||
$: account &&
|
||||
employeeQuery.query(
|
||||
contact.class.Employee,
|
||||
{ _id: account.employee },
|
||||
(res) => {
|
||||
;[employee] = res
|
||||
},
|
||||
{ limit: 1 }
|
||||
)
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
@ -44,7 +57,7 @@
|
||||
<div class="label">
|
||||
<div class="bold">
|
||||
{#if employee}
|
||||
{formatName(employee.name)}
|
||||
{getName(employee)}
|
||||
{/if}
|
||||
</div>
|
||||
<span class="lower">
|
||||
|
@ -14,7 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { Employee, EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import { PersonPresenter } from '@hcengineering/contact-resources'
|
||||
import { EmployeePresenter } from '@hcengineering/contact-resources'
|
||||
import { AccountRole, getCurrentAccount, IdMap, SortingOrder, toIdMap } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { DropdownIntlItem, DropdownLabelsIntl, Icon, Label } from '@hcengineering/ui'
|
||||
@ -70,7 +70,7 @@
|
||||
{@const employee = employees.get(account.employee)}
|
||||
<div class="flex-between">
|
||||
{#if employee}
|
||||
<PersonPresenter value={employee} isInteractive={false} />
|
||||
<EmployeePresenter value={employee} isInteractive={false} />
|
||||
{:else}
|
||||
{formatName(account.name)}
|
||||
{/if}
|
||||
|
@ -30,6 +30,7 @@
|
||||
let employee: Employee | undefined
|
||||
let firstName: string
|
||||
let lastName: string
|
||||
let displayName: string = ''
|
||||
const employeeQ = createQuery()
|
||||
|
||||
const account = getCurrentAccount() as EmployeeAccount
|
||||
@ -43,6 +44,7 @@
|
||||
employee = res[0]
|
||||
firstName = getFirstName(employee.name)
|
||||
lastName = getLastName(employee.name)
|
||||
displayName = employee.displayName ?? ''
|
||||
},
|
||||
{ limit: 1 }
|
||||
)
|
||||
@ -76,6 +78,14 @@
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function changeDisplayName () {
|
||||
if (employee) {
|
||||
client.update(employee, {
|
||||
displayName: displayName === '' ? null : displayName
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<FocusHandler {manager} />
|
||||
@ -118,6 +128,13 @@
|
||||
changeName(firstName, lastName)
|
||||
}}
|
||||
/>
|
||||
<EditBox
|
||||
placeholder={contactRes.string.DisplayName}
|
||||
bind:value={displayName}
|
||||
kind={'large-style'}
|
||||
focusIndex={2}
|
||||
on:change={changeDisplayName}
|
||||
/>
|
||||
<div class="location">
|
||||
<AttributeEditor
|
||||
maxWidth="20rem"
|
||||
|
@ -1,4 +1,4 @@
|
||||
import contact, { EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import contact, { EmployeeAccount, getName } from '@hcengineering/contact'
|
||||
import { Class, Doc, Hierarchy, Ref } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import setting from '@hcengineering/setting'
|
||||
@ -62,5 +62,10 @@ export async function getOwnerName (provider: TemplateDataProvider): Promise<str
|
||||
const employeeAccount = await client.findOne(contact.class.EmployeeAccount, {
|
||||
_id: value.modifiedBy as Ref<EmployeeAccount>
|
||||
})
|
||||
return employeeAccount != null ? formatName(employeeAccount.name) : undefined
|
||||
if (employeeAccount !== undefined) {
|
||||
const employee = await client.findOne(contact.class.Employee, {
|
||||
_id: employeeAccount.employee
|
||||
})
|
||||
return employee != null ? getName(employee) : undefined
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
<script lang="ts">
|
||||
import attachment from '@hcengineering/attachment'
|
||||
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
|
||||
import contact, { Channel, Contact, EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import contact, { Channel, Contact, EmployeeAccount, getName as getContactName } from '@hcengineering/contact'
|
||||
import { Class, generateId, getCurrentAccount, Ref, SortingOrder, Space } from '@hcengineering/core'
|
||||
import { NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
@ -221,7 +221,7 @@
|
||||
<span class="wrapped-title">Telegram</span>
|
||||
<span class="wrapped-subtitle">
|
||||
<Label label={telegram.string.YouAnd} />
|
||||
<b>{formatName(object.name)}</b>
|
||||
<b>{getContactName(object)}</b>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Employee, formatName } from '@hcengineering/contact'
|
||||
import { Employee, getName } from '@hcengineering/contact'
|
||||
import core, {
|
||||
AttachedData,
|
||||
Class,
|
||||
@ -406,7 +406,7 @@ export async function mapKanbanCategories (
|
||||
.map((employee) => {
|
||||
return {
|
||||
_id: employee._id,
|
||||
title: formatName(employee.name),
|
||||
title: getName(employee),
|
||||
color: UNSET_COLOR,
|
||||
icon: undefined
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { formatName } from '@hcengineering/contact'
|
||||
import contact, { Contact, getName } from '@hcengineering/contact'
|
||||
import { Class, ClassifierKind, Doc, Mixin, Obj, Ref } from '@hcengineering/core'
|
||||
import notification from '@hcengineering/notification'
|
||||
import { Panel } from '@hcengineering/panel'
|
||||
@ -40,6 +40,8 @@
|
||||
export let _id: Ref<Doc>
|
||||
export let _class: Ref<Class<Doc>>
|
||||
|
||||
console.log('OPEN EDIT DOC')
|
||||
|
||||
let realObjectClass: Ref<Class<Doc>> = _class
|
||||
let lastId: Ref<Doc> = _id
|
||||
let lastClass: Ref<Class<Doc>> = _class
|
||||
@ -223,7 +225,7 @@
|
||||
const name = (object as any).name
|
||||
if (name !== undefined) {
|
||||
if (hierarchy.isDerived(object._class, contact.class.Person)) {
|
||||
return formatName(name)
|
||||
return getName(object as Contact)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import contact, { Contact, contactId, Employee, formatName, Organization, Person } from '@hcengineering/contact'
|
||||
import contact, { Contact, contactId, Employee, getName, Organization, Person } from '@hcengineering/contact'
|
||||
import core, {
|
||||
AnyAttribute,
|
||||
ArrOf,
|
||||
@ -279,7 +279,7 @@ export function personHTMLPresenter (doc: Doc, control: TriggerControl): string
|
||||
const front = getMetadata(login.metadata.FrontUrl) ?? ''
|
||||
const path = `${workbenchId}/${control.workspace.name}/${contactId}#${view.component.EditDoc}|${person._id}|${person._class}|content`
|
||||
const link = concatLink(front, path)
|
||||
return `<a href="${link}">${formatName(person.name)}</a>`
|
||||
return `<a href="${link}">${getName(person)}</a>`
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,7 +287,7 @@ export function personHTMLPresenter (doc: Doc, control: TriggerControl): string
|
||||
*/
|
||||
export function personTextPresenter (doc: Doc): string {
|
||||
const person = doc as Person
|
||||
return `${formatName(person.name)}`
|
||||
return `${getName(person)}`
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import contact, { Contact, Employee, EmployeeAccount, formatName } from '@hcengineering/contact'
|
||||
import contact, { Contact, Employee, EmployeeAccount, formatName, getName } from '@hcengineering/contact'
|
||||
import core, {
|
||||
Doc,
|
||||
Ref,
|
||||
@ -318,7 +318,7 @@ export async function OnRequestRemove (tx: Tx, control: TriggerControl): Promise
|
||||
export async function RequestHTMLPresenter (doc: Doc, control: TriggerControl): Promise<string> {
|
||||
const request = doc as Request
|
||||
const employee = (await control.findAll(contact.class.Employee, { _id: request.attachedTo }))[0]
|
||||
const who = formatName(employee.name)
|
||||
const who = getName(employee)
|
||||
const type = await translate(control.modelDb.getObject(request.type).label, {})
|
||||
|
||||
const date = tzDateEqual(request.tzDate, request.tzDueDate)
|
||||
@ -336,7 +336,7 @@ export async function RequestHTMLPresenter (doc: Doc, control: TriggerControl):
|
||||
export async function RequestTextPresenter (doc: Doc, control: TriggerControl): Promise<string> {
|
||||
const request = doc as Request
|
||||
const employee = (await control.findAll(contact.class.Employee, { _id: request.attachedTo }))[0]
|
||||
const who = formatName(employee.name)
|
||||
const who = getName(employee)
|
||||
const type = await translate(control.modelDb.getObject(request.type).label, {})
|
||||
|
||||
const date = tzDateEqual(request.tzDate, request.tzDueDate)
|
||||
|
Loading…
Reference in New Issue
Block a user