TSK-1682: Slightly reorganized recruit files for future changes (#5196)

Signed-off-by: Petr Vyazovetskiy <develop.pit@gmail.com>
This commit is contained in:
Pete Anøther 2024-04-05 07:59:35 -03:00 committed by GitHub
parent c9b4fa16fd
commit ceac67f3a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 360 additions and 347 deletions

View File

@ -13,188 +13,44 @@
// limitations under the License.
//
import type { Employee, Organization } from '@hcengineering/contact'
import { IndexKind, type Lookup, type Ref, SortingOrder, type Status, type Timestamp } from '@hcengineering/core'
import {
type Builder,
Collection,
Hidden,
Index,
Mixin,
Model,
Prop,
ReadOnly,
TypeBoolean,
TypeCollaborativeMarkup,
TypeDate,
TypeMarkup,
TypeRef,
TypeString,
UX
} from '@hcengineering/model'
import activity from '@hcengineering/activity'
import { type Lookup, type Ref, SortingOrder } from '@hcengineering/core'
import { type Builder } from '@hcengineering/model'
import attachment from '@hcengineering/model-attachment'
import calendar from '@hcengineering/model-calendar'
import chunter from '@hcengineering/model-chunter'
import contact, { TOrganization, TPerson } from '@hcengineering/model-contact'
import core, { TAttachedDoc, TSpace } from '@hcengineering/model-core'
import contact from '@hcengineering/model-contact'
import core from '@hcengineering/model-core'
import { generateClassNotificationTypes } from '@hcengineering/model-notification'
import presentation from '@hcengineering/model-presentation'
import tags from '@hcengineering/model-tags'
import task, { DOMAIN_TASK, TProject, TTask, actionTemplates } from '@hcengineering/model-task'
import task, { actionTemplates } from '@hcengineering/model-task'
import tracker from '@hcengineering/model-tracker'
import view, { createAction, showColorsViewOption, actionTemplates as viewTemplates } from '@hcengineering/model-view'
import view, { actionTemplates as viewTemplates, createAction, showColorsViewOption } from '@hcengineering/model-view'
import workbench, { type Application, createNavigateAction } from '@hcengineering/model-workbench'
import notification from '@hcengineering/notification'
import { type IntlString, getEmbeddedLabel } from '@hcengineering/platform'
import {
type Applicant,
type ApplicantMatch,
type Candidate,
type Candidates,
type Vacancy,
type VacancyList,
recruitId
} from '@hcengineering/recruit'
import { type IntlString } from '@hcengineering/platform'
import { type Applicant, recruitId } from '@hcengineering/recruit'
import setting from '@hcengineering/setting'
import { type KeyBinding, type ViewOptionModel, type ViewOptionsModel } from '@hcengineering/view'
import activity from '@hcengineering/activity'
import recruit from './plugin'
import { createReviewModel, reviewTableConfig, reviewTableOptions } from './review'
import { TOpinion, TReview } from './review-model'
import {
TApplicant,
TApplicantMatch,
TCandidate,
TCandidates,
TOpinion,
TReview,
TVacancy,
TVacancyList
} from './types'
export { recruitId } from '@hcengineering/recruit'
export { recruitOperation } from './migration'
export { default } from './plugin'
@Model(recruit.class.Vacancy, task.class.Project)
@UX(recruit.string.Vacancy, recruit.icon.Vacancy, 'VCN', 'name', undefined, recruit.string.Vacancies)
export class TVacancy extends TProject implements Vacancy {
@Prop(TypeCollaborativeMarkup(), recruit.string.FullDescription)
@Index(IndexKind.FullText)
fullDescription?: string
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files })
attachments?: number
@Prop(TypeDate(), recruit.string.Due, recruit.icon.Calendar)
dueTo?: Timestamp
@Prop(TypeString(), recruit.string.Location, recruit.icon.Location)
@Index(IndexKind.FullText)
location?: string
@Prop(TypeRef(contact.class.Organization), recruit.string.Company, { icon: contact.icon.Company })
company?: Ref<Organization>
@Prop(Collection(chunter.class.ChatMessage), chunter.string.Comments)
comments?: number
@Prop(TypeString(), recruit.string.Vacancy)
@Index(IndexKind.FullText)
@Hidden()
number!: number
}
@Model(recruit.class.Candidates, core.class.Space)
@UX(recruit.string.TalentPools, recruit.icon.RecruitApplication)
export class TCandidates extends TSpace implements Candidates {}
@Mixin(recruit.mixin.Candidate, contact.class.Person)
@UX(recruit.string.Talent, recruit.icon.RecruitApplication, 'TLNT', 'name', undefined, recruit.string.Talents)
export class TCandidate extends TPerson implements Candidate {
@Prop(TypeString(), recruit.string.Title)
@Index(IndexKind.FullText)
title?: string
@Prop(Collection(recruit.class.Applicant), recruit.string.Applications, {
shortLabel: recruit.string.ApplicationsShort
})
applications?: number
@Prop(TypeBoolean(), recruit.string.Onsite)
onsite?: boolean
@Prop(TypeBoolean(), recruit.string.Remote)
remote?: boolean
@Prop(TypeString(), recruit.string.Source)
@Index(IndexKind.FullText)
source?: string
@Prop(Collection(tags.class.TagReference, recruit.string.SkillLabel), recruit.string.SkillsLabel, {
icon: recruit.icon.Skills,
schema: '3'
})
skills?: number
@Prop(Collection(recruit.class.Review, recruit.string.Review), recruit.string.Reviews)
reviews?: number
@Prop(
Collection(recruit.class.ApplicantMatch, getEmbeddedLabel('Vacancy match')),
getEmbeddedLabel('Vacancy Matches')
)
vacancyMatch?: number
}
@Mixin(recruit.mixin.VacancyList, contact.class.Organization)
@UX(recruit.string.VacancyList, recruit.icon.RecruitApplication, 'CM', 'name')
export class TVacancyList extends TOrganization implements VacancyList {
@Prop(Collection(recruit.class.Vacancy), recruit.string.Vacancies)
vacancies!: number
}
@Model(recruit.class.Applicant, task.class.Task)
@UX(recruit.string.Application, recruit.icon.Application, 'APP', 'number', undefined, recruit.string.Applications)
export class TApplicant extends TTask implements Applicant {
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.mixin.Candidate), recruit.string.Talent)
@Index(IndexKind.Indexed)
@ReadOnly()
declare attachedTo: Ref<Candidate>
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.class.Vacancy), recruit.string.Vacancy)
@Index(IndexKind.Indexed)
declare space: Ref<Vacancy>
@Prop(TypeDate(), task.string.StartDate)
startDate!: Timestamp | null
@Prop(TypeRef(contact.mixin.Employee), recruit.string.AssignedRecruiter)
@Index(IndexKind.Indexed)
declare assignee: Ref<Employee> | null
@Prop(TypeRef(core.class.Status), task.string.TaskState, { _id: recruit.attribute.State })
@Index(IndexKind.Indexed)
declare status: Ref<Status>
}
@Model(recruit.class.ApplicantMatch, core.class.AttachedDoc, DOMAIN_TASK)
@UX(recruit.string.Application, recruit.icon.Application, 'APP', 'number')
export class TApplicantMatch extends TAttachedDoc implements ApplicantMatch {
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.mixin.Candidate), recruit.string.Talent)
@Index(IndexKind.Indexed)
declare attachedTo: Ref<Candidate>
@Prop(TypeBoolean(), getEmbeddedLabel('Complete'))
@ReadOnly()
complete!: boolean
@Prop(TypeString(), getEmbeddedLabel('Vacancy'))
@ReadOnly()
vacancy!: string
@Prop(TypeString(), getEmbeddedLabel('Summary'))
@ReadOnly()
summary!: string
@Prop(TypeMarkup(), getEmbeddedLabel('Response'))
@ReadOnly()
response!: string
}
export * from './types'
export function createModel (builder: Builder): void {
builder.createModel(TVacancy, TCandidates, TCandidate, TApplicant, TReview, TOpinion, TVacancyList, TApplicantMatch)

View File

@ -1,59 +0,0 @@
import { type Organization } from '@hcengineering/contact'
import { type Domain, IndexKind, type Ref } from '@hcengineering/core'
import { Collection, Index, Model, Prop, TypeMarkup, TypeRef, TypeString, UX } from '@hcengineering/model'
import attachment from '@hcengineering/model-attachment'
import calendar, { TEvent } from '@hcengineering/model-calendar'
import contact from '@hcengineering/model-contact'
import core, { TAttachedDoc } from '@hcengineering/model-core'
import task from '@hcengineering/model-task'
import { type Applicant, type Candidate, type Opinion, type Review } from '@hcengineering/recruit'
import chunter from '@hcengineering/model-chunter'
import recruit from './plugin'
@Model(recruit.class.Review, calendar.class.Event)
@UX(recruit.string.Review, recruit.icon.Review, 'RVE', 'number', undefined, recruit.string.Reviews)
export class TReview extends TEvent implements Review {
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.mixin.Candidate), recruit.string.Talent)
declare attachedTo: Ref<Candidate>
@Prop(TypeString(), recruit.string.Review)
number!: number
@Prop(TypeString(), recruit.string.Verdict)
@Index(IndexKind.FullText)
verdict!: string
@Prop(TypeRef(recruit.class.Applicant), recruit.string.Application, { icon: recruit.icon.Application })
application?: Ref<Applicant>
@Prop(TypeRef(contact.class.Organization), recruit.string.Company, { icon: contact.icon.Company })
company?: Ref<Organization>
@Prop(Collection(recruit.class.Opinion), recruit.string.Opinions)
opinions?: number
}
@Model(recruit.class.Opinion, core.class.AttachedDoc, 'recruit' as Domain)
@UX(recruit.string.Opinion, recruit.icon.Opinion, 'OPE')
export class TOpinion extends TAttachedDoc implements Opinion {
@Prop(TypeString(), task.string.TaskNumber)
number!: number
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.class.Review), recruit.string.Review)
declare attachedTo: Ref<Review>
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files })
attachments?: number
@Prop(Collection(chunter.class.ChatMessage), chunter.string.Comments)
comments?: number
@Prop(TypeMarkup(), recruit.string.Description)
description!: string
@Prop(TypeString(), recruit.string.OpinionValue)
value!: string
}

228
models/recruit/src/types.ts Normal file
View File

@ -0,0 +1,228 @@
//
// Copyright © 2024 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.
//
import type { Employee, Organization } from '@hcengineering/contact'
import { type Domain, IndexKind, type Ref, type Status, type Timestamp } from '@hcengineering/core'
import {
Collection,
Hidden,
Index,
Mixin,
Model,
Prop,
ReadOnly,
TypeBoolean,
TypeCollaborativeMarkup,
TypeDate,
TypeMarkup,
TypeRef,
TypeString,
UX
} from '@hcengineering/model'
import attachment from '@hcengineering/model-attachment'
import calendar, { TEvent } from '@hcengineering/model-calendar'
import chunter from '@hcengineering/model-chunter'
import contact, { TOrganization, TPerson } from '@hcengineering/model-contact'
import core, { TAttachedDoc, TSpace } from '@hcengineering/model-core'
import tags from '@hcengineering/model-tags'
import task, { DOMAIN_TASK, TProject, TTask } from '@hcengineering/model-task'
import { getEmbeddedLabel } from '@hcengineering/platform'
import type {
Applicant,
ApplicantMatch,
Candidate,
Candidates,
Opinion,
Review,
Vacancy,
VacancyList
} from '@hcengineering/recruit'
import recruit from './plugin'
@Model(recruit.class.Vacancy, task.class.Project)
@UX(recruit.string.Vacancy, recruit.icon.Vacancy, 'VCN', 'name', undefined, recruit.string.Vacancies)
export class TVacancy extends TProject implements Vacancy {
@Prop(TypeCollaborativeMarkup(), recruit.string.FullDescription)
@Index(IndexKind.FullText)
fullDescription?: string
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files })
attachments?: number
@Prop(TypeDate(), recruit.string.Due, recruit.icon.Calendar)
dueTo?: Timestamp
@Prop(TypeString(), recruit.string.Location, recruit.icon.Location)
@Index(IndexKind.FullText)
location?: string
@Prop(TypeRef(contact.class.Organization), recruit.string.Company, { icon: contact.icon.Company })
company?: Ref<Organization>
@Prop(Collection(chunter.class.ChatMessage), chunter.string.Comments)
comments?: number
@Prop(TypeString(), recruit.string.Vacancy)
@Index(IndexKind.FullText)
@Hidden()
number!: number
}
@Model(recruit.class.Candidates, core.class.Space)
@UX(recruit.string.TalentPools, recruit.icon.RecruitApplication)
export class TCandidates extends TSpace implements Candidates {}
@Mixin(recruit.mixin.Candidate, contact.class.Person)
@UX(recruit.string.Talent, recruit.icon.RecruitApplication, 'TLNT', 'name', undefined, recruit.string.Talents)
export class TCandidate extends TPerson implements Candidate {
@Prop(TypeString(), recruit.string.Title)
@Index(IndexKind.FullText)
title?: string
@Prop(Collection(recruit.class.Applicant), recruit.string.Applications, {
shortLabel: recruit.string.ApplicationsShort
})
applications?: number
@Prop(TypeBoolean(), recruit.string.Onsite)
onsite?: boolean
@Prop(TypeBoolean(), recruit.string.Remote)
remote?: boolean
@Prop(TypeString(), recruit.string.Source)
@Index(IndexKind.FullText)
source?: string
@Prop(Collection(tags.class.TagReference, recruit.string.SkillLabel), recruit.string.SkillsLabel, {
icon: recruit.icon.Skills,
schema: '3'
})
skills?: number
@Prop(Collection(recruit.class.Review, recruit.string.Review), recruit.string.Reviews)
reviews?: number
@Prop(
Collection(recruit.class.ApplicantMatch, getEmbeddedLabel('Vacancy match')),
getEmbeddedLabel('Vacancy Matches')
)
vacancyMatch?: number
}
@Mixin(recruit.mixin.VacancyList, contact.class.Organization)
@UX(recruit.string.VacancyList, recruit.icon.RecruitApplication, 'CM', 'name')
export class TVacancyList extends TOrganization implements VacancyList {
@Prop(Collection(recruit.class.Vacancy), recruit.string.Vacancies)
vacancies!: number
}
@Model(recruit.class.Applicant, task.class.Task)
@UX(recruit.string.Application, recruit.icon.Application, 'APP', 'number', undefined, recruit.string.Applications)
export class TApplicant extends TTask implements Applicant {
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.mixin.Candidate), recruit.string.Talent)
@Index(IndexKind.Indexed)
@ReadOnly()
declare attachedTo: Ref<Candidate>
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.class.Vacancy), recruit.string.Vacancy)
@Index(IndexKind.Indexed)
declare space: Ref<Vacancy>
@Prop(TypeDate(), task.string.StartDate)
startDate!: Timestamp | null
@Prop(TypeRef(contact.mixin.Employee), recruit.string.AssignedRecruiter)
@Index(IndexKind.Indexed)
declare assignee: Ref<Employee> | null
@Prop(TypeRef(core.class.Status), task.string.TaskState, { _id: recruit.attribute.State })
@Index(IndexKind.Indexed)
declare status: Ref<Status>
}
@Model(recruit.class.ApplicantMatch, core.class.AttachedDoc, DOMAIN_TASK)
@UX(recruit.string.Application, recruit.icon.Application, 'APP', 'number')
export class TApplicantMatch extends TAttachedDoc implements ApplicantMatch {
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.mixin.Candidate), recruit.string.Talent)
@Index(IndexKind.Indexed)
declare attachedTo: Ref<Candidate>
@Prop(TypeBoolean(), getEmbeddedLabel('Complete'))
@ReadOnly()
complete!: boolean
@Prop(TypeString(), getEmbeddedLabel('Vacancy'))
@ReadOnly()
vacancy!: string
@Prop(TypeString(), getEmbeddedLabel('Summary'))
@ReadOnly()
summary!: string
@Prop(TypeMarkup(), getEmbeddedLabel('Response'))
@ReadOnly()
response!: string
}
@Model(recruit.class.Review, calendar.class.Event)
@UX(recruit.string.Review, recruit.icon.Review, 'RVE', 'number', undefined, recruit.string.Reviews)
export class TReview extends TEvent implements Review {
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.mixin.Candidate), recruit.string.Talent)
declare attachedTo: Ref<Candidate>
@Prop(TypeString(), recruit.string.Review)
number!: number
@Prop(TypeString(), recruit.string.Verdict)
@Index(IndexKind.FullText)
verdict!: string
@Prop(TypeRef(recruit.class.Applicant), recruit.string.Application, { icon: recruit.icon.Application })
application?: Ref<Applicant>
@Prop(TypeRef(contact.class.Organization), recruit.string.Company, { icon: contact.icon.Company })
company?: Ref<Organization>
@Prop(Collection(recruit.class.Opinion), recruit.string.Opinions)
opinions?: number
}
@Model(recruit.class.Opinion, core.class.AttachedDoc, 'recruit' as Domain)
@UX(recruit.string.Opinion, recruit.icon.Opinion, 'OPE')
export class TOpinion extends TAttachedDoc implements Opinion {
@Prop(TypeString(), task.string.TaskNumber)
number!: number
// We need to declare, to provide property with label
@Prop(TypeRef(recruit.class.Review), recruit.string.Review)
declare attachedTo: Ref<Review>
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files })
attachments?: number
@Prop(Collection(chunter.class.ChatMessage), chunter.string.Comments)
comments?: number
@Prop(TypeMarkup(), recruit.string.Description)
description!: string
@Prop(TypeString(), recruit.string.OpinionValue)
value!: string
}

View File

@ -13,134 +13,15 @@
// limitations under the License.
//
import { Calendar, Event } from '@hcengineering/calendar'
import type { Channel, Organization, Person } from '@hcengineering/contact'
import type {
AttachedData,
AttachedDoc,
Attribute,
Class,
Doc,
Mixin,
Ref,
Space,
Status,
Timestamp
} from '@hcengineering/core'
import { Calendar } from '@hcengineering/calendar'
import type { Attribute, Class, Doc, Mixin, Ref, Status } from '@hcengineering/core'
import type { Asset, IntlString, Plugin, Resource } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import { TagReference } from '@hcengineering/tags'
import type { Project, ProjectTypeDescriptor, Task, TaskType } from '@hcengineering/task'
import type { ProjectTypeDescriptor, TaskType } from '@hcengineering/task'
import { AnyComponent, ResolvedLocation } from '@hcengineering/ui'
import type { Applicant, ApplicantMatch, Candidate, Candidates, Opinion, Review, Vacancy, VacancyList } from './types'
/**
* @public
*/
export interface Vacancy extends Project {
fullDescription?: string
attachments?: number
dueTo?: Timestamp
location?: string
company?: Ref<Organization>
comments?: number
number: number
}
/**
* @public
*/
export interface VacancyList extends Organization {
vacancies: number
}
/**
* @public
*/
export interface Candidates extends Space {}
/**
* @public
*/
export interface Candidate extends Person {
title?: string
applications?: number
onsite?: boolean
remote?: boolean
source?: string
skills?: number
reviews?: number
}
/**
* @public
*/
export interface CandidateDraft {
_id: 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
*/
export interface Applicant extends Task {
space: Ref<Vacancy>
attachedTo: Ref<Candidate>
status: Ref<Status>
startDate: Timestamp | null
}
/**
* @public
*/
export interface ApplicantMatch extends AttachedDoc {
attachedTo: Ref<Candidate>
complete: boolean
vacancy: string
summary: string
response: string
}
/**
* @public
*/
export interface Review extends Event {
attachedTo: Ref<Candidate>
number: number
verdict: string
application?: Ref<Applicant>
company?: Ref<Organization>
opinions?: number
}
/**
* @public
*/
export interface Opinion extends AttachedDoc {
number: number
attachedTo: Ref<Review>
comments?: number
attachments?: number
description: string
value: string
}
export * from './types'
/**
* @public

View File

@ -0,0 +1,107 @@
//
// Copyright © 2024 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.
//
import { Event } from '@hcengineering/calendar'
import type { Channel, Organization, Person } from '@hcengineering/contact'
import type { AttachedData, AttachedDoc, Ref, Space, Status, Timestamp } from '@hcengineering/core'
import { TagReference } from '@hcengineering/tags'
import type { Project, Task } from '@hcengineering/task'
/** @public */
export interface Candidates extends Space {}
/** @public */
export interface Vacancy extends Project {
fullDescription?: string
attachments?: number
dueTo?: Timestamp
location?: string
company?: Ref<Organization>
comments?: number
number: number
}
/** @public */
export interface VacancyList extends Organization {
vacancies: number
}
/** @public */
export interface Candidate extends Person {
title?: string
applications?: number
onsite?: boolean
remote?: boolean
source?: string
skills?: number
reviews?: number
}
/** @public */
export interface CandidateDraft {
_id: 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 */
export interface Applicant extends Task {
space: Ref<Vacancy>
attachedTo: Ref<Candidate>
status: Ref<Status>
startDate: Timestamp | null
}
/** @public */
export interface ApplicantMatch extends AttachedDoc {
attachedTo: Ref<Candidate>
complete: boolean
vacancy: string
summary: string
response: string
}
/** @public */
export interface Review extends Event {
attachedTo: Ref<Candidate>
number: number
verdict: string
application?: Ref<Applicant>
company?: Ref<Organization>
opinions?: number
}
/** @public */
export interface Opinion extends AttachedDoc {
number: number
attachedTo: Ref<Review>
comments?: number
attachments?: number
description: string
value: string
}