mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 11:42:30 +03:00
TSK-344: Draft for new Candidate/Person etc (#2432)
This commit is contained in:
parent
fdeba8ea65
commit
2a4661748d
@ -224,7 +224,8 @@ export function createModel (builder: Builder): void {
|
|||||||
icon: contact.icon.Person,
|
icon: contact.icon.Person,
|
||||||
label: recruit.string.Talents,
|
label: recruit.string.Talents,
|
||||||
createLabel: recruit.string.TalentCreateLabel,
|
createLabel: recruit.string.TalentCreateLabel,
|
||||||
createComponent: recruit.component.CreateCandidate
|
createComponent: recruit.component.CreateCandidate,
|
||||||
|
createComponentProps: { shouldSaveDraft: true }
|
||||||
},
|
},
|
||||||
position: 'vacancy'
|
position: 'vacancy'
|
||||||
},
|
},
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
async function showSelectionPopup (e: MouseEvent) {
|
async function showSelectionPopup (e: MouseEvent) {
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
showPopup(SelectAvatarPopup, { avatar, email, id, icon, onSubmit: handlePopupSubmit })
|
showPopup(SelectAvatarPopup, { avatar, email, id, file: direct, icon, onSubmit: handlePopupSubmit })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
const [schema, uri] = avatar?.split('://') || []
|
const [schema, uri] = avatar?.split('://') || []
|
||||||
|
|
||||||
const initialSelectedType = (() => {
|
const initialSelectedType = (() => {
|
||||||
|
if (file) {
|
||||||
|
return AvatarType.IMAGE
|
||||||
|
}
|
||||||
if (!avatar) {
|
if (!avatar) {
|
||||||
return AvatarType.COLOR
|
return AvatarType.COLOR
|
||||||
}
|
}
|
||||||
@ -117,6 +120,7 @@
|
|||||||
selectedFile = undefined
|
selectedFile = undefined
|
||||||
} else {
|
} else {
|
||||||
selectedFile = blob
|
selectedFile = blob
|
||||||
|
selectedAvatarType = AvatarType.IMAGE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
if (component) {
|
if (component) {
|
||||||
action = async () => {
|
action = async () => {
|
||||||
closePopup()
|
closePopup()
|
||||||
showPopup(component, {}, 'top')
|
showPopup(component, { shouldSaveDraft: true }, 'top')
|
||||||
}
|
}
|
||||||
} else if (create) {
|
} else if (create) {
|
||||||
action = await getResource(create)
|
action = await getResource(create)
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
"Talent": "Talent",
|
"Talent": "Talent",
|
||||||
"TalentCreateLabel": "Talent",
|
"TalentCreateLabel": "Talent",
|
||||||
"CreateTalent": "New Talent",
|
"CreateTalent": "New Talent",
|
||||||
|
"CreateTalentDialogClose": "Do you want to close this dialog?",
|
||||||
|
"CreateTalentDialogCloseNote": "All changes will be lost",
|
||||||
|
"ResumeDraft": "Resume draft",
|
||||||
"AssignRecruiter": "Assign recruiter",
|
"AssignRecruiter": "Assign recruiter",
|
||||||
"UnAssignRecruiter": "Unassign recruiter",
|
"UnAssignRecruiter": "Unassign recruiter",
|
||||||
"UnAssignCompany": "Unassign Company",
|
"UnAssignCompany": "Unassign Company",
|
||||||
|
@ -17,8 +17,11 @@
|
|||||||
"CreateApplication": "Новый Кандидат",
|
"CreateApplication": "Новый Кандидат",
|
||||||
"SelectVacancy": "Выбрать вакансию",
|
"SelectVacancy": "Выбрать вакансию",
|
||||||
"Talent": "Талант",
|
"Talent": "Талант",
|
||||||
"TalentCreateLabel": "Таланта",
|
"TalentCreateLabel": "Талант",
|
||||||
"CreateTalent": "Новый Талант",
|
"CreateTalent": "Новый Талант",
|
||||||
|
"CreateTalentDialogClose": "Вы действительно хотите закрыть окно?",
|
||||||
|
"CreateTalentDialogCloseNote": "Все внесенные изменения будут потеряны",
|
||||||
|
"ResumeDraft": "Восстановить черновик",
|
||||||
"AssignRecruiter": "Назначить рекрутера",
|
"AssignRecruiter": "Назначить рекрутера",
|
||||||
"UnAssignRecruiter": "Отменить назначение рекрутера",
|
"UnAssignRecruiter": "Отменить назначение рекрутера",
|
||||||
"UnAssignCompany": "Отменить назначение компании",
|
"UnAssignCompany": "Отменить назначение компании",
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import attachment from '@hcengineering/attachment'
|
import attachment from '@hcengineering/attachment'
|
||||||
|
import { deleteFile } from '@hcengineering/attachment-resources/src/utils'
|
||||||
import contact, { Channel, ChannelProvider, combineName, findContacts, Person } from '@hcengineering/contact'
|
import contact, { Channel, ChannelProvider, combineName, findContacts, Person } from '@hcengineering/contact'
|
||||||
import { ChannelsDropdown } from '@hcengineering/contact-resources'
|
import { ChannelsDropdown } from '@hcengineering/contact-resources'
|
||||||
import PersonPresenter from '@hcengineering/contact-resources/src/components/PersonPresenter.svelte'
|
import PersonPresenter from '@hcengineering/contact-resources/src/components/PersonPresenter.svelte'
|
||||||
@ -36,10 +37,13 @@
|
|||||||
EditableAvatar,
|
EditableAvatar,
|
||||||
getClient,
|
getClient,
|
||||||
getFileUrl,
|
getFileUrl,
|
||||||
|
getUserDraft,
|
||||||
KeyedAttribute,
|
KeyedAttribute,
|
||||||
PDFViewer
|
MessageBox,
|
||||||
|
PDFViewer,
|
||||||
|
updateUserDraft
|
||||||
} from '@hcengineering/presentation'
|
} from '@hcengineering/presentation'
|
||||||
import type { Candidate } from '@hcengineering/recruit'
|
import type { Candidate, CandidateDraft } from '@hcengineering/recruit'
|
||||||
import { recognizeDocument } from '@hcengineering/rekoni'
|
import { recognizeDocument } from '@hcengineering/rekoni'
|
||||||
import tags, { findTagCategory, TagElement, TagReference } from '@hcengineering/tags'
|
import tags, { findTagCategory, TagElement, TagReference } from '@hcengineering/tags'
|
||||||
import {
|
import {
|
||||||
@ -56,24 +60,24 @@
|
|||||||
showPopup,
|
showPopup,
|
||||||
Spinner
|
Spinner
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
|
import deepEqual from 'deep-equal'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import recruit from '../plugin'
|
import recruit from '../plugin'
|
||||||
import FileUpload from './icons/FileUpload.svelte'
|
import FileUpload from './icons/FileUpload.svelte'
|
||||||
import YesNo from './YesNo.svelte'
|
import YesNo from './YesNo.svelte'
|
||||||
|
|
||||||
let firstName = ''
|
export let shouldSaveDraft: boolean = false
|
||||||
let lastName = ''
|
export let onDraftChanged: () => void
|
||||||
let createMore: boolean = false
|
|
||||||
|
|
||||||
export function canClose (): boolean {
|
const draft: CandidateDraft | undefined = shouldSaveDraft ? getUserDraft(recruit.mixin.Candidate) : undefined
|
||||||
return firstName === '' && lastName === '' && resume.uuid === undefined
|
const emptyObject = {
|
||||||
|
title: '',
|
||||||
|
city: '',
|
||||||
|
avatar: undefined,
|
||||||
|
onsite: undefined,
|
||||||
|
remote: undefined
|
||||||
}
|
}
|
||||||
|
type resumeFile = {
|
||||||
let avatarEditor: EditableAvatar
|
|
||||||
|
|
||||||
let object: Candidate = {} as Candidate
|
|
||||||
|
|
||||||
const resume = {} as {
|
|
||||||
name: string
|
name: string
|
||||||
uuid: string
|
uuid: string
|
||||||
size: number
|
size: number
|
||||||
@ -81,21 +85,58 @@
|
|||||||
lastModified: number
|
lastModified: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let candidateId = draft ? draft.candidateId : generateId()
|
||||||
|
let firstName = draft?.firstName || ''
|
||||||
|
let lastName = draft?.lastName || ''
|
||||||
|
let createMore: boolean = false
|
||||||
|
let saveTimer: number | undefined
|
||||||
|
|
||||||
|
export function canClose (): boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let avatarEditor: EditableAvatar
|
||||||
|
|
||||||
|
function toCandidate (draft: CandidateDraft | undefined): Candidate {
|
||||||
|
if (!draft) {
|
||||||
|
return emptyObject as Candidate
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
title: draft?.title || '',
|
||||||
|
city: draft?.city || '',
|
||||||
|
onsite: draft?.onsite,
|
||||||
|
remote: draft?.remote
|
||||||
|
} as Candidate
|
||||||
|
}
|
||||||
|
|
||||||
|
let object: Candidate = toCandidate(draft)
|
||||||
|
|
||||||
|
function resumeDraft () {
|
||||||
|
return {
|
||||||
|
uuid: draft?.resumeUuid,
|
||||||
|
name: draft?.resumeName,
|
||||||
|
size: draft?.resumeSize,
|
||||||
|
type: draft?.resumeType,
|
||||||
|
lastModified: draft?.resumeLastModified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let resume = resumeDraft() as resumeFile
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
let candidateId = generateId()
|
|
||||||
|
|
||||||
let inputFile: HTMLInputElement
|
let inputFile: HTMLInputElement
|
||||||
let loading = false
|
let loading = false
|
||||||
let dragover = false
|
let dragover = false
|
||||||
|
|
||||||
let avatar: File | undefined
|
let avatar: File | undefined = draft?.avatar
|
||||||
let channels: AttachedData<Channel>[] = []
|
let channels: AttachedData<Channel>[] = draft?.channels || []
|
||||||
|
|
||||||
let matches: WithLookup<Person>[] = []
|
let matches: WithLookup<Person>[] = []
|
||||||
let matchedChannels: AttachedData<Channel>[] = []
|
let matchedChannels: AttachedData<Channel>[] = []
|
||||||
|
|
||||||
let skills: TagReference[] = []
|
let skills: TagReference[] = draft?.skills || []
|
||||||
const key: KeyedAttribute = {
|
const key: KeyedAttribute = {
|
||||||
key: 'skills',
|
key: 'skills',
|
||||||
attr: client.getHierarchy().getAttribute(recruit.mixin.Candidate, 'skills')
|
attr: client.getHierarchy().getAttribute(recruit.mixin.Candidate, 'skills')
|
||||||
@ -122,6 +163,85 @@
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
$: updateDraft(object, firstName, lastName, avatar, channels, skills, resume)
|
||||||
|
|
||||||
|
async function updateDraft (...param: any) {
|
||||||
|
if (saveTimer) {
|
||||||
|
clearTimeout(saveTimer)
|
||||||
|
}
|
||||||
|
saveTimer = setTimeout(() => {
|
||||||
|
saveDraft()
|
||||||
|
}, 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveDraft () {
|
||||||
|
if (!shouldSaveDraft) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let newDraft: Data<CandidateDraft> | undefined = createDraftFromObject()
|
||||||
|
const isEmpty = await isDraftEmpty(newDraft)
|
||||||
|
|
||||||
|
if (isEmpty) {
|
||||||
|
newDraft = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUserDraft(recruit.mixin.Candidate, newDraft)
|
||||||
|
|
||||||
|
if (onDraftChanged) {
|
||||||
|
return onDraftChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDraftFromObject () {
|
||||||
|
const newDraft: Data<CandidateDraft> = {
|
||||||
|
candidateId: candidateId as Ref<Candidate>,
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
title: object.title,
|
||||||
|
city: object.city,
|
||||||
|
resumeUuid: resume?.uuid,
|
||||||
|
resumeName: resume?.name,
|
||||||
|
resumeType: resume?.type,
|
||||||
|
resumeSize: resume?.size,
|
||||||
|
resumeLastModified: resume?.lastModified,
|
||||||
|
avatar,
|
||||||
|
channels,
|
||||||
|
onsite: object.onsite,
|
||||||
|
remote: object.remote,
|
||||||
|
skills
|
||||||
|
}
|
||||||
|
|
||||||
|
return newDraft
|
||||||
|
}
|
||||||
|
|
||||||
|
async function isDraftEmpty (draft: Data<CandidateDraft>): Promise<boolean> {
|
||||||
|
const emptyDraft: Partial<CandidateDraft> = {
|
||||||
|
firstName: '',
|
||||||
|
lastName: '',
|
||||||
|
title: '',
|
||||||
|
city: '',
|
||||||
|
resumeUuid: undefined,
|
||||||
|
resumeName: undefined,
|
||||||
|
resumeType: undefined,
|
||||||
|
resumeSize: undefined,
|
||||||
|
resumeLastModified: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
channels: [],
|
||||||
|
onsite: undefined,
|
||||||
|
remote: undefined,
|
||||||
|
skills: []
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key of Object.keys(emptyDraft)) {
|
||||||
|
if (!deepEqual((emptyDraft as any)[key], (draft as any)[key])) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
async function createCandidate () {
|
async function createCandidate () {
|
||||||
const candidate: Data<Person> = {
|
const candidate: Data<Person> = {
|
||||||
name: combineName(firstName, lastName),
|
name: combineName(firstName, lastName),
|
||||||
@ -202,17 +322,11 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (createMore) {
|
if (!createMore) {
|
||||||
// Prepare for next
|
|
||||||
object = {} as Candidate
|
|
||||||
candidateId = generateId()
|
|
||||||
avatar = undefined
|
|
||||||
firstName = ''
|
|
||||||
lastName = ''
|
|
||||||
channels = []
|
|
||||||
} else {
|
|
||||||
dispatch('close', id)
|
dispatch('close', id)
|
||||||
}
|
}
|
||||||
|
resetObject()
|
||||||
|
saveDraft()
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUndef (value?: string): boolean {
|
function isUndef (value?: string): boolean {
|
||||||
@ -327,6 +441,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function deleteResume (): Promise<void> {
|
||||||
|
if (resume.uuid) {
|
||||||
|
await deleteFile(resume.uuid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function createAttachment (file: File) {
|
async function createAttachment (file: File) {
|
||||||
loading = true
|
loading = true
|
||||||
try {
|
try {
|
||||||
@ -398,6 +518,52 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const manager = createFocusManager()
|
const manager = createFocusManager()
|
||||||
|
|
||||||
|
function resetObject (): void {
|
||||||
|
object = emptyObject as Candidate
|
||||||
|
candidateId = generateId()
|
||||||
|
avatar = undefined
|
||||||
|
firstName = ''
|
||||||
|
lastName = ''
|
||||||
|
channels = []
|
||||||
|
skills = []
|
||||||
|
resume = {} as resumeFile
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function onOutsideClick () {
|
||||||
|
saveDraft()
|
||||||
|
|
||||||
|
if (onDraftChanged) {
|
||||||
|
return onDraftChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function showConfirmationDialog () {
|
||||||
|
const newDraft = createDraftFromObject()
|
||||||
|
const isFormEmpty = await isDraftEmpty(newDraft)
|
||||||
|
|
||||||
|
if (isFormEmpty) {
|
||||||
|
console.log('isFormEmpty')
|
||||||
|
dispatch('close')
|
||||||
|
} else {
|
||||||
|
showPopup(
|
||||||
|
MessageBox,
|
||||||
|
{
|
||||||
|
label: recruit.string.CreateTalentDialogClose,
|
||||||
|
message: recruit.string.CreateTalentDialogCloseNote
|
||||||
|
},
|
||||||
|
'top',
|
||||||
|
(result?: boolean) => {
|
||||||
|
if (result === true) {
|
||||||
|
dispatch('close')
|
||||||
|
deleteResume()
|
||||||
|
resetObject()
|
||||||
|
saveDraft()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FocusHandler {manager} />
|
<FocusHandler {manager} />
|
||||||
@ -409,6 +575,7 @@
|
|||||||
on:close={() => {
|
on:close={() => {
|
||||||
dispatch('close')
|
dispatch('close')
|
||||||
}}
|
}}
|
||||||
|
onCancel={showConfirmationDialog}
|
||||||
bind:createMore
|
bind:createMore
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="header">
|
<svelte:fragment slot="header">
|
||||||
|
@ -13,12 +13,19 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { isUserDraftExists } from '@hcengineering/presentation'
|
||||||
import { Button, showPopup } from '@hcengineering/ui'
|
import { Button, showPopup } from '@hcengineering/ui'
|
||||||
import recruit from '../plugin'
|
import recruit from '../plugin'
|
||||||
import CreateCandidate from './CreateCandidate.svelte'
|
import CreateCandidate from './CreateCandidate.svelte'
|
||||||
|
|
||||||
async function newIssue (): Promise<void> {
|
let draftExists: boolean = isUserDraftExists(recruit.mixin.Candidate)
|
||||||
showPopup(CreateCandidate, {}, 'top')
|
|
||||||
|
const handleDraftChanged = () => {
|
||||||
|
draftExists = isUserDraftExists(recruit.mixin.Candidate)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function newCandidate (): Promise<void> {
|
||||||
|
showPopup(CreateCandidate, { shouldSaveDraft: true, onDraftChanged: handleDraftChanged }, 'top')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -26,10 +33,29 @@
|
|||||||
<div class="flex-grow text-md">
|
<div class="flex-grow text-md">
|
||||||
<Button
|
<Button
|
||||||
icon={recruit.icon.CreateCandidate}
|
icon={recruit.icon.CreateCandidate}
|
||||||
label={recruit.string.CreateTalent}
|
label={draftExists ? recruit.string.ResumeDraft : recruit.string.CreateTalent}
|
||||||
justify={'left'}
|
justify={'left'}
|
||||||
width={'100%'}
|
width={'100%'}
|
||||||
on:click={newIssue}
|
on:click={newCandidate}
|
||||||
/>
|
>
|
||||||
|
<div slot="content" class="draft-circle-container">
|
||||||
|
{#if draftExists}
|
||||||
|
<div class="draft-circle" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.draft-circle-container {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draft-circle {
|
||||||
|
height: 6px;
|
||||||
|
width: 6px;
|
||||||
|
background-color: var(--primary-bg-color);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -48,6 +48,9 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
Talent: '' as IntlString,
|
Talent: '' as IntlString,
|
||||||
TalentCreateLabel: '' as IntlString,
|
TalentCreateLabel: '' as IntlString,
|
||||||
CreateTalent: '' as IntlString,
|
CreateTalent: '' as IntlString,
|
||||||
|
CreateTalentDialogClose: '' as IntlString,
|
||||||
|
CreateTalentDialogCloseNote: '' as IntlString,
|
||||||
|
ResumeDraft: '' as IntlString,
|
||||||
AssignRecruiter: '' as IntlString,
|
AssignRecruiter: '' as IntlString,
|
||||||
Recruiters: '' as IntlString,
|
Recruiters: '' as IntlString,
|
||||||
UnAssignRecruiter: '' as IntlString,
|
UnAssignRecruiter: '' as IntlString,
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
"@hcengineering/chunter": "~0.6.1",
|
"@hcengineering/chunter": "~0.6.1",
|
||||||
"@hcengineering/task": "~0.6.0",
|
"@hcengineering/task": "~0.6.0",
|
||||||
"@hcengineering/calendar": "~0.6.1",
|
"@hcengineering/calendar": "~0.6.1",
|
||||||
"@hcengineering/ui": "^0.6.2"
|
"@hcengineering/ui": "^0.6.2",
|
||||||
|
"@hcengineering/tags": "~0.6.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,13 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import { Event } from '@hcengineering/calendar'
|
import { Event } from '@hcengineering/calendar'
|
||||||
import type { Organization, Person } from '@hcengineering/contact'
|
import type { Channel, Organization, Person } from '@hcengineering/contact'
|
||||||
import type { AttachedDoc, Class, Doc, Mixin, Ref, Space, Timestamp } from '@hcengineering/core'
|
import type { AttachedData, AttachedDoc, Class, Doc, Mixin, Ref, Space, Timestamp } from '@hcengineering/core'
|
||||||
import type { Asset, Plugin } from '@hcengineering/platform'
|
import type { Asset, Plugin } from '@hcengineering/platform'
|
||||||
import { plugin } from '@hcengineering/platform'
|
import { plugin } from '@hcengineering/platform'
|
||||||
import type { KanbanTemplateSpace, SpaceWithStates, Task } from '@hcengineering/task'
|
import type { KanbanTemplateSpace, SpaceWithStates, Task } from '@hcengineering/task'
|
||||||
import { AnyComponent } from '@hcengineering/ui'
|
import { AnyComponent } from '@hcengineering/ui'
|
||||||
|
import { TagReference } from '@hcengineering/tags'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -58,6 +59,27 @@ export interface Candidate extends Person {
|
|||||||
reviews?: number
|
reviews?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface CandidateDraft extends Doc {
|
||||||
|
candidateId: Ref<Candidate>
|
||||||
|
firstName?: string
|
||||||
|
lastName?: string
|
||||||
|
title?: string
|
||||||
|
city: string
|
||||||
|
resumeUuid?: string
|
||||||
|
resumeName?: string
|
||||||
|
resumeSize?: number
|
||||||
|
resumeType?: string
|
||||||
|
resumeLastModified?: number
|
||||||
|
avatar?: File | undefined
|
||||||
|
channels: AttachedData<Channel>[]
|
||||||
|
onsite?: boolean
|
||||||
|
remote?: boolean
|
||||||
|
skills: TagReference[]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
|
@ -43,7 +43,7 @@ test.describe('recruit tests', () => {
|
|||||||
// Click :nth-match(:text("Cancel"), 2)
|
// Click :nth-match(:text("Cancel"), 2)
|
||||||
// await page.click('button:has-text("Cancel")')
|
// await page.click('button:has-text("Cancel")')
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
await page.keyboard.press('Escape')
|
// await page.keyboard.press('Escape')
|
||||||
// Click button:has-text("Create")
|
// Click button:has-text("Create")
|
||||||
await page.click('button:has-text("Create")')
|
await page.click('button:has-text("Create")')
|
||||||
await page.waitForSelector('form.antiCard', { state: 'detached' })
|
await page.waitForSelector('form.antiCard', { state: 'detached' })
|
||||||
|
Loading…
Reference in New Issue
Block a user