mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 11:42:30 +03:00
UBER-665: Rename EmployeeAccount->PersonAccount (#3550)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
9acc1b86a0
commit
161d26ebeb
@ -49,7 +49,7 @@ export async function generateIssues (
|
|||||||
options: IssueOptions
|
options: IssueOptions
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const connection = await connect(transactorUrl, workspaceId)
|
const connection = await connect(transactorUrl, workspaceId)
|
||||||
const accounts = await connection.findAll(contact.class.EmployeeAccount, {})
|
const accounts = await connection.findAll(contact.class.PersonAccount, {})
|
||||||
const account = faker.random.arrayElement(accounts)
|
const account = faker.random.arrayElement(accounts)
|
||||||
const client = new TxOperations(connection, account._id)
|
const client = new TxOperations(connection, account._id)
|
||||||
const ctx = new MeasureMetricsContext('recruit', {})
|
const ctx = new MeasureMetricsContext('recruit', {})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import contact, { Channel, Employee, EmployeeAccount, Person } from '@hcengineering/contact'
|
import contact, { Channel, PersonAccount, Person, Employee } from '@hcengineering/contact'
|
||||||
import core, {
|
import core, {
|
||||||
AttachedData,
|
AttachedData,
|
||||||
Data,
|
Data,
|
||||||
@ -48,9 +48,9 @@ export async function generateContacts (
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const connection = await connect(transactorUrl, workspaceId)
|
const connection = await connect(transactorUrl, workspaceId)
|
||||||
|
|
||||||
const accounts = await connection.findAll(contact.class.EmployeeAccount, {})
|
const accounts = await connection.findAll(contact.class.PersonAccount, {})
|
||||||
const accountIds = accounts.map((a) => a._id)
|
const accountIds = accounts.map((a) => a._id)
|
||||||
const emoloyeeIds = accounts.map((a) => a.employee)
|
const emoloyeeIds = accounts.map((a) => a.person as Ref<Employee>)
|
||||||
|
|
||||||
const account = faker.random.arrayElement(accounts)
|
const account = faker.random.arrayElement(accounts)
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ export async function generateContacts (
|
|||||||
|
|
||||||
async function genVacansyApplicants (
|
async function genVacansyApplicants (
|
||||||
ctx: MeasureContext,
|
ctx: MeasureContext,
|
||||||
accountIds: Ref<EmployeeAccount>[],
|
accountIds: Ref<PersonAccount>[],
|
||||||
options: RecruitOptions,
|
options: RecruitOptions,
|
||||||
i: number,
|
i: number,
|
||||||
client: TxOperations,
|
client: TxOperations,
|
||||||
|
@ -207,7 +207,7 @@ export async function benchmark (
|
|||||||
'avg',
|
'avg',
|
||||||
{},
|
{},
|
||||||
async () =>
|
async () =>
|
||||||
await monitorConnection?.findAll(contact.class.Employee, {}).then((res) => {
|
await monitorConnection?.findAll(contact.mixin.Employee, {}).then((res) => {
|
||||||
const cur = Date.now() - st
|
const cur = Date.now() - st
|
||||||
opTime += cur
|
opTime += cur
|
||||||
moment = cur
|
moment = cur
|
||||||
|
@ -76,7 +76,7 @@ export async function cleanWorkspace (
|
|||||||
if (opt.recruit) {
|
if (opt.recruit) {
|
||||||
const contacts = await ops.findAll(recruit.mixin.Candidate, {})
|
const contacts = await ops.findAll(recruit.mixin.Candidate, {})
|
||||||
console.log('removing Talents', contacts.length)
|
console.log('removing Talents', contacts.length)
|
||||||
const filter = contacts.filter((it) => !hierarchy.isDerived(it._class, contact.class.Employee))
|
const filter = contacts.filter((it) => !hierarchy.isDerived(it._class, contact.mixin.Employee))
|
||||||
|
|
||||||
while (filter.length > 0) {
|
while (filter.length > 0) {
|
||||||
const part = filter.splice(0, 100)
|
const part = filter.splice(0, 100)
|
||||||
|
@ -33,7 +33,7 @@ export async function diffWorkspace (mongoUrl: string, workspace: WorkspaceId, r
|
|||||||
.find<Tx>({
|
.find<Tx>({
|
||||||
objectSpace: core.space.Model,
|
objectSpace: core.space.Model,
|
||||||
modifiedBy: core.account.System,
|
modifiedBy: core.account.System,
|
||||||
objectClass: { $ne: contact.class.EmployeeAccount }
|
objectClass: { $ne: contact.class.PersonAccount }
|
||||||
})
|
})
|
||||||
.toArray()
|
.toArray()
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ export async function diffWorkspace (mongoUrl: string, workspace: WorkspaceId, r
|
|||||||
return (
|
return (
|
||||||
tx.objectSpace === core.space.Model &&
|
tx.objectSpace === core.space.Model &&
|
||||||
tx.modifiedBy === core.account.System &&
|
tx.modifiedBy === core.account.System &&
|
||||||
(tx as any).objectClass !== contact.class.EmployeeAccount
|
(tx as any).objectClass !== contact.class.PersonAccount
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -88,10 +88,10 @@ export class TCard extends TTask implements Card {
|
|||||||
@Index(IndexKind.FullText)
|
@Index(IndexKind.FullText)
|
||||||
location?: string
|
location?: string
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), board.string.Assignee)
|
@Prop(TypeRef(contact.mixin.Employee), board.string.Assignee)
|
||||||
declare assignee: Ref<Employee> | null
|
declare assignee: Ref<Employee> | null
|
||||||
|
|
||||||
@Prop(ArrOf(TypeRef(contact.class.Employee)), board.string.Members)
|
@Prop(ArrOf(TypeRef(contact.mixin.Employee)), board.string.Members)
|
||||||
members?: Ref<Employee>[]
|
members?: Ref<Employee>[]
|
||||||
|
|
||||||
@Prop(TypeCardCover(), board.string.Cover)
|
@Prop(TypeCardCover(), board.string.Cover)
|
||||||
|
@ -22,7 +22,7 @@ import contact from '@hcengineering/contact'
|
|||||||
|
|
||||||
async function migrateCalendars (tx: TxOperations): Promise<void> {
|
async function migrateCalendars (tx: TxOperations): Promise<void> {
|
||||||
const existCalendars = new Set((await tx.findAll(calendar.class.Calendar, {})).map((p) => p._id))
|
const existCalendars = new Set((await tx.findAll(calendar.class.Calendar, {})).map((p) => p._id))
|
||||||
const users = await tx.findAll(contact.class.EmployeeAccount, {})
|
const users = await tx.findAll(contact.class.PersonAccount, {})
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
if (!existCalendars.has(`${user._id}_calendar` as Ref<Calendar>)) {
|
if (!existCalendars.has(`${user._id}_calendar` as Ref<Calendar>)) {
|
||||||
await tx.createDoc(
|
await tx.createDoc(
|
||||||
|
@ -27,7 +27,7 @@ import {
|
|||||||
SavedMessages,
|
SavedMessages,
|
||||||
ThreadMessage
|
ThreadMessage
|
||||||
} from '@hcengineering/chunter'
|
} from '@hcengineering/chunter'
|
||||||
import contact, { Employee } from '@hcengineering/contact'
|
import contact, { Person } from '@hcengineering/contact'
|
||||||
import type { Account, Class, Doc, Domain, Ref, Space, Timestamp } from '@hcengineering/core'
|
import type { Account, Class, Doc, Domain, Ref, Space, Timestamp } from '@hcengineering/core'
|
||||||
import { IndexKind } from '@hcengineering/core'
|
import { IndexKind } from '@hcengineering/core'
|
||||||
import {
|
import {
|
||||||
@ -113,8 +113,8 @@ export class TMessage extends TChunterMessage implements Message {
|
|||||||
|
|
||||||
declare attachedToClass: Ref<Class<Space>>
|
declare attachedToClass: Ref<Class<Space>>
|
||||||
|
|
||||||
@Prop(ArrOf(TypeRef(contact.class.Employee)), chunter.string.Replies)
|
@Prop(ArrOf(TypeRef(contact.class.Person)), chunter.string.Replies)
|
||||||
replies?: Ref<Employee>[]
|
replies?: Ref<Person>[]
|
||||||
|
|
||||||
repliesCount?: number
|
repliesCount?: number
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import {
|
|||||||
Contact,
|
Contact,
|
||||||
ContactsTab,
|
ContactsTab,
|
||||||
Employee,
|
Employee,
|
||||||
EmployeeAccount,
|
PersonAccount,
|
||||||
GetAvatarUrl,
|
GetAvatarUrl,
|
||||||
Member,
|
Member,
|
||||||
Organization,
|
Organization,
|
||||||
@ -39,8 +39,11 @@ import {
|
|||||||
Collection,
|
Collection,
|
||||||
Hidden,
|
Hidden,
|
||||||
Index,
|
Index,
|
||||||
|
Mixin,
|
||||||
Model,
|
Model,
|
||||||
Prop,
|
Prop,
|
||||||
|
ReadOnly,
|
||||||
|
TypeBoolean,
|
||||||
TypeDate,
|
TypeDate,
|
||||||
TypeRef,
|
TypeRef,
|
||||||
TypeString,
|
TypeString,
|
||||||
@ -153,27 +156,30 @@ export class TStatus extends TAttachedDoc implements Status {
|
|||||||
dueDate!: Timestamp
|
dueDate!: Timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
@Model(contact.class.Employee, contact.class.Person)
|
@Mixin(contact.mixin.Employee, contact.class.Person)
|
||||||
@UX(contact.string.Employee, contact.icon.Person, 'EMP', 'name')
|
@UX(contact.string.Employee, contact.icon.Person, 'EMP', 'name')
|
||||||
export class TEmployee extends TPerson implements Employee {
|
export class TEmployee extends TPerson implements Employee {
|
||||||
active!: boolean
|
@Prop(TypeBoolean(), contact.string.Active)
|
||||||
|
@ReadOnly()
|
||||||
|
@Hidden()
|
||||||
|
active!: boolean
|
||||||
|
|
||||||
@Prop(Collection(contact.class.Status), contact.string.Status)
|
@Prop(Collection(contact.class.Status), contact.string.Status)
|
||||||
|
@Hidden()
|
||||||
statuses?: number
|
statuses?: number
|
||||||
|
|
||||||
mergedTo?: Ref<Employee>
|
|
||||||
|
|
||||||
@Prop(TypeString(), contact.string.DisplayName)
|
@Prop(TypeString(), contact.string.DisplayName)
|
||||||
|
@Hidden()
|
||||||
displayName?: string | null
|
displayName?: string | null
|
||||||
|
|
||||||
@Prop(TypeString(), contact.string.Position)
|
@Prop(TypeString(), contact.string.Position)
|
||||||
|
@Hidden()
|
||||||
position?: string | null
|
position?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Model(contact.class.EmployeeAccount, core.class.Account)
|
@Model(contact.class.PersonAccount, core.class.Account)
|
||||||
export class TEmployeeAccount extends TAccount implements EmployeeAccount {
|
export class TPersonAccount extends TAccount implements PersonAccount {
|
||||||
employee!: Ref<Employee>
|
person!: Ref<Person>
|
||||||
mergedTo!: Ref<EmployeeAccount>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Model(contact.class.Organizations, core.class.Space)
|
@Model(contact.class.Organizations, core.class.Space)
|
||||||
@ -201,14 +207,14 @@ export function createModel (builder: Builder): void {
|
|||||||
TOrganization,
|
TOrganization,
|
||||||
TOrganizations,
|
TOrganizations,
|
||||||
TEmployee,
|
TEmployee,
|
||||||
TEmployeeAccount,
|
TPersonAccount,
|
||||||
TChannel,
|
TChannel,
|
||||||
TStatus,
|
TStatus,
|
||||||
TMember,
|
TMember,
|
||||||
TContactsTab
|
TContactsTab
|
||||||
)
|
)
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.ObjectFactory, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.ObjectFactory, {
|
||||||
component: contact.component.CreateEmployee
|
component: contact.component.CreateEmployee
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -239,7 +245,7 @@ export function createModel (builder: Builder): void {
|
|||||||
icon: contact.icon.Person,
|
icon: contact.icon.Person,
|
||||||
label: contact.string.Employee,
|
label: contact.string.Employee,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
_class: contact.class.Employee,
|
_class: contact.mixin.Employee,
|
||||||
icon: contact.icon.Person,
|
icon: contact.icon.Person,
|
||||||
label: contact.string.Employee,
|
label: contact.string.Employee,
|
||||||
createLabel: contact.string.CreateEmployee,
|
createLabel: contact.string.CreateEmployee,
|
||||||
@ -253,6 +259,9 @@ export function createModel (builder: Builder): void {
|
|||||||
label: contact.string.Person,
|
label: contact.string.Person,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
_class: contact.class.Person,
|
_class: contact.class.Person,
|
||||||
|
baseQuery: {
|
||||||
|
[contact.mixin.Employee]: { $exists: false }
|
||||||
|
},
|
||||||
icon: contact.icon.Person,
|
icon: contact.icon.Person,
|
||||||
label: contact.string.Person,
|
label: contact.string.Person,
|
||||||
createLabel: contact.string.CreatePerson,
|
createLabel: contact.string.CreatePerson,
|
||||||
@ -337,7 +346,7 @@ export function createModel (builder: Builder): void {
|
|||||||
baseQuery: {
|
baseQuery: {
|
||||||
_class: {
|
_class: {
|
||||||
$in: [contact.class.Person],
|
$in: [contact.class.Person],
|
||||||
$nin: [contact.class.Employee]
|
$nin: [contact.mixin.Employee]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -347,7 +356,7 @@ export function createModel (builder: Builder): void {
|
|||||||
view.class.Viewlet,
|
view.class.Viewlet,
|
||||||
core.space.Model,
|
core.space.Model,
|
||||||
{
|
{
|
||||||
attachTo: contact.class.Employee,
|
attachTo: contact.mixin.Employee,
|
||||||
descriptor: view.viewlet.Table,
|
descriptor: view.viewlet.Table,
|
||||||
config: [
|
config: [
|
||||||
'',
|
'',
|
||||||
@ -400,7 +409,7 @@ export function createModel (builder: Builder): void {
|
|||||||
pinned: true
|
pinned: true
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.ObjectEditor, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.ObjectEditor, {
|
||||||
editor: contact.component.EditEmployee,
|
editor: contact.component.EditEmployee,
|
||||||
pinned: true
|
pinned: true
|
||||||
})
|
})
|
||||||
@ -418,7 +427,7 @@ export function createModel (builder: Builder): void {
|
|||||||
editor: contact.component.Members
|
editor: contact.component.Members
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.ArrayEditor, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.ArrayEditor, {
|
||||||
inlineEditor: contact.component.EmployeeArrayEditor
|
inlineEditor: contact.component.EmployeeArrayEditor
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -450,7 +459,7 @@ export function createModel (builder: Builder): void {
|
|||||||
inlineEditor: contact.component.PersonEditor
|
inlineEditor: contact.component.PersonEditor
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.AttributeEditor, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.AttributeEditor, {
|
||||||
inlineEditor: contact.component.EmployeeEditor
|
inlineEditor: contact.component.EmployeeEditor
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -466,15 +475,15 @@ export function createModel (builder: Builder): void {
|
|||||||
encode: contact.function.GetContactLink
|
encode: contact.function.GetContactLink
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.AttributeFilterPresenter, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.AttributeFilterPresenter, {
|
||||||
presenter: contact.component.EmployeeFilterValuePresenter
|
presenter: contact.component.EmployeeFilterValuePresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(core.class.Account, core.class.Class, view.mixin.AttributeFilterPresenter, {
|
builder.mixin(core.class.Account, core.class.Class, view.mixin.AttributeFilterPresenter, {
|
||||||
presenter: contact.component.EmployeeAccountFilterValuePresenter
|
presenter: contact.component.PersonAccountFilterValuePresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.AttributeFilter, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.AttributeFilter, {
|
||||||
component: contact.component.EmployeeFilter
|
component: contact.component.EmployeeFilter
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -621,15 +630,15 @@ export function createModel (builder: Builder): void {
|
|||||||
inlineEditor: contact.component.AccountArrayEditor
|
inlineEditor: contact.component.AccountArrayEditor
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.EmployeeAccount, core.class.Class, view.mixin.ArrayEditor, {
|
builder.mixin(contact.class.PersonAccount, core.class.Class, view.mixin.ArrayEditor, {
|
||||||
inlineEditor: contact.component.AccountArrayEditor
|
inlineEditor: contact.component.AccountArrayEditor
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(core.class.Account, core.class.Class, view.mixin.ObjectPresenter, {
|
builder.mixin(core.class.Account, core.class.Class, view.mixin.ObjectPresenter, {
|
||||||
presenter: contact.component.EmployeeAccountPresenter
|
presenter: contact.component.PersonAccountPresenter
|
||||||
})
|
})
|
||||||
builder.mixin(core.class.Account, core.class.Class, view.mixin.AttributePresenter, {
|
builder.mixin(core.class.Account, core.class.Class, view.mixin.AttributePresenter, {
|
||||||
presenter: contact.component.EmployeeAccountRefPresenter
|
presenter: contact.component.PersonAccountRefPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Organization, core.class.Class, view.mixin.ObjectPresenter, {
|
builder.mixin(contact.class.Organization, core.class.Class, view.mixin.ObjectPresenter, {
|
||||||
@ -640,11 +649,11 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: contact.component.ContactPresenter
|
presenter: contact.component.ContactPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.ObjectPresenter, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.ObjectPresenter, {
|
||||||
presenter: contact.component.EmployeePresenter
|
presenter: contact.component.EmployeePresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.SortFuncs, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.SortFuncs, {
|
||||||
func: contact.function.EmployeeSort
|
func: contact.function.EmployeeSort
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -656,11 +665,11 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: contact.component.ContactRefPresenter
|
presenter: contact.component.ContactRefPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.AttributePresenter, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.AttributePresenter, {
|
||||||
presenter: contact.component.EmployeeRefPresenter
|
presenter: contact.component.EmployeeRefPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.IgnoreActions, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.IgnoreActions, {
|
||||||
actions: [view.action.Delete]
|
actions: [view.action.Delete]
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -671,7 +680,7 @@ export function createModel (builder: Builder): void {
|
|||||||
builder.mixin(contact.class.Person, core.class.Class, view.mixin.ClassFilters, {
|
builder.mixin(contact.class.Person, core.class.Class, view.mixin.ClassFilters, {
|
||||||
filters: []
|
filters: []
|
||||||
})
|
})
|
||||||
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.ClassFilters, {
|
builder.mixin(contact.mixin.Employee, core.class.Class, view.mixin.ClassFilters, {
|
||||||
filters: []
|
filters: []
|
||||||
})
|
})
|
||||||
builder.mixin(contact.class.Organization, core.class.Class, view.mixin.ClassFilters, {
|
builder.mixin(contact.class.Organization, core.class.Class, view.mixin.ClassFilters, {
|
||||||
@ -737,7 +746,7 @@ export function createModel (builder: Builder): void {
|
|||||||
active: true
|
active: true
|
||||||
},
|
},
|
||||||
category: contact.category.Contact,
|
category: contact.category.Contact,
|
||||||
target: contact.class.Employee,
|
target: contact.mixin.Employee,
|
||||||
input: 'focus',
|
input: 'focus',
|
||||||
context: {
|
context: {
|
||||||
mode: ['context'],
|
mode: ['context'],
|
||||||
@ -757,7 +766,7 @@ export function createModel (builder: Builder): void {
|
|||||||
active: false
|
active: false
|
||||||
},
|
},
|
||||||
category: contact.category.Contact,
|
category: contact.category.Contact,
|
||||||
target: contact.class.Employee,
|
target: contact.mixin.Employee,
|
||||||
input: 'focus',
|
input: 'focus',
|
||||||
context: {
|
context: {
|
||||||
mode: ['context'],
|
mode: ['context'],
|
||||||
@ -773,18 +782,16 @@ export function createModel (builder: Builder): void {
|
|||||||
{
|
{
|
||||||
action: view.actionImpl.ShowPopup,
|
action: view.actionImpl.ShowPopup,
|
||||||
actionProps: {
|
actionProps: {
|
||||||
component: contact.component.MergeEmployee,
|
component: contact.component.MergePersons,
|
||||||
element: 'top',
|
element: 'top',
|
||||||
fillProps: {
|
fillProps: {
|
||||||
_object: 'value'
|
_object: 'value'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
query: {
|
query: {},
|
||||||
active: false
|
label: contact.string.MergePersons,
|
||||||
},
|
|
||||||
label: contact.string.MergeEmployee,
|
|
||||||
category: contact.category.Contact,
|
category: contact.category.Contact,
|
||||||
target: contact.class.Employee,
|
target: contact.class.Person,
|
||||||
input: 'focus',
|
input: 'focus',
|
||||||
context: {
|
context: {
|
||||||
mode: ['context'],
|
mode: ['context'],
|
||||||
@ -792,7 +799,7 @@ export function createModel (builder: Builder): void {
|
|||||||
},
|
},
|
||||||
secured: true
|
secured: true
|
||||||
},
|
},
|
||||||
contact.action.MergeEmployee
|
contact.action.MergePersons
|
||||||
)
|
)
|
||||||
|
|
||||||
// Allow to use fuzzy search for mixins
|
// Allow to use fuzzy search for mixins
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import { TxOperations } from '@hcengineering/core'
|
import { Class, DOMAIN_TX, Doc, Domain, Ref, TxOperations } from '@hcengineering/core'
|
||||||
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model'
|
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model'
|
||||||
|
import { DOMAIN_COMMENT } from '@hcengineering/model-chunter'
|
||||||
import core from '@hcengineering/model-core'
|
import core from '@hcengineering/model-core'
|
||||||
import contact from './index'
|
import { DOMAIN_VIEW } from '@hcengineering/model-view'
|
||||||
|
import contact, { DOMAIN_CONTACT } from './index'
|
||||||
|
|
||||||
async function createSpace (tx: TxOperations): Promise<void> {
|
async function createSpace (tx: TxOperations): Promise<void> {
|
||||||
const current = await tx.findOne(core.class.Space, {
|
const current = await tx.findOne(core.class.Space, {
|
||||||
@ -43,14 +45,14 @@ async function createSpace (tx: TxOperations): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function createEmployeeEmail (client: TxOperations): Promise<void> {
|
async function createEmployeeEmail (client: TxOperations): Promise<void> {
|
||||||
const employees = await client.findAll(contact.class.Employee, {})
|
const employees = await client.findAll(contact.mixin.Employee, {})
|
||||||
const channels = await client.findAll(contact.class.Channel, {
|
const channels = await client.findAll(contact.class.Channel, {
|
||||||
provider: contact.channelProvider.Email,
|
provider: contact.channelProvider.Email,
|
||||||
attachedTo: { $in: employees.map((p) => p._id) }
|
attachedTo: { $in: employees.map((p) => p._id) }
|
||||||
})
|
})
|
||||||
const channelsMap = new Map(channels.map((p) => [p.attachedTo, p]))
|
const channelsMap = new Map(channels.map((p) => [p.attachedTo, p]))
|
||||||
for (const employee of employees) {
|
for (const employee of employees) {
|
||||||
const acc = await client.findOne(contact.class.EmployeeAccount, { employee: employee._id })
|
const acc = await client.findOne(contact.class.PersonAccount, { person: employee._id })
|
||||||
if (acc === undefined) continue
|
if (acc === undefined) continue
|
||||||
const current = channelsMap.get(employee._id)
|
const current = channelsMap.get(employee._id)
|
||||||
if (current === undefined) {
|
if (current === undefined) {
|
||||||
@ -58,7 +60,7 @@ async function createEmployeeEmail (client: TxOperations): Promise<void> {
|
|||||||
contact.class.Channel,
|
contact.class.Channel,
|
||||||
contact.space.Contacts,
|
contact.space.Contacts,
|
||||||
employee._id,
|
employee._id,
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
'channels',
|
'channels',
|
||||||
{
|
{
|
||||||
provider: contact.channelProvider.Email,
|
provider: contact.channelProvider.Email,
|
||||||
@ -74,7 +76,88 @@ async function createEmployeeEmail (client: TxOperations): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const contactOperation: MigrateOperation = {
|
export const contactOperation: MigrateOperation = {
|
||||||
async migrate (client: MigrationClient): Promise<void> {},
|
async migrate (client: MigrationClient): Promise<void> {
|
||||||
|
await client.update(
|
||||||
|
DOMAIN_TX,
|
||||||
|
{
|
||||||
|
objectClass: 'contact:class:EmployeeAccount'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$rename: { 'attributes.employee': 'attributes.person' },
|
||||||
|
$set: { objectClass: contact.class.PersonAccount }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await client.update(
|
||||||
|
DOMAIN_TX,
|
||||||
|
{
|
||||||
|
objectClass: 'contact:class:Employee'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$set: { objectClass: contact.mixin.Employee }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await client.update(
|
||||||
|
DOMAIN_TX,
|
||||||
|
{
|
||||||
|
'tx.attributes.backlinkClass': 'contact:class:Employee'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$set: { 'tx.attributes.backlinkClass': contact.mixin.Employee }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await client.update(
|
||||||
|
DOMAIN_TX,
|
||||||
|
{
|
||||||
|
'tx.attributes.backlinkClass': 'contact:class:Employee'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$set: { 'tx.attributes.backlinkClass': contact.mixin.Employee }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
for (const d of client.hierarchy.domains()) {
|
||||||
|
await client.update(
|
||||||
|
d,
|
||||||
|
{ attachedToClass: 'contact:class:Employee' },
|
||||||
|
{ $set: { attachedToClass: contact.mixin.Employee } }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
await client.update(
|
||||||
|
DOMAIN_COMMENT,
|
||||||
|
{ backlinkClass: 'contact:class:Employee' },
|
||||||
|
{ $set: { backlinkClass: contact.mixin.Employee } }
|
||||||
|
)
|
||||||
|
await client.update(
|
||||||
|
'tags' as Domain,
|
||||||
|
{ targetClass: 'contact:class:Employee' },
|
||||||
|
{ $set: { targetClass: contact.mixin.Employee } }
|
||||||
|
)
|
||||||
|
await client.update(
|
||||||
|
DOMAIN_VIEW,
|
||||||
|
{ filterClass: 'contact:class:Employee' },
|
||||||
|
{ $set: { filterClass: contact.mixin.Employee } }
|
||||||
|
)
|
||||||
|
await client.update(
|
||||||
|
DOMAIN_CONTACT,
|
||||||
|
{
|
||||||
|
_class: 'contact:class:Employee' as Ref<Class<Doc>>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$rename: {
|
||||||
|
active: `${contact.mixin.Employee as string}.active`,
|
||||||
|
statuses: `${contact.mixin.Employee as string}.statuses`,
|
||||||
|
displayName: `${contact.mixin.Employee as string}.displayName`,
|
||||||
|
position: `${contact.mixin.Employee as string}.position`
|
||||||
|
},
|
||||||
|
$set: {
|
||||||
|
_class: contact.class.Person
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
async upgrade (client: MigrationUpgradeClient): Promise<void> {
|
async upgrade (client: MigrationUpgradeClient): Promise<void> {
|
||||||
const tx = new TxOperations(client, core.account.System)
|
const tx = new TxOperations(client, core.account.System)
|
||||||
await createSpace(tx)
|
await createSpace(tx)
|
||||||
|
@ -36,8 +36,8 @@ export default mergeIds(contactId, contact, {
|
|||||||
OrganizationPresenter: '' as AnyComponent,
|
OrganizationPresenter: '' as AnyComponent,
|
||||||
Contacts: '' as AnyComponent,
|
Contacts: '' as AnyComponent,
|
||||||
ContactsTabs: '' as AnyComponent,
|
ContactsTabs: '' as AnyComponent,
|
||||||
EmployeeAccountPresenter: '' as AnyComponent,
|
PersonAccountPresenter: '' as AnyComponent,
|
||||||
EmployeeAccountRefPresenter: '' as AnyComponent,
|
PersonAccountRefPresenter: '' as AnyComponent,
|
||||||
OrganizationEditor: '' as AnyComponent,
|
OrganizationEditor: '' as AnyComponent,
|
||||||
EmployeePresenter: '' as AnyComponent,
|
EmployeePresenter: '' as AnyComponent,
|
||||||
EmployeeRefPresenter: '' as AnyComponent,
|
EmployeeRefPresenter: '' as AnyComponent,
|
||||||
@ -52,13 +52,13 @@ export default mergeIds(contactId, contact, {
|
|||||||
CreateEmployee: '' as AnyComponent,
|
CreateEmployee: '' as AnyComponent,
|
||||||
AccountArrayEditor: '' as AnyComponent,
|
AccountArrayEditor: '' as AnyComponent,
|
||||||
ChannelFilter: '' as AnyComponent,
|
ChannelFilter: '' as AnyComponent,
|
||||||
MergeEmployee: '' as AnyComponent,
|
MergePersons: '' as AnyComponent,
|
||||||
ActivityChannelMessage: '' as AnyComponent,
|
ActivityChannelMessage: '' as AnyComponent,
|
||||||
ChannelPanel: '' as AnyComponent,
|
ChannelPanel: '' as AnyComponent,
|
||||||
ActivityChannelPresenter: '' as AnyComponent,
|
ActivityChannelPresenter: '' as AnyComponent,
|
||||||
EmployeeFilter: '' as AnyComponent,
|
EmployeeFilter: '' as AnyComponent,
|
||||||
EmployeeFilterValuePresenter: '' as AnyComponent,
|
EmployeeFilterValuePresenter: '' as AnyComponent,
|
||||||
EmployeeAccountFilterValuePresenter: '' as AnyComponent
|
PersonAccountFilterValuePresenter: '' as AnyComponent
|
||||||
},
|
},
|
||||||
string: {
|
string: {
|
||||||
Persons: '' as IntlString,
|
Persons: '' as IntlString,
|
||||||
@ -114,7 +114,7 @@ export default mergeIds(contactId, contact, {
|
|||||||
action: {
|
action: {
|
||||||
KickEmployee: '' as Ref<Action>,
|
KickEmployee: '' as Ref<Action>,
|
||||||
DeleteEmployee: '' as Ref<Action>,
|
DeleteEmployee: '' as Ref<Action>,
|
||||||
MergeEmployee: '' as Ref<Action>
|
MergePersons: '' as Ref<Action>
|
||||||
},
|
},
|
||||||
actionImpl: {
|
actionImpl: {
|
||||||
KickEmployee: '' as ViewAction,
|
KickEmployee: '' as ViewAction,
|
||||||
|
@ -133,13 +133,13 @@ export class TDocument extends TDoc implements Document {
|
|||||||
@Hidden()
|
@Hidden()
|
||||||
versions!: number
|
versions!: number
|
||||||
|
|
||||||
@Prop(ArrOf(TypeRef(contact.class.Employee)), document.string.Authors)
|
@Prop(ArrOf(TypeRef(contact.mixin.Employee)), document.string.Authors)
|
||||||
authors!: Ref<Employee>[]
|
authors!: Ref<Employee>[]
|
||||||
|
|
||||||
@Prop(ArrOf(TypeRef(contact.class.Employee)), document.string.Reviewers)
|
@Prop(ArrOf(TypeRef(contact.mixin.Employee)), document.string.Reviewers)
|
||||||
reviewers!: Ref<Employee>[]
|
reviewers!: Ref<Employee>[]
|
||||||
|
|
||||||
@Prop(ArrOf(TypeRef(contact.class.Employee)), document.string.Approvers)
|
@Prop(ArrOf(TypeRef(contact.mixin.Employee)), document.string.Approvers)
|
||||||
approvers!: Ref<Employee>[]
|
approvers!: Ref<Employee>[]
|
||||||
|
|
||||||
@Prop(Collection(document.class.DocumentRequest), document.string.Requests)
|
@Prop(Collection(document.class.DocumentRequest), document.string.Requests)
|
||||||
|
@ -43,7 +43,7 @@ import {
|
|||||||
import attachment from '@hcengineering/model-attachment'
|
import attachment from '@hcengineering/model-attachment'
|
||||||
import calendar from '@hcengineering/model-calendar'
|
import calendar from '@hcengineering/model-calendar'
|
||||||
import chunter from '@hcengineering/model-chunter'
|
import chunter from '@hcengineering/model-chunter'
|
||||||
import contact, { TEmployee, TEmployeeAccount } from '@hcengineering/model-contact'
|
import contact, { TEmployee, TPersonAccount } from '@hcengineering/model-contact'
|
||||||
import core, { TAttachedDoc, TDoc, TSpace, TType } from '@hcengineering/model-core'
|
import core, { TAttachedDoc, TDoc, TSpace, TType } from '@hcengineering/model-core'
|
||||||
import view, { classPresenter, createAction } from '@hcengineering/model-view'
|
import view, { classPresenter, createAction } from '@hcengineering/model-view'
|
||||||
import workbench from '@hcengineering/model-workbench'
|
import workbench from '@hcengineering/model-workbench'
|
||||||
@ -80,7 +80,7 @@ export class TDepartment extends TSpace implements Department {
|
|||||||
|
|
||||||
avatar?: string | null
|
avatar?: string | null
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), hr.string.TeamLead)
|
@Prop(TypeRef(contact.mixin.Employee), hr.string.TeamLead)
|
||||||
teamLead!: Ref<Employee> | null
|
teamLead!: Ref<Employee> | null
|
||||||
|
|
||||||
@Prop(ArrOf(TypeRef(hr.class.DepartmentMember)), contact.string.Members)
|
@Prop(ArrOf(TypeRef(hr.class.DepartmentMember)), contact.string.Members)
|
||||||
@ -89,15 +89,15 @@ export class TDepartment extends TSpace implements Department {
|
|||||||
@Prop(ArrOf(TypeRef(contact.class.Contact)), hr.string.Subscribers)
|
@Prop(ArrOf(TypeRef(contact.class.Contact)), hr.string.Subscribers)
|
||||||
subscribers?: Arr<Ref<Contact>>
|
subscribers?: Arr<Ref<Contact>>
|
||||||
|
|
||||||
@Prop(ArrOf(TypeRef(contact.class.Employee)), hr.string.Managers)
|
@Prop(ArrOf(TypeRef(contact.mixin.Employee)), hr.string.Managers)
|
||||||
managers!: Arr<Ref<Employee>>
|
managers!: Arr<Ref<Employee>>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Model(hr.class.DepartmentMember, contact.class.EmployeeAccount)
|
@Model(hr.class.DepartmentMember, contact.class.PersonAccount)
|
||||||
@UX(contact.string.Employee, hr.icon.HR)
|
@UX(contact.string.Employee, hr.icon.HR)
|
||||||
export class TDepartmentMember extends TEmployeeAccount implements DepartmentMember {}
|
export class TDepartmentMember extends TPersonAccount implements DepartmentMember {}
|
||||||
|
|
||||||
@Mixin(hr.mixin.Staff, contact.class.Employee)
|
@Mixin(hr.mixin.Staff, contact.mixin.Employee)
|
||||||
@UX(hr.string.Staff, hr.icon.HR, 'STFF', 'name')
|
@UX(hr.string.Staff, hr.icon.HR, 'STFF', 'name')
|
||||||
export class TStaff extends TEmployee implements Staff {
|
export class TStaff extends TEmployee implements Staff {
|
||||||
@Prop(TypeRef(hr.class.Department), hr.string.Department)
|
@Prop(TypeRef(hr.class.Department), hr.string.Department)
|
||||||
|
@ -78,7 +78,7 @@ export class TLead extends TTask implements Lead {
|
|||||||
@Index(IndexKind.FullText)
|
@Index(IndexKind.FullText)
|
||||||
title!: string
|
title!: string
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), lead.string.Assignee)
|
@Prop(TypeRef(contact.mixin.Employee), lead.string.Assignee)
|
||||||
declare assignee: Ref<Employee> | null
|
declare assignee: Ref<Employee> | null
|
||||||
|
|
||||||
@Prop(TypeRef(task.class.State), task.string.TaskState, { _id: task.attribute.State })
|
@Prop(TypeRef(task.class.State), task.string.TaskState, { _id: task.attribute.State })
|
||||||
|
@ -162,7 +162,7 @@ export class TApplicant extends TTask implements Applicant {
|
|||||||
@Prop(TypeDate(), task.string.StartDate)
|
@Prop(TypeDate(), task.string.StartDate)
|
||||||
startDate!: Timestamp | null
|
startDate!: Timestamp | null
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), recruit.string.AssignedRecruiter)
|
@Prop(TypeRef(contact.mixin.Employee), recruit.string.AssignedRecruiter)
|
||||||
declare assignee: Ref<Employee> | null
|
declare assignee: Ref<Employee> | null
|
||||||
|
|
||||||
@Prop(TypeRef(task.class.State), task.string.TaskState, { _id: task.attribute.State })
|
@Prop(TypeRef(task.class.State), task.string.TaskState, { _id: task.attribute.State })
|
||||||
@ -1105,7 +1105,7 @@ export function createModel (builder: Builder): void {
|
|||||||
actionPopup: view.component.ValueSelector,
|
actionPopup: view.component.ValueSelector,
|
||||||
actionProps: {
|
actionProps: {
|
||||||
attribute: 'assignee',
|
attribute: 'assignee',
|
||||||
_class: contact.class.Employee,
|
_class: contact.mixin.Employee,
|
||||||
query: {},
|
query: {},
|
||||||
placeholder: recruit.string.AssignRecruiter
|
placeholder: recruit.string.AssignRecruiter
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,7 @@ import { generateClassNotificationTypes } from '@hcengineering/model-notificatio
|
|||||||
export const reviewTableOptions: FindOptions<Review> = {
|
export const reviewTableOptions: FindOptions<Review> = {
|
||||||
lookup: {
|
lookup: {
|
||||||
attachedTo: recruit.mixin.Candidate,
|
attachedTo: recruit.mixin.Candidate,
|
||||||
participants: contact.class.Employee,
|
participants: contact.mixin.Employee,
|
||||||
company: contact.class.Organization
|
company: contact.class.Organization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
import activity from '@hcengineering/activity'
|
import activity from '@hcengineering/activity'
|
||||||
import chunter from '@hcengineering/chunter'
|
import chunter from '@hcengineering/chunter'
|
||||||
import type { EmployeeAccount } from '@hcengineering/contact'
|
import type { PersonAccount } from '@hcengineering/contact'
|
||||||
import contact from '@hcengineering/contact'
|
import contact from '@hcengineering/contact'
|
||||||
import { Domain, IndexKind, Ref, Tx } from '@hcengineering/core'
|
import { Domain, IndexKind, Ref, Tx } from '@hcengineering/core'
|
||||||
import {
|
import {
|
||||||
@ -48,13 +48,13 @@ export const DOMAIN_REQUEST = 'request' as Domain
|
|||||||
@Model(request.class.Request, core.class.AttachedDoc, DOMAIN_REQUEST)
|
@Model(request.class.Request, core.class.AttachedDoc, DOMAIN_REQUEST)
|
||||||
@UX(request.string.Request, request.icon.Requests)
|
@UX(request.string.Request, request.icon.Requests)
|
||||||
export class TRequest extends TAttachedDoc implements Request {
|
export class TRequest extends TAttachedDoc implements Request {
|
||||||
@Prop(ArrOf(TypeRef(contact.class.EmployeeAccount)), request.string.Requested)
|
@Prop(ArrOf(TypeRef(contact.class.PersonAccount)), request.string.Requested)
|
||||||
@Index(IndexKind.Indexed)
|
@Index(IndexKind.Indexed)
|
||||||
requested!: Ref<EmployeeAccount>[]
|
requested!: Ref<PersonAccount>[]
|
||||||
|
|
||||||
@Prop(ArrOf(TypeRef(contact.class.EmployeeAccount)), request.string.Approved)
|
@Prop(ArrOf(TypeRef(contact.class.PersonAccount)), request.string.Approved)
|
||||||
@ReadOnly()
|
@ReadOnly()
|
||||||
approved!: Ref<EmployeeAccount>[]
|
approved!: Ref<PersonAccount>[]
|
||||||
|
|
||||||
requiredApprovesCount!: number
|
requiredApprovesCount!: number
|
||||||
|
|
||||||
@ -64,9 +64,9 @@ export class TRequest extends TAttachedDoc implements Request {
|
|||||||
|
|
||||||
tx!: Tx
|
tx!: Tx
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.EmployeeAccount), request.string.Rejected)
|
@Prop(TypeRef(contact.class.PersonAccount), request.string.Rejected)
|
||||||
@ReadOnly()
|
@ReadOnly()
|
||||||
rejected?: Ref<EmployeeAccount>
|
rejected?: Ref<PersonAccount>
|
||||||
|
|
||||||
@Prop(Collection(chunter.class.Comment), chunter.string.Comments)
|
@Prop(Collection(chunter.class.Comment), chunter.string.Comments)
|
||||||
comments?: number
|
comments?: number
|
||||||
|
@ -34,10 +34,10 @@ export function createModel (builder: Builder): void {
|
|||||||
})
|
})
|
||||||
|
|
||||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||||
trigger: serverCalendar.trigger.OnEmployeeAccountCreate,
|
trigger: serverCalendar.trigger.OnPersonAccountCreate,
|
||||||
txMatch: {
|
txMatch: {
|
||||||
_class: core.class.TxCreateDoc,
|
_class: core.class.TxCreateDoc,
|
||||||
objectClass: contact.class.EmployeeAccount
|
objectClass: contact.class.PersonAccount
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -55,12 +55,4 @@ export function createModel (builder: Builder): void {
|
|||||||
_class: core.class.TxUpdateDoc
|
_class: core.class.TxUpdateDoc
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
|
||||||
trigger: serverContact.trigger.OnEmployeeUpdate,
|
|
||||||
txMatch: {
|
|
||||||
objectClass: contact.class.Employee,
|
|
||||||
_class: core.class.TxUpdateDoc
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import type { Employee } from '@hcengineering/contact'
|
import type { Employee, Person } from '@hcengineering/contact'
|
||||||
import contact from '@hcengineering/contact'
|
import contact from '@hcengineering/contact'
|
||||||
import attachment from '@hcengineering/model-attachment'
|
import attachment from '@hcengineering/model-attachment'
|
||||||
import chunter from '@hcengineering/model-chunter'
|
import chunter from '@hcengineering/model-chunter'
|
||||||
@ -101,8 +101,8 @@ export class TTask extends TAttachedDoc implements Task {
|
|||||||
@Hidden()
|
@Hidden()
|
||||||
number!: number
|
number!: number
|
||||||
|
|
||||||
// @Prop(TypeRef(contact.class.Employee), task.string.TaskAssignee)
|
// @Prop(TypeRef(contact.mixin.Employee), task.string.TaskAssignee)
|
||||||
assignee!: Ref<Employee> | null
|
assignee!: Ref<Person> | null
|
||||||
|
|
||||||
@Prop(TypeDate(), task.string.DueDate, { editor: task.component.DueDateEditor })
|
@Prop(TypeDate(), task.string.DueDate, { editor: task.component.DueDateEditor })
|
||||||
dueDate!: Timestamp | null
|
dueDate!: Timestamp | null
|
||||||
@ -126,7 +126,7 @@ export class TTodoItem extends TAttachedDoc implements TodoItem {
|
|||||||
@Index(IndexKind.FullText)
|
@Index(IndexKind.FullText)
|
||||||
name!: string
|
name!: string
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), task.string.TaskAssignee)
|
@Prop(TypeRef(contact.mixin.Employee), task.string.TaskAssignee)
|
||||||
assignee!: Ref<Employee> | null
|
assignee!: Ref<Employee> | null
|
||||||
|
|
||||||
@Prop(TypeBoolean(), task.string.TaskDone)
|
@Prop(TypeBoolean(), task.string.TaskDone)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import activity from '@hcengineering/activity'
|
import activity from '@hcengineering/activity'
|
||||||
import contact, { Employee } from '@hcengineering/contact'
|
import contact, { Employee, Person } from '@hcengineering/contact'
|
||||||
import {
|
import {
|
||||||
DOMAIN_MODEL,
|
DOMAIN_MODEL,
|
||||||
DateRangeMode,
|
DateRangeMode,
|
||||||
@ -135,7 +135,7 @@ export class TProject extends TSpaceWithStates implements Project {
|
|||||||
@Prop(TypeRef(tracker.class.IssueStatus), tracker.string.DefaultIssueStatus)
|
@Prop(TypeRef(tracker.class.IssueStatus), tracker.string.DefaultIssueStatus)
|
||||||
defaultIssueStatus!: Ref<IssueStatus>
|
defaultIssueStatus!: Ref<IssueStatus>
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), tracker.string.DefaultAssignee)
|
@Prop(TypeRef(contact.mixin.Employee), tracker.string.DefaultAssignee)
|
||||||
defaultAssignee!: Ref<Employee>
|
defaultAssignee!: Ref<Employee>
|
||||||
|
|
||||||
declare defaultTimeReportDay: TimeReportDayType
|
declare defaultTimeReportDay: TimeReportDayType
|
||||||
@ -183,9 +183,9 @@ export class TIssue extends TTask implements Issue {
|
|||||||
@ReadOnly()
|
@ReadOnly()
|
||||||
number!: number
|
number!: number
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), tracker.string.Assignee)
|
@Prop(TypeRef(contact.class.Person), tracker.string.Assignee)
|
||||||
@Index(IndexKind.Indexed)
|
@Index(IndexKind.Indexed)
|
||||||
assignee!: Ref<Employee> | null
|
assignee!: Ref<Person> | null
|
||||||
|
|
||||||
@Prop(TypeRef(tracker.class.Component), tracker.string.Component, { icon: tracker.icon.Component })
|
@Prop(TypeRef(tracker.class.Component), tracker.string.Component, { icon: tracker.icon.Component })
|
||||||
@Index(IndexKind.Indexed)
|
@Index(IndexKind.Indexed)
|
||||||
@ -256,8 +256,8 @@ export class TIssueTemplate extends TDoc implements IssueTemplate {
|
|||||||
@Prop(TypeIssuePriority(), tracker.string.Priority)
|
@Prop(TypeIssuePriority(), tracker.string.Priority)
|
||||||
priority!: IssuePriority
|
priority!: IssuePriority
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), tracker.string.Assignee)
|
@Prop(TypeRef(contact.class.Person), tracker.string.Assignee)
|
||||||
assignee!: Ref<Employee> | null
|
assignee!: Ref<Person> | null
|
||||||
|
|
||||||
@Prop(TypeRef(tracker.class.Component), tracker.string.Component)
|
@Prop(TypeRef(tracker.class.Component), tracker.string.Component)
|
||||||
component!: Ref<Component> | null
|
component!: Ref<Component> | null
|
||||||
@ -298,7 +298,7 @@ export class TTimeSpendReport extends TAttachedDoc implements TimeSpendReport {
|
|||||||
@Prop(TypeRef(tracker.class.Issue), tracker.string.Parent)
|
@Prop(TypeRef(tracker.class.Issue), tracker.string.Parent)
|
||||||
declare attachedTo: Ref<Issue>
|
declare attachedTo: Ref<Issue>
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), contact.string.Employee)
|
@Prop(TypeRef(contact.mixin.Employee), contact.string.Employee)
|
||||||
employee!: Ref<Employee>
|
employee!: Ref<Employee>
|
||||||
|
|
||||||
@Prop(TypeDate(), tracker.string.TimeSpendReportDate)
|
@Prop(TypeDate(), tracker.string.TimeSpendReportDate)
|
||||||
@ -324,7 +324,7 @@ export class TComponent extends TDoc implements Component {
|
|||||||
@Prop(TypeMarkup(), tracker.string.Description)
|
@Prop(TypeMarkup(), tracker.string.Description)
|
||||||
description?: Markup
|
description?: Markup
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), tracker.string.ComponentLead)
|
@Prop(TypeRef(contact.mixin.Employee), tracker.string.ComponentLead)
|
||||||
lead!: Ref<Employee> | null
|
lead!: Ref<Employee> | null
|
||||||
|
|
||||||
@Prop(Collection(chunter.class.Comment), chunter.string.Comments)
|
@Prop(Collection(chunter.class.Comment), chunter.string.Comments)
|
||||||
@ -1584,7 +1584,7 @@ export function createModel (builder: Builder): void {
|
|||||||
actionPopup: view.component.ValueSelector,
|
actionPopup: view.component.ValueSelector,
|
||||||
actionProps: {
|
actionProps: {
|
||||||
attribute: 'assignee',
|
attribute: 'assignee',
|
||||||
_class: contact.class.Employee,
|
_class: contact.mixin.Employee,
|
||||||
query: {},
|
query: {},
|
||||||
placeholder: tracker.string.AssignTo
|
placeholder: tracker.string.AssignTo
|
||||||
},
|
},
|
||||||
@ -2006,7 +2006,7 @@ export function createModel (builder: Builder): void {
|
|||||||
dividerBefore: true,
|
dividerBefore: true,
|
||||||
key: 'lead'
|
key: 'lead'
|
||||||
},
|
},
|
||||||
props: { _class: tracker.class.Component, defaultClass: contact.class.Employee, shouldShowLabel: false }
|
props: { _class: tracker.class.Component, defaultClass: contact.mixin.Employee, shouldShowLabel: false }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -279,16 +279,17 @@ async function loadModel (
|
|||||||
console.log('find' + (lastTxTime >= 0 ? 'full model' : 'model diff'), atxes.length, Date.now() - t)
|
console.log('find' + (lastTxTime >= 0 ? 'full model' : 'model diff'), atxes.length, Date.now() - t)
|
||||||
|
|
||||||
// Ignore Employee accounts.
|
// Ignore Employee accounts.
|
||||||
function isEmployeeAccount (tx: Tx): boolean {
|
function isPersonAccount (tx: Tx): boolean {
|
||||||
return (
|
return (
|
||||||
(tx._class === core.class.TxCreateDoc ||
|
(tx._class === core.class.TxCreateDoc ||
|
||||||
tx._class === core.class.TxUpdateDoc ||
|
tx._class === core.class.TxUpdateDoc ||
|
||||||
tx._class === core.class.TxRemoveDoc) &&
|
tx._class === core.class.TxRemoveDoc) &&
|
||||||
(tx as TxCUD<Doc>).objectClass === 'contact:class:EmployeeAccount'
|
((tx as TxCUD<Doc>).objectClass === 'contact:class:PersonAccount' ||
|
||||||
|
(tx as TxCUD<Doc>).objectClass === 'contact:class:Account')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
atxes.forEach((tx) => (tx.modifiedBy === core.account.System && !isEmployeeAccount(tx) ? systemTx : userTx).push(tx))
|
atxes.forEach((tx) => (tx.modifiedBy === core.account.System && !isPersonAccount(tx) ? systemTx : userTx).push(tx))
|
||||||
|
|
||||||
if (allowedPlugins != null) {
|
if (allowedPlugins != null) {
|
||||||
fillConfiguration(systemTx, configs)
|
fillConfiguration(systemTx, configs)
|
||||||
|
@ -227,10 +227,11 @@ export class TxOperations implements Omit<Client, 'notify'> {
|
|||||||
modifiedBy?: Ref<Account>
|
modifiedBy?: Ref<Account>
|
||||||
): Promise<TxResult> {
|
): Promise<TxResult> {
|
||||||
const hierarchy = this.client.getHierarchy()
|
const hierarchy = this.client.getHierarchy()
|
||||||
if (hierarchy.isMixin(doc._class)) {
|
const mixClass = Hierarchy.mixinOrClass(doc)
|
||||||
|
if (hierarchy.isMixin(mixClass)) {
|
||||||
// TODO: Rework it is wrong, we need to split values to mixin update and original document update if mixed.
|
// TODO: Rework it is wrong, we need to split values to mixin update and original document update if mixed.
|
||||||
const baseClass = hierarchy.getBaseClass(doc._class)
|
const baseClass = hierarchy.getBaseClass(doc._class)
|
||||||
return this.updateMixin(doc._id, baseClass, doc.space, doc._class, update, modifiedOn, modifiedBy)
|
return this.updateMixin(doc._id, baseClass, doc.space, mixClass, update, modifiedOn, modifiedBy)
|
||||||
}
|
}
|
||||||
if (hierarchy.isDerived(doc._class, core.class.AttachedDoc)) {
|
if (hierarchy.isDerived(doc._class, core.class.AttachedDoc)) {
|
||||||
const adoc = doc as unknown as AttachedDoc
|
const adoc = doc as unknown as AttachedDoc
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
"AccountAlreadyExists": "Account already exists",
|
"AccountAlreadyExists": "Account already exists",
|
||||||
"WorkspaceRateLimit": "Server is busy, Please wait a bit and try again",
|
"WorkspaceRateLimit": "Server is busy, Please wait a bit and try again",
|
||||||
"AccountAlreadyConfirmed": "Account already confirmed",
|
"AccountAlreadyConfirmed": "Account already confirmed",
|
||||||
"AccountWasMerged": "Account was merged",
|
|
||||||
"WorkspaceAlreadyExists": "Workspace already exists",
|
"WorkspaceAlreadyExists": "Workspace already exists",
|
||||||
"ProductIdMismatch": "Product Mismatch"
|
"ProductIdMismatch": "Product Mismatch"
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
"AccountAlreadyExists": "Аккаунт уже существует",
|
"AccountAlreadyExists": "Аккаунт уже существует",
|
||||||
"WorkspaceRateLimit": "Сервер перегружен, Пожалуйста подождите",
|
"WorkspaceRateLimit": "Сервер перегружен, Пожалуйста подождите",
|
||||||
"AccountAlreadyConfirmed": "Аккаунт уже подтвержден",
|
"AccountAlreadyConfirmed": "Аккаунт уже подтвержден",
|
||||||
"AccountWasMerged": "Аккаунт был объединен",
|
|
||||||
"WorkspaceAlreadyExists": "Рабочее пространство уже существует",
|
"WorkspaceAlreadyExists": "Рабочее пространство уже существует",
|
||||||
"ProductIdMismatch": "Продукт не соответсвует"
|
"ProductIdMismatch": "Продукт не соответсвует"
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,6 @@ export default plugin(platformId, {
|
|||||||
InvalidPassword: '' as StatusCode<{ account: string }>,
|
InvalidPassword: '' as StatusCode<{ account: string }>,
|
||||||
AccountAlreadyExists: '' as StatusCode<{ account: string }>,
|
AccountAlreadyExists: '' as StatusCode<{ account: string }>,
|
||||||
AccountAlreadyConfirmed: '' as StatusCode<{ account: string }>,
|
AccountAlreadyConfirmed: '' as StatusCode<{ account: string }>,
|
||||||
AccountWasMerged: '' as StatusCode<{ account: string }>,
|
|
||||||
WorkspaceAlreadyExists: '' as StatusCode<{ workspace: string }>,
|
WorkspaceAlreadyExists: '' as StatusCode<{ workspace: string }>,
|
||||||
WorkspaceRateLimit: '' as StatusCode<{ workspace: string }>,
|
WorkspaceRateLimit: '' as StatusCode<{ workspace: string }>,
|
||||||
ProductIdMismatch: '' as StatusCode<{ productId: string }>
|
ProductIdMismatch: '' as StatusCode<{ productId: string }>
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
<svelte:component
|
<svelte:component
|
||||||
this={editor}
|
this={editor}
|
||||||
readonly={isReadonly}
|
readonly={isReadonly}
|
||||||
|
disabled="(isReadonly)"
|
||||||
label={attribute?.label}
|
label={attribute?.label}
|
||||||
placeholder={attribute?.label}
|
placeholder={attribute?.label}
|
||||||
{kind}
|
{kind}
|
||||||
@ -101,6 +102,7 @@
|
|||||||
{attributeKey}
|
{attributeKey}
|
||||||
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
|
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
|
||||||
readonly={isReadonly}
|
readonly={isReadonly}
|
||||||
|
disabled="(isReadonly)"
|
||||||
space={object.space}
|
space={object.space}
|
||||||
{onChange}
|
{onChange}
|
||||||
{focus}
|
{focus}
|
||||||
|
@ -47,6 +47,10 @@
|
|||||||
export let readonly = false
|
export let readonly = false
|
||||||
export let disallowDeselect: Ref<Doc>[] | undefined = undefined
|
export let disallowDeselect: Ref<Doc>[] | undefined = undefined
|
||||||
|
|
||||||
|
export let filter: (it: Doc) => boolean = () => {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
const created: Doc[] = []
|
const created: Doc[] = []
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
@ -75,9 +79,9 @@
|
|||||||
})
|
})
|
||||||
if (created.length > 0) {
|
if (created.length > 0) {
|
||||||
const cmap = new Set(created.map((it) => it._id))
|
const cmap = new Set(created.map((it) => it._id))
|
||||||
objects = [...created, ...result.filter((d) => !cmap.has(d._id))]
|
objects = [...created, ...result.filter((d) => !cmap.has(d._id))].filter(filter)
|
||||||
} else {
|
} else {
|
||||||
objects = result
|
objects = result.filter(filter)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ ...(options ?? {}), limit: 200 }
|
{ ...(options ?? {}), limit: 200 }
|
||||||
|
@ -48,6 +48,12 @@
|
|||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
function correctClass (clName: string): string {
|
||||||
|
if (clName === 'contact:class:Employee') {
|
||||||
|
return 'contact:mixin:Employee'
|
||||||
|
}
|
||||||
|
return clName
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if nodes}
|
{#if nodes}
|
||||||
@ -121,7 +127,7 @@
|
|||||||
props={{
|
props={{
|
||||||
objectId: node.getAttribute('data-id'),
|
objectId: node.getAttribute('data-id'),
|
||||||
title: node.getAttribute('data-label'),
|
title: node.getAttribute('data-label'),
|
||||||
_class: node.getAttribute('data-objectclass'),
|
_class: correctClass(node.getAttribute('data-objectclass')),
|
||||||
inline: true
|
inline: true
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import type { DisplayTx, TxViewlet } from '@hcengineering/activity'
|
import type { DisplayTx, TxViewlet } from '@hcengineering/activity'
|
||||||
import attachment from '@hcengineering/attachment'
|
import attachment from '@hcengineering/attachment'
|
||||||
import chunter from '@hcengineering/chunter'
|
import chunter from '@hcengineering/chunter'
|
||||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
import contact, { Employee, PersonAccount, getName } from '@hcengineering/contact'
|
||||||
import core, { AnyAttribute, Class, Doc, Ref, TxCUD, getCurrentAccount } from '@hcengineering/core'
|
import core, { AnyAttribute, Class, Doc, Ref, TxCUD, getCurrentAccount } from '@hcengineering/core'
|
||||||
import { Asset } from '@hcengineering/platform'
|
import { Asset } from '@hcengineering/platform'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
let viewlet: TxDisplayViewlet | undefined
|
let viewlet: TxDisplayViewlet | undefined
|
||||||
let props: any
|
let props: any
|
||||||
let account: EmployeeAccount | undefined
|
let account: PersonAccount | undefined
|
||||||
let employee: Employee | undefined
|
let employee: Employee | undefined
|
||||||
let model: AttributeModel[] = []
|
let model: AttributeModel[] = []
|
||||||
let modelIcon: Asset | undefined = undefined
|
let modelIcon: Asset | undefined = undefined
|
||||||
@ -97,8 +97,8 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
$: query.query(
|
$: query.query(
|
||||||
contact.class.EmployeeAccount,
|
contact.class.PersonAccount,
|
||||||
{ _id: tx.tx.modifiedBy as Ref<EmployeeAccount> },
|
{ _id: tx.tx.modifiedBy as Ref<PersonAccount> },
|
||||||
(res) => {
|
(res) => {
|
||||||
;[account] = res
|
;[account] = res
|
||||||
},
|
},
|
||||||
@ -107,8 +107,8 @@
|
|||||||
|
|
||||||
$: account &&
|
$: account &&
|
||||||
employeeQuery.query(
|
employeeQuery.query(
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
{ _id: account.employee },
|
{ _id: account.person as Ref<Employee> },
|
||||||
(res) => {
|
(res) => {
|
||||||
;[employee] = res
|
;[employee] = res
|
||||||
},
|
},
|
||||||
@ -213,7 +213,7 @@
|
|||||||
<div class="msgactivity-content__title labels-row">
|
<div class="msgactivity-content__title labels-row">
|
||||||
<span class={withAvatar ? 'bold' : 'strong'}>
|
<span class={withAvatar ? 'bold' : 'strong'}>
|
||||||
{#if employee}
|
{#if employee}
|
||||||
{getName(employee)}
|
{getName(client.getHierarchy(), employee)}
|
||||||
{:else}
|
{:else}
|
||||||
<Label label={core.string.System} />
|
<Label label={core.string.System} />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Attachment } from '@hcengineering/attachment'
|
import { Attachment } from '@hcengineering/attachment'
|
||||||
import contact, { Employee, EmployeeAccount } from '@hcengineering/contact'
|
import contact, { Person, PersonAccount } from '@hcengineering/contact'
|
||||||
import core, { Class, getCurrentAccount, Ref, Space } from '@hcengineering/core'
|
import core, { Class, getCurrentAccount, Ref, Space } from '@hcengineering/core'
|
||||||
import { getClient } from '@hcengineering/presentation'
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { Label, Loading, navigate, TabList, SearchEdit, getLocation } from '@hcengineering/ui'
|
import { Label, Loading, navigate, TabList, SearchEdit, getLocation } from '@hcengineering/ui'
|
||||||
@ -38,8 +38,8 @@
|
|||||||
navigate(loc)
|
navigate(loc)
|
||||||
}
|
}
|
||||||
export let requestedSpaceClasses: Ref<Class<Space>>[] = []
|
export let requestedSpaceClasses: Ref<Class<Space>>[] = []
|
||||||
const currentUser = getCurrentAccount() as EmployeeAccount
|
const currentUser = getCurrentAccount() as PersonAccount
|
||||||
let selectedParticipants: Ref<Employee>[] = [currentUser.employee]
|
let selectedParticipants: Ref<Person>[] = [currentUser.person]
|
||||||
let selectedSpaces: Ref<Space>[] = []
|
let selectedSpaces: Ref<Space>[] = []
|
||||||
export let search: string = ''
|
export let search: string = ''
|
||||||
let isLoading = false
|
let isLoading = false
|
||||||
@ -58,14 +58,14 @@
|
|||||||
selectedSort_: FileBrowserSortMode,
|
selectedSort_: FileBrowserSortMode,
|
||||||
selectedFileTypeId_: string,
|
selectedFileTypeId_: string,
|
||||||
selectedDateId_: string,
|
selectedDateId_: string,
|
||||||
selectedParticipants_: Ref<Employee>[],
|
selectedParticipants_: Ref<Person>[],
|
||||||
selectedSpaces_: Ref<Space>[]
|
selectedSpaces_: Ref<Space>[]
|
||||||
) {
|
) {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
|
|
||||||
const nameQuery = searchQuery_ ? { name: { $like: '%' + searchQuery_ + '%' } } : {}
|
const nameQuery = searchQuery_ ? { name: { $like: '%' + searchQuery_ + '%' } } : {}
|
||||||
|
|
||||||
const accounts = await client.findAll(contact.class.EmployeeAccount, { employee: { $in: selectedParticipants_ } })
|
const accounts = await client.findAll(contact.class.PersonAccount, { person: { $in: selectedParticipants_ } })
|
||||||
const senderQuery = accounts.length ? { modifiedBy: { $in: accounts.map((a) => a._id) } } : {}
|
const senderQuery = accounts.length ? { modifiedBy: { $in: accounts.map((a) => a._id) } } : {}
|
||||||
|
|
||||||
let spaceQuery: { space: any }
|
let spaceQuery: { space: any }
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee } from '@hcengineering/contact'
|
import { Person } from '@hcengineering/contact'
|
||||||
import { Class, Ref, Space } from '@hcengineering/core'
|
import { Class, Ref, Space } from '@hcengineering/core'
|
||||||
import { SpaceMultiBoxList } from '@hcengineering/presentation'
|
import { SpaceMultiBoxList } from '@hcengineering/presentation'
|
||||||
import { Component, DropdownLabelsIntl } from '@hcengineering/ui'
|
import { Component, DropdownLabelsIntl } from '@hcengineering/ui'
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
export let requestedSpaceClasses: Ref<Class<Space>>[]
|
export let requestedSpaceClasses: Ref<Class<Space>>[]
|
||||||
export let spaceId: Ref<Space> | undefined
|
export let spaceId: Ref<Space> | undefined
|
||||||
export let selectedParticipants: Ref<Employee>[]
|
export let selectedParticipants: Ref<Person>[]
|
||||||
export let selectedSpaces: Ref<Space>[]
|
export let selectedSpaces: Ref<Space>[]
|
||||||
export let selectedDateId: string
|
export let selectedDateId: string
|
||||||
export let selectedFileTypeId: string
|
export let selectedFileTypeId: string
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import attachment, { Attachment } from '@hcengineering/attachment'
|
import attachment, { Attachment } from '@hcengineering/attachment'
|
||||||
import chunter, { Comment } from '@hcengineering/chunter'
|
import chunter, { Comment } from '@hcengineering/chunter'
|
||||||
import contact, { Channel, combineName, Contact, EmployeeAccount } from '@hcengineering/contact'
|
import contact, { Channel, combineName, Contact, Employee, PersonAccount } from '@hcengineering/contact'
|
||||||
import core, {
|
import core, {
|
||||||
Account,
|
Account,
|
||||||
AccountRole,
|
AccountRole,
|
||||||
@ -489,8 +489,8 @@ interface SyncOptionsExtra {
|
|||||||
ownerTypeValues: BitrixOwnerType[]
|
ownerTypeValues: BitrixOwnerType[]
|
||||||
commentFieldKeys: string[]
|
commentFieldKeys: string[]
|
||||||
allMappings: FindResult<BitrixEntityMapping>
|
allMappings: FindResult<BitrixEntityMapping>
|
||||||
allEmployee: FindResult<EmployeeAccount>
|
allEmployee: FindResult<PersonAccount>
|
||||||
userList: Map<string, Ref<EmployeeAccount>>
|
userList: Map<string, Ref<PersonAccount>>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -505,7 +505,7 @@ export async function performSynchronization (ops: SyncOptions): Promise<BitrixS
|
|||||||
|
|
||||||
const commentFieldKeys = Object.keys(commentFields.result)
|
const commentFieldKeys = Object.keys(commentFields.result)
|
||||||
|
|
||||||
const allEmployee = await ops.client.findAll(contact.class.EmployeeAccount, {})
|
const allEmployee = await ops.client.findAll(contact.class.PersonAccount, {})
|
||||||
|
|
||||||
const allMappings = await ops.client.findAll<BitrixEntityMapping>(
|
const allMappings = await ops.client.findAll<BitrixEntityMapping>(
|
||||||
bitrix.class.EntityMapping,
|
bitrix.class.EntityMapping,
|
||||||
@ -519,7 +519,7 @@ export async function performSynchronization (ops: SyncOptions): Promise<BitrixS
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const userList = new Map<string, Ref<EmployeeAccount>>()
|
const userList = new Map<string, Ref<PersonAccount>>()
|
||||||
|
|
||||||
// Fill all users and create new ones, if required.
|
// Fill all users and create new ones, if required.
|
||||||
await synchronizeUsers(userList, ops, allEmployee)
|
await synchronizeUsers(userList, ops, allEmployee)
|
||||||
@ -764,7 +764,7 @@ async function downloadComments (
|
|||||||
syncEmails?: boolean
|
syncEmails?: boolean
|
||||||
},
|
},
|
||||||
commentFieldKeys: string[],
|
commentFieldKeys: string[],
|
||||||
userList: Map<string, Ref<EmployeeAccount>>,
|
userList: Map<string, Ref<PersonAccount>>,
|
||||||
ownerTypeValues: BitrixOwnerType[]
|
ownerTypeValues: BitrixOwnerType[]
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const entityType = ops.mapping.type.replace('crm.', '')
|
const entityType = ops.mapping.type.replace('crm.', '')
|
||||||
@ -887,7 +887,7 @@ async function downloadComments (
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function synchronizeUsers (
|
async function synchronizeUsers (
|
||||||
userList: Map<string, Ref<EmployeeAccount>>,
|
userList: Map<string, Ref<PersonAccount>>,
|
||||||
ops: {
|
ops: {
|
||||||
client: TxOperations
|
client: TxOperations
|
||||||
bitrixClient: BitrixClient
|
bitrixClient: BitrixClient
|
||||||
@ -900,13 +900,13 @@ async function synchronizeUsers (
|
|||||||
monitor: (total: number) => void
|
monitor: (total: number) => void
|
||||||
blobProvider?: ((blobRef: { file: string, id: string }) => Promise<Blob | undefined>) | undefined
|
blobProvider?: ((blobRef: { file: string, id: string }) => Promise<Blob | undefined>) | undefined
|
||||||
},
|
},
|
||||||
allEmployee: FindResult<EmployeeAccount>
|
allEmployee: FindResult<PersonAccount>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
let totalUsers = 1
|
let totalUsers = 1
|
||||||
let next = 0
|
let next = 0
|
||||||
|
|
||||||
const employeesList = await ops.client.findAll(
|
const employeesList = await ops.client.findAll(
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
lookup: {
|
lookup: {
|
||||||
@ -929,23 +929,25 @@ async function synchronizeUsers (
|
|||||||
// Try to find from employee
|
// Try to find from employee
|
||||||
employeesList.forEach((it) => {
|
employeesList.forEach((it) => {
|
||||||
if ((it.$lookup?.channels as Channel[])?.some((q) => q.value === u.EMAIL)) {
|
if ((it.$lookup?.channels as Channel[])?.some((q) => q.value === u.EMAIL)) {
|
||||||
account = allEmployee.find((qit) => qit.employee === it._id)
|
account = allEmployee.find((qit) => qit.person === it._id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let accountId = account?._id
|
let accountId = account?._id
|
||||||
if (accountId === undefined) {
|
if (accountId === undefined) {
|
||||||
const employeeId = await ops.client.createDoc(contact.class.Employee, contact.space.Contacts, {
|
const employeeId = await ops.client.createDoc(contact.class.Person, contact.space.Contacts, {
|
||||||
name: combineName(u.NAME, u.LAST_NAME),
|
name: combineName(u.NAME, u.LAST_NAME),
|
||||||
avatar: u.PERSONAL_PHOTO,
|
avatar: u.PERSONAL_PHOTO,
|
||||||
active: u.ACTIVE,
|
|
||||||
city: u.PERSONAL_CITY
|
city: u.PERSONAL_CITY
|
||||||
})
|
})
|
||||||
accountId = await ops.client.createDoc(contact.class.EmployeeAccount, core.space.Model, {
|
await ops.client.createMixin(employeeId, contact.class.Person, contact.space.Contacts, contact.mixin.Employee, {
|
||||||
|
active: u.ACTIVE
|
||||||
|
})
|
||||||
|
accountId = await ops.client.createDoc(contact.class.PersonAccount, core.space.Model, {
|
||||||
email: u.EMAIL,
|
email: u.EMAIL,
|
||||||
name: combineName(u.NAME, u.LAST_NAME),
|
name: combineName(u.NAME, u.LAST_NAME),
|
||||||
employee: employeeId,
|
person: employeeId,
|
||||||
role: AccountRole.User
|
role: AccountRole.User
|
||||||
})
|
})
|
||||||
if (u.EMAIL !== undefined && u.EMAIL !== null) {
|
if (u.EMAIL !== undefined && u.EMAIL !== null) {
|
||||||
@ -953,7 +955,7 @@ async function synchronizeUsers (
|
|||||||
contact.class.Channel,
|
contact.class.Channel,
|
||||||
contact.space.Contacts,
|
contact.space.Contacts,
|
||||||
employeeId,
|
employeeId,
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
'channels',
|
'channels',
|
||||||
{
|
{
|
||||||
provider: contact.channelProvider.Email,
|
provider: contact.channelProvider.Email,
|
||||||
@ -963,7 +965,7 @@ async function synchronizeUsers (
|
|||||||
}
|
}
|
||||||
await ops.client.createMixin<Doc, BitrixSyncDoc>(
|
await ops.client.createMixin<Doc, BitrixSyncDoc>(
|
||||||
employeeId,
|
employeeId,
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
contact.space.Contacts,
|
contact.space.Contacts,
|
||||||
bitrix.mixin.BitrixSyncDoc,
|
bitrix.mixin.BitrixSyncDoc,
|
||||||
{
|
{
|
||||||
@ -973,7 +975,7 @@ async function synchronizeUsers (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else if (account != null) {
|
} else if (account != null) {
|
||||||
const emp = employees.get(account.employee)
|
const emp = employees.get(account.person as unknown as Ref<Employee>)
|
||||||
if (emp !== undefined && !ops.client.getHierarchy().hasMixin(emp, bitrix.mixin.BitrixSyncDoc)) {
|
if (emp !== undefined && !ops.client.getHierarchy().hasMixin(emp, bitrix.mixin.BitrixSyncDoc)) {
|
||||||
await ops.client.createMixin<Doc, BitrixSyncDoc>(emp._id, emp._class, emp.space, bitrix.mixin.BitrixSyncDoc, {
|
await ops.client.createMixin<Doc, BitrixSyncDoc>(emp._id, emp._class, emp.space, bitrix.mixin.BitrixSyncDoc, {
|
||||||
type: 'employee',
|
type: 'employee',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import attachment, { Attachment } from '@hcengineering/attachment'
|
import attachment, { Attachment } from '@hcengineering/attachment'
|
||||||
import contact, { Channel, EmployeeAccount, Organization } from '@hcengineering/contact'
|
import contact, { Channel, PersonAccount, Organization } from '@hcengineering/contact'
|
||||||
import core, {
|
import core, {
|
||||||
AnyAttribute,
|
AnyAttribute,
|
||||||
AttachedDoc,
|
AttachedDoc,
|
||||||
@ -102,7 +102,7 @@ export async function convert (
|
|||||||
space: Ref<Space>,
|
space: Ref<Space>,
|
||||||
fields: BitrixFieldMapping[],
|
fields: BitrixFieldMapping[],
|
||||||
rawDocument: any,
|
rawDocument: any,
|
||||||
userList: Map<string, Ref<EmployeeAccount>>,
|
userList: Map<string, Ref<PersonAccount>>,
|
||||||
existingDoc: WithLookup<Doc> | undefined,
|
existingDoc: WithLookup<Doc> | undefined,
|
||||||
defaultCategories: TagCategory[],
|
defaultCategories: TagCategory[],
|
||||||
allTagElements: TagElement[],
|
allTagElements: TagElement[],
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
import { Ref } from '@hcengineering/core'
|
import { Ref } from '@hcengineering/core'
|
||||||
|
|
||||||
import contact from '@hcengineering/contact'
|
import contact from '@hcengineering/contact'
|
||||||
import board from '../plugin'
|
|
||||||
import { Component } from '@hcengineering/ui'
|
import { Component } from '@hcengineering/ui'
|
||||||
|
import board from '../plugin'
|
||||||
|
|
||||||
export let value: Ref<Employee>[]
|
export let value: Ref<Employee>[]
|
||||||
export let readonly = false
|
export let readonly = false
|
||||||
|
@ -16,20 +16,20 @@
|
|||||||
import { Employee } from '@hcengineering/contact'
|
import { Employee } from '@hcengineering/contact'
|
||||||
import { EmployeeBox } from '@hcengineering/contact-resources'
|
import { EmployeeBox } from '@hcengineering/contact-resources'
|
||||||
import { Ref } from '@hcengineering/core'
|
import { Ref } from '@hcengineering/core'
|
||||||
import { createQuery, getClient, MessageBox } from '@hcengineering/presentation'
|
import { MessageBox, createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import type { TodoItem } from '@hcengineering/task'
|
import type { TodoItem } from '@hcengineering/task'
|
||||||
import task, { calcRank } from '@hcengineering/task'
|
import task, { calcRank } from '@hcengineering/task'
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
CheckBox,
|
CheckBox,
|
||||||
DateRangePresenter,
|
DateRangePresenter,
|
||||||
getEventPopupPositionElement,
|
|
||||||
IconAdd,
|
IconAdd,
|
||||||
IconDelete,
|
IconDelete,
|
||||||
IconMoreH,
|
IconMoreH,
|
||||||
Progress,
|
Progress,
|
||||||
showPopup,
|
TextAreaEditor,
|
||||||
TextAreaEditor
|
getEventPopupPositionElement,
|
||||||
|
showPopup
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import { ContextMenu, HTMLPresenter } from '@hcengineering/view-resources'
|
import { ContextMenu, HTMLPresenter } from '@hcengineering/view-resources'
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Card } from '@hcengineering/board'
|
import { Card } from '@hcengineering/board'
|
||||||
import { Employee, EmployeeAccount } from '@hcengineering/contact'
|
import { Employee, PersonAccount } from '@hcengineering/contact'
|
||||||
import {
|
import {
|
||||||
TxOperations as Client,
|
TxOperations as Client,
|
||||||
TxResult,
|
TxResult,
|
||||||
@ -86,9 +86,9 @@ export function canAddCurrentUser (card: Card): boolean {
|
|||||||
if (card.members == null) {
|
if (card.members == null) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
const employee = (getCurrentAccount() as EmployeeAccount).employee
|
const employee = (getCurrentAccount() as PersonAccount).person
|
||||||
|
|
||||||
return !card.members.includes(employee)
|
return !card.members.includes(employee as Ref<Employee>)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasCover (card: Card): boolean {
|
export function hasCover (card: Card): boolean {
|
||||||
@ -100,13 +100,13 @@ export function hasDate (card: Card): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function addCurrentUser (card: Card, client: Client): Promise<TxResult> | undefined {
|
export function addCurrentUser (card: Card, client: Client): Promise<TxResult> | undefined {
|
||||||
const employee = (getCurrentAccount() as EmployeeAccount).employee
|
const employee = (getCurrentAccount() as PersonAccount).person
|
||||||
|
|
||||||
if (card.members?.includes(employee) === true) {
|
if (card.members?.includes(employee as Ref<Employee>) === true) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return client.update(card, { $push: { members: employee } })
|
return client.update(card, { $push: { members: employee as Ref<Employee> } })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function archiveCard (card: Card, client: Client): Promise<TxResult> | undefined {
|
export function archiveCard (card: Card, client: Client): Promise<TxResult> | undefined {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar, Event, getAllEvents } from '@hcengineering/calendar'
|
import { Calendar, Event, getAllEvents } from '@hcengineering/calendar'
|
||||||
import { EmployeeAccount } from '@hcengineering/contact'
|
import { PersonAccount } from '@hcengineering/contact'
|
||||||
import {
|
import {
|
||||||
Class,
|
Class,
|
||||||
Doc,
|
Doc,
|
||||||
@ -58,7 +58,7 @@
|
|||||||
CalendarMode.Year
|
CalendarMode.Year
|
||||||
]
|
]
|
||||||
|
|
||||||
const me = getCurrentAccount() as EmployeeAccount
|
const me = getCurrentAccount() as PersonAccount
|
||||||
|
|
||||||
const mondayStart = true
|
const mondayStart = true
|
||||||
let mode: CalendarMode = allowedModes.includes(CalendarMode.Days) ? CalendarMode.Days : allowedModes[0]
|
let mode: CalendarMode = allowedModes.includes(CalendarMode.Days) ? CalendarMode.Days : allowedModes[0]
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar, generateEventId } from '@hcengineering/calendar'
|
import { Calendar, generateEventId } from '@hcengineering/calendar'
|
||||||
import { Employee, EmployeeAccount } from '@hcengineering/contact'
|
import { Employee, PersonAccount } from '@hcengineering/contact'
|
||||||
import { UserBoxList } from '@hcengineering/contact-resources'
|
import { UserBoxList } from '@hcengineering/contact-resources'
|
||||||
import { Class, DateRangeMode, Doc, Ref, getCurrentAccount } from '@hcengineering/core'
|
import { Class, DateRangeMode, Doc, Ref, getCurrentAccount } from '@hcengineering/core'
|
||||||
import { Card, getClient } from '@hcengineering/presentation'
|
import { Card, getClient } from '@hcengineering/presentation'
|
||||||
@ -40,8 +40,8 @@
|
|||||||
let dueDateRef: DateRangePresenter
|
let dueDateRef: DateRangePresenter
|
||||||
let allDay = false
|
let allDay = false
|
||||||
|
|
||||||
const currentUser = getCurrentAccount() as EmployeeAccount
|
const currentUser = getCurrentAccount() as PersonAccount
|
||||||
let participants: Ref<Employee>[] = [currentUser.employee]
|
let participants: Ref<Employee>[] = [currentUser.person as Ref<Employee>]
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar, Event, generateEventId } from '@hcengineering/calendar'
|
import { Calendar, Event, generateEventId } from '@hcengineering/calendar'
|
||||||
import { Employee, EmployeeAccount } from '@hcengineering/contact'
|
import { Employee, PersonAccount } from '@hcengineering/contact'
|
||||||
import { UserBoxList } from '@hcengineering/contact-resources'
|
import { UserBoxList } from '@hcengineering/contact-resources'
|
||||||
import { Class, DateRangeMode, Doc, Ref, getCurrentAccount } from '@hcengineering/core'
|
import { Class, DateRangeMode, Doc, Ref, getCurrentAccount } from '@hcengineering/core'
|
||||||
import { Card, getClient } from '@hcengineering/presentation'
|
import { Card, getClient } from '@hcengineering/presentation'
|
||||||
@ -29,8 +29,8 @@
|
|||||||
let _title = title
|
let _title = title
|
||||||
|
|
||||||
let value: number | null | undefined = null
|
let value: number | null | undefined = null
|
||||||
const currentUser = getCurrentAccount() as EmployeeAccount
|
const currentUser = getCurrentAccount() as PersonAccount
|
||||||
let participants: Ref<Employee>[] = [currentUser.employee]
|
let participants: Ref<Employee>[] = [currentUser.person as Ref<Employee>]
|
||||||
const defaultDuration = 30 * 60 * 1000
|
const defaultDuration = 30 * 60 * 1000
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { EmployeeAccount } from '@hcengineering/contact'
|
import { PersonAccount } from '@hcengineering/contact'
|
||||||
import { Doc, getCurrentAccount } from '@hcengineering/core'
|
import { Doc, getCurrentAccount } from '@hcengineering/core'
|
||||||
import { getClient } from '@hcengineering/presentation'
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { Button, showPopup } from '@hcengineering/ui'
|
import { Button, showPopup } from '@hcengineering/ui'
|
||||||
@ -34,10 +34,10 @@
|
|||||||
if (isEvent) {
|
if (isEvent) {
|
||||||
showPopup(SaveEventReminder, { objectId: value._id, objectClass: value._class }, ev.target as HTMLElement)
|
showPopup(SaveEventReminder, { objectId: value._id, objectClass: value._class }, ev.target as HTMLElement)
|
||||||
} else {
|
} else {
|
||||||
const currentUser = getCurrentAccount() as EmployeeAccount
|
const currentUser = getCurrentAccount() as PersonAccount
|
||||||
const current = await client.findOne(calendar.class.Event, {
|
const current = await client.findOne(calendar.class.Event, {
|
||||||
attachedTo: value._id,
|
attachedTo: value._id,
|
||||||
participants: currentUser.employee
|
participants: currentUser.person
|
||||||
})
|
})
|
||||||
if (current === undefined) {
|
if (current === undefined) {
|
||||||
showPopup(
|
showPopup(
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Event } from '@hcengineering/calendar'
|
import { Event } from '@hcengineering/calendar'
|
||||||
import { EmployeeAccount } from '@hcengineering/contact'
|
import { PersonAccount } from '@hcengineering/contact'
|
||||||
import { Class, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
|
import { Class, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||||
import { createQuery } from '@hcengineering/presentation'
|
import { createQuery } from '@hcengineering/presentation'
|
||||||
import { Button, deviceOptionsStore as deviceInfo, IconAdd, Label, Scroller, showPopup } from '@hcengineering/ui'
|
import { Button, deviceOptionsStore as deviceInfo, IconAdd, Label, Scroller, showPopup } from '@hcengineering/ui'
|
||||||
@ -26,14 +26,14 @@
|
|||||||
export let attachedToClass: Ref<Class<Doc>>
|
export let attachedToClass: Ref<Class<Doc>>
|
||||||
export let title: string | undefined
|
export let title: string | undefined
|
||||||
|
|
||||||
const currentUser = getCurrentAccount() as EmployeeAccount
|
const currentUser = getCurrentAccount() as PersonAccount
|
||||||
let events: Event[] = []
|
let events: Event[] = []
|
||||||
const query = createQuery()
|
const query = createQuery()
|
||||||
$: query.query(
|
$: query.query(
|
||||||
calendar.class.Event,
|
calendar.class.Event,
|
||||||
{
|
{
|
||||||
attachedTo,
|
attachedTo,
|
||||||
participants: currentUser.employee
|
participants: currentUser.person
|
||||||
},
|
},
|
||||||
(res) => {
|
(res) => {
|
||||||
events = res.filter((p) => p.reminders !== undefined && p.reminders.length > 0)
|
events = res.filter((p) => p.reminders !== undefined && p.reminders.length > 0)
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
import calendar from '../plugin'
|
import calendar from '../plugin'
|
||||||
import { showPanel, tooltip } from '@hcengineering/ui'
|
import { showPanel, tooltip } from '@hcengineering/ui'
|
||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
|
|
||||||
export let value: Person | Person[]
|
export let value: Person | Person[]
|
||||||
export let inline: boolean = false
|
export let inline: boolean = false
|
||||||
@ -30,15 +31,17 @@
|
|||||||
async function onClick (p: Person) {
|
async function onClick (p: Person) {
|
||||||
showPanel(view.component.EditDoc, p._id, Hierarchy.mixinOrClass(p), 'content')
|
showPanel(view.component.EditDoc, p._id, Hierarchy.mixinOrClass(p), 'content')
|
||||||
}
|
}
|
||||||
|
const client = getClient()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<div class="flex persons">
|
<div class="flex persons">
|
||||||
{#each persons as p}
|
{#each persons as p}
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
use:tooltip={{ label: calendar.string.PersonsLabel, props: { name: getName(p) } }}
|
use:tooltip={{ label: calendar.string.PersonsLabel, props: { name: getName(client.getHierarchy(), p) } }}
|
||||||
on:click={() => onClick(p)}
|
on:click={() => onClick(p)}
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { Backlink } from '@hcengineering/chunter'
|
import { Backlink } from '@hcengineering/chunter'
|
||||||
import contact, { EmployeeAccount } from '@hcengineering/contact'
|
import contact, { PersonAccount } from '@hcengineering/contact'
|
||||||
import { Account, Class, Client, Data, Doc, DocumentQuery, Ref, TxOperations } from '@hcengineering/core'
|
import { Account, Class, Client, Data, Doc, DocumentQuery, Ref, TxOperations } from '@hcengineering/core'
|
||||||
import chunter from './plugin'
|
import chunter from './plugin'
|
||||||
|
|
||||||
export async function getUser (
|
export async function getUser (
|
||||||
client: Client,
|
client: Client,
|
||||||
user: Ref<EmployeeAccount> | Ref<Account>
|
user: Ref<PersonAccount> | Ref<Account>
|
||||||
): Promise<EmployeeAccount | undefined> {
|
): Promise<PersonAccount | undefined> {
|
||||||
return await client.findOne(contact.class.EmployeeAccount, { _id: user as Ref<EmployeeAccount> })
|
return await client.findOne(contact.class.PersonAccount, { _id: user as Ref<PersonAccount> })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTime (time: number): string {
|
export function getTime (time: number): string {
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
requestedSpaceClasses: [plugin.class.Channel, plugin.class.DirectMessage]
|
requestedSpaceClasses: [plugin.class.Channel, plugin.class.DirectMessage]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ searchType: SearchType.Contacts, component: EmployeeBrowser, filterClass: contact.class.Employee }
|
{ searchType: SearchType.Contacts, component: EmployeeBrowser, filterClass: contact.mixin.Employee }
|
||||||
]
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getName, Person } from '@hcengineering/contact'
|
import { getName, Person } from '@hcengineering/contact'
|
||||||
import { Avatar } from '@hcengineering/contact-resources'
|
import { Avatar } from '@hcengineering/contact-resources'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
|
|
||||||
interface IMessage {
|
interface IMessage {
|
||||||
text: string
|
text: string
|
||||||
@ -23,12 +24,13 @@
|
|||||||
|
|
||||||
export let user: Person
|
export let user: Person
|
||||||
export let message: IMessage
|
export let message: IMessage
|
||||||
|
const client = getClient()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex-nowrap">
|
<div class="flex-nowrap">
|
||||||
<div class="avatar"><Avatar size={'medium'} /></div>
|
<div class="avatar"><Avatar size={'medium'} /></div>
|
||||||
<div class="flex-col-stretch message">
|
<div class="flex-col-stretch message">
|
||||||
<div class="header">{getName(user)}<span>{message.createDate}</span></div>
|
<div class="header">{getName(client.getHierarchy(), user)}<span>{message.createDate}</span></div>
|
||||||
<div class="text">{message.text}</div>
|
<div class="text">{message.text}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
import { AttachmentDocList } from '@hcengineering/attachment-resources'
|
import { AttachmentDocList } from '@hcengineering/attachment-resources'
|
||||||
import type { Comment } from '@hcengineering/chunter'
|
import type { Comment } from '@hcengineering/chunter'
|
||||||
import chunter from '@hcengineering/chunter'
|
import chunter from '@hcengineering/chunter'
|
||||||
import { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
import { Person, PersonAccount, getName } from '@hcengineering/contact'
|
||||||
import { Avatar, employeeAccountByIdStore, employeeByIdStore } from '@hcengineering/contact-resources'
|
import { Avatar, personByIdStore, personAccountByIdStore } from '@hcengineering/contact-resources'
|
||||||
import { IdMap, Ref } from '@hcengineering/core'
|
import { IdMap, Ref } from '@hcengineering/core'
|
||||||
import { MessageViewer } from '@hcengineering/presentation'
|
import { MessageViewer, getClient } from '@hcengineering/presentation'
|
||||||
import { Icon, ShowMore, TimeSince } from '@hcengineering/ui'
|
import { Icon, ShowMore, TimeSince } from '@hcengineering/ui'
|
||||||
import { LinkPresenter } from '@hcengineering/view-resources'
|
import { LinkPresenter } from '@hcengineering/view-resources'
|
||||||
|
|
||||||
@ -28,18 +28,20 @@
|
|||||||
export let inline: boolean = false
|
export let inline: boolean = false
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
const cutId = (str: string): string => {
|
const cutId = (str: string): string => {
|
||||||
return str.slice(0, 4) + '...' + str.slice(-4)
|
return str.slice(0, 4) + '...' + str.slice(-4)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getEmployee (
|
async function getEmployee (
|
||||||
value: Comment,
|
value: Comment,
|
||||||
employees: IdMap<Employee>,
|
employees: IdMap<Person>,
|
||||||
accounts: IdMap<EmployeeAccount>
|
accounts: IdMap<PersonAccount>
|
||||||
): Promise<Employee | undefined> {
|
): Promise<Person | undefined> {
|
||||||
const acc = accounts.get(value.modifiedBy as Ref<EmployeeAccount>)
|
const acc = accounts.get(value.modifiedBy as Ref<PersonAccount>)
|
||||||
if (acc !== undefined) {
|
if (acc !== undefined) {
|
||||||
const emp = employees.get(acc.employee)
|
const emp = employees.get(acc.person)
|
||||||
return emp
|
return emp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,14 +78,14 @@
|
|||||||
<span class="content-dark-color">#{cutId(value._id.toString())}</span>
|
<span class="content-dark-color">#{cutId(value._id.toString())}</span>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="flex-row-top">
|
<div class="flex-row-top">
|
||||||
{#await getEmployee(value, $employeeByIdStore, $employeeAccountByIdStore) then employee}
|
{#await getEmployee(value, $personByIdStore, $personAccountByIdStore) then employee}
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<Avatar size={'medium'} avatar={employee?.avatar} />
|
<Avatar size={'medium'} avatar={employee?.avatar} />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow flex-col select-text">
|
<div class="flex-grow flex-col select-text">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="fs-title">
|
<div class="fs-title">
|
||||||
{#if employee}{getName(employee)}{/if}
|
{#if employee}{getName(client.getHierarchy(), employee)}{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="content-dark-color ml-4"><TimeSince value={value.modifiedOn} /></div>
|
<div class="content-dark-color ml-4"><TimeSince value={value.modifiedOn} /></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
let employeeIds: Ref<Employee>[] = []
|
let employeeIds: Ref<Employee>[] = []
|
||||||
|
|
||||||
async function createDirectMessage () {
|
async function createDirectMessage () {
|
||||||
const employeeAccounts = await client.findAll(contact.class.EmployeeAccount, { employee: { $in: employeeIds } })
|
const employeeAccounts = await client.findAll(contact.class.PersonAccount, { person: { $in: employeeIds } })
|
||||||
|
|
||||||
const accIds = [myAccId, ...employeeAccounts.filter((ea) => ea._id !== myAccId).map((ea) => ea._id)].sort()
|
const accIds = [myAccId, ...employeeAccounts.filter((ea) => ea._id !== myAccId).map((ea) => ea._id)].sort()
|
||||||
const existingDms = await client.findAll(chunter.class.DirectMessage, {})
|
const existingDms = await client.findAll(chunter.class.DirectMessage, {})
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
import { getCurrentAccount } from '@hcengineering/core'
|
import { getCurrentAccount } from '@hcengineering/core'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { CombineAvatars } from '@hcengineering/contact-resources'
|
import { CombineAvatars } from '@hcengineering/contact-resources'
|
||||||
import contact, { EmployeeAccount } from '@hcengineering/contact'
|
import contact, { PersonAccount } from '@hcengineering/contact'
|
||||||
import { SearchEdit, showPanel } from '@hcengineering/ui'
|
import { SearchEdit, showPanel } from '@hcengineering/ui'
|
||||||
import chunter from '../plugin'
|
import chunter from '../plugin'
|
||||||
import { getDmName, navigateToSpecial } from '../utils'
|
import { getDmName, navigateToSpecial } from '../utils'
|
||||||
@ -42,11 +42,11 @@
|
|||||||
async function getEmpolyeeIds () {
|
async function getEmpolyeeIds () {
|
||||||
const empAccIds = dm?.members.length !== 1 ? dm?.members.filter((accId) => accId !== myAccId) : dm?.members
|
const empAccIds = dm?.members.length !== 1 ? dm?.members.filter((accId) => accId !== myAccId) : dm?.members
|
||||||
|
|
||||||
const employeeAccounts = await client.findAll(contact.class.EmployeeAccount, {
|
const employeeAccounts = await client.findAll(contact.class.PersonAccount, {
|
||||||
_id: { $in: empAccIds as Ref<EmployeeAccount>[] }
|
_id: { $in: empAccIds as Ref<PersonAccount>[] }
|
||||||
})
|
})
|
||||||
|
|
||||||
return employeeAccounts.map((ea) => ea.employee)
|
return employeeAccounts.map((ea) => ea.person)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onSpaceEdit (): Promise<void> {
|
async function onSpaceEdit (): Promise<void> {
|
||||||
@ -62,7 +62,7 @@
|
|||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div class="ac-header__wrap-title" on:click={onSpaceEdit}>
|
<div class="ac-header__wrap-title" on:click={onSpaceEdit}>
|
||||||
<div class="ac-header__icon">
|
<div class="ac-header__icon">
|
||||||
<CombineAvatars _class={contact.class.Employee} items={empolyeeIds} size={'x-small'} />
|
<CombineAvatars _class={contact.mixin.Employee} items={empolyeeIds} size={'x-small'} />
|
||||||
</div>
|
</div>
|
||||||
<span class="ac-header__title">{name}</span>
|
<span class="ac-header__title">{name}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
import { Attachment } from '@hcengineering/attachment'
|
import { Attachment } from '@hcengineering/attachment'
|
||||||
import { AttachmentList, AttachmentRefInput } from '@hcengineering/attachment-resources'
|
import { AttachmentList, AttachmentRefInput } from '@hcengineering/attachment-resources'
|
||||||
import type { ChunterMessage, Message, Reaction } from '@hcengineering/chunter'
|
import type { ChunterMessage, Message, Reaction } from '@hcengineering/chunter'
|
||||||
import { EmployeeAccount } from '@hcengineering/contact'
|
import { PersonAccount } from '@hcengineering/contact'
|
||||||
import { Avatar, employeeByIdStore, EmployeePresenter } from '@hcengineering/contact-resources'
|
import { Avatar, personByIdStore, EmployeePresenter } from '@hcengineering/contact-resources'
|
||||||
import { getCurrentAccount, Ref, WithLookup } from '@hcengineering/core'
|
import { getCurrentAccount, Ref, WithLookup } from '@hcengineering/core'
|
||||||
import { getResource } from '@hcengineering/platform'
|
import { getResource } from '@hcengineering/platform'
|
||||||
import { getClient, MessageViewer } from '@hcengineering/presentation'
|
import { getClient, MessageViewer } from '@hcengineering/presentation'
|
||||||
@ -46,8 +46,8 @@
|
|||||||
|
|
||||||
let refInput: AttachmentRefInput
|
let refInput: AttachmentRefInput
|
||||||
|
|
||||||
$: empRef = (message.$lookup?.createBy as EmployeeAccount)?.employee
|
$: empRef = (message.$lookup?.createBy as PersonAccount)?.person
|
||||||
$: employee = empRef !== undefined ? $employeeByIdStore.get(empRef) : undefined
|
$: employee = empRef !== undefined ? $personByIdStore.get(empRef) : undefined
|
||||||
$: attachments = (message.$lookup?.attachments ?? []) as Attachment[]
|
$: attachments = (message.$lookup?.attachments ?? []) as Attachment[]
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import chunter, { ChunterMessage } from '@hcengineering/chunter'
|
import chunter, { ChunterMessage } from '@hcengineering/chunter'
|
||||||
import { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
import { Person, PersonAccount, getName } from '@hcengineering/contact'
|
||||||
import { Avatar, employeeAccountByIdStore, employeeByIdStore } from '@hcengineering/contact-resources'
|
import { Avatar, personAccountByIdStore, personByIdStore } from '@hcengineering/contact-resources'
|
||||||
import { IdMap, Ref, Space } from '@hcengineering/core'
|
import { IdMap, Ref, Space } from '@hcengineering/core'
|
||||||
import { MessageViewer, createQuery } from '@hcengineering/presentation'
|
import { MessageViewer, createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { IconClose } from '@hcengineering/ui'
|
import { IconClose } from '@hcengineering/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import { UnpinMessage } from '../index'
|
import { UnpinMessage } from '../index'
|
||||||
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
export let space: Ref<Space>
|
export let space: Ref<Space>
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
const pinnedQuery = createQuery()
|
const pinnedQuery = createQuery()
|
||||||
let pinnedIds: Ref<ChunterMessage>[] = []
|
let pinnedIds: Ref<ChunterMessage>[] = []
|
||||||
pinnedQuery.query(
|
pinnedQuery.query(
|
||||||
@ -34,27 +36,28 @@
|
|||||||
|
|
||||||
function getEmployee (
|
function getEmployee (
|
||||||
message: ChunterMessage,
|
message: ChunterMessage,
|
||||||
employeeAccounts: IdMap<EmployeeAccount>,
|
employeeAccounts: IdMap<PersonAccount>,
|
||||||
employees: IdMap<Employee>
|
employees: IdMap<Person>
|
||||||
): Employee | undefined {
|
): Person | undefined {
|
||||||
const acc = employeeAccounts.get(message.createBy as Ref<EmployeeAccount>)
|
const acc = employeeAccounts.get(message.createBy as Ref<PersonAccount>)
|
||||||
if (acc) {
|
if (acc) {
|
||||||
return employees.get(acc.employee)
|
return employees.get(acc.person)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="antiPopup vScroll popup">
|
<div class="antiPopup vScroll popup">
|
||||||
{#each pinnedMessages as message}
|
{#each pinnedMessages as message}
|
||||||
{@const employee = getEmployee(message, $employeeAccountByIdStore, $employeeByIdStore)}
|
{@const employee = getEmployee(message, $personAccountByIdStore, $personByIdStore)}
|
||||||
<div class="message">
|
<div class="message">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<Avatar size={'medium'} avatar={employee?.avatar} />
|
<Avatar size={'medium'} avatar={employee?.avatar} />
|
||||||
</div>
|
</div>
|
||||||
<span class="name">
|
<span class="name">
|
||||||
{employee ? getName(employee) : ''}
|
{employee ? getName(client.getHierarchy(), employee) : ''}
|
||||||
</span>
|
</span>
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
class="cross"
|
class="cross"
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
import { Person, PersonAccount, getName } from '@hcengineering/contact'
|
||||||
import { employeeAccountByIdStore, employeeByIdStore } from '@hcengineering/contact-resources'
|
import { personAccountByIdStore, personByIdStore } from '@hcengineering/contact-resources'
|
||||||
import { Account, IdMap, Ref } from '@hcengineering/core'
|
import { Account, IdMap, Ref } from '@hcengineering/core'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
|
|
||||||
export let reactionAccounts: Ref<Account>[]
|
export let reactionAccounts: Ref<Account>[]
|
||||||
|
|
||||||
function getAccName (acc: Ref<Account>, accounts: IdMap<EmployeeAccount>, employees: IdMap<Employee>): string {
|
const client = getClient()
|
||||||
const account = accounts.get(acc as Ref<EmployeeAccount>)
|
function getAccName (acc: Ref<Account>, accounts: IdMap<PersonAccount>, employees: IdMap<Person>): string {
|
||||||
|
const account = accounts.get(acc as Ref<PersonAccount>)
|
||||||
if (account !== undefined) {
|
if (account !== undefined) {
|
||||||
const emp = employees.get(account.employee)
|
const emp = employees.get(account.person)
|
||||||
return emp ? getName(emp) : ''
|
return emp ? getName(client.getHierarchy(), emp) : ''
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
@ -17,6 +19,6 @@
|
|||||||
|
|
||||||
{#each reactionAccounts as acc}
|
{#each reactionAccounts as acc}
|
||||||
<div>
|
<div>
|
||||||
{getAccName(acc, $employeeAccountByIdStore, $employeeByIdStore)}
|
{getAccName(acc, $personAccountByIdStore, $personByIdStore)}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Message } from '@hcengineering/chunter'
|
import { Message } from '@hcengineering/chunter'
|
||||||
import { Employee } from '@hcengineering/contact'
|
import { Person } from '@hcengineering/contact'
|
||||||
import { employeeByIdStore } from '@hcengineering/contact-resources'
|
import { personByIdStore } from '@hcengineering/contact-resources'
|
||||||
import { IdMap, Ref } from '@hcengineering/core'
|
import { IdMap, Ref } from '@hcengineering/core'
|
||||||
import { Avatar } from '@hcengineering/contact-resources'
|
import { Avatar } from '@hcengineering/contact-resources'
|
||||||
import { Label, TimeSince } from '@hcengineering/ui'
|
import { Label, TimeSince } from '@hcengineering/ui'
|
||||||
@ -26,11 +26,11 @@
|
|||||||
$: employees = new Set(message.replies)
|
$: employees = new Set(message.replies)
|
||||||
|
|
||||||
const shown: number = 4
|
const shown: number = 4
|
||||||
let showReplies: Employee[] = []
|
let showReplies: Person[] = []
|
||||||
|
|
||||||
$: updateQuery(employees, $employeeByIdStore)
|
$: updateQuery(employees, $personByIdStore)
|
||||||
|
|
||||||
function updateQuery (employees: Set<Ref<Employee>>, map: IdMap<Employee>) {
|
function updateQuery (employees: Set<Ref<Person>>, map: IdMap<Person>) {
|
||||||
showReplies = []
|
showReplies = []
|
||||||
for (const employee of employees) {
|
for (const employee of employees) {
|
||||||
const emp = map.get(employee)
|
const emp = map.get(employee)
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
import attachment, { Attachment } from '@hcengineering/attachment'
|
import attachment, { Attachment } from '@hcengineering/attachment'
|
||||||
import { AttachmentPreview } from '@hcengineering/attachment-resources'
|
import { AttachmentPreview } from '@hcengineering/attachment-resources'
|
||||||
import { ChunterMessage } from '@hcengineering/chunter'
|
import { ChunterMessage } from '@hcengineering/chunter'
|
||||||
import { EmployeeAccount, getName as getContactName } from '@hcengineering/contact'
|
import { Person, PersonAccount, getName as getContactName } from '@hcengineering/contact'
|
||||||
import { employeeAccountByIdStore, employeeByIdStore } from '@hcengineering/contact-resources'
|
import { personAccountByIdStore, personByIdStore } from '@hcengineering/contact-resources'
|
||||||
import core, { IdMap, Ref, WithLookup } from '@hcengineering/core'
|
import core, { IdMap, Ref, WithLookup } from '@hcengineering/core'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { Label, Scroller } from '@hcengineering/ui'
|
import { Label, Scroller } from '@hcengineering/ui'
|
||||||
@ -74,12 +74,16 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName (a: Attachment, employeeAccountByIdStore: IdMap<EmployeeAccount>): string | undefined {
|
function getName (
|
||||||
const acc = employeeAccountByIdStore.get(a.modifiedBy as Ref<EmployeeAccount>)
|
a: Attachment,
|
||||||
|
personAccountByIdStore: IdMap<PersonAccount>,
|
||||||
|
personByIdStore: IdMap<Person>
|
||||||
|
): string | undefined {
|
||||||
|
const acc = personAccountByIdStore.get(a.modifiedBy as Ref<PersonAccount>)
|
||||||
if (acc !== undefined) {
|
if (acc !== undefined) {
|
||||||
const emp = $employeeByIdStore.get(acc?.employee)
|
const emp = personByIdStore.get(acc?.person)
|
||||||
if (emp !== undefined) {
|
if (emp !== undefined) {
|
||||||
return getContactName(emp)
|
return getContactName(client.getHierarchy(), emp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,7 +116,7 @@
|
|||||||
<div class="label">
|
<div class="label">
|
||||||
<Label
|
<Label
|
||||||
label={chunter.string.SharedBy}
|
label={chunter.string.SharedBy}
|
||||||
params={{ name: getName(att, $employeeAccountByIdStore), time: getTime(att.modifiedOn) }}
|
params={{ name: getName(att, $personAccountByIdStore, $personByIdStore), time: getTime(att.modifiedOn) }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
import attachment, { Attachment } from '@hcengineering/attachment'
|
import attachment, { Attachment } from '@hcengineering/attachment'
|
||||||
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
|
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
|
||||||
import type { ChunterSpace, Message, ThreadMessage } from '@hcengineering/chunter'
|
import type { ChunterSpace, Message, ThreadMessage } from '@hcengineering/chunter'
|
||||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
import contact, { Person, PersonAccount, getName } from '@hcengineering/contact'
|
||||||
import { employeeByIdStore } from '@hcengineering/contact-resources'
|
import { personByIdStore } from '@hcengineering/contact-resources'
|
||||||
import core, { FindOptions, IdMap, Ref, SortingOrder, generateId, getCurrentAccount } from '@hcengineering/core'
|
import core, { FindOptions, IdMap, Ref, SortingOrder, generateId, getCurrentAccount } from '@hcengineering/core'
|
||||||
import { NotificationClientImpl } from '@hcengineering/notification-resources'
|
import { NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
@ -98,21 +98,21 @@
|
|||||||
async function getParticipants (
|
async function getParticipants (
|
||||||
comments: ThreadMessage[],
|
comments: ThreadMessage[],
|
||||||
parent: Message | undefined,
|
parent: Message | undefined,
|
||||||
employees: IdMap<Employee>
|
employees: IdMap<Person>
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
const refs = new Set(comments.map((p) => p.createBy))
|
const refs = new Set(comments.map((p) => p.createBy))
|
||||||
if (parent !== undefined) {
|
if (parent !== undefined) {
|
||||||
refs.add(parent.createBy)
|
refs.add(parent.createBy)
|
||||||
}
|
}
|
||||||
refs.delete(getCurrentAccount()._id)
|
refs.delete(getCurrentAccount()._id)
|
||||||
const accounts = await client.findAll(contact.class.EmployeeAccount, {
|
const accounts = await client.findAll(contact.class.PersonAccount, {
|
||||||
_id: { $in: Array.from(refs) as Ref<EmployeeAccount>[] }
|
_id: { $in: Array.from(refs) as Ref<PersonAccount>[] }
|
||||||
})
|
})
|
||||||
const res: string[] = []
|
const res: string[] = []
|
||||||
for (const account of accounts) {
|
for (const account of accounts) {
|
||||||
const employee = employees.get(account.employee)
|
const employee = employees.get(account.person)
|
||||||
if (employee !== undefined) {
|
if (employee !== undefined) {
|
||||||
res.push(getName(employee))
|
res.push(getName(client.getHierarchy(), employee))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
@ -159,7 +159,7 @@
|
|||||||
<DmPresenter value={channel} />
|
<DmPresenter value={channel} />
|
||||||
{/if}
|
{/if}
|
||||||
{/await}
|
{/await}
|
||||||
{#await getParticipants(comments, parent, $employeeByIdStore) then participants}
|
{#await getParticipants(comments, parent, $personByIdStore) then participants}
|
||||||
{participants.join(', ')}
|
{participants.join(', ')}
|
||||||
<Label label={chunter.string.AndYou} params={{ participants: participants.length }} />
|
<Label label={chunter.string.AndYou} params={{ participants: participants.length }} />
|
||||||
{/await}
|
{/await}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { chunterId, ChunterMessage, Comment, ThreadMessage } from '@hcengineering/chunter'
|
import { chunterId, ChunterMessage, Comment, ThreadMessage } from '@hcengineering/chunter'
|
||||||
import contact, { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
import contact, { Employee, PersonAccount, getName } from '@hcengineering/contact'
|
||||||
import { employeeByIdStore } from '@hcengineering/contact-resources'
|
import { employeeByIdStore } from '@hcengineering/contact-resources'
|
||||||
import { Class, Client, Doc, getCurrentAccount, IdMap, Obj, Ref, Space, Timestamp } from '@hcengineering/core'
|
import { Class, Client, Doc, getCurrentAccount, IdMap, Obj, Ref, Space, Timestamp } from '@hcengineering/core'
|
||||||
import { Asset } from '@hcengineering/platform'
|
import { Asset } from '@hcengineering/platform'
|
||||||
@ -48,8 +48,8 @@ export function classIcon (client: Client, _class: Ref<Class<Obj>>): Asset | und
|
|||||||
export async function getDmName (client: Client, dm: Space): Promise<string> {
|
export async function getDmName (client: Client, dm: Space): Promise<string> {
|
||||||
const myAccId = getCurrentAccount()._id
|
const myAccId = getCurrentAccount()._id
|
||||||
|
|
||||||
let employeeAccounts: EmployeeAccount[] = await client.findAll(contact.class.EmployeeAccount, {
|
let employeeAccounts: PersonAccount[] = await client.findAll(contact.class.PersonAccount, {
|
||||||
_id: { $in: dm.members as Array<Ref<EmployeeAccount>> }
|
_id: { $in: dm.members as Array<Ref<PersonAccount>> }
|
||||||
})
|
})
|
||||||
|
|
||||||
if (dm.members.length > 1) {
|
if (dm.members.length > 1) {
|
||||||
@ -72,9 +72,9 @@ export async function getDmName (client: Client, dm: Space): Promise<string> {
|
|||||||
const names: string[] = []
|
const names: string[] = []
|
||||||
|
|
||||||
for (const acc of employeeAccounts) {
|
for (const acc of employeeAccounts) {
|
||||||
const employee = map.get(acc.employee)
|
const employee = map.get(acc.person as unknown as Ref<Employee>)
|
||||||
if (employee !== undefined) {
|
if (employee !== undefined) {
|
||||||
names.push(getName(employee))
|
names.push(getName(client.getHierarchy(), employee))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const name = names.join(', ')
|
const name = names.join(', ')
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import type { Employee } from '@hcengineering/contact'
|
import type { Person } from '@hcengineering/contact'
|
||||||
import type { Account, AttachedDoc, Class, Doc, Ref, RelatedDocument, Space, Timestamp } from '@hcengineering/core'
|
import type { Account, AttachedDoc, Class, Doc, Ref, RelatedDocument, Space, Timestamp } from '@hcengineering/core'
|
||||||
import { NotificationType } from '@hcengineering/notification'
|
import { NotificationType } from '@hcengineering/notification'
|
||||||
import type { Asset, Plugin, Resource } from '@hcengineering/platform'
|
import type { Asset, Plugin, Resource } from '@hcengineering/platform'
|
||||||
@ -66,7 +66,7 @@ export interface ThreadMessage extends ChunterMessage {
|
|||||||
export interface Message extends ChunterMessage {
|
export interface Message extends ChunterMessage {
|
||||||
attachedTo: Ref<Space>
|
attachedTo: Ref<Space>
|
||||||
attachedToClass: Ref<Class<Space>>
|
attachedToClass: Ref<Class<Space>>
|
||||||
replies?: Ref<Employee>[]
|
replies?: Ref<Person>[]
|
||||||
repliesCount?: number
|
repliesCount?: number
|
||||||
lastReply?: Timestamp
|
lastReply?: Timestamp
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
"Email": "Email",
|
"Email": "Email",
|
||||||
"CreateEmployee": "Employee",
|
"CreateEmployee": "Employee",
|
||||||
"Inactive": "Inactive",
|
"Inactive": "Inactive",
|
||||||
|
"Active": "Active",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
"UseImage": "Attached photo",
|
"UseImage": "Attached photo",
|
||||||
"UseGravatar": "Gravatar",
|
"UseGravatar": "Gravatar",
|
||||||
@ -79,9 +80,9 @@
|
|||||||
"Profile": "Profile",
|
"Profile": "Profile",
|
||||||
"ProfilePlaceholder": "Profile...",
|
"ProfilePlaceholder": "Profile...",
|
||||||
"CurrentEmployee": "Current employee",
|
"CurrentEmployee": "Current employee",
|
||||||
"MergeEmployee": "Merge employee",
|
"MergePersons": "Merge contacts",
|
||||||
"MergeEmployeeFrom": "From(inactive)",
|
"MergePersonsFrom": "Source contact",
|
||||||
"MergeEmployeeTo": "To employee",
|
"MergePersonsTo": "Final contact",
|
||||||
"DisplayName": "Display name",
|
"DisplayName": "Display name",
|
||||||
"SelectAvatar": "Select avatar",
|
"SelectAvatar": "Select avatar",
|
||||||
"AvatarProvider": "Avatar provider",
|
"AvatarProvider": "Avatar provider",
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
"Email": "Email",
|
"Email": "Email",
|
||||||
"CreateEmployee": "Сотрудник",
|
"CreateEmployee": "Сотрудник",
|
||||||
"Inactive": "Не активный",
|
"Inactive": "Не активный",
|
||||||
|
"Active": "Активный",
|
||||||
"Birthday": "День рождения",
|
"Birthday": "День рождения",
|
||||||
"UseImage": "Загруженное Фото",
|
"UseImage": "Загруженное Фото",
|
||||||
"UseGravatar": "Граватар",
|
"UseGravatar": "Граватар",
|
||||||
@ -80,9 +81,9 @@
|
|||||||
"Profile": "Профиль",
|
"Profile": "Профиль",
|
||||||
"ProfilePlaceholder": "Профиль...",
|
"ProfilePlaceholder": "Профиль...",
|
||||||
"CurrentEmployee": "Текущий сотрудник",
|
"CurrentEmployee": "Текущий сотрудник",
|
||||||
"MergeEmployee": "Объединить сотрудника",
|
"MergePersons": "Объеденить контакта",
|
||||||
"MergeEmployeeFrom": "Из (неактивный)",
|
"MergePersonsFrom": "Исходный контакт",
|
||||||
"MergeEmployeeTo": "В сотрудника",
|
"MergePersonsTo": "Финальный контакт",
|
||||||
"DisplayName": "Отображаемое имя",
|
"DisplayName": "Отображаемое имя",
|
||||||
"SelectAvatar": "Выбрать аватар",
|
"SelectAvatar": "Выбрать аватар",
|
||||||
"GravatarsManaged": "Граватары управляются",
|
"GravatarsManaged": "Граватары управляются",
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Employee, EmployeeAccount } from '@hcengineering/contact'
|
import contact, { Employee, PersonAccount } from '@hcengineering/contact'
|
||||||
import core, { Account, Ref } from '@hcengineering/core'
|
import core, { Account, Ref } from '@hcengineering/core'
|
||||||
import { IntlString } from '@hcengineering/platform'
|
import { IntlString } from '@hcengineering/platform'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { ButtonKind, ButtonSize } from '@hcengineering/ui'
|
import { ButtonKind, ButtonSize } from '@hcengineering/ui'
|
||||||
import { employeeAccountByIdStore } from '../utils'
|
import { personAccountByIdStore } from '../utils'
|
||||||
import UserBoxList from './UserBoxList.svelte'
|
import UserBoxList from './UserBoxList.svelte'
|
||||||
|
|
||||||
export let label: IntlString
|
export let label: IntlString
|
||||||
@ -36,7 +36,7 @@
|
|||||||
function onUpdate (evt: CustomEvent<Ref<Employee>[]>): void {
|
function onUpdate (evt: CustomEvent<Ref<Employee>[]>): void {
|
||||||
clearTimeout(timer)
|
clearTimeout(timer)
|
||||||
timer = setTimeout(async () => {
|
timer = setTimeout(async () => {
|
||||||
const accounts = await client.findAll(contact.class.EmployeeAccount, { employee: { $in: evt.detail } })
|
const accounts = await client.findAll(contact.class.PersonAccount, { person: { $in: evt.detail } })
|
||||||
onChange(accounts.map((it) => it._id))
|
onChange(accounts.map((it) => it._id))
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
@ -55,14 +55,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: employees = Array.from(
|
$: employees = Array.from(
|
||||||
(value ?? []).map((it) => $employeeAccountByIdStore.get(it as Ref<EmployeeAccount>)?.employee)
|
(value ?? []).map((it) => $personAccountByIdStore.get(it as Ref<PersonAccount>)?.person)
|
||||||
).filter((it) => it !== undefined) as Ref<Employee>[]
|
).filter((it) => it !== undefined) as Ref<Employee>[]
|
||||||
|
|
||||||
$: docQuery =
|
$: docQuery =
|
||||||
excluded.length > 0
|
excluded.length > 0
|
||||||
? {
|
? {
|
||||||
active: true,
|
active: true,
|
||||||
_id: { $nin: excluded.map((p) => (p as EmployeeAccount).employee) }
|
_id: { $nin: excluded.map((p) => (p as PersonAccount).person as Ref<Employee>) }
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
active: true
|
active: true
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee, EmployeeAccount } from '@hcengineering/contact'
|
import { Person, PersonAccount } from '@hcengineering/contact'
|
||||||
import core, { Account, DocumentQuery, Ref, matchQuery } from '@hcengineering/core'
|
import core, { Account, DocumentQuery, Ref, matchQuery } from '@hcengineering/core'
|
||||||
import { IntlString } from '@hcengineering/platform'
|
import { IntlString } from '@hcengineering/platform'
|
||||||
import { ButtonKind, ButtonSize } from '@hcengineering/ui'
|
import { ButtonKind, ButtonSize } from '@hcengineering/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import contact from '../plugin'
|
import contact from '../plugin'
|
||||||
import { employeeAccountByIdStore } from '../utils'
|
import { personAccountByIdStore } from '../utils'
|
||||||
import UserBox from './UserBox.svelte'
|
import UserBox from './UserBox.svelte'
|
||||||
import { getClient } from '@hcengineering/presentation'
|
import { getClient } from '@hcengineering/presentation'
|
||||||
|
|
||||||
@ -33,21 +33,21 @@
|
|||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
$: accounts = matchQuery<Account>(
|
$: accounts = matchQuery<Account>(
|
||||||
Array.from($employeeAccountByIdStore.values()),
|
Array.from($personAccountByIdStore.values()),
|
||||||
docQuery,
|
docQuery,
|
||||||
core.class.Account,
|
core.class.Account,
|
||||||
hierarchy
|
hierarchy
|
||||||
) as EmployeeAccount[]
|
) as PersonAccount[]
|
||||||
|
|
||||||
let map: Map<Ref<Employee>, Ref<Account>> = new Map()
|
let map: Map<Ref<Person>, Ref<Account>> = new Map()
|
||||||
$: map = new Map(accounts.map((p) => [p.employee, p._id]))
|
$: map = new Map(accounts.map((p) => [p.person, p._id]))
|
||||||
|
|
||||||
$: employees = accounts.map((p) => p.employee)
|
$: employees = accounts.map((p) => p.person)
|
||||||
$: selectedEmp = value && accounts.find((p) => p._id === value)?.employee
|
$: selectedEmp = value && accounts.find((p) => p._id === value)?.person
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
function change (e: CustomEvent<Ref<Employee> | null>) {
|
function change (e: CustomEvent<Ref<Person> | null>) {
|
||||||
if (e.detail === null) {
|
if (e.detail === null) {
|
||||||
dispatch('change', null)
|
dispatch('change', null)
|
||||||
} else {
|
} else {
|
||||||
@ -58,7 +58,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<UserBox
|
<UserBox
|
||||||
_class={contact.class.Employee}
|
_class={contact.mixin.Employee}
|
||||||
docQuery={{ _id: { $in: employees } }}
|
docQuery={{ _id: { $in: employees } }}
|
||||||
showNavigate={false}
|
showNavigate={false}
|
||||||
{kind}
|
{kind}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee, EmployeeAccount, getName } from '@hcengineering/contact'
|
import { Person, PersonAccount, getName } from '@hcengineering/contact'
|
||||||
import core, { IdMap, Ref, Space } from '@hcengineering/core'
|
import core, { IdMap, Ref, Space } from '@hcengineering/core'
|
||||||
import presentation, { getClient } from '@hcengineering/presentation'
|
import presentation, { getClient } from '@hcengineering/presentation'
|
||||||
import { ActionIcon, Button, IconClose, Label } from '@hcengineering/ui'
|
import { ActionIcon, Button, IconClose, Label } from '@hcengineering/ui'
|
||||||
@ -11,19 +11,17 @@
|
|||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
const employees: IdMap<Employee> = new Map()
|
const employees: IdMap<Person> = new Map()
|
||||||
|
|
||||||
let membersToAdd: EmployeeAccount[] = []
|
let membersToAdd: PersonAccount[] = []
|
||||||
let channelMembers: Ref<Employee>[] = []
|
let channelMembers: Ref<Person>[] = []
|
||||||
client.findAll(core.class.Account, { _id: { $in: value.members } }).then((res) => {
|
client.findAll(core.class.Account, { _id: { $in: value.members } }).then((res) => {
|
||||||
channelMembers = res
|
channelMembers = res.filter((e) => e._class === contact.class.PersonAccount).map((e) => (e as PersonAccount).person)
|
||||||
.filter((e) => e._class === contact.class.EmployeeAccount)
|
|
||||||
.map((e) => (e as EmployeeAccount).employee)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
async function changeMembersToAdd (employees: Ref<Employee>[]) {
|
async function changeMembersToAdd (employees: Ref<Person>[]) {
|
||||||
if (employees) {
|
if (employees) {
|
||||||
await client.findAll(contact.class.EmployeeAccount, { employee: { $in: employees } }).then((res) => {
|
await client.findAll(contact.class.PersonAccount, { person: { $in: employees } }).then((res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
membersToAdd = res
|
membersToAdd = res
|
||||||
}
|
}
|
||||||
@ -31,9 +29,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: selectedEmployees = membersToAdd.map((e) => e.employee)
|
$: selectedEmployees = membersToAdd.map((e) => e.person)
|
||||||
|
|
||||||
function removeMember (_id: Ref<EmployeeAccount>) {
|
function removeMember (_id: Ref<PersonAccount>) {
|
||||||
membersToAdd = membersToAdd.filter((m) => m._id !== _id)
|
membersToAdd = membersToAdd.filter((m) => m._id !== _id)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -56,9 +54,9 @@
|
|||||||
{#if membersToAdd.length}
|
{#if membersToAdd.length}
|
||||||
<div class="flex-row-top flex-wrap ml-6 mr-6 mt-4">
|
<div class="flex-row-top flex-wrap ml-6 mr-6 mt-4">
|
||||||
{#each membersToAdd as m}
|
{#each membersToAdd as m}
|
||||||
{@const employee = employees.get(m.employee)}
|
{@const employee = employees.get(m.person)}
|
||||||
<div class="mr-2 p-1 item">
|
<div class="mr-2 p-1 item">
|
||||||
{employee ? getName(employee) : ''}
|
{employee ? getName(client.getHierarchy(), employee) : ''}
|
||||||
<div class="tool">
|
<div class="tool">
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
icon={IconClose}
|
icon={IconClose}
|
||||||
@ -75,7 +73,7 @@
|
|||||||
<div class="ml-8 mr-8 mb-6 mt-4">
|
<div class="ml-8 mr-8 mb-6 mt-4">
|
||||||
<UsersPopup
|
<UsersPopup
|
||||||
selected={undefined}
|
selected={undefined}
|
||||||
_class={contact.class.Employee}
|
_class={contact.mixin.Employee}
|
||||||
docQuery={{
|
docQuery={{
|
||||||
active: true
|
active: true
|
||||||
}}
|
}}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Contact, Employee, getName } from '@hcengineering/contact'
|
import contact, { Contact, Employee, Person, getName } from '@hcengineering/contact'
|
||||||
import { Class, DocumentQuery, FindOptions, Hierarchy, Ref } from '@hcengineering/core'
|
import { Class, DocumentQuery, FindOptions, Hierarchy, Ref } from '@hcengineering/core'
|
||||||
import { getEmbeddedLabel, IntlString } from '@hcengineering/platform'
|
import { getEmbeddedLabel, IntlString } from '@hcengineering/platform'
|
||||||
import {
|
import {
|
||||||
@ -34,13 +34,13 @@
|
|||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import presentation, { getClient } from '@hcengineering/presentation'
|
import presentation, { getClient } from '@hcengineering/presentation'
|
||||||
import { PersonLabelTooltip, employeeByIdStore } from '..'
|
import { PersonLabelTooltip, personByIdStore } from '..'
|
||||||
import AssigneePopup from './AssigneePopup.svelte'
|
import AssigneePopup from './AssigneePopup.svelte'
|
||||||
import IconPerson from './icons/Person.svelte'
|
import IconPerson from './icons/Person.svelte'
|
||||||
import UserInfo from './UserInfo.svelte'
|
import UserInfo from './UserInfo.svelte'
|
||||||
import EmployeePresenter from './EmployeePresenter.svelte'
|
import EmployeePresenter from './EmployeePresenter.svelte'
|
||||||
|
|
||||||
export let _class: Ref<Class<Employee>> = contact.class.Employee
|
export let _class: Ref<Class<Employee>> = contact.mixin.Employee
|
||||||
export let excluded: Ref<Contact>[] | undefined = undefined
|
export let excluded: Ref<Contact>[] | undefined = undefined
|
||||||
export let options: FindOptions<Employee> | undefined = undefined
|
export let options: FindOptions<Employee> | undefined = undefined
|
||||||
export let docQuery: DocumentQuery<Employee> | undefined = {
|
export let docQuery: DocumentQuery<Employee> | undefined = {
|
||||||
@ -48,8 +48,8 @@
|
|||||||
}
|
}
|
||||||
export let label: IntlString
|
export let label: IntlString
|
||||||
export let placeholder: IntlString = presentation.string.Search
|
export let placeholder: IntlString = presentation.string.Search
|
||||||
export let value: Ref<Employee> | null | undefined
|
export let value: Ref<Person> | null | undefined
|
||||||
export let prevAssigned: Ref<Employee>[] | undefined = []
|
export let prevAssigned: Ref<Person>[] | undefined = []
|
||||||
export let componentLead: Ref<Employee> | undefined = undefined
|
export let componentLead: Ref<Employee> | undefined = undefined
|
||||||
export let members: Ref<Employee>[] | undefined = []
|
export let members: Ref<Employee>[] | undefined = []
|
||||||
export let allowDeselect = true
|
export let allowDeselect = true
|
||||||
@ -71,13 +71,15 @@
|
|||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let selected: Employee | undefined
|
let selected: Person | undefined
|
||||||
let container: HTMLElement
|
let container: HTMLElement
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
async function updateSelected (value: Ref<Employee> | null | undefined) {
|
async function updateSelected (value: Ref<Person> | null | undefined) {
|
||||||
selected = value ? $employeeByIdStore.get(value) ?? (await client.findOne(_class, { _id: value })) : undefined
|
selected = value
|
||||||
|
? $personByIdStore.get(value) ?? (await client.findOne(contact.class.Person, { _id: value }))
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
$: updateSelected(value)
|
$: updateSelected(value)
|
||||||
@ -132,7 +134,9 @@
|
|||||||
<div
|
<div
|
||||||
class="w-full h-full flex-streatch"
|
class="w-full h-full flex-streatch"
|
||||||
on:click={_click}
|
on:click={_click}
|
||||||
use:tooltip={selected !== undefined ? { label: getEmbeddedLabel(getName(selected)) } : undefined}
|
use:tooltip={selected !== undefined
|
||||||
|
? { label: getEmbeddedLabel(getName(client.getHierarchy(), selected)) }
|
||||||
|
: undefined}
|
||||||
>
|
>
|
||||||
<slot name="content" />
|
<slot name="content" />
|
||||||
</div>
|
</div>
|
||||||
@ -158,13 +162,15 @@
|
|||||||
style:width={showNavigate && selected
|
style:width={showNavigate && selected
|
||||||
? `calc(${width ?? 'min-content'} - 1.5rem)`
|
? `calc(${width ?? 'min-content'} - 1.5rem)`
|
||||||
: `${width ?? 'min-content'}`}
|
: `${width ?? 'min-content'}`}
|
||||||
use:tooltip={selected !== undefined ? { label: getEmbeddedLabel(getName(selected)) } : undefined}
|
use:tooltip={selected !== undefined
|
||||||
|
? { label: getEmbeddedLabel(getName(client.getHierarchy(), selected)) }
|
||||||
|
: undefined}
|
||||||
>
|
>
|
||||||
{#if selected}
|
{#if selected}
|
||||||
{#if hideIcon || selected}
|
{#if hideIcon || selected}
|
||||||
<UserInfo value={selected} size={avatarSize} {icon} {short} on:accent-color />
|
<UserInfo value={selected} size={avatarSize} {icon} {short} on:accent-color />
|
||||||
{:else}
|
{:else}
|
||||||
{getName(selected)}
|
{getName(client.getHierarchy(), selected)}
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<div class="flex-presenter not-selected">
|
<div class="flex-presenter not-selected">
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Contact, Employee, EmployeeAccount, Person } from '@hcengineering/contact'
|
import contact, { Contact, PersonAccount, Person, Employee } from '@hcengineering/contact'
|
||||||
import { DocumentQuery, FindOptions, getCurrentAccount, Ref } from '@hcengineering/core'
|
import { DocumentQuery, FindOptions, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||||
import type { Asset, IntlString } from '@hcengineering/platform'
|
import type { Asset, IntlString } from '@hcengineering/platform'
|
||||||
import {
|
import {
|
||||||
@ -52,9 +52,7 @@
|
|||||||
export let showCategories: boolean = true
|
export let showCategories: boolean = true
|
||||||
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
||||||
|
|
||||||
// const client = getClient()
|
const currentEmployee = (getCurrentAccount() as PersonAccount).person
|
||||||
// const hierarchy = client.getHierarchy()
|
|
||||||
const currentEmployee = (getCurrentAccount() as EmployeeAccount).employee
|
|
||||||
|
|
||||||
let search: string = ''
|
let search: string = ''
|
||||||
let objects: Contact[] = []
|
let objects: Contact[] = []
|
||||||
@ -66,7 +64,7 @@
|
|||||||
const query = createQuery()
|
const query = createQuery()
|
||||||
|
|
||||||
$: query.query<Contact>(
|
$: query.query<Contact>(
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
{
|
{
|
||||||
...(docQuery ?? {}),
|
...(docQuery ?? {}),
|
||||||
[searchField]: { $like: '%' + search + '%' },
|
[searchField]: { $like: '%' + search + '%' },
|
||||||
|
@ -28,9 +28,7 @@
|
|||||||
export let items: Ref<Contact>[] = []
|
export let items: Ref<Contact>[] = []
|
||||||
export let _class: Ref<Class<Contact>> = contact.class.Contact
|
export let _class: Ref<Class<Contact>> = contact.class.Contact
|
||||||
export let label: IntlString
|
export let label: IntlString
|
||||||
export let docQuery: DocumentQuery<Contact> | undefined = {
|
export let docQuery: DocumentQuery<Contact> | undefined = {}
|
||||||
active: true
|
|
||||||
}
|
|
||||||
|
|
||||||
export let kind: ButtonKind = 'no-border'
|
export let kind: ButtonKind = 'no-border'
|
||||||
export let size: ButtonSize = 'small'
|
export let size: ButtonSize = 'small'
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
function isEmployee (value: Contact): boolean {
|
function isEmployee (value: Contact): boolean {
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
return hierarchy.isDerived(value._class, contact.class.Employee)
|
return hierarchy.isDerived(value._class, contact.mixin.Employee)
|
||||||
}
|
}
|
||||||
const toOrg = (contact: Contact) => contact as Organization
|
const toOrg = (contact: Contact) => contact as Organization
|
||||||
const toEmployee = (contact: Contact) => contact as Employee
|
const toEmployee = (contact: Contact) => contact as Employee
|
||||||
|
@ -48,20 +48,22 @@
|
|||||||
async function createPerson () {
|
async function createPerson () {
|
||||||
changeEmail()
|
changeEmail()
|
||||||
const name = combineName(firstName, lastName)
|
const name = combineName(firstName, lastName)
|
||||||
const person: Data<Employee> = {
|
const person: Data<Person> = {
|
||||||
name,
|
name,
|
||||||
city: object.city,
|
city: object.city
|
||||||
active: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
person.avatar = await avatarEditor.createAvatar()
|
person.avatar = await avatarEditor.createAvatar()
|
||||||
|
|
||||||
await client.createDoc(contact.class.Employee, contact.space.Contacts, person, id)
|
await client.createDoc(contact.class.Person, contact.space.Contacts, person, id)
|
||||||
|
await client.createMixin(id, contact.class.Person, contact.space.Contacts, contact.mixin.Employee, {
|
||||||
|
active: true
|
||||||
|
})
|
||||||
|
|
||||||
await client.createDoc(contact.class.EmployeeAccount, core.space.Model, {
|
await client.createDoc(contact.class.PersonAccount, core.space.Model, {
|
||||||
email: email.trim(),
|
email: email.trim(),
|
||||||
name,
|
name,
|
||||||
employee: id,
|
person: id,
|
||||||
role: AccountRole.User
|
role: AccountRole.User
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -17,22 +17,22 @@
|
|||||||
import { AccountRole, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
|
import { AccountRole, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||||
import view from '@hcengineering/view-resources/src/plugin'
|
import view from '@hcengineering/view-resources/src/plugin'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import { EmployeeAccount } from '@hcengineering/contact'
|
import { PersonAccount } from '@hcengineering/contact'
|
||||||
import { employeeAccountByIdStore } from '../utils'
|
import { personAccountByIdStore } from '../utils'
|
||||||
import ui, { Button, Label } from '@hcengineering/ui'
|
import ui, { Button, Label } from '@hcengineering/ui'
|
||||||
import EmployeeAccountRefPresenter from './EmployeeAccountRefPresenter.svelte'
|
import PersonAccountRefPresenter from './PersonAccountRefPresenter.svelte'
|
||||||
import EmployeeAccountPresenter from './EmployeeAccountPresenter.svelte'
|
import PersonAccountPresenter from './PersonAccountPresenter.svelte'
|
||||||
|
|
||||||
export let object: Doc | Doc[]
|
export let object: Doc | Doc[]
|
||||||
export let deleteAction: () => void
|
export let deleteAction: () => void
|
||||||
const objectArray = Array.isArray(object) ? object : [object]
|
const objectArray = Array.isArray(object) ? object : [object]
|
||||||
const owners: EmployeeAccount[] = Array.from($employeeAccountByIdStore.values()).filter(
|
const owners: PersonAccount[] = Array.from($personAccountByIdStore.values()).filter(
|
||||||
(acc) => acc.role === AccountRole.Owner
|
(acc) => acc.role === AccountRole.Owner
|
||||||
)
|
)
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
$: creators = [...new Set(objectArray.map((obj) => obj.createdBy as Ref<EmployeeAccount>))]
|
$: creators = [...new Set(objectArray.map((obj) => obj.createdBy as Ref<PersonAccount>))]
|
||||||
$: canDelete =
|
$: canDelete =
|
||||||
(creators.length === 1 && creators.includes(getCurrentAccount()._id as Ref<EmployeeAccount>)) ||
|
(creators.length === 1 && creators.includes(getCurrentAccount()._id as Ref<PersonAccount>)) ||
|
||||||
getCurrentAccount().role === AccountRole.Owner
|
getCurrentAccount().role === AccountRole.Owner
|
||||||
$: label = canDelete ? view.string.DeleteObject : view.string.DeletePopupNoPermissionTitle
|
$: label = canDelete ? view.string.DeleteObject : view.string.DeletePopupNoPermissionTitle
|
||||||
</script>
|
</script>
|
||||||
@ -62,7 +62,7 @@
|
|||||||
<Label label={view.string.DeletePopupCreatorLabel} />
|
<Label label={view.string.DeletePopupCreatorLabel} />
|
||||||
{#each creators as account}
|
{#each creators as account}
|
||||||
<div class="my-2">
|
<div class="my-2">
|
||||||
<EmployeeAccountRefPresenter value={account} />
|
<PersonAccountRefPresenter value={account} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
<Label label={view.string.DeletePopupOwnerLabel} />
|
<Label label={view.string.DeletePopupOwnerLabel} />
|
||||||
{#each owners as owner}
|
{#each owners as owner}
|
||||||
<div class="my-2">
|
<div class="my-2">
|
||||||
<EmployeeAccountPresenter value={owner} />
|
<PersonAccountPresenter value={owner} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Channel, Employee, EmployeeAccount, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
import { Channel, Employee, PersonAccount, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
||||||
import { AccountRole, getCurrentAccount, Ref } from '@hcengineering/core'
|
import { AccountRole, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||||
import login from '@hcengineering/login'
|
import login from '@hcengineering/login'
|
||||||
import { getResource } from '@hcengineering/platform'
|
import { getResource } from '@hcengineering/platform'
|
||||||
@ -28,28 +28,27 @@
|
|||||||
import ChannelsEditor from './ChannelsEditor.svelte'
|
import ChannelsEditor from './ChannelsEditor.svelte'
|
||||||
import EditableAvatar from './EditableAvatar.svelte'
|
import EditableAvatar from './EditableAvatar.svelte'
|
||||||
|
|
||||||
export let object: Employee
|
export let object: Person
|
||||||
export let readonly = false
|
export let readonly = false
|
||||||
|
|
||||||
export let channels: Channel[] | undefined = undefined
|
export let channels: Channel[] | undefined = undefined
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
const account = getCurrentAccount() as EmployeeAccount
|
const account = getCurrentAccount() as PersonAccount
|
||||||
|
|
||||||
let avatarEditor: EditableAvatar
|
let avatarEditor: EditableAvatar
|
||||||
|
|
||||||
$: owner = account.employee === object._id
|
$: owner = account.person === object._id
|
||||||
$: editable = !readonly && (account.role >= AccountRole.Maintainer || owner)
|
$: editable = !readonly && (account.role >= AccountRole.Maintainer || owner)
|
||||||
let firstName = getFirstName(object.name)
|
let firstName = getFirstName(object.name)
|
||||||
let lastName = getLastName(object.name)
|
let lastName = getLastName(object.name)
|
||||||
let displayName = object.displayName ?? ''
|
|
||||||
|
|
||||||
$: setName(object)
|
$: setName(object)
|
||||||
|
|
||||||
let email: string | undefined
|
let email: string | undefined
|
||||||
$: if (editable) {
|
$: if (editable) {
|
||||||
client.findOne(contact.class.EmployeeAccount, { employee: (object as Employee)._id }).then((acc) => {
|
client.findOne(contact.class.PersonAccount, { person: (object as Employee)._id }).then((acc) => {
|
||||||
email = acc?.email
|
email = acc?.email
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -71,12 +70,6 @@
|
|||||||
await changeName(getFirstName(object.name), lastName)
|
await changeName(getFirstName(object.name), lastName)
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeDisplayName () {
|
|
||||||
client.update(object, {
|
|
||||||
displayName: displayName.trim() === '' ? null : displayName
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let integrations: Set<Ref<IntegrationType>> = new Set<Ref<IntegrationType>>()
|
let integrations: Set<Ref<IntegrationType>> = new Set<Ref<IntegrationType>>()
|
||||||
const settingsQuery = createQuery()
|
const settingsQuery = createQuery()
|
||||||
$: settingsQuery.query(setting.class.Integration, { createdBy: account._id, disabled: false }, (res) => {
|
$: settingsQuery.query(setting.class.Integration, { createdBy: account._id, disabled: false }, (res) => {
|
||||||
@ -146,19 +139,6 @@
|
|||||||
{lastName}
|
{lastName}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="name">
|
|
||||||
{#if editable}
|
|
||||||
<EditBox
|
|
||||||
placeholder={contact.string.DisplayName}
|
|
||||||
bind:value={displayName}
|
|
||||||
on:change={changeDisplayName}
|
|
||||||
disabled={!editable}
|
|
||||||
focusIndex={1}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
{displayName}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="location">
|
<div class="location">
|
||||||
<AttributeEditor maxWidth="20rem" _class={contact.class.Person} {editable} {object} key="city" focusIndex={3} />
|
<AttributeEditor maxWidth="20rem" _class={contact.class.Person} {editable} {object} key="city" focusIndex={3} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { combineName, EmployeeAccount, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
import { combineName, PersonAccount, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
||||||
import { getCurrentAccount, Ref } from '@hcengineering/core'
|
import { getCurrentAccount, Ref } from '@hcengineering/core'
|
||||||
import { AttributeEditor, createQuery, getClient } from '@hcengineering/presentation'
|
import { AttributeEditor, createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import setting, { IntegrationType } from '@hcengineering/setting'
|
import setting, { IntegrationType } from '@hcengineering/setting'
|
||||||
@ -27,7 +27,7 @@
|
|||||||
export let object: Person
|
export let object: Person
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
const account = getCurrentAccount() as EmployeeAccount
|
const account = getCurrentAccount() as PersonAccount
|
||||||
|
|
||||||
let avatarEditor: EditableAvatar
|
let avatarEditor: EditableAvatar
|
||||||
|
|
||||||
|
@ -14,22 +14,22 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Employee } from '@hcengineering/contact'
|
import contact, { Employee, Person } from '@hcengineering/contact'
|
||||||
import type { Class, DocumentQuery, FindOptions, Ref } from '@hcengineering/core'
|
import type { Class, DocumentQuery, FindOptions, Ref } from '@hcengineering/core'
|
||||||
import type { IntlString } from '@hcengineering/platform'
|
import type { IntlString } from '@hcengineering/platform'
|
||||||
import { ButtonKind, ButtonSize, IconSize, LabelAndProps } from '@hcengineering/ui'
|
|
||||||
import presentation from '@hcengineering/presentation'
|
import presentation from '@hcengineering/presentation'
|
||||||
import IconPerson from './icons/Person.svelte'
|
import { ButtonKind, ButtonSize, IconSize, LabelAndProps } from '@hcengineering/ui'
|
||||||
import UserBox from './UserBox.svelte'
|
import UserBox from './UserBox.svelte'
|
||||||
|
import IconPerson from './icons/Person.svelte'
|
||||||
|
|
||||||
export let _class: Ref<Class<Employee>> = contact.class.Employee
|
export let _class: Ref<Class<Employee>> = contact.mixin.Employee
|
||||||
export let options: FindOptions<Employee> | undefined = undefined
|
export let options: FindOptions<Employee> | undefined = undefined
|
||||||
export let docQuery: DocumentQuery<Employee> | undefined = {
|
export let docQuery: DocumentQuery<Employee> | undefined = {
|
||||||
active: true
|
active: true
|
||||||
}
|
}
|
||||||
export let label: IntlString
|
export let label: IntlString
|
||||||
export let placeholder: IntlString = presentation.string.Search
|
export let placeholder: IntlString = presentation.string.Search
|
||||||
export let value: Ref<Employee> | null | undefined
|
export let value: Ref<Person> | null | undefined
|
||||||
export let allowDeselect = false
|
export let allowDeselect = false
|
||||||
export let titleDeselect: IntlString | undefined = undefined
|
export let titleDeselect: IntlString | undefined = undefined
|
||||||
export let kind: ButtonKind = 'no-border'
|
export let kind: ButtonKind = 'no-border'
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
async function updateEmployees (resultQuery: DocumentQuery<Employee>) {
|
async function updateEmployees (resultQuery: DocumentQuery<Employee>) {
|
||||||
employees = await client.findAll(
|
employees = await client.findAll(
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
{
|
{
|
||||||
...resultQuery
|
...resultQuery
|
||||||
},
|
},
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
export let readonly = false
|
export let readonly = false
|
||||||
export let showNavigate = true
|
export let showNavigate = true
|
||||||
|
|
||||||
$: _class = type?.to ?? contact.class.Employee
|
$: _class = type?.to ?? contact.mixin.Employee
|
||||||
|
|
||||||
const query: DocumentQuery<Employee> = {
|
const query: DocumentQuery<Employee> = {
|
||||||
active: true
|
active: true
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
: {
|
: {
|
||||||
_id: { $in: Array.from(targets.keys()) }
|
_id: { $in: Array.from(targets.keys()) }
|
||||||
}
|
}
|
||||||
objectsPromise = client.findAll(contact.class.Employee, resultQuery, { sort: { name: SortingOrder.Ascending } })
|
objectsPromise = client.findAll(contact.mixin.Employee, resultQuery, { sort: { name: SortingOrder.Ascending } })
|
||||||
values = await objectsPromise
|
values = await objectsPromise
|
||||||
if (targets.has(undefined)) {
|
if (targets.has(undefined)) {
|
||||||
values.unshift(undefined)
|
values.unshift(undefined)
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee } from '@hcengineering/contact'
|
import { Person } from '@hcengineering/contact'
|
||||||
import { Ref } from '@hcengineering/core'
|
import { Ref } from '@hcengineering/core'
|
||||||
import CombineAvatars from './CombineAvatars.svelte'
|
import CombineAvatars from './CombineAvatars.svelte'
|
||||||
import contact from '../plugin'
|
import contact from '../plugin'
|
||||||
|
|
||||||
export let value: Ref<Employee>[]
|
export let value: Ref<Person>[]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CombineAvatars _class={contact.class.Employee} items={value} limit={5} size={'x-small'} />
|
<CombineAvatars _class={contact.mixin.Employee} items={value} limit={5} size={'x-small'} />
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee } from '@hcengineering/contact'
|
import { Employee, Person } from '@hcengineering/contact'
|
||||||
import { Ref, WithLookup } from '@hcengineering/core'
|
import { Ref, WithLookup } from '@hcengineering/core'
|
||||||
import { IntlString } from '@hcengineering/platform'
|
import { IntlString } from '@hcengineering/platform'
|
||||||
import ui, { IconSize } from '@hcengineering/ui'
|
import ui, { IconSize } from '@hcengineering/ui'
|
||||||
import { PersonLabelTooltip, employeeByIdStore } from '..'
|
import { PersonLabelTooltip, employeeByIdStore, personByIdStore } from '..'
|
||||||
import PersonPresenter from '../components/PersonPresenter.svelte'
|
import PersonPresenter from '../components/PersonPresenter.svelte'
|
||||||
import contact from '../plugin'
|
import contact from '../plugin'
|
||||||
|
|
||||||
export let value: Ref<Employee> | WithLookup<Employee> | null | undefined
|
export let value: Ref<Person> | WithLookup<Person> | null | undefined
|
||||||
export let tooltipLabels: PersonLabelTooltip | undefined = undefined
|
export let tooltipLabels: PersonLabelTooltip | undefined = undefined
|
||||||
export let shouldShowAvatar: boolean = true
|
export let shouldShowAvatar: boolean = true
|
||||||
export let shouldShowName: boolean = true
|
export let shouldShowName: boolean = true
|
||||||
@ -21,7 +21,10 @@
|
|||||||
export let defaultName: IntlString | undefined = ui.string.NotSelected
|
export let defaultName: IntlString | undefined = ui.string.NotSelected
|
||||||
export let element: HTMLElement | undefined = undefined
|
export let element: HTMLElement | undefined = undefined
|
||||||
|
|
||||||
$: employeeValue = typeof value === 'string' ? $employeeByIdStore.get(value) : value
|
$: employeeValue = typeof value === 'string' ? $personByIdStore.get(value) : value
|
||||||
|
|
||||||
|
$: active =
|
||||||
|
employeeValue !== undefined ? $employeeByIdStore.get(employeeValue?._id as Ref<Employee>)?.active ?? false : false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<PersonPresenter
|
<PersonPresenter
|
||||||
@ -38,6 +41,6 @@
|
|||||||
{colorInherit}
|
{colorInherit}
|
||||||
{accent}
|
{accent}
|
||||||
{defaultName}
|
{defaultName}
|
||||||
statusLabel={employeeValue?.active === false && shouldShowName ? contact.string.Inactive : undefined}
|
statusLabel={active === false && shouldShowName ? contact.string.Inactive : undefined}
|
||||||
on:accent-color
|
on:accent-color
|
||||||
/>
|
/>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee, EmployeeAccount, getName, Status } from '@hcengineering/contact'
|
import { Employee, PersonAccount, getName, Status } from '@hcengineering/contact'
|
||||||
import { getCurrentAccount, Ref } from '@hcengineering/core'
|
import { getCurrentAccount, Ref } from '@hcengineering/core'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import Avatar from './Avatar.svelte'
|
import Avatar from './Avatar.svelte'
|
||||||
@ -15,12 +15,12 @@
|
|||||||
export let employeeId: Ref<Employee>
|
export let employeeId: Ref<Employee>
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const me = (getCurrentAccount() as EmployeeAccount).employee
|
const me = (getCurrentAccount() as PersonAccount).person
|
||||||
$: editable = employeeId === me
|
$: editable = employeeId === me
|
||||||
|
|
||||||
const statusesQuery = createQuery()
|
const statusesQuery = createQuery()
|
||||||
let status: Status | undefined = undefined
|
let status: Status | undefined = undefined
|
||||||
$: employee = $employeeByIdStore.get(employeeId)
|
$: employee = $employeeByIdStore.get(employeeId) as Employee
|
||||||
statusesQuery.query(contact.class.Status, { attachedTo: employeeId }, (res) => (status = res[0]))
|
statusesQuery.query(contact.class.Status, { attachedTo: employeeId }, (res) => (status = res[0]))
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
@ -39,7 +39,7 @@
|
|||||||
} else if (status && !newStatus) {
|
} else if (status && !newStatus) {
|
||||||
client.removeDoc(contact.class.Status, status.space, status._id)
|
client.removeDoc(contact.class.Status, status.space, status._id)
|
||||||
} else {
|
} else {
|
||||||
client.addCollection(contact.class.Status, employee!.space, employeeId, contact.class.Employee, 'statuses', {
|
client.addCollection(contact.class.Status, employee!.space, employeeId, contact.mixin.Employee, 'statuses', {
|
||||||
name: newStatus.name,
|
name: newStatus.name,
|
||||||
dueDate: newStatus.dueDate
|
dueDate: newStatus.dueDate
|
||||||
})
|
})
|
||||||
@ -60,7 +60,7 @@
|
|||||||
<div class="flex-col-center pb-2">
|
<div class="flex-col-center pb-2">
|
||||||
<Avatar size="x-large" avatar={employee.avatar} />
|
<Avatar size="x-large" avatar={employee.avatar} />
|
||||||
</div>
|
</div>
|
||||||
<div class="pb-2">{getName(employee)}</div>
|
<div class="pb-2">{getName(client.getHierarchy(), employee)}</div>
|
||||||
<DocNavLink object={employee}>
|
<DocNavLink object={employee}>
|
||||||
<Label label={contact.string.ViewFullProfile} />
|
<Label label={contact.string.ViewFullProfile} />
|
||||||
</DocNavLink>
|
</DocNavLink>
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
showPopup(
|
showPopup(
|
||||||
UsersPopup,
|
UsersPopup,
|
||||||
{
|
{
|
||||||
_class: contact.class.Employee,
|
_class: contact.mixin.Employee,
|
||||||
selectedUsers: members,
|
selectedUsers: members,
|
||||||
allowDeselect: true,
|
allowDeselect: true,
|
||||||
multiSelect: true,
|
multiSelect: true,
|
||||||
|
@ -13,14 +13,14 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee } from '@hcengineering/contact'
|
import { Person } from '@hcengineering/contact'
|
||||||
import { Class, Doc, Ref } from '@hcengineering/core'
|
import { Class, Doc, Ref } from '@hcengineering/core'
|
||||||
import { getAttribute, getAttributeEditor, getClient } from '@hcengineering/presentation'
|
import { getAttribute, getAttributeEditor, getClient } from '@hcengineering/presentation'
|
||||||
import MergeComparer from './MergeComparer.svelte'
|
import MergeComparer from './MergeComparer.svelte'
|
||||||
|
|
||||||
export let value: Employee
|
export let value: Person
|
||||||
export let _class: Ref<Class<Doc>>
|
export let _class: Ref<Class<Doc>>
|
||||||
export let targetEmp: Employee
|
export let targetEmp: Person
|
||||||
export let key: string
|
export let key: string
|
||||||
export let onChange: (key: string, value: boolean) => void
|
export let onChange: (key: string, value: boolean) => void
|
||||||
export let selected = false
|
export let selected = false
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee } from '@hcengineering/contact'
|
import { Person } from '@hcengineering/contact'
|
||||||
import { Doc, Mixin, Ref } from '@hcengineering/core'
|
import { Doc, Mixin, Ref } from '@hcengineering/core'
|
||||||
import { getClient } from '@hcengineering/presentation'
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { CheckBox, Label } from '@hcengineering/ui'
|
import { CheckBox, Label } from '@hcengineering/ui'
|
||||||
|
|
||||||
export let value: Employee
|
export let value: Person
|
||||||
export let targetEmp: Employee
|
export let targetEmp: Person
|
||||||
export let cast: Ref<Mixin<Doc>> | undefined = undefined
|
export let cast: Ref<Mixin<Doc>> | undefined = undefined
|
||||||
export let key: string
|
export let key: string
|
||||||
export let selected = false
|
export let selected = false
|
||||||
@ -28,7 +28,7 @@
|
|||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
|
|
||||||
function isEqual (value: Employee, targetEmp: Employee, key: string) {
|
function isEqual (value: Person, targetEmp: Person, key: string) {
|
||||||
if (cast !== undefined) {
|
if (cast !== undefined) {
|
||||||
value = hierarchy.as(value, cast)
|
value = hierarchy.as(value, cast)
|
||||||
targetEmp = hierarchy.as(targetEmp, cast)
|
targetEmp = hierarchy.as(targetEmp, cast)
|
||||||
|
@ -13,9 +13,9 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Channel, Employee, getName } from '@hcengineering/contact'
|
import { Channel, Person, getName } from '@hcengineering/contact'
|
||||||
import core, { Doc, DocumentUpdate, Mixin, Ref, TxProcessor } from '@hcengineering/core'
|
import core, { Doc, DocumentUpdate, Mixin, Ref, RefTo, Tx, TxOperations, TxProcessor } from '@hcengineering/core'
|
||||||
import { Card, createQuery, getClient } from '@hcengineering/presentation'
|
import { Card, createQuery, getClient, updateAttribute } from '@hcengineering/presentation'
|
||||||
import { Toggle } from '@hcengineering/ui'
|
import { Toggle } from '@hcengineering/ui'
|
||||||
import { isCollectionAttr } from '@hcengineering/view-resources'
|
import { isCollectionAttr } from '@hcengineering/view-resources'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
@ -24,40 +24,40 @@
|
|||||||
import ChannelPresenter from './ChannelPresenter.svelte'
|
import ChannelPresenter from './ChannelPresenter.svelte'
|
||||||
import ChannelsDropdown from './ChannelsDropdown.svelte'
|
import ChannelsDropdown from './ChannelsDropdown.svelte'
|
||||||
import EditEmployee from './EditEmployee.svelte'
|
import EditEmployee from './EditEmployee.svelte'
|
||||||
import EmployeeBox from './EmployeeBox.svelte'
|
|
||||||
import MergeAttributeComparer from './MergeAttributeComparer.svelte'
|
import MergeAttributeComparer from './MergeAttributeComparer.svelte'
|
||||||
import MergeComparer from './MergeComparer.svelte'
|
import MergeComparer from './MergeComparer.svelte'
|
||||||
|
import UserBox from './UserBox.svelte'
|
||||||
|
|
||||||
export let value: Employee
|
export let value: Person
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
const parent = hierarchy.getParentClass(contact.class.Employee)
|
const parent = hierarchy.getParentClass(contact.class.Person)
|
||||||
const mixins = hierarchy.getDescendants(parent).filter((p) => hierarchy.isMixin(p))
|
const mixins = hierarchy.getDescendants(parent).filter((p) => hierarchy.isMixin(p))
|
||||||
|
|
||||||
let sourceEmployee = value._id
|
let sourcePersonRef = value._id
|
||||||
let sourceEmp: Employee | undefined = undefined
|
let sourcePerson: Person | undefined = undefined
|
||||||
|
|
||||||
let targetEmployee: Ref<Employee> | undefined = undefined
|
let targetPersonRf: Ref<Person> | undefined = undefined
|
||||||
let targetEmp: Employee | undefined = undefined
|
let targetPerson: Person | undefined = undefined
|
||||||
|
|
||||||
const targetQuery = createQuery()
|
const targetQuery = createQuery()
|
||||||
$: targetEmployee &&
|
$: targetPersonRf &&
|
||||||
sourceEmployee &&
|
sourcePersonRef &&
|
||||||
targetQuery.query(contact.class.Employee, { _id: { $in: [sourceEmployee, targetEmployee] } }, (res) => {
|
targetQuery.query(contact.class.Person, { _id: { $in: [sourcePersonRef, targetPersonRf] } }, (res) => {
|
||||||
// ;[targetEmp] = res
|
// ;[targetEmp] = res
|
||||||
sourceEmp = res.find((it) => it._id === sourceEmployee)
|
sourcePerson = res.find((it) => it._id === sourcePersonRef)
|
||||||
targetEmp = res.find((it) => it._id === targetEmployee)
|
targetPerson = res.find((it) => it._id === targetPersonRf)
|
||||||
if (sourceEmp && targetEmp) {
|
if (sourcePerson && targetPerson) {
|
||||||
update = fillUpdate(sourceEmp, targetEmp)
|
update = fillUpdate(sourcePerson, targetPerson)
|
||||||
mixinUpdate = fillMixinUpdate(sourceEmp, targetEmp)
|
mixinUpdate = fillMixinUpdate(sourcePerson, targetPerson)
|
||||||
applyUpdate(update)
|
applyUpdate(update)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function fillUpdate (source: Employee, target: Employee): DocumentUpdate<Employee> {
|
function fillUpdate (source: Person, target: Person): DocumentUpdate<Person> {
|
||||||
const res: DocumentUpdate<Employee> = {}
|
const res: DocumentUpdate<Person> = {}
|
||||||
const attributes = hierarchy.getOwnAttributes(contact.class.Employee)
|
const attributes = hierarchy.getOwnAttributes(contact.class.Person)
|
||||||
for (const attribute of attributes) {
|
for (const attribute of attributes) {
|
||||||
const key = attribute[0]
|
const key = attribute[0]
|
||||||
if (attribute[1].hidden) continue
|
if (attribute[1].hidden) continue
|
||||||
@ -69,7 +69,7 @@
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillMixinUpdate (source: Employee, target: Employee): Record<Ref<Mixin<Doc>>, DocumentUpdate<Doc>> {
|
function fillMixinUpdate (source: Person, target: Person): Record<Ref<Mixin<Doc>>, DocumentUpdate<Doc>> {
|
||||||
const res: Record<Ref<Mixin<Doc>>, DocumentUpdate<Doc>> = {}
|
const res: Record<Ref<Mixin<Doc>>, DocumentUpdate<Doc>> = {}
|
||||||
for (const mixin of mixins) {
|
for (const mixin of mixins) {
|
||||||
if (!hierarchy.hasMixin(source, mixin)) continue
|
if (!hierarchy.hasMixin(source, mixin)) continue
|
||||||
@ -88,30 +88,31 @@
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
let update: DocumentUpdate<Employee> = {}
|
let update: DocumentUpdate<Person> = {}
|
||||||
let mixinUpdate: Record<Ref<Mixin<Doc>>, DocumentUpdate<Doc>> = {}
|
let mixinUpdate: Record<Ref<Mixin<Doc>>, DocumentUpdate<Doc>> = {}
|
||||||
|
|
||||||
let result: Employee = { ...value }
|
let result: Person = { ...value }
|
||||||
|
|
||||||
function applyUpdate (update: DocumentUpdate<Employee>): void {
|
function applyUpdate (update: DocumentUpdate<Person>): void {
|
||||||
const r = hierarchy.clone(targetEmp)
|
const r = hierarchy.clone(targetPerson)
|
||||||
TxProcessor.applyUpdate(r, update)
|
TxProcessor.applyUpdate(r, update)
|
||||||
result = r
|
result = r
|
||||||
}
|
}
|
||||||
|
|
||||||
async function merge (): Promise<void> {
|
async function merge (): Promise<void> {
|
||||||
if (sourceEmp === undefined || targetEmp === undefined) return
|
if (sourcePerson === undefined || targetPerson === undefined) return
|
||||||
if (Object.keys(update).length > 0) {
|
if (Object.keys(update).length > 0) {
|
||||||
if (update.avatar !== undefined || sourceEmp.avatar === targetEmp.avatar) {
|
if (update.avatar !== undefined || sourcePerson.avatar === targetPerson.avatar) {
|
||||||
// We replace avatar, we need to update source with target
|
// We replace avatar, we need to update source with target
|
||||||
await client.update(sourceEmp, { avatar: sourceEmp.avatar === targetEmp.avatar ? '' : targetEmp.avatar })
|
await client.update(sourcePerson, {
|
||||||
|
avatar: sourcePerson.avatar === targetPerson.avatar ? '' : targetPerson.avatar
|
||||||
|
})
|
||||||
}
|
}
|
||||||
await client.update(targetEmp, update)
|
await client.update(targetPerson, update)
|
||||||
}
|
}
|
||||||
await client.update(sourceEmp, { mergedTo: targetEmp._id, active: false })
|
|
||||||
for (const channel of resultChannels.values()) {
|
for (const channel of resultChannels.values()) {
|
||||||
if (channel.attachedTo !== targetEmp._id) continue
|
if (channel.attachedTo !== targetPerson._id) continue
|
||||||
await client.update(channel, { attachedTo: targetEmp._id })
|
await client.update(channel, { attachedTo: targetPerson._id })
|
||||||
}
|
}
|
||||||
for (const old of oldChannels) {
|
for (const old of oldChannels) {
|
||||||
if ((enabledChannels.get(old._id) ?? true) === false) {
|
if ((enabledChannels.get(old._id) ?? true) === false) {
|
||||||
@ -121,18 +122,31 @@
|
|||||||
for (const mixin in mixinUpdate) {
|
for (const mixin in mixinUpdate) {
|
||||||
const attrs = (mixinUpdate as any)[mixin]
|
const attrs = (mixinUpdate as any)[mixin]
|
||||||
if (Object.keys(attrs).length > 0) {
|
if (Object.keys(attrs).length > 0) {
|
||||||
await client.updateMixin(targetEmp._id, targetEmp._class, targetEmp.space, mixin as Ref<Mixin<Doc>>, attrs)
|
await client.updateMixin(
|
||||||
} else if (!hierarchy.hasMixin(targetEmp, mixin as Ref<Mixin<Doc>>)) {
|
targetPerson._id,
|
||||||
await client.createMixin(targetEmp._id, targetEmp._class, targetEmp.space, mixin as Ref<Mixin<Doc>>, {})
|
targetPerson._class,
|
||||||
|
targetPerson.space,
|
||||||
|
mixin as Ref<Mixin<Doc>>,
|
||||||
|
attrs
|
||||||
|
)
|
||||||
|
} else if (!hierarchy.hasMixin(targetPerson, mixin as Ref<Mixin<Doc>>)) {
|
||||||
|
await client.createMixin(
|
||||||
|
targetPerson._id,
|
||||||
|
targetPerson._class,
|
||||||
|
targetPerson.space,
|
||||||
|
mixin as Ref<Mixin<Doc>>,
|
||||||
|
{}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await updateAllRefs(client, sourcePerson, targetPerson)
|
||||||
|
|
||||||
dispatch('close')
|
dispatch('close')
|
||||||
}
|
}
|
||||||
|
|
||||||
function select (field: string, targetValue: boolean) {
|
function select (field: string, targetValue: boolean) {
|
||||||
if (!targetValue) {
|
if (!targetValue) {
|
||||||
;(update as any)[field] = (sourceEmp as any)[field]
|
;(update as any)[field] = (sourcePerson as any)[field]
|
||||||
} else {
|
} else {
|
||||||
delete (update as any)[field]
|
delete (update as any)[field]
|
||||||
}
|
}
|
||||||
@ -166,20 +180,20 @@
|
|||||||
let oldChannels: Channel[] = []
|
let oldChannels: Channel[] = []
|
||||||
const valueChannelsQuery = createQuery()
|
const valueChannelsQuery = createQuery()
|
||||||
|
|
||||||
$: valueChannelsQuery.query(contact.class.Channel, { attachedTo: sourceEmployee }, (res) => {
|
$: valueChannelsQuery.query(contact.class.Channel, { attachedTo: sourcePersonRef }, (res) => {
|
||||||
oldChannels = res
|
oldChannels = res
|
||||||
})
|
})
|
||||||
|
|
||||||
let targetChannels: Channel[] = []
|
let targetChannels: Channel[] = []
|
||||||
const targetChannelsQuery = createQuery()
|
const targetChannelsQuery = createQuery()
|
||||||
$: targetEmployee &&
|
$: targetPersonRf &&
|
||||||
targetChannelsQuery.query(contact.class.Channel, { attachedTo: targetEmployee }, (res) => {
|
targetChannelsQuery.query(contact.class.Channel, { attachedTo: targetPersonRf }, (res) => {
|
||||||
targetChannels = res
|
targetChannels = res
|
||||||
})
|
})
|
||||||
|
|
||||||
$: resultChannels = mergeChannels(oldChannels, targetChannels, enabledChannels)
|
$: resultChannels = mergeChannels(oldChannels, targetChannels, enabledChannels)
|
||||||
|
|
||||||
const attributes = hierarchy.getAllAttributes(contact.class.Employee, core.class.Doc)
|
const attributes = hierarchy.getAllAttributes(contact.mixin.Employee, core.class.Doc)
|
||||||
const ignoreKeys = ['name', 'avatar', 'createdOn']
|
const ignoreKeys = ['name', 'avatar', 'createdOn']
|
||||||
const objectAttributes = Array.from(attributes.entries()).filter(
|
const objectAttributes = Array.from(attributes.entries()).filter(
|
||||||
(p) => !p[1].hidden && !ignoreKeys.includes(p[0]) && !isCollectionAttr(hierarchy, { key: p[0], attr: p[1] })
|
(p) => !p[1].hidden && !ignoreKeys.includes(p[0]) && !isCollectionAttr(hierarchy, { key: p[0], attr: p[1] })
|
||||||
@ -200,25 +214,111 @@
|
|||||||
}
|
}
|
||||||
mixinUpdate[mixin] = upd
|
mixinUpdate[mixin] = upd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateAllRefs (client: TxOperations, sourceAccount: Person, targetAccount: Person): Promise<Tx[]> {
|
||||||
|
const accounts = await client.findAll(contact.class.PersonAccount, { person: sourceAccount._id })
|
||||||
|
|
||||||
|
const h = client.getHierarchy()
|
||||||
|
console.log('merge employee:', sourceAccount.name, 'to', targetAccount.name)
|
||||||
|
// Move all possible references to Account and Employee and replace to target one.
|
||||||
|
const reftos = (await client.findAll(core.class.Attribute, { 'type._class': core.class.RefTo })).filter((it) => {
|
||||||
|
const to = it.type as RefTo<Doc>
|
||||||
|
return (
|
||||||
|
to.to === contact.class.Person ||
|
||||||
|
to.to === contact.mixin.Employee ||
|
||||||
|
to.to === core.class.Account ||
|
||||||
|
to.to === contact.class.PersonAccount
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const attr of reftos) {
|
||||||
|
if (attr.name === '_id') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const to = attr.type as RefTo<Doc>
|
||||||
|
if (to.to === contact.mixin.Employee || to.to === contact.class.Person) {
|
||||||
|
const descendants = h.getDescendants(attr.attributeOf)
|
||||||
|
for (const d of descendants) {
|
||||||
|
if (h.isDerived(d, core.class.Tx)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (h.findDomain(d) !== undefined) {
|
||||||
|
while (true) {
|
||||||
|
const values = await client.findAll(d, { [attr.name]: sourceAccount._id }, { limit: 100 })
|
||||||
|
if (values.length === 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
const builder = client.apply(sourceAccount._id)
|
||||||
|
for (const v of values) {
|
||||||
|
await updateAttribute(builder, v, d, { key: attr.name, attr }, targetAccount._id)
|
||||||
|
}
|
||||||
|
if (builder.txes.length > 0) {
|
||||||
|
console.log('merge employee:', sourceAccount.name, 'to', targetAccount.name, d, builder.txes.length)
|
||||||
|
await builder.commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const arrs = await client.findAll(core.class.Attribute, { 'type._class': core.class.ArrOf })
|
||||||
|
for (const attr of arrs) {
|
||||||
|
if (attr.name === '_id') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const to = attr.type as RefTo<Doc>
|
||||||
|
if (to.to === contact.mixin.Employee || to.to === contact.class.Person) {
|
||||||
|
const descendants = h.getDescendants(attr.attributeOf)
|
||||||
|
for (const d of descendants) {
|
||||||
|
if (h.isDerived(d, core.class.Tx)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (h.findDomain(d) !== undefined) {
|
||||||
|
while (true) {
|
||||||
|
const values = await client.findAll(attr.attributeOf, { [attr.name]: sourceAccount._id }, { limit: 100 })
|
||||||
|
if (values.length === 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
const builder = client.apply(sourceAccount._id)
|
||||||
|
for (const v of values) {
|
||||||
|
await updateAttribute(builder, v, d, { key: attr.name, attr }, targetAccount._id)
|
||||||
|
}
|
||||||
|
console.log('merge employee:', sourceAccount.name, 'to', targetAccount.name, d, builder.txes.length)
|
||||||
|
await builder.commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.remove(sourceAccount)
|
||||||
|
for (const account of accounts) {
|
||||||
|
await client.update(account, { person: targetAccount._id })
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
const toAny = (a: any) => a
|
const toAny = (a: any) => a
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Card
|
<Card
|
||||||
label={contact.string.MergeEmployee}
|
label={contact.string.MergePersons}
|
||||||
okLabel={contact.string.MergeEmployee}
|
okLabel={contact.string.MergePersons}
|
||||||
fullSize
|
fullSize
|
||||||
okAction={merge}
|
okAction={merge}
|
||||||
canSave={targetEmp !== undefined}
|
canSave={targetPerson !== undefined}
|
||||||
onCancel={() => dispatch('close')}
|
onCancel={() => dispatch('close')}
|
||||||
on:changeContent
|
on:changeContent
|
||||||
>
|
>
|
||||||
<div class="flex-row flex-between">
|
<div class="flex-row flex-between">
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center">
|
||||||
<EmployeeBox
|
<UserBox
|
||||||
|
_class={contact.class.Person}
|
||||||
showNavigate={false}
|
showNavigate={false}
|
||||||
label={contact.string.MergeEmployeeFrom}
|
label={contact.string.MergePersonsFrom}
|
||||||
docQuery={{ active: { $in: [true, false] } }}
|
docQuery={{}}
|
||||||
bind:value={sourceEmployee}
|
bind:value={sourcePersonRef}
|
||||||
/>
|
/>
|
||||||
<ChannelsDropdown
|
<ChannelsDropdown
|
||||||
value={oldChannels}
|
value={oldChannels}
|
||||||
@ -231,11 +331,12 @@
|
|||||||
</div>
|
</div>
|
||||||
>>
|
>>
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center">
|
||||||
<EmployeeBox
|
<UserBox
|
||||||
|
_class={contact.class.Person}
|
||||||
showNavigate={false}
|
showNavigate={false}
|
||||||
label={contact.string.MergeEmployeeTo}
|
label={contact.string.MergePersonsTo}
|
||||||
docQuery={{ active: { $in: [true, false] } }}
|
docQuery={{ _id: { $ne: sourcePersonRef } }}
|
||||||
bind:value={targetEmployee}
|
bind:value={targetPersonRf}
|
||||||
/>
|
/>
|
||||||
<ChannelsDropdown
|
<ChannelsDropdown
|
||||||
value={targetChannels}
|
value={targetChannels}
|
||||||
@ -247,13 +348,13 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#key [targetEmployee, sourceEmployee]}
|
{#key [targetPersonRf, sourcePersonRef]}
|
||||||
{#if targetEmp && sourceEmp}
|
{#if targetPerson && sourcePerson}
|
||||||
<div class="flex-col flex-grow">
|
<div class="flex-col flex-grow">
|
||||||
<MergeComparer
|
<MergeComparer
|
||||||
key="avatar"
|
key="avatar"
|
||||||
value={sourceEmp}
|
value={sourcePerson}
|
||||||
{targetEmp}
|
targetEmp={targetPerson}
|
||||||
onChange={select}
|
onChange={select}
|
||||||
selected={update.avatar !== undefined}
|
selected={update.avatar !== undefined}
|
||||||
>
|
>
|
||||||
@ -261,18 +362,24 @@
|
|||||||
<Avatar avatar={item.avatar} size={'x-large'} icon={contact.icon.Person} />
|
<Avatar avatar={item.avatar} size={'x-large'} icon={contact.icon.Person} />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</MergeComparer>
|
</MergeComparer>
|
||||||
<MergeComparer key="name" value={sourceEmp} {targetEmp} onChange={select} selected={update.name !== undefined}>
|
<MergeComparer
|
||||||
|
key="name"
|
||||||
|
value={sourcePerson}
|
||||||
|
targetEmp={targetPerson}
|
||||||
|
onChange={select}
|
||||||
|
selected={update.name !== undefined}
|
||||||
|
>
|
||||||
<svelte:fragment slot="item" let:item>
|
<svelte:fragment slot="item" let:item>
|
||||||
{getName(item)}
|
{getName(client.getHierarchy(), item)}
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</MergeComparer>
|
</MergeComparer>
|
||||||
{#each objectAttributes as attribute}
|
{#each objectAttributes as attribute}
|
||||||
<MergeAttributeComparer
|
<MergeAttributeComparer
|
||||||
key={attribute[0]}
|
key={attribute[0]}
|
||||||
value={sourceEmp}
|
value={sourcePerson}
|
||||||
{targetEmp}
|
targetEmp={targetPerson}
|
||||||
onChange={select}
|
onChange={select}
|
||||||
_class={contact.class.Employee}
|
_class={contact.mixin.Employee}
|
||||||
selected={toAny(update)[attribute[0]] !== undefined}
|
selected={toAny(update)[attribute[0]] !== undefined}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
@ -281,8 +388,8 @@
|
|||||||
{#each attributes as attribute}
|
{#each attributes as attribute}
|
||||||
<MergeAttributeComparer
|
<MergeAttributeComparer
|
||||||
key={attribute}
|
key={attribute}
|
||||||
value={sourceEmp}
|
value={sourcePerson}
|
||||||
{targetEmp}
|
targetEmp={targetPerson}
|
||||||
onChange={(key, value) => selectMixin(mixin, key, value)}
|
onChange={(key, value) => selectMixin(mixin, key, value)}
|
||||||
_class={mixin}
|
_class={mixin}
|
||||||
selected={toAny(mixinUpdate)?.[mixin]?.[attribute] !== undefined}
|
selected={toAny(mixinUpdate)?.[mixin]?.[attribute] !== undefined}
|
@ -13,17 +13,17 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee, EmployeeAccount } from '@hcengineering/contact'
|
import { Employee, PersonAccount } from '@hcengineering/contact'
|
||||||
import { Ref } from '@hcengineering/core'
|
import { Ref } from '@hcengineering/core'
|
||||||
import contact from '../plugin'
|
import contact from '../plugin'
|
||||||
import { employeeAccountByIdStore } from '../utils'
|
import { personAccountByIdStore } from '../utils'
|
||||||
import CombineAvatars from './CombineAvatars.svelte'
|
import CombineAvatars from './CombineAvatars.svelte'
|
||||||
|
|
||||||
export let value: Ref<EmployeeAccount>[]
|
export let value: Ref<PersonAccount>[]
|
||||||
|
|
||||||
$: employees = value
|
$: employees = value
|
||||||
.map((p) => $employeeAccountByIdStore.get(p)?.employee)
|
.map((p) => $personAccountByIdStore.get(p)?.person)
|
||||||
.filter((p) => p !== undefined) as Ref<Employee>[]
|
.filter((p) => p !== undefined) as Ref<Employee>[]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CombineAvatars _class={contact.class.Employee} items={employees} limit={5} size={'x-small'} />
|
<CombineAvatars _class={contact.mixin.Employee} items={employees} limit={5} size={'x-small'} />
|
@ -14,13 +14,14 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { EmployeeAccount } from '@hcengineering/contact'
|
import { Employee, PersonAccount } from '@hcengineering/contact'
|
||||||
import core, { Account, systemAccountEmail } from '@hcengineering/core'
|
import core, { Account, Ref, systemAccountEmail } from '@hcengineering/core'
|
||||||
import { getEmbeddedLabel } from '@hcengineering/platform'
|
import { getEmbeddedLabel } from '@hcengineering/platform'
|
||||||
import { Label, tooltip, IconSize } from '@hcengineering/ui'
|
import { IconSize, Label, tooltip } from '@hcengineering/ui'
|
||||||
import { employeeByIdStore } from '../utils'
|
import { employeeByIdStore, personAccountPersonByIdStore } from '../utils'
|
||||||
import Avatar from './Avatar.svelte'
|
import Avatar from './Avatar.svelte'
|
||||||
import EmployeePresenter from './EmployeePresenter.svelte'
|
import EmployeePresenter from './EmployeePresenter.svelte'
|
||||||
|
import PersonPresenter from './PersonPresenter.svelte'
|
||||||
|
|
||||||
export let value: Account
|
export let value: Account
|
||||||
export let avatarSize: IconSize = 'x-small'
|
export let avatarSize: IconSize = 'x-small'
|
||||||
@ -28,8 +29,9 @@
|
|||||||
export let inline: boolean = false
|
export let inline: boolean = false
|
||||||
export let accent: boolean = false
|
export let accent: boolean = false
|
||||||
|
|
||||||
$: employee = $employeeByIdStore.get((value as EmployeeAccount)?.employee)
|
$: employee = $employeeByIdStore.get((value as PersonAccount)?.person as Ref<Employee>)
|
||||||
|
|
||||||
|
$: person = $personAccountPersonByIdStore.get((value as PersonAccount)?.person)
|
||||||
const valueLabel = value?.email === systemAccountEmail ? core.string.System : getEmbeddedLabel(value?.email)
|
const valueLabel = value?.email === systemAccountEmail ? core.string.System : getEmbeddedLabel(value?.email)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -37,6 +39,8 @@
|
|||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
{#if employee}
|
{#if employee}
|
||||||
<EmployeePresenter value={employee} {disabled} {inline} {accent} {avatarSize} on:accent-color />
|
<EmployeePresenter value={employee} {disabled} {inline} {accent} {avatarSize} on:accent-color />
|
||||||
|
{:else if person}
|
||||||
|
<PersonPresenter value={person} {disabled} {inline} {accent} {avatarSize} on:accent-color />
|
||||||
{:else}
|
{:else}
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center">
|
||||||
<Avatar size={avatarSize} />
|
<Avatar size={avatarSize} />
|
@ -14,21 +14,21 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { EmployeeAccount } from '@hcengineering/contact'
|
import { PersonAccount } from '@hcengineering/contact'
|
||||||
import { Ref } from '@hcengineering/core'
|
import { Ref } from '@hcengineering/core'
|
||||||
import { IconSize } from '@hcengineering/ui'
|
import { IconSize } from '@hcengineering/ui'
|
||||||
import { employeeAccountByIdStore } from '../utils'
|
import { personAccountByIdStore } from '../utils'
|
||||||
import EmployeeAccountPresenter from './EmployeeAccountPresenter.svelte'
|
import PersonAccountPresenter from './PersonAccountPresenter.svelte'
|
||||||
|
|
||||||
export let value: Ref<EmployeeAccount>
|
export let value: Ref<PersonAccount>
|
||||||
export let avatarSize: IconSize = 'x-small'
|
export let avatarSize: IconSize = 'x-small'
|
||||||
export let disabled: boolean = false
|
export let disabled: boolean = false
|
||||||
export let inline: boolean = false
|
export let inline: boolean = false
|
||||||
export let accent: boolean = false
|
export let accent: boolean = false
|
||||||
|
|
||||||
$: account = $employeeAccountByIdStore.get(value)
|
$: account = $personAccountByIdStore.get(value)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if account}
|
{#if account}
|
||||||
<EmployeeAccountPresenter value={account} {disabled} {inline} {avatarSize} on:accent-color />
|
<PersonAccountPresenter value={account} {disabled} {inline} {avatarSize} on:accent-color />
|
||||||
{/if}
|
{/if}
|
@ -15,7 +15,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import attachment from '@hcengineering/attachment'
|
import attachment from '@hcengineering/attachment'
|
||||||
import contact, { Channel, Contact, getName } from '@hcengineering/contact'
|
import contact, { Channel, Contact, getName } from '@hcengineering/contact'
|
||||||
import { createQuery } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import Avatar from './Avatar.svelte'
|
import Avatar from './Avatar.svelte'
|
||||||
import { Component, Label } from '@hcengineering/ui'
|
import { Component, Label } from '@hcengineering/ui'
|
||||||
import { DocNavLink } from '@hcengineering/view-resources'
|
import { DocNavLink } from '@hcengineering/view-resources'
|
||||||
@ -24,6 +24,8 @@
|
|||||||
export let object: Contact
|
export let object: Contact
|
||||||
export let disabled: boolean = false
|
export let disabled: boolean = false
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
let channels: Channel[] = []
|
let channels: Channel[] = []
|
||||||
const channelsQuery = createQuery()
|
const channelsQuery = createQuery()
|
||||||
channelsQuery.query(
|
channelsQuery.query(
|
||||||
@ -46,7 +48,7 @@
|
|||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<DocNavLink {object} {disabled}>
|
<DocNavLink {object} {disabled}>
|
||||||
<div class="name lines-limit-2">
|
<div class="name lines-limit-2">
|
||||||
{getName(object)}
|
{getName(client.getHierarchy(), object)}
|
||||||
</div>
|
</div>
|
||||||
</DocNavLink>
|
</DocNavLink>
|
||||||
<div class="description overflow-label">{object.city ?? ''}</div>
|
<div class="description overflow-label">{object.city ?? ''}</div>
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
import { DocNavLink } from '@hcengineering/view-resources'
|
import { DocNavLink } from '@hcengineering/view-resources'
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
import Avatar from './Avatar.svelte'
|
import Avatar from './Avatar.svelte'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
|
|
||||||
export let value: Person | Employee | undefined | null
|
export let value: Person | Employee | undefined | null
|
||||||
export let inline: boolean = false
|
export let inline: boolean = false
|
||||||
@ -45,6 +46,8 @@
|
|||||||
export let accent: boolean = false
|
export let accent: boolean = false
|
||||||
export let maxWidth = ''
|
export let maxWidth = ''
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
const onEditClick = (evt: MouseEvent) => {
|
const onEditClick = (evt: MouseEvent) => {
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
onEdit?.(evt)
|
onEdit?.(evt)
|
||||||
@ -83,7 +86,9 @@
|
|||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if shouldShowName}
|
{#if shouldShowName}
|
||||||
<span class="eContentPresenterLabel" class:colorInherit class:fs-bold={accent}>{getName(value)}</span>
|
<span class="eContentPresenterLabel" class:colorInherit class:fs-bold={accent}
|
||||||
|
>{getName(client.getHierarchy(), value)}</span
|
||||||
|
>
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
</DocNavLink>
|
</DocNavLink>
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
import type { LabelAndProps, IconSize } from '@hcengineering/ui'
|
import type { LabelAndProps, IconSize } from '@hcengineering/ui'
|
||||||
import { PersonLabelTooltip } from '..'
|
import { PersonLabelTooltip } from '..'
|
||||||
import PersonContent from './PersonContent.svelte'
|
import PersonContent from './PersonContent.svelte'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
|
|
||||||
export let value: Person | null | undefined
|
export let value: Person | null | undefined
|
||||||
export let inline = false
|
export let inline = false
|
||||||
@ -36,6 +37,8 @@
|
|||||||
export let accent: boolean = false
|
export let accent: boolean = false
|
||||||
export let maxWidth = ''
|
export let maxWidth = ''
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
function getTooltip (
|
function getTooltip (
|
||||||
tooltipLabels: PersonLabelTooltip | undefined,
|
tooltipLabels: PersonLabelTooltip | undefined,
|
||||||
value: Person | null | undefined
|
value: Person | null | undefined
|
||||||
@ -44,7 +47,7 @@
|
|||||||
return !value
|
return !value
|
||||||
? undefined
|
? undefined
|
||||||
: {
|
: {
|
||||||
label: getEmbeddedLabel(getName(value))
|
label: getEmbeddedLabel(getName(client.getHierarchy(), value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const direction = tooltipLabels?.direction
|
const direction = tooltipLabels?.direction
|
||||||
@ -52,11 +55,15 @@
|
|||||||
const label = value
|
const label = value
|
||||||
? tooltipLabels.personLabel
|
? tooltipLabels.personLabel
|
||||||
? tooltipLabels.personLabel
|
? tooltipLabels.personLabel
|
||||||
: getEmbeddedLabel(getName(value))
|
: getEmbeddedLabel(getName(client.getHierarchy(), value))
|
||||||
: tooltipLabels.placeholderLabel
|
: tooltipLabels.placeholderLabel
|
||||||
? tooltipLabels.placeholderLabel
|
? tooltipLabels.placeholderLabel
|
||||||
: undefined
|
: undefined
|
||||||
const props = tooltipLabels.props ? tooltipLabels.props : value ? { value: getName(value) } : undefined
|
const props = tooltipLabels.props
|
||||||
|
? tooltipLabels.props
|
||||||
|
: value
|
||||||
|
? { value: getName(client.getHierarchy(), value) }
|
||||||
|
: undefined
|
||||||
return {
|
return {
|
||||||
component,
|
component,
|
||||||
label,
|
label,
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
import UsersPopup from './UsersPopup.svelte'
|
import UsersPopup from './UsersPopup.svelte'
|
||||||
|
|
||||||
export let items: Ref<Employee>[] = []
|
export let items: Ref<Employee>[] = []
|
||||||
export let _class: Ref<Class<Employee>> = contact.class.Employee
|
export let _class: Ref<Class<Employee>> = contact.mixin.Employee
|
||||||
export let docQuery: DocumentQuery<Employee> | undefined = {
|
export let docQuery: DocumentQuery<Employee> | undefined = {
|
||||||
active: true
|
active: true
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Employee, EmployeeAccount } from '@hcengineering/contact'
|
import contact, { Person, PersonAccount, Employee } from '@hcengineering/contact'
|
||||||
import { Account, AccountRole, DocumentQuery, getCurrentAccount, Ref, SortingOrder, Space } from '@hcengineering/core'
|
import { Account, AccountRole, DocumentQuery, getCurrentAccount, Ref, SortingOrder, Space } from '@hcengineering/core'
|
||||||
import { translate } from '@hcengineering/platform'
|
import { translate } from '@hcengineering/platform'
|
||||||
import presentation, { getClient } from '@hcengineering/presentation'
|
import presentation, { getClient } from '@hcengineering/presentation'
|
||||||
@ -33,29 +33,24 @@
|
|||||||
}
|
}
|
||||||
let search: string = ''
|
let search: string = ''
|
||||||
$: isSearch = search.trim().length
|
$: isSearch = search.trim().length
|
||||||
let members: Set<Ref<Employee>> = new Set<Ref<Employee>>()
|
let members: Set<Ref<Person>> = new Set<Ref<Person>>()
|
||||||
|
|
||||||
async function getUsers (accounts: Ref<Account>[], search: string): Promise<Employee[]> {
|
async function getUsers (accounts: Ref<Account>[], search: string): Promise<Person[]> {
|
||||||
const query: DocumentQuery<EmployeeAccount> =
|
const query: DocumentQuery<PersonAccount> =
|
||||||
isSearch > 0 ? { name: { $like: '%' + search + '%' } } : { _id: { $in: accounts as Ref<EmployeeAccount>[] } }
|
isSearch > 0 ? { name: { $like: '%' + search + '%' } } : { _id: { $in: accounts as Ref<PersonAccount>[] } }
|
||||||
const employess = await client.findAll(contact.class.EmployeeAccount, query)
|
const employess = await client.findAll(contact.class.PersonAccount, query)
|
||||||
members = new Set(
|
members = new Set(employess.filter((p) => accounts.includes(p._id)).map((p) => p.person))
|
||||||
employess
|
|
||||||
.filter((it) => it.mergedTo == null)
|
|
||||||
.filter((p) => accounts.includes(p._id))
|
|
||||||
.map((p) => p.employee)
|
|
||||||
)
|
|
||||||
return await client.findAll(
|
return await client.findAll(
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
{
|
{
|
||||||
_id: { $in: employess.map((e) => e.employee) }
|
_id: { $in: employess.map((e) => e.person as Ref<Employee>) }
|
||||||
},
|
},
|
||||||
{ sort: { name: SortingOrder.Descending } }
|
{ sort: { name: SortingOrder.Descending } }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function add (employee: Ref<Employee>): Promise<void> {
|
async function add (employee: Ref<Person>): Promise<void> {
|
||||||
const account = await client.findOne(contact.class.EmployeeAccount, { employee })
|
const account = await client.findOne(contact.class.PersonAccount, { employee })
|
||||||
if (account === undefined) return
|
if (account === undefined) return
|
||||||
await client.update(space, {
|
await client.update(space, {
|
||||||
$push: {
|
$push: {
|
||||||
@ -64,14 +59,14 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeMember (employee: Ref<Employee>): Promise<void> {
|
async function removeMember (employee: Ref<Person>): Promise<void> {
|
||||||
const account = await client.findOne(contact.class.EmployeeAccount, { employee })
|
const account = await client.findOne(contact.class.PersonAccount, { employee })
|
||||||
if (account === undefined) return
|
if (account === undefined) return
|
||||||
await client.update(space, { $pull: { members: account._id } })
|
await client.update(space, { $pull: { members: account._id } })
|
||||||
}
|
}
|
||||||
|
|
||||||
function openAddMembersPopup () {
|
function openAddMembersPopup () {
|
||||||
showPopup(AddMembersPopup, { value: space }, undefined, async (membersIds: Ref<EmployeeAccount>[]) => {
|
showPopup(AddMembersPopup, { value: space }, undefined, async (membersIds: Ref<PersonAccount>[]) => {
|
||||||
if (membersIds) {
|
if (membersIds) {
|
||||||
for (const member of membersIds) {
|
for (const member of membersIds) {
|
||||||
if (space.members.includes(member)) continue
|
if (space.members.includes(member)) continue
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Contact, getName } from '@hcengineering/contact'
|
import contact, { Contact, getName } from '@hcengineering/contact'
|
||||||
import { Class, DocumentQuery, FindOptions, Hierarchy, Ref } from '@hcengineering/core'
|
import { Class, DocumentQuery, FindOptions, Hierarchy, Ref, Doc } from '@hcengineering/core'
|
||||||
import { Asset, getEmbeddedLabel, IntlString } from '@hcengineering/platform'
|
import { Asset, getEmbeddedLabel, IntlString } from '@hcengineering/platform'
|
||||||
import { getClient, ObjectCreate } from '@hcengineering/presentation'
|
import { getClient, ObjectCreate } from '@hcengineering/presentation'
|
||||||
import {
|
import {
|
||||||
@ -42,6 +42,7 @@
|
|||||||
import UsersPopup from './UsersPopup.svelte'
|
import UsersPopup from './UsersPopup.svelte'
|
||||||
|
|
||||||
export let _class: Ref<Class<Contact>>
|
export let _class: Ref<Class<Contact>>
|
||||||
|
export let _previewClass: Ref<Class<Contact>> = contact.class.Contact
|
||||||
export let excluded: Ref<Contact>[] | undefined = undefined
|
export let excluded: Ref<Contact>[] | undefined = undefined
|
||||||
export let options: FindOptions<Contact> | undefined = undefined
|
export let options: FindOptions<Contact> | undefined = undefined
|
||||||
export let docQuery: DocumentQuery<Contact> | undefined = undefined
|
export let docQuery: DocumentQuery<Contact> | undefined = undefined
|
||||||
@ -61,6 +62,9 @@
|
|||||||
export let showTooltip: LabelAndProps | undefined = undefined
|
export let showTooltip: LabelAndProps | undefined = undefined
|
||||||
export let showNavigate = true
|
export let showNavigate = true
|
||||||
export let id: string | undefined = undefined
|
export let id: string | undefined = undefined
|
||||||
|
export let filter: (it: Doc) => boolean = () => {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
export let create: ObjectCreate | undefined = undefined
|
export let create: ObjectCreate | undefined = undefined
|
||||||
|
|
||||||
@ -72,7 +76,7 @@
|
|||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
async function updateSelected (value: Ref<Contact> | null | undefined) {
|
async function updateSelected (value: Ref<Contact> | null | undefined) {
|
||||||
selected = value ? await client.findOne(_class, { _id: value }) : undefined
|
selected = value ? await client.findOne(_previewClass, { _id: value }) : undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
$: updateSelected(value)
|
$: updateSelected(value)
|
||||||
@ -93,7 +97,8 @@
|
|||||||
selected: value,
|
selected: value,
|
||||||
titleDeselect,
|
titleDeselect,
|
||||||
placeholder,
|
placeholder,
|
||||||
create
|
create,
|
||||||
|
filter
|
||||||
},
|
},
|
||||||
!$$slots.content ? container : getEventPositionElement(ev),
|
!$$slots.content ? container : getEventPositionElement(ev),
|
||||||
(result) => {
|
(result) => {
|
||||||
@ -121,7 +126,9 @@
|
|||||||
class="w-full h-full flex-streatch"
|
class="w-full h-full flex-streatch"
|
||||||
on:click={_click}
|
on:click={_click}
|
||||||
class:content-color={selected === undefined}
|
class:content-color={selected === undefined}
|
||||||
use:tooltip={selected !== undefined ? { label: getEmbeddedLabel(getName(selected)) } : undefined}
|
use:tooltip={selected !== undefined
|
||||||
|
? { label: getEmbeddedLabel(getName(client.getHierarchy(), selected)) }
|
||||||
|
: undefined}
|
||||||
>
|
>
|
||||||
<slot name="content" />
|
<slot name="content" />
|
||||||
</div>
|
</div>
|
||||||
@ -148,13 +155,15 @@
|
|||||||
style:width={showNavigate && selected
|
style:width={showNavigate && selected
|
||||||
? `calc(${width ?? 'min-content'} - 1.5rem)`
|
? `calc(${width ?? 'min-content'} - 1.5rem)`
|
||||||
: `${width ?? 'min-content'}`}
|
: `${width ?? 'min-content'}`}
|
||||||
use:tooltip={selected !== undefined ? { label: getEmbeddedLabel(getName(selected)) } : undefined}
|
use:tooltip={selected !== undefined
|
||||||
|
? { label: getEmbeddedLabel(getName(client.getHierarchy(), selected)) }
|
||||||
|
: undefined}
|
||||||
>
|
>
|
||||||
{#if selected}
|
{#if selected}
|
||||||
{#if hideIcon || selected}
|
{#if hideIcon || selected}
|
||||||
<UserInfo value={selected} size={avatarSize} {icon} />
|
<UserInfo value={selected} size={avatarSize} {icon} />
|
||||||
{:else}
|
{:else}
|
||||||
{getName(selected)}
|
{getName(client.getHierarchy(), selected)}
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<div class="flex-presenter not-selected">
|
<div class="flex-presenter not-selected">
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Employee } from '@hcengineering/contact'
|
import contact, { Employee } from '@hcengineering/contact'
|
||||||
import type { Class, DocumentQuery, IdMap, Ref } from '@hcengineering/core'
|
import type { Class, Doc, DocumentQuery, IdMap, Ref } from '@hcengineering/core'
|
||||||
import type { IntlString } from '@hcengineering/platform'
|
import type { IntlString } from '@hcengineering/platform'
|
||||||
import { Label, showPopup, ActionIcon, IconClose, IconAdd, Icon } from '@hcengineering/ui'
|
import { Label, showPopup, ActionIcon, IconClose, IconAdd, Icon } from '@hcengineering/ui'
|
||||||
import type { IconSize } from '@hcengineering/ui'
|
import type { IconSize } from '@hcengineering/ui'
|
||||||
@ -23,13 +23,12 @@
|
|||||||
import { employeeByIdStore } from '../utils'
|
import { employeeByIdStore } from '../utils'
|
||||||
import UserInfo from './UserInfo.svelte'
|
import UserInfo from './UserInfo.svelte'
|
||||||
import UsersPopup from './UsersPopup.svelte'
|
import UsersPopup from './UsersPopup.svelte'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
|
|
||||||
export let items: Ref<Employee>[] = []
|
export let items: Ref<Employee>[] = []
|
||||||
export let readonlyItems: Ref<Employee>[] = []
|
export let readonlyItems: Ref<Employee>[] = []
|
||||||
export let _class: Ref<Class<Employee>> = contact.class.Employee
|
export let _class: Ref<Class<Employee>> = contact.mixin.Employee
|
||||||
export let docQuery: DocumentQuery<Employee> | undefined = {
|
export let docQuery: DocumentQuery<Employee> | undefined = {}
|
||||||
active: true
|
|
||||||
}
|
|
||||||
|
|
||||||
export let label: IntlString | undefined = undefined
|
export let label: IntlString | undefined = undefined
|
||||||
export let actionLabel: IntlString = plugin.string.AddMember
|
export let actionLabel: IntlString = plugin.string.AddMember
|
||||||
@ -42,6 +41,8 @@
|
|||||||
let readonlyPersons: Employee[] = getPersons(readonlyItems, $employeeByIdStore)
|
let readonlyPersons: Employee[] = getPersons(readonlyItems, $employeeByIdStore)
|
||||||
$: readonlyPersons = getPersons(readonlyItems, $employeeByIdStore)
|
$: readonlyPersons = getPersons(readonlyItems, $employeeByIdStore)
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
async function addPerson (evt: Event): Promise<void> {
|
async function addPerson (evt: Event): Promise<void> {
|
||||||
@ -55,7 +56,13 @@
|
|||||||
allowDeselect: false,
|
allowDeselect: false,
|
||||||
selectedUsers: items,
|
selectedUsers: items,
|
||||||
ignoreUsers: readonlyItems,
|
ignoreUsers: readonlyItems,
|
||||||
readonly
|
readonly,
|
||||||
|
filter: (it: Doc) => {
|
||||||
|
if (client.getHierarchy().hasMixin(it, contact.mixin.Employee)) {
|
||||||
|
return client.getHierarchy().as(it, contact.mixin.Employee).active
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
evt.target as HTMLElement,
|
evt.target as HTMLElement,
|
||||||
undefined,
|
undefined,
|
||||||
|
@ -14,23 +14,22 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Employee } from '@hcengineering/contact'
|
import contact, { Employee } from '@hcengineering/contact'
|
||||||
import type { Class, DocumentQuery, Ref } from '@hcengineering/core'
|
import type { Class, DocumentQuery, Ref, Doc } from '@hcengineering/core'
|
||||||
import type { IntlString } from '@hcengineering/platform'
|
import type { IntlString } from '@hcengineering/platform'
|
||||||
import { Button, Label, showPopup } from '@hcengineering/ui'
|
|
||||||
import type { ButtonKind, ButtonSize, TooltipAlignment } from '@hcengineering/ui'
|
import type { ButtonKind, ButtonSize, TooltipAlignment } from '@hcengineering/ui'
|
||||||
|
import { Button, Label, showPopup } from '@hcengineering/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import plugin from '../plugin'
|
import plugin from '../plugin'
|
||||||
import { employeeByIdStore } from '../utils'
|
import { employeeByIdStore } from '../utils'
|
||||||
import CombineAvatars from './CombineAvatars.svelte'
|
import CombineAvatars from './CombineAvatars.svelte'
|
||||||
import Members from './icons/Members.svelte'
|
|
||||||
import UserInfo from './UserInfo.svelte'
|
import UserInfo from './UserInfo.svelte'
|
||||||
import UsersPopup from './UsersPopup.svelte'
|
import UsersPopup from './UsersPopup.svelte'
|
||||||
|
import Members from './icons/Members.svelte'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
|
|
||||||
export let items: Ref<Employee>[] = []
|
export let items: Ref<Employee>[] = []
|
||||||
export let _class: Ref<Class<Employee>> = contact.class.Employee
|
export let _class: Ref<Class<Employee>> = contact.mixin.Employee
|
||||||
export let docQuery: DocumentQuery<Employee> | undefined = {
|
export let docQuery: DocumentQuery<Employee> | undefined = {}
|
||||||
active: true
|
|
||||||
}
|
|
||||||
|
|
||||||
export let label: IntlString | undefined = undefined
|
export let label: IntlString | undefined = undefined
|
||||||
export let kind: ButtonKind = 'no-border'
|
export let kind: ButtonKind = 'no-border'
|
||||||
@ -45,6 +44,7 @@
|
|||||||
$: persons = items.map((p) => $employeeByIdStore.get(p)).filter((p) => p !== undefined) as Employee[]
|
$: persons = items.map((p) => $employeeByIdStore.get(p)).filter((p) => p !== undefined) as Employee[]
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
async function addPerson (evt: Event): Promise<void> {
|
async function addPerson (evt: Event): Promise<void> {
|
||||||
showPopup(
|
showPopup(
|
||||||
@ -56,6 +56,12 @@
|
|||||||
multiSelect: true,
|
multiSelect: true,
|
||||||
allowDeselect: false,
|
allowDeselect: false,
|
||||||
selectedUsers: items,
|
selectedUsers: items,
|
||||||
|
filter: (it: Doc) => {
|
||||||
|
const h = client.getHierarchy()
|
||||||
|
if (h.hasMixin(it, contact.mixin.Employee)) {
|
||||||
|
return h.as(it, contact.mixin.Employee).active
|
||||||
|
}
|
||||||
|
},
|
||||||
readonly
|
readonly
|
||||||
},
|
},
|
||||||
evt.target as HTMLElement,
|
evt.target as HTMLElement,
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
import { getName, Person } from '@hcengineering/contact'
|
import { getName, Person } from '@hcengineering/contact'
|
||||||
import { Asset } from '@hcengineering/platform'
|
import { Asset } from '@hcengineering/platform'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { AnySvelteComponent, IconSize } from '@hcengineering/ui'
|
import { AnySvelteComponent, IconSize } from '@hcengineering/ui'
|
||||||
|
|
||||||
export let value: Person
|
export let value: Person
|
||||||
@ -24,6 +25,8 @@
|
|||||||
export let size: IconSize
|
export let size: IconSize
|
||||||
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
||||||
export let short: boolean = false
|
export let short: boolean = false
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
@ -31,6 +34,6 @@
|
|||||||
<Avatar avatar={value.avatar} {size} {icon} on:accent-color />
|
<Avatar avatar={value.avatar} {size} {icon} on:accent-color />
|
||||||
<div class="flex-col min-w-0 {size === 'tiny' || size === 'inline' ? 'ml-1' : 'ml-2'}" class:max-w-20={short}>
|
<div class="flex-col min-w-0 {size === 'tiny' || size === 'inline' ? 'ml-1' : 'ml-2'}" class:max-w-20={short}>
|
||||||
{#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if}
|
{#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if}
|
||||||
<div class="label overflow-label text-left">{getName(value)}</div>
|
<div class="label overflow-label text-left">{getName(client.getHierarchy(), value)}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Contact, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
import contact, { Contact, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
||||||
import type { Class, Doc, DocumentQuery, FindOptions, Ref } from '@hcengineering/core'
|
import type { Class, Doc, DocumentQuery, FindOptions, Ref } from '@hcengineering/core'
|
||||||
import type { Asset, IntlString } from '@hcengineering/platform'
|
import type { Asset, IntlString } from '@hcengineering/platform'
|
||||||
import presentation, { getClient, ObjectCreate, ObjectPopup } from '@hcengineering/presentation'
|
import presentation, { getClient, ObjectCreate, ObjectPopup } from '@hcengineering/presentation'
|
||||||
@ -26,6 +26,15 @@
|
|||||||
export let selected: Ref<Person> | undefined
|
export let selected: Ref<Person> | undefined
|
||||||
export let docQuery: DocumentQuery<Contact> | undefined = undefined
|
export let docQuery: DocumentQuery<Contact> | undefined = undefined
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
|
export let filter: (it: Doc) => boolean = (it) => {
|
||||||
|
if (client.getHierarchy().hasMixin(it, contact.mixin.Employee)) {
|
||||||
|
return client.getHierarchy().as(it, contact.mixin.Employee).active
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
export let multiSelect: boolean = false
|
export let multiSelect: boolean = false
|
||||||
export let allowDeselect: boolean = false
|
export let allowDeselect: boolean = false
|
||||||
export let titleDeselect: IntlString | undefined = undefined
|
export let titleDeselect: IntlString | undefined = undefined
|
||||||
@ -61,6 +70,7 @@
|
|||||||
{titleDeselect}
|
{titleDeselect}
|
||||||
{placeholder}
|
{placeholder}
|
||||||
{docQuery}
|
{docQuery}
|
||||||
|
{filter}
|
||||||
groupBy={'_class'}
|
groupBy={'_class'}
|
||||||
bind:selectedObjects={selectedUsers}
|
bind:selectedObjects={selectedUsers}
|
||||||
bind:ignoreObjects={ignoreUsers}
|
bind:ignoreObjects={ignoreUsers}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
import contact, { Channel, Contact, getName } from '@hcengineering/contact'
|
import contact, { Channel, Contact, getName } from '@hcengineering/contact'
|
||||||
import { Ref } from '@hcengineering/core'
|
import { Ref } from '@hcengineering/core'
|
||||||
import { getEmbeddedLabel } from '@hcengineering/platform'
|
import { getEmbeddedLabel } from '@hcengineering/platform'
|
||||||
import { createQuery } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { CircleButton, tooltip } from '@hcengineering/ui'
|
import { CircleButton, tooltip } from '@hcengineering/ui'
|
||||||
import { DocNavLink } from '@hcengineering/view-resources'
|
import { DocNavLink } from '@hcengineering/view-resources'
|
||||||
import { channelProviders } from '../../utils'
|
import { channelProviders } from '../../utils'
|
||||||
@ -27,6 +27,8 @@
|
|||||||
let target: Contact | undefined
|
let target: Contact | undefined
|
||||||
const query = createQuery()
|
const query = createQuery()
|
||||||
$: query.query(contact.class.Contact, { _id: value.attachedTo as Ref<Contact> }, (res) => ([target] = res))
|
$: query.query(contact.class.Contact, { _id: value.attachedTo as Ref<Contact> }, (res) => ([target] = res))
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex-row-center" use:tooltip={{ label: getEmbeddedLabel(value.value) }}>
|
<div class="flex-row-center" use:tooltip={{ label: getEmbeddedLabel(value.value) }}>
|
||||||
@ -36,7 +38,7 @@
|
|||||||
{#if target}
|
{#if target}
|
||||||
<div class="ml-1">
|
<div class="ml-1">
|
||||||
<DocNavLink object={target}>
|
<DocNavLink object={target}>
|
||||||
{getName(target)}
|
{getName(client.getHierarchy(), target)}
|
||||||
</DocNavLink>
|
</DocNavLink>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import { Channel, Contact, Employee, getGravatarUrl, getName } from '@hcengineering/contact'
|
import { Channel, Contact, getGravatarUrl, getName, Person } from '@hcengineering/contact'
|
||||||
import { Class, Client, DocumentQuery, Ref, RelatedDocument, WithLookup } from '@hcengineering/core'
|
import { Class, Client, DocumentQuery, Ref, RelatedDocument, WithLookup } from '@hcengineering/core'
|
||||||
import login from '@hcengineering/login'
|
import login from '@hcengineering/login'
|
||||||
import { IntlString, Resources, getResource } from '@hcengineering/platform'
|
import { IntlString, Resources, getResource } from '@hcengineering/platform'
|
||||||
@ -55,9 +55,9 @@ import EditMember from './components/EditMember.svelte'
|
|||||||
import EditOrganization from './components/EditOrganization.svelte'
|
import EditOrganization from './components/EditOrganization.svelte'
|
||||||
import EditPerson from './components/EditPerson.svelte'
|
import EditPerson from './components/EditPerson.svelte'
|
||||||
import EditableAvatar from './components/EditableAvatar.svelte'
|
import EditableAvatar from './components/EditableAvatar.svelte'
|
||||||
import EmployeeAccountFilterValuePresenter from './components/EmployeeAccountFilterValuePresenter.svelte'
|
import PersonAccountFilterValuePresenter from './components/PersonAccountFilterValuePresenter.svelte'
|
||||||
import EmployeeAccountPresenter from './components/EmployeeAccountPresenter.svelte'
|
import PersonAccountPresenter from './components/PersonAccountPresenter.svelte'
|
||||||
import EmployeeAccountRefPresenter from './components/EmployeeAccountRefPresenter.svelte'
|
import PersonAccountRefPresenter from './components/PersonAccountRefPresenter.svelte'
|
||||||
import EmployeeArrayEditor from './components/EmployeeArrayEditor.svelte'
|
import EmployeeArrayEditor from './components/EmployeeArrayEditor.svelte'
|
||||||
import EmployeeBox from './components/EmployeeBox.svelte'
|
import EmployeeBox from './components/EmployeeBox.svelte'
|
||||||
import EmployeeBrowser from './components/EmployeeBrowser.svelte'
|
import EmployeeBrowser from './components/EmployeeBrowser.svelte'
|
||||||
@ -70,7 +70,7 @@ import MemberPresenter from './components/MemberPresenter.svelte'
|
|||||||
import Members from './components/Members.svelte'
|
import Members from './components/Members.svelte'
|
||||||
import MembersBox from './components/MembersBox.svelte'
|
import MembersBox from './components/MembersBox.svelte'
|
||||||
import MembersPresenter from './components/MembersPresenter.svelte'
|
import MembersPresenter from './components/MembersPresenter.svelte'
|
||||||
import MergeEmployee from './components/MergeEmployee.svelte'
|
import MergePersons from './components/MergePersons.svelte'
|
||||||
import OrganizationEditor from './components/OrganizationEditor.svelte'
|
import OrganizationEditor from './components/OrganizationEditor.svelte'
|
||||||
import OrganizationPresenter from './components/OrganizationPresenter.svelte'
|
import OrganizationPresenter from './components/OrganizationPresenter.svelte'
|
||||||
import PersonEditor from './components/PersonEditor.svelte'
|
import PersonEditor from './components/PersonEditor.svelte'
|
||||||
@ -121,7 +121,7 @@ export {
|
|||||||
EmployeeBrowser,
|
EmployeeBrowser,
|
||||||
MemberPresenter,
|
MemberPresenter,
|
||||||
EmployeeEditor,
|
EmployeeEditor,
|
||||||
EmployeeAccountRefPresenter,
|
PersonAccountRefPresenter,
|
||||||
MembersPresenter,
|
MembersPresenter,
|
||||||
EditPerson,
|
EditPerson,
|
||||||
EmployeeRefPresenter,
|
EmployeeRefPresenter,
|
||||||
@ -148,7 +148,7 @@ export {
|
|||||||
|
|
||||||
const toObjectSearchResult = (e: WithLookup<Contact>): ObjectSearchResult => ({
|
const toObjectSearchResult = (e: WithLookup<Contact>): ObjectSearchResult => ({
|
||||||
doc: e,
|
doc: e,
|
||||||
title: getName(e),
|
title: getName(getClient().getHierarchy(), e),
|
||||||
icon: Avatar,
|
icon: Avatar,
|
||||||
iconProps: { size: 'x-small', avatar: e.avatar },
|
iconProps: { size: 'x-small', avatar: e.avatar },
|
||||||
component: UserInfo,
|
component: UserInfo,
|
||||||
@ -171,13 +171,13 @@ async function queryEmployee (
|
|||||||
filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }
|
filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }
|
||||||
): Promise<ObjectSearchResult[]> {
|
): Promise<ObjectSearchResult[]> {
|
||||||
const q1 = await doContactQuery(
|
const q1 = await doContactQuery(
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
{ name: { $like: `%${search}%` }, active: true },
|
{ name: { $like: `%${search}%` }, active: true },
|
||||||
filter,
|
filter,
|
||||||
client
|
client
|
||||||
)
|
)
|
||||||
const q2 = await doContactQuery(
|
const q2 = await doContactQuery(
|
||||||
contact.class.Employee,
|
contact.mixin.Employee,
|
||||||
{ displayName: { $like: `%${search}%` }, active: true },
|
{ displayName: { $like: `%${search}%` }, active: true },
|
||||||
{
|
{
|
||||||
in: filter?.in,
|
in: filter?.in,
|
||||||
@ -195,7 +195,7 @@ async function doContactQuery<T extends Contact> (
|
|||||||
filter: { in?: RelatedDocument[] | undefined, nin?: RelatedDocument[] | undefined } | undefined,
|
filter: { in?: RelatedDocument[] | undefined, nin?: RelatedDocument[] | undefined } | undefined,
|
||||||
client: Client
|
client: Client
|
||||||
): Promise<ObjectSearchResult[]> {
|
): Promise<ObjectSearchResult[]> {
|
||||||
if (_class === contact.class.Employee) {
|
if (_class === contact.mixin.Employee) {
|
||||||
q = { ...q, active: true }
|
q = { ...q, active: true }
|
||||||
}
|
}
|
||||||
if (filter?.in !== undefined || filter?.nin !== undefined) {
|
if (filter?.in !== undefined || filter?.nin !== undefined) {
|
||||||
@ -210,10 +210,12 @@ async function doContactQuery<T extends Contact> (
|
|||||||
return (await client.findAll(_class, q, { limit: 200 })).map(toObjectSearchResult)
|
return (await client.findAll(_class, q, { limit: 200 })).map(toObjectSearchResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function kickEmployee (doc: Employee): Promise<void> {
|
async function kickEmployee (doc: Person): Promise<void> {
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const email = await client.findOne(contact.class.EmployeeAccount, { employee: doc._id })
|
|
||||||
if (!doc.active) {
|
const employee = client.getHierarchy().as(doc, contact.mixin.Employee)
|
||||||
|
const email = await client.findOne(contact.class.PersonAccount, { person: doc._id })
|
||||||
|
if (!employee.active) {
|
||||||
showPopup(
|
showPopup(
|
||||||
MessageBox,
|
MessageBox,
|
||||||
{
|
{
|
||||||
@ -230,7 +232,7 @@ async function kickEmployee (doc: Employee): Promise<void> {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (email === undefined) {
|
if (email === undefined) {
|
||||||
await client.update(doc, { active: false })
|
await client.update(employee, { active: false })
|
||||||
} else {
|
} else {
|
||||||
showPopup(
|
showPopup(
|
||||||
MessageBox,
|
MessageBox,
|
||||||
@ -288,7 +290,7 @@ export default async (): Promise<Resources> => ({
|
|||||||
SocialEditor,
|
SocialEditor,
|
||||||
Contacts,
|
Contacts,
|
||||||
ContactsTabs,
|
ContactsTabs,
|
||||||
EmployeeAccountPresenter,
|
PersonAccountPresenter,
|
||||||
EmployeePresenter,
|
EmployeePresenter,
|
||||||
EmployeeRefPresenter,
|
EmployeeRefPresenter,
|
||||||
Members,
|
Members,
|
||||||
@ -300,7 +302,7 @@ export default async (): Promise<Resources> => ({
|
|||||||
CreateEmployee,
|
CreateEmployee,
|
||||||
AccountArrayEditor,
|
AccountArrayEditor,
|
||||||
ChannelFilter,
|
ChannelFilter,
|
||||||
MergeEmployee,
|
MergePersons,
|
||||||
Avatar,
|
Avatar,
|
||||||
UserBoxList,
|
UserBoxList,
|
||||||
ActivityChannelMessage,
|
ActivityChannelMessage,
|
||||||
@ -312,9 +314,9 @@ export default async (): Promise<Resources> => ({
|
|||||||
UserBoxItems,
|
UserBoxItems,
|
||||||
EmployeeFilter,
|
EmployeeFilter,
|
||||||
EmployeeFilterValuePresenter,
|
EmployeeFilterValuePresenter,
|
||||||
EmployeeAccountFilterValuePresenter,
|
PersonAccountFilterValuePresenter,
|
||||||
DeleteConfirmationPopup,
|
DeleteConfirmationPopup,
|
||||||
EmployeeAccountRefPresenter
|
PersonAccountRefPresenter
|
||||||
},
|
},
|
||||||
completion: {
|
completion: {
|
||||||
EmployeeQuery: async (
|
EmployeeQuery: async (
|
||||||
|
@ -60,10 +60,11 @@ export default mergeIds(contactId, contact, {
|
|||||||
Email: '' as IntlString,
|
Email: '' as IntlString,
|
||||||
CreateEmployee: '' as IntlString,
|
CreateEmployee: '' as IntlString,
|
||||||
Inactive: '' as IntlString,
|
Inactive: '' as IntlString,
|
||||||
|
Active: '' as IntlString,
|
||||||
NotSpecified: '' as IntlString,
|
NotSpecified: '' as IntlString,
|
||||||
MergeEmployee: '' as IntlString,
|
MergePersons: '' as IntlString,
|
||||||
MergeEmployeeFrom: '' as IntlString,
|
MergePersonsFrom: '' as IntlString,
|
||||||
MergeEmployeeTo: '' as IntlString,
|
MergePersonsTo: '' as IntlString,
|
||||||
SelectAvatar: '' as IntlString,
|
SelectAvatar: '' as IntlString,
|
||||||
GravatarsManaged: '' as IntlString,
|
GravatarsManaged: '' as IntlString,
|
||||||
Through: '' as IntlString,
|
Through: '' as IntlString,
|
||||||
|
@ -18,25 +18,26 @@ import {
|
|||||||
AvatarProvider,
|
AvatarProvider,
|
||||||
AvatarType,
|
AvatarType,
|
||||||
ChannelProvider,
|
ChannelProvider,
|
||||||
Contact,
|
|
||||||
contactId,
|
|
||||||
Employee,
|
Employee,
|
||||||
EmployeeAccount,
|
Contact,
|
||||||
|
PersonAccount,
|
||||||
|
contactId,
|
||||||
formatName,
|
formatName,
|
||||||
getFirstName,
|
getFirstName,
|
||||||
getLastName,
|
getLastName,
|
||||||
getName
|
getName,
|
||||||
|
Person
|
||||||
} from '@hcengineering/contact'
|
} from '@hcengineering/contact'
|
||||||
import { Client, Doc, getCurrentAccount, IdMap, ObjQueryType, Ref, Timestamp, toIdMap } from '@hcengineering/core'
|
import { Client, Doc, IdMap, ObjQueryType, Ref, Timestamp, getCurrentAccount, toIdMap } from '@hcengineering/core'
|
||||||
|
import notification, { DocUpdateTx, DocUpdates } from '@hcengineering/notification'
|
||||||
|
import { getResource } from '@hcengineering/platform'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { TemplateDataProvider } from '@hcengineering/templates'
|
import { TemplateDataProvider } from '@hcengineering/templates'
|
||||||
import { TabItem, getCurrentResolvedLocation, getPanelURI, Location, ResolvedLocation } from '@hcengineering/ui'
|
import { Location, ResolvedLocation, TabItem, getCurrentResolvedLocation, getPanelURI } from '@hcengineering/ui'
|
||||||
import view, { Filter } from '@hcengineering/view'
|
import view, { Filter } from '@hcengineering/view'
|
||||||
import { FilterQuery } from '@hcengineering/view-resources'
|
import { FilterQuery } from '@hcengineering/view-resources'
|
||||||
import { get, writable } from 'svelte/store'
|
import { derived, get, writable } from 'svelte/store'
|
||||||
import contact from './plugin'
|
import contact from './plugin'
|
||||||
import notification, { DocUpdates, DocUpdateTx } from '@hcengineering/notification'
|
|
||||||
import { getResource } from '@hcengineering/platform'
|
|
||||||
|
|
||||||
export function formatDate (dueDateMs: Timestamp): string {
|
export function formatDate (dueDateMs: Timestamp): string {
|
||||||
return new Date(dueDateMs).toLocaleString('default', {
|
return new Date(dueDateMs).toLocaleString('default', {
|
||||||
@ -48,6 +49,7 @@ export function formatDate (dueDateMs: Timestamp): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function employeeSort (value: Array<Ref<Employee>>): Promise<Array<Ref<Employee>>> {
|
export async function employeeSort (value: Array<Ref<Employee>>): Promise<Array<Ref<Employee>>> {
|
||||||
|
const h = getClient().getHierarchy()
|
||||||
return value.sort((a, b) => {
|
return value.sort((a, b) => {
|
||||||
const employeeId1 = a as Ref<Employee> | null | undefined
|
const employeeId1 = a as Ref<Employee> | null | undefined
|
||||||
const employeeId2 = b as Ref<Employee> | null | undefined
|
const employeeId2 = b as Ref<Employee> | null | undefined
|
||||||
@ -63,8 +65,8 @@ export async function employeeSort (value: Array<Ref<Employee>>): Promise<Array<
|
|||||||
if (employeeId1 != null && employeeId2 != null) {
|
if (employeeId1 != null && employeeId2 != null) {
|
||||||
const employee1 = get(employeeByIdStore).get(employeeId1)
|
const employee1 = get(employeeByIdStore).get(employeeId1)
|
||||||
const employee2 = get(employeeByIdStore).get(employeeId2)
|
const employee2 = get(employeeByIdStore).get(employeeId2)
|
||||||
const name1 = employee1 != null ? getName(employee1) : ''
|
const name1 = employee1 != null ? getName(h, employee1) : ''
|
||||||
const name2 = employee2 != null ? getName(employee2) : ''
|
const name2 = employee2 != null ? getName(h, employee2) : ''
|
||||||
|
|
||||||
return name1.localeCompare(name2)
|
return name1.localeCompare(name2)
|
||||||
}
|
}
|
||||||
@ -137,19 +139,19 @@ export async function getRefs (
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getCurrentEmployeeName (): Promise<string> {
|
export async function getCurrentEmployeeName (): Promise<string> {
|
||||||
const me = getCurrentAccount() as EmployeeAccount
|
const me = getCurrentAccount() as PersonAccount
|
||||||
return formatName(me.name)
|
return formatName(me.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCurrentEmployeeEmail (): Promise<string> {
|
export async function getCurrentEmployeeEmail (): Promise<string> {
|
||||||
const me = getCurrentAccount() as EmployeeAccount
|
const me = getCurrentAccount() as PersonAccount
|
||||||
return me.email
|
return me.email
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCurrentEmployeePosition (): Promise<string | undefined> {
|
export async function getCurrentEmployeePosition (): Promise<string | undefined> {
|
||||||
const me = getCurrentAccount() as EmployeeAccount
|
const me = getCurrentAccount() as PersonAccount
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const employee = await client.findOne(contact.class.Employee, { _id: me.employee })
|
const employee = await client.findOne<Employee>(contact.mixin.Employee, { _id: me.person as Ref<Employee> })
|
||||||
if (employee !== undefined) {
|
if (employee !== undefined) {
|
||||||
return employee.position ?? ''
|
return employee.position ?? ''
|
||||||
}
|
}
|
||||||
@ -161,7 +163,7 @@ export async function getContactName (provider: TemplateDataProvider): Promise<s
|
|||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
if (hierarchy.isDerived(value._class, contact.class.Person)) {
|
if (hierarchy.isDerived(value._class, contact.class.Person)) {
|
||||||
return getName(value)
|
return getName(client.getHierarchy(), value)
|
||||||
} else {
|
} else {
|
||||||
return value.name
|
return value.name
|
||||||
}
|
}
|
||||||
@ -234,7 +236,7 @@ async function generateLocation (loc: Location, id: Ref<Contact>): Promise<Resol
|
|||||||
const workspace = loc.path[1] ?? ''
|
const workspace = loc.path[1] ?? ''
|
||||||
const special = client.getHierarchy().isDerived(doc._class, contact.class.Organization)
|
const special = client.getHierarchy().isDerived(doc._class, contact.class.Organization)
|
||||||
? 'companies'
|
? 'companies'
|
||||||
: client.getHierarchy().isDerived(doc._class, contact.class.Employee)
|
: client.getHierarchy().isDerived(doc._class, contact.mixin.Employee)
|
||||||
? 'employees'
|
? 'employees'
|
||||||
: 'persons'
|
: 'persons'
|
||||||
return {
|
return {
|
||||||
@ -252,33 +254,43 @@ async function generateLocation (loc: Location, id: Ref<Contact>): Promise<Resol
|
|||||||
export const employeeByIdStore = writable<IdMap<Employee>>(new Map())
|
export const employeeByIdStore = writable<IdMap<Employee>>(new Map())
|
||||||
export const employeesStore = writable<Employee[]>([])
|
export const employeesStore = writable<Employee[]>([])
|
||||||
|
|
||||||
export const employeeAccountByIdStore = writable<IdMap<EmployeeAccount>>(new Map())
|
export const personAccountByIdStore = writable<IdMap<PersonAccount>>(new Map())
|
||||||
|
|
||||||
export const channelProviders = writable<ChannelProvider[]>([])
|
export const channelProviders = writable<ChannelProvider[]>([])
|
||||||
|
|
||||||
|
export const personAccountPersonByIdStore = writable<IdMap<Person>>(new Map())
|
||||||
|
|
||||||
|
export const personByIdStore = derived([personAccountPersonByIdStore, employeeByIdStore], (vals) => {
|
||||||
|
const m1 = Array.from(vals[0].entries())
|
||||||
|
const m2 = Array.from(vals[1].entries())
|
||||||
|
return new Map([...m1, ...m2])
|
||||||
|
})
|
||||||
|
|
||||||
function fillStores (): void {
|
function fillStores (): void {
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
if (client !== undefined) {
|
if (client !== undefined) {
|
||||||
|
const accountPersonQuery = createQuery(true)
|
||||||
|
|
||||||
const query = createQuery(true)
|
const query = createQuery(true)
|
||||||
query.query(contact.class.Employee, {}, (res) => {
|
query.query(contact.mixin.Employee, {}, (res) => {
|
||||||
employeesStore.set(res)
|
employeesStore.set(res)
|
||||||
employeeByIdStore.set(toIdMap(res))
|
employeeByIdStore.set(toIdMap(res))
|
||||||
})
|
})
|
||||||
|
|
||||||
const accountQ = createQuery(true)
|
const accountQ = createQuery(true)
|
||||||
accountQ.query(contact.class.EmployeeAccount, {}, (res) => {
|
accountQ.query(contact.class.PersonAccount, {}, (res) => {
|
||||||
const mergedEmployees = res.filter((it) => it.mergedTo !== undefined)
|
personAccountByIdStore.set(toIdMap(res))
|
||||||
const activeEmployees = res.filter((it) => it.mergedTo === undefined)
|
|
||||||
const ids = toIdMap(activeEmployees)
|
const persons = res.map((it) => it.person)
|
||||||
for (const e of mergedEmployees) {
|
|
||||||
if (e.mergedTo !== undefined) {
|
accountPersonQuery.query(
|
||||||
const mergeTo = ids.get(e.mergedTo)
|
contact.class.Person,
|
||||||
if (mergeTo !== undefined) {
|
{ _id: { $in: persons }, [contact.mixin.Employee]: { $exists: false } },
|
||||||
ids.set(e._id, mergeTo)
|
(res) => {
|
||||||
}
|
personAccountPersonByIdStore.set(toIdMap(res))
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
employeeAccountByIdStore.set(ids)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const providerQuery = createQuery(true)
|
const providerQuery = createQuery(true)
|
||||||
@ -332,5 +344,5 @@ export function getAvatarProviderId (avatar?: string | null): Ref<AvatarProvider
|
|||||||
export async function contactTitleProvider (client: Client, ref: Ref<Contact>): Promise<string> {
|
export async function contactTitleProvider (client: Client, ref: Ref<Contact>): Promise<string> {
|
||||||
const object = await client.findOne(contact.class.Contact, { _id: ref })
|
const object = await client.findOne(contact.class.Contact, { _id: ref })
|
||||||
if (object === undefined) return ''
|
if (object === undefined) return ''
|
||||||
return getName(object)
|
return getName(client.getHierarchy(), object)
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,6 @@ export interface Status extends AttachedDoc {
|
|||||||
*/
|
*/
|
||||||
export interface Employee extends Person {
|
export interface Employee extends Person {
|
||||||
active: boolean
|
active: boolean
|
||||||
mergedTo?: Ref<Employee>
|
|
||||||
statuses?: number
|
statuses?: number
|
||||||
displayName?: string | null
|
displayName?: string | null
|
||||||
position?: string | null
|
position?: string | null
|
||||||
@ -147,9 +146,8 @@ export interface Employee extends Person {
|
|||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export interface EmployeeAccount extends Account {
|
export interface PersonAccount extends Account {
|
||||||
employee: Ref<Employee>
|
person: Ref<Person>
|
||||||
mergedTo?: Ref<EmployeeAccount>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,11 +178,13 @@ export const contactPlugin = plugin(contactId, {
|
|||||||
Member: '' as Ref<Class<Member>>,
|
Member: '' as Ref<Class<Member>>,
|
||||||
Organization: '' as Ref<Class<Organization>>,
|
Organization: '' as Ref<Class<Organization>>,
|
||||||
Organizations: '' as Ref<Class<Organizations>>,
|
Organizations: '' as Ref<Class<Organizations>>,
|
||||||
Employee: '' as Ref<Class<Employee>>,
|
PersonAccount: '' as Ref<Class<PersonAccount>>,
|
||||||
EmployeeAccount: '' as Ref<Class<EmployeeAccount>>,
|
|
||||||
Status: '' as Ref<Class<Status>>,
|
Status: '' as Ref<Class<Status>>,
|
||||||
ContactsTab: '' as Ref<Class<ContactsTab>>
|
ContactsTab: '' as Ref<Class<ContactsTab>>
|
||||||
},
|
},
|
||||||
|
mixin: {
|
||||||
|
Employee: '' as Ref<Class<Employee>>
|
||||||
|
},
|
||||||
component: {
|
component: {
|
||||||
SocialEditor: '' as AnyComponent,
|
SocialEditor: '' as AnyComponent,
|
||||||
CreateOrganization: '' as AnyComponent,
|
CreateOrganization: '' as AnyComponent,
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import { AttachedData, Class, Client, Doc, FindResult, Ref } from '@hcengineering/core'
|
import { AttachedData, Class, Client, Doc, FindResult, Ref, Hierarchy } from '@hcengineering/core'
|
||||||
import { IconSize } from '@hcengineering/ui'
|
import { IconSize } from '@hcengineering/ui'
|
||||||
import { MD5 } from 'crypto-js'
|
import { MD5 } from 'crypto-js'
|
||||||
import { Channel, Contact, contactPlugin, Employee, Person } from '.'
|
import { Channel, Contact, contactPlugin, Employee, Person } from '.'
|
||||||
@ -211,9 +211,9 @@ export function formatName (name: string): string {
|
|||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export function getName (value: Contact): string {
|
export function getName (hierarchy: Hierarchy, value: Contact): string {
|
||||||
if (isEmployee(value)) {
|
if (isEmployee(hierarchy, value)) {
|
||||||
return value.displayName ?? formatName(value.name)
|
return hierarchy.as(value, contactPlugin.mixin.Employee).displayName ?? formatName(value.name)
|
||||||
}
|
}
|
||||||
if (isPerson(value)) {
|
if (isPerson(value)) {
|
||||||
return formatName(value.name)
|
return formatName(value.name)
|
||||||
@ -221,8 +221,8 @@ export function getName (value: Contact): string {
|
|||||||
return value.name
|
return value.name
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEmployee (value: Contact): value is Employee {
|
function isEmployee (hierarchy: Hierarchy, value: Contact): value is Employee {
|
||||||
return value._class === contactPlugin.class.Employee
|
return hierarchy.hasMixin(value, contactPlugin.mixin.Employee)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPerson (value: Contact): value is Person {
|
function isPerson (value: Contact): value is Person {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user