Allow create employee (#2179)

Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
This commit is contained in:
Denis Bykhov 2022-06-30 16:26:31 +06:00 committed by GitHub
parent 55aa3a5292
commit 643544c4cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 176 additions and 9 deletions

View File

@ -6,6 +6,7 @@ Core:
- Allow to leave workspace
- Allow to kick employee
- Allow to create employee
HR:

View File

@ -10622,13 +10622,15 @@ packages:
dev: false
file:projects/contact-resources.tgz_1e3963ebf0ceeb25b2fa6a1cc87e253c:
resolution: {integrity: sha512-emAawKeZ3rkJfH0KM59uoKyBBjXhxQkDlOuZhAHgpyCwK/6aJysXuVNTtg5IpqKo6ug3GQWhp1QUWWyIpr7SPQ==, tarball: file:projects/contact-resources.tgz}
resolution: {integrity: sha512-b2YgdY2vY4E+zM1fRAgN8qc+ofFdYr8dY1RE6n4Iz5aXvzhoc/2EQyHgYyquA330Pl8/iZTb7kRB9XbcIPwaIA==, tarball: file:projects/contact-resources.tgz}
id: file:projects/contact-resources.tgz
name: '@rush-temp/contact-resources'
version: 0.0.0
dependencies:
'@types/email-addresses': 3.0.0
'@typescript-eslint/eslint-plugin': 5.27.0_738fa17fa57f8a69ace69c90e5cfa1d5
'@typescript-eslint/parser': 5.27.0_eslint@7.32.0+typescript@4.7.2
email-addresses: 5.0.0
eslint: 7.32.0
eslint-config-standard-with-typescript: 21.0.1_99a5fe2f2ae1dc64d6b59974c931eb2a
eslint-plugin-import: 2.26.0_c21022bc9feaeb7b200d3d631eeae46c
@ -11448,13 +11450,15 @@ packages:
dev: false
file:projects/login-resources.tgz_1e3963ebf0ceeb25b2fa6a1cc87e253c:
resolution: {integrity: sha512-z/UZS/JzqzigMk6IlK5Bqj/85K9Rto2HujvHzvID+jYKQ23YnuWjNbHm+8s8R4DXh42vpjeSTwi6RxtS+VWzZQ==, tarball: file:projects/login-resources.tgz}
resolution: {integrity: sha512-THKHVmV1AWGGi/FemAYNCxemKXLSu8Bg0/0x5nmNVeh0YG0V0YRSteBPHL3EZTAOYBGS0VKZPZ5hOChnkHXb0Q==, tarball: file:projects/login-resources.tgz}
id: file:projects/login-resources.tgz
name: '@rush-temp/login-resources'
version: 0.0.0
dependencies:
'@types/email-addresses': 3.0.0
'@typescript-eslint/eslint-plugin': 5.27.0_738fa17fa57f8a69ace69c90e5cfa1d5
'@typescript-eslint/parser': 5.27.0_eslint@7.32.0+typescript@4.7.2
email-addresses: 5.0.0
eslint: 7.32.0
eslint-config-standard-with-typescript: 21.0.1_99a5fe2f2ae1dc64d6b59974c931eb2a
eslint-plugin-import: 2.26.0_c21022bc9feaeb7b200d3d631eeae46c
@ -11694,7 +11698,7 @@ packages:
dev: false
file:projects/model-contact.tgz_typescript@4.7.2:
resolution: {integrity: sha512-YcuQBjpqHjvTwBbcYHoBgM+b1VwMPsd3Wei4GLhHL2uOF6TKUG1bbz3z/p3kv/SwMrDVszOxUD1LkNHb+x5oNA==, tarball: file:projects/model-contact.tgz}
resolution: {integrity: sha512-we/DHl9Mt7a5yNpFYCF7RI5OKFtpAejWzOqp7quGzgNLDsloZSJFrzlR6T7Txez2dKA8L5p3IIWRv2oYtgxwaA==, tarball: file:projects/model-contact.tgz}
id: file:projects/model-contact.tgz
name: '@rush-temp/model-contact'
version: 0.0.0
@ -14606,7 +14610,7 @@ packages:
dev: false
file:projects/tracker-resources.tgz_1e3963ebf0ceeb25b2fa6a1cc87e253c:
resolution: {integrity: sha512-bNqQvwzdPa61s2z+M0xrwW5bSvv46yBY8BXt6cqKEHwp1Zv78P5NHU/ScAgVRuJSvwknhrykBK1mK7zghMr3Hg==, tarball: file:projects/tracker-resources.tgz}
resolution: {integrity: sha512-ShvJGnS3CzpTi2IxUX5oAe18j2CwHXnDl5PDYeQg4uSLw9CpOTx02zcBr/xmstZNwRaj5QBl6+ua7rE0eYRFbQ==, tarball: file:projects/tracker-resources.tgz}
id: file:projects/tracker-resources.tgz
name: '@rush-temp/tracker-resources'
version: 0.0.0

View File

@ -157,6 +157,10 @@ export function createModel (builder: Builder): void {
TMember
)
builder.mixin(contact.class.Employee, core.class.Class, view.mixin.ObjectFactory, {
component: contact.component.CreateEmployee
})
builder.mixin(contact.class.Person, core.class.Class, view.mixin.ObjectFactory, {
component: contact.component.CreatePerson
})

View File

@ -40,7 +40,8 @@ export default mergeIds(contactId, contact, {
MemberPresenter: '' as AnyComponent,
EditMember: '' as AnyComponent,
EmployeeArrayEditor: '' as AnyComponent,
EmployeeEditor: '' as AnyComponent
EmployeeEditor: '' as AnyComponent,
CreateEmployee: '' as AnyComponent
},
string: {
Persons: '' as IntlString,

View File

@ -65,6 +65,8 @@
"NoMembers": "No members added",
"AddMember": "Add member",
"KickEmployee": "Kick an employee",
"KickEmployeeDescr": "Are you sure you want to kick the employee out of the workspace? This action cannot be undone"
"KickEmployeeDescr": "Are you sure you want to kick the employee out of the workspace? This action cannot be undone",
"Email": "Email",
"CreateEmployee": "Create an employee"
}
}

View File

@ -65,6 +65,8 @@
"NoMembers": "Нет добавленных сотрудников",
"AddMember": "Добавить сотрудника",
"KickEmployee": "Исключить сотрудника",
"KickEmployeeDescr": "Вы действительно хотите выгнать сотрудника из рабочего пространства? Это действие нельзя отменить"
"KickEmployeeDescr": "Вы действительно хотите выгнать сотрудника из рабочего пространства? Это действие нельзя отменить",
"Email": "Email",
"CreateEmployee": "Создать сотрудника"
}
}

View File

@ -0,0 +1,149 @@
<!--
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import attachment from '@anticrm/attachment'
import { Channel, combineName, Employee, findPerson, Person } from '@anticrm/contact'
import core, { AttachedData, Data, generateId, Ref } from '@anticrm/core'
import { getResource } from '@anticrm/platform'
import { Card, EditableAvatar, getClient } from '@anticrm/presentation'
import { EditBox, IconInfo, Label, createFocusManager, FocusHandler } from '@anticrm/ui'
import { createEventDispatcher } from 'svelte'
import { ChannelsDropdown } from '..'
import contact from '../plugin'
import PersonPresenter from './PersonPresenter.svelte'
let firstName = ''
let lastName = ''
let email = ''
const id: Ref<Employee> = generateId()
export function canClose (): boolean {
return firstName === '' && lastName === '' && email === ''
}
const object: Employee = {} as Employee
const dispatch = createEventDispatcher()
const client = getClient()
let avatar: File | undefined
function onAvatarDone (e: any) {
const { file } = e.detail
avatar = file
}
function removeAvatar (): void {
avatar = undefined
}
async function createPerson () {
const name = combineName(firstName, lastName)
const person: Data<Employee> = {
name,
city: object.city,
active: true
}
if (avatar !== undefined) {
const uploadFile = await getResource(attachment.helper.UploadFile)
person.avatar = await uploadFile(avatar)
}
await client.createDoc(contact.class.Employee, contact.space.Contacts, person, id)
await client.createDoc(contact.class.EmployeeAccount, core.space.Model, {
email: email.trim(),
name,
employee: id
})
for (const channel of channels) {
await client.addCollection(contact.class.Channel, contact.space.Contacts, id, contact.class.Person, 'channels', {
value: channel.value,
provider: channel.provider
})
}
dispatch('close')
}
let channels: AttachedData<Channel>[] = []
let matches: Person[] = []
$: findPerson(client, { ...object, name: combineName(firstName, lastName) }, channels).then((p) => {
matches = p
})
const manager = createFocusManager()
</script>
<FocusHandler {manager} />
<Card
label={contact.string.CreateEmployee}
okAction={createPerson}
canSave={firstName.trim().length > 0 && lastName.trim().length > 0 && matches.length === 0 && email.trim().length > 0}
on:close={() => {
dispatch('close')
}}
>
<svelte:fragment slot="error">
{#if matches.length > 0}
<div class="flex-row-center error-color">
<IconInfo size={'small'} />
<span class="text-sm overflow-label ml-2">
<Label label={contact.string.PersonAlreadyExists} />
</span>
<div class="ml-4"><PersonPresenter value={matches[0]} /></div>
</div>
{/if}
</svelte:fragment>
<div class="flex-row-center">
<div class="flex-grow flex-col">
<EditBox
placeholder={contact.string.PersonFirstNamePlaceholder}
bind:value={firstName}
kind={'large-style'}
maxWidth={'32rem'}
focus
focusIndex={1}
/>
<EditBox
placeholder={contact.string.PersonLastNamePlaceholder}
bind:value={lastName}
kind={'large-style'}
maxWidth={'32rem'}
focusIndex={2}
/>
<div class="mt-1">
<EditBox
placeholder={contact.string.Email}
bind:value={email}
kind={'small-style'}
maxWidth={'32rem'}
focusIndex={3}
/>
</div>
</div>
<div class="ml-4">
<EditableAvatar avatar={object.avatar} size={'large'} on:done={onAvatarDone} on:remove={removeAvatar} />
</div>
</div>
<svelte:fragment slot="pool">
<ChannelsDropdown bind:value={channels} focusIndex={10} kind={'no-border'} editable />
</svelte:fragment>
</Card>

View File

@ -47,6 +47,7 @@ import MemberPresenter from './components/MemberPresenter.svelte'
import EditMember from './components/EditMember.svelte'
import EmployeeArrayEditor from './components/EmployeeArrayEditor.svelte'
import EmployeeEditor from './components/EmployeeEditor.svelte'
import CreateEmployee from './components/CreateEmployee.svelte'
import { leaveWorkspace } from '@anticrm/login-resources'
export {
@ -122,7 +123,8 @@ export default async (): Promise<Resources> => ({
MemberPresenter,
EditMember,
EmployeeArrayEditor,
EmployeeEditor
EmployeeEditor,
CreateEmployee
},
completion: {
EmployeeQuery: async (client: Client, query: string) => await queryContact(contact.class.Employee, client, query),

View File

@ -58,6 +58,8 @@ export default mergeIds(contactId, contact, {
NoMembers: '' as IntlString,
AddMember: '' as IntlString,
KickEmployee: '' as IntlString,
KickEmployeeDescr: '' as IntlString
KickEmployeeDescr: '' as IntlString,
Email: '' as IntlString,
CreateEmployee: '' as IntlString
}
})