Employee email channel (#2711)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov
2023-03-06 15:51:41 +07:00
committed by GitHub
parent 5696f216ca
commit 3179d122b8
9 changed files with 114 additions and 24 deletions
+32
View File
@@ -101,6 +101,37 @@ async function setCreate (client: MigrationClient): Promise<void> {
}
}
async function createEmployeeEmail (client: TxOperations): Promise<void> {
const employees = await client.findAll(contact.class.Employee, {})
const channels = await client.findAll(contact.class.Channel, {
provider: contact.channelProvider.Email,
attachedTo: { $in: employees.map((p) => p._id) }
})
const channelsMap = new Map(channels.map((p) => [p.attachedTo, p]))
for (const employee of employees) {
const acc = await client.findOne(contact.class.EmployeeAccount, { employee: employee._id })
if (acc === undefined) continue
const current = channelsMap.get(employee._id)
if (current === undefined) {
await client.addCollection(
contact.class.Channel,
contact.space.Contacts,
employee._id,
contact.class.Employee,
'channels',
{
provider: contact.channelProvider.Email,
value: acc.email.trim()
},
undefined,
employee.modifiedOn
)
} else if (current.value !== acc.email.trim()) {
await client.update(current, { value: acc.email.trim() }, false, current.modifiedOn)
}
}
}
export const contactOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
await setCreate(client)
@@ -108,5 +139,6 @@ export const contactOperation: MigrateOperation = {
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createSpace(tx)
await createEmployeeEmail(tx)
}
}
+13
View File
@@ -856,6 +856,19 @@ async function synchronizeUsers (
employee: employeeId,
role: AccountRole.User
})
if (u.EMAIL !== undefined && u.EMAIL !== null) {
await ops.client.addCollection(
contact.class.Channel,
contact.space.Contacts,
employeeId,
contact.class.Employee,
'channels',
{
provider: contact.channelProvider.Email,
value: u.EMAIL.trim()
}
)
}
await ops.client.createMixin<Doc, BitrixSyncDoc>(
employeeId,
contact.class.Employee,
@@ -47,6 +47,7 @@
export let shape: 'circle' | undefined = undefined
export let integrations: Set<Ref<Doc>> = new Set<Ref<Doc>>()
export let focusIndex = -1
export let restricted: Ref<ChannelProvider>[] = []
const notificationClient = NotificationClientImpl.getClient()
const lastViews = notificationClient.getLastViews()
@@ -263,7 +264,7 @@
{shape}
highlight={item.integration || item.notification}
on:click={(ev) => {
if (editable) {
if (editable && !restricted.includes(item.provider)) {
closeTooltip()
editChannel(eventToHTMLElement(ev), i, item)
} else {
@@ -34,6 +34,7 @@
export let size: ButtonSize = 'small'
export let length: 'short' | 'full' = 'full'
export let shape: 'circle' | undefined = 'circle'
export let restricted: Ref<ChannelProvider>[] = []
let channels: Channel[] = []
@@ -123,6 +124,7 @@
{length}
{integrations}
{editable}
{restricted}
{shape}
{focusIndex}
on:change={(e) => {
@@ -40,6 +40,7 @@
const client = getClient()
async function createPerson () {
changeEmail()
const name = combineName(firstName, lastName)
const person: Data<Employee> = {
createOn: Date.now(),
@@ -68,7 +69,12 @@
dispatch('close')
}
let channels: AttachedData<Channel>[] = []
let channels: AttachedData<Channel>[] = [
{
provider: contact.channelProvider.Email,
value: ''
}
]
let matches: Person[] = []
$: findPerson(client, { ...object, name: combineName(firstName, lastName) }, channels).then((p) => {
@@ -76,6 +82,19 @@
})
const manager = createFocusManager()
function changeEmail () {
const index = channels.findIndex((p) => p.provider === contact.channelProvider.Email)
if (index !== -1) {
channels[index].value = email.trim()
} else {
channels.push({
provider: contact.channelProvider.Email,
value: email.trim()
})
}
channels = channels
}
</script>
<FocusHandler {manager} />
@@ -115,7 +134,13 @@
focusIndex={2}
/>
<div class="mt-1">
<EditBox placeholder={contact.string.Email} bind:value={email} kind={'small-style'} focusIndex={3} />
<EditBox
placeholder={contact.string.Email}
bind:value={email}
kind={'small-style'}
focusIndex={3}
on:blur={changeEmail}
/>
</div>
</div>
<div class="ml-4">
@@ -123,6 +148,12 @@
</div>
</div>
<svelte:fragment slot="pool">
<ChannelsDropdown bind:value={channels} focusIndex={10} kind={'no-border'} editable />
<ChannelsDropdown
bind:value={channels}
focusIndex={10}
kind={'no-border'}
editable
restricted={[contact.channelProvider.Email]}
/>
</svelte:fragment>
</Card>
@@ -128,7 +128,13 @@
/>
</div>
<div class="separator" />
<ChannelsEditor attachedTo={employee._id} attachedClass={employee._class} focusIndex={10} allowOpen={false} />
<ChannelsEditor
attachedTo={employee._id}
attachedClass={employee._class}
focusIndex={10}
allowOpen={false}
restricted={[contact.channelProvider.Email]}
/>
</div>
</div>
{/if}
+5 -1
View File
@@ -583,12 +583,16 @@ async function createEmployee (ops: TxOperations, name: string, email: string):
avatar: `${AvatarType.COLOR}://${getAvatarColorForId(id)}`
})
}
await ops.addCollection(contact.class.Channel, contact.space.Contacts, id, contact.class.Employee, 'channels', {
provider: contact.channelProvider.Email,
value: email.trim()
})
return id
}
async function createEmployeeAccount (account: Account, productId: string, workspace: string): Promise<void> {
const connection = await connect(getTransactor(), getWorkspaceId(workspace, productId), account.email)
const connection = await connect(getTransactor(), getWorkspaceId(workspace, productId))
try {
const ops = new TxOperations(connection, core.account.System)
+15 -13
View File
@@ -39,24 +39,26 @@ export class ModifiedMiddleware extends BaseMiddleware implements Middleware {
}
async tx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> {
tx.modifiedOn = Date.now()
if (this.storage.hierarchy.isDerived(tx._class, core.class.TxCreateDoc)) {
const createTx = tx as TxCreateDoc<Doc & { createOn: Timestamp }>
const hasCreateOn = this.storage.hierarchy.findAttribute(createTx.objectClass, 'createOn')
if (hasCreateOn !== undefined) {
createTx.attributes.createOn = tx.modifiedOn
}
}
if (this.storage.hierarchy.isDerived(tx._class, core.class.TxCollectionCUD)) {
const coltx = tx as TxCollectionCUD<Doc, AttachedDoc>
coltx.tx.modifiedOn = tx.modifiedOn
if (this.storage.hierarchy.isDerived(coltx.tx._class, core.class.TxCreateDoc)) {
const createTx = coltx.tx as TxCreateDoc<AttachedDoc & { createOn: Timestamp }>
if (tx.modifiedBy !== core.account.System) {
tx.modifiedOn = Date.now()
if (this.storage.hierarchy.isDerived(tx._class, core.class.TxCreateDoc)) {
const createTx = tx as TxCreateDoc<Doc & { createOn: Timestamp }>
const hasCreateOn = this.storage.hierarchy.findAttribute(createTx.objectClass, 'createOn')
if (hasCreateOn !== undefined) {
createTx.attributes.createOn = tx.modifiedOn
}
}
if (this.storage.hierarchy.isDerived(tx._class, core.class.TxCollectionCUD)) {
const coltx = tx as TxCollectionCUD<Doc, AttachedDoc>
coltx.tx.modifiedOn = tx.modifiedOn
if (this.storage.hierarchy.isDerived(coltx.tx._class, core.class.TxCreateDoc)) {
const createTx = coltx.tx as TxCreateDoc<AttachedDoc & { createOn: Timestamp }>
const hasCreateOn = this.storage.hierarchy.findAttribute(createTx.objectClass, 'createOn')
if (hasCreateOn !== undefined) {
createTx.attributes.createOn = tx.modifiedOn
}
}
}
}
return await this.provideTx(ctx, tx)
}
+4 -5
View File
@@ -25,14 +25,13 @@ test.describe('contact tests', () => {
await page.fill('[placeholder="Location"]', 'LoPlaza')
// Click .flex-center.icon-button
if ((await page.locator('[id="gmail:string:Email"]').count()) === 0) {
if ((await page.locator('[id="contact:string:Phone"]').count()) === 0) {
await page.click('[id="presentation:string:AddSocialLinks"]')
await page.click('.popup button:has-text("Email")')
await page.click('.popup button:has-text("Phone")')
} else {
await page.click('id=gmail:string:Email')
await page.click('id=contact:string:Phone')
}
// await page.hover('[id="gmail:string:Email"]')
await page.fill('[placeholder="john\\.appleseed\\@apple\\.com"]', 'wer@qwe.com')
await page.fill('[placeholder="+1 555 333 7777"]', '+1 555 333 7777')
// Click text=Apply
await page.click('.editor-container button:nth-child(3)')
})