From 7128585f05596bdfa96a27f2807b710c98db547c Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Fri, 17 May 2024 16:56:00 +0500 Subject: [PATCH] Send emails to applicants action (#5615) Signed-off-by: Denis Bykhov --- models/chunter/src/index.ts | 1 - models/document/src/index.ts | 1 - models/gmail/src/index.ts | 1 - models/guest/src/utils.ts | 1 - models/hr/src/index.ts | 1 - models/lead/src/index.ts | 1 - models/notification/src/index.ts | 3 --- models/recruit/package.json | 1 + models/recruit/src/index.ts | 33 +++++++++++++++++++------- models/recruit/src/plugin.ts | 13 ++++++++-- models/time/src/index.ts | 3 --- models/tracker/src/actions.ts | 12 ---------- models/workbench/src/index.ts | 1 - plugins/recruit-resources/src/index.ts | 30 +++++++++++++++++++++-- 14 files changed, 65 insertions(+), 37 deletions(-) diff --git a/models/chunter/src/index.ts b/models/chunter/src/index.ts index 4d8e84ac50..20bbbe89c2 100644 --- a/models/chunter/src/index.ts +++ b/models/chunter/src/index.ts @@ -433,7 +433,6 @@ export function createModel (builder: Builder): void { }, label: chunter.string.CopyLink, icon: chunter.icon.Copy, - keyBinding: [], input: 'none', category: chunter.category.Chunter, target: activity.class.ActivityMessage, diff --git a/models/document/src/index.ts b/models/document/src/index.ts index 6bf8a7b0f4..dcea580104 100644 --- a/models/document/src/index.ts +++ b/models/document/src/index.ts @@ -361,7 +361,6 @@ function defineDocument (builder: Builder): void { }, label: document.string.CopyDocumentUrl, icon: view.icon.CopyLink, - keyBinding: [], input: 'focus', category: document.category.Document, target: document.class.Document, diff --git a/models/gmail/src/index.ts b/models/gmail/src/index.ts index 4a2102a8cd..e320a7d45e 100644 --- a/models/gmail/src/index.ts +++ b/models/gmail/src/index.ts @@ -233,7 +233,6 @@ export function createModel (builder: Builder): void { label: gmail.string.WriteEmail, icon: contact.icon.Email, visibilityTester: gmail.function.HasEmail, - keyBinding: [], input: 'any', category: contact.category.Contact, target: contact.class.Contact, diff --git a/models/guest/src/utils.ts b/models/guest/src/utils.ts index 828f35bb5e..705c6f4c12 100644 --- a/models/guest/src/utils.ts +++ b/models/guest/src/utils.ts @@ -18,7 +18,6 @@ export function createPublicLinkAction (builder: Builder, _class: Ref }, label: guest.string.PublicLink, icon: guest.icon.Link, - keyBinding: [], input: 'any', category: guest.category.Guest, target: _class, diff --git a/models/hr/src/index.ts b/models/hr/src/index.ts index 914cf818d4..9a0d2403e7 100644 --- a/models/hr/src/index.ts +++ b/models/hr/src/index.ts @@ -448,7 +448,6 @@ export function createModel (builder: Builder): void { }, label: hr.string.Department, icon: hr.icon.Department, - keyBinding: [], input: 'none', category: hr.category.HR, target: hr.mixin.Staff, diff --git a/models/lead/src/index.ts b/models/lead/src/index.ts index 5059a81ae8..c303e0a705 100644 --- a/models/lead/src/index.ts +++ b/models/lead/src/index.ts @@ -589,7 +589,6 @@ export function createModel (builder: Builder): void { }, label: lead.string.CreateLead, icon: lead.icon.Lead, - keyBinding: [], input: 'none', category: lead.category.Lead, target: core.class.Doc, diff --git a/models/notification/src/index.ts b/models/notification/src/index.ts index 469ec9f1ff..f3e3045f24 100644 --- a/models/notification/src/index.ts +++ b/models/notification/src/index.ts @@ -624,7 +624,6 @@ export function createModel (builder: Builder): void { action: notification.actionImpl.ArchiveAll, label: notification.string.ArchiveAll, icon: view.icon.CheckCircle, - keyBinding: [], input: 'none', category: notification.category.Notification, target: core.class.Doc, @@ -642,7 +641,6 @@ export function createModel (builder: Builder): void { action: notification.actionImpl.ReadAll, label: notification.string.MarkReadAll, icon: view.icon.Eye, - keyBinding: [], input: 'none', category: notification.category.Notification, target: core.class.Doc, @@ -660,7 +658,6 @@ export function createModel (builder: Builder): void { action: notification.actionImpl.UnreadAll, label: notification.string.MarkUnreadAll, icon: view.icon.EyeCrossed, - keyBinding: [], input: 'none', category: notification.category.Notification, target: core.class.Doc, diff --git a/models/recruit/package.json b/models/recruit/package.json index 6cf66ee992..360e8081ef 100644 --- a/models/recruit/package.json +++ b/models/recruit/package.json @@ -42,6 +42,7 @@ "@hcengineering/model-notification": "^0.6.0", "@hcengineering/model-presentation": "^0.6.0", "@hcengineering/model-tags": "^0.6.0", + "@hcengineering/model-gmail": "^0.6.0", "@hcengineering/model-task": "^0.6.0", "@hcengineering/model-tracker": "^0.6.0", "@hcengineering/model-view": "^0.6.0", diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 29df2da6d9..c1e6c7aaa9 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -33,6 +33,7 @@ import { type IntlString } from '@hcengineering/platform' import { recruitId, type Applicant } from '@hcengineering/recruit' import setting from '@hcengineering/setting' import { type KeyBinding, type ViewOptionModel, type ViewOptionsModel } from '@hcengineering/view' +import gmail from '@hcengineering/model-gmail' import recruit from './plugin' import { createReviewModel, reviewTableConfig, reviewTableOptions } from './review' @@ -988,7 +989,6 @@ export function createModel (builder: Builder): void { }, label: recruit.string.CreateVacancy, icon: recruit.icon.Create, - keyBinding: [], input: 'none', category: recruit.category.Recruit, target: core.class.Doc, @@ -1009,7 +1009,6 @@ export function createModel (builder: Builder): void { }, label: recruit.string.CreateApplication, icon: recruit.icon.Create, - keyBinding: [], input: 'none', category: recruit.category.Recruit, target: core.class.Doc, @@ -1164,7 +1163,6 @@ export function createModel (builder: Builder): void { }, label: recruit.string.AssignRecruiter, icon: contact.icon.Person, - keyBinding: [], input: 'none', category: recruit.category.Recruit, target: recruit.class.Applicant, @@ -1205,7 +1203,6 @@ export function createModel (builder: Builder): void { }, label: recruit.string.CopyId, icon: view.icon.CopyId, - keyBinding: [], input: 'none', category: recruit.category.Recruit, target: recruit.class.Applicant, @@ -1226,7 +1223,6 @@ export function createModel (builder: Builder): void { }, label: recruit.string.CopyLink, icon: view.icon.CopyLink, - keyBinding: [], input: 'none', category: recruit.category.Recruit, target: recruit.class.Applicant, @@ -1247,7 +1243,6 @@ export function createModel (builder: Builder): void { }, label: recruit.string.CopyLink, icon: view.icon.CopyLink, - keyBinding: [], input: 'none', category: recruit.category.Recruit, target: recruit.class.Vacancy, @@ -1469,7 +1464,6 @@ export function createModel (builder: Builder): void { }, input: 'any', category: recruit.category.Recruit, - keyBinding: [], target: recruit.mixin.Candidate, context: { mode: ['context', 'browser'], @@ -1538,7 +1532,6 @@ export function createModel (builder: Builder): void { }, label: recruit.string.GetTalentIds, icon: view.icon.CopyId, - keyBinding: [], input: 'any', category: recruit.category.Recruit, target: recruit.mixin.Candidate, @@ -1551,5 +1544,29 @@ export function createModel (builder: Builder): void { recruit.action.GetTalentIds ) + createAction( + builder, + { + action: view.actionImpl.ShowPopup, + actionProps: { + component: gmail.component.NewMessages, + element: 'float', + fillProps: { + attachedTo: 'value' + } + }, + label: gmail.string.WriteEmail, + icon: contact.icon.Email, + visibilityTester: recruit.function.ApplicantHasEmail, + input: 'any', + category: recruit.category.Recruit, + target: recruit.class.Applicant, + context: { + mode: ['context', 'browser'] + } + }, + recruit.action.WriteEmail + ) + defineSpaceType(builder) } diff --git a/models/recruit/src/plugin.ts b/models/recruit/src/plugin.ts index 3033d275df..3a12398d44 100644 --- a/models/recruit/src/plugin.ts +++ b/models/recruit/src/plugin.ts @@ -21,7 +21,14 @@ import { recruitId } from '@hcengineering/recruit' import recruit from '@hcengineering/recruit-resources/src/plugin' import { type TaskTypeDescriptor, type ProjectType } from '@hcengineering/task' import type { AnyComponent, Location } from '@hcengineering/ui/src/types' -import type { Action, ActionCategory, ViewAction, ViewQueryAction, Viewlet } from '@hcengineering/view' +import type { + Action, + ActionCategory, + ViewAction, + ViewActionAvailabilityFunction, + ViewQueryAction, + Viewlet +} from '@hcengineering/view' import { type DocUpdateMessageViewlet } from '@hcengineering/activity' import { type ChatMessageViewlet } from '@hcengineering/chunter' @@ -34,6 +41,7 @@ export default mergeIds(recruitId, recruit, { CopyCandidateLink: '' as Ref>, MoveApplicant: '' as Ref, GetTalentIds: '' as Ref>, + WriteEmail: '' as Ref>, EditStatuses: '' as Ref }, actionImpl: { @@ -49,7 +57,8 @@ export default mergeIds(recruitId, recruit, { GetObjectLink: '' as Resource<(doc: Doc, props: Record) => Promise>, GetTalentId: '' as Resource<(doc: Doc, props: Record) => Promise>, HideDoneState: '' as ViewQueryAction, - HideArchivedVacancies: '' as ViewQueryAction + HideArchivedVacancies: '' as ViewQueryAction, + ApplicantHasEmail: '' as Resource }, string: { ApplicationsShort: '' as IntlString, diff --git a/models/time/src/index.ts b/models/time/src/index.ts index 7bbd8666e9..33be2f0f91 100644 --- a/models/time/src/index.ts +++ b/models/time/src/index.ts @@ -255,7 +255,6 @@ export function createModel (builder: Builder): void { }, label: time.string.CreateToDo, icon: time.icon.Calendar, - keyBinding: [], input: 'none', category: time.category.Time, target: core.class.Doc, @@ -281,7 +280,6 @@ export function createModel (builder: Builder): void { }, label: time.string.CreateToDo, icon: time.icon.Calendar, - keyBinding: [], input: 'none', category: time.category.Time, target: core.class.Doc, @@ -303,7 +301,6 @@ export function createModel (builder: Builder): void { }, label: time.string.EditToDo, icon: view.icon.Edit, - keyBinding: [], input: 'focus', category: time.category.Time, target: time.class.ToDo, diff --git a/models/tracker/src/actions.ts b/models/tracker/src/actions.ts index 6532142f97..14ff64464e 100644 --- a/models/tracker/src/actions.ts +++ b/models/tracker/src/actions.ts @@ -233,7 +233,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.NewIssue, icon: tracker.icon.NewIssue, - keyBinding: [], input: 'none', category: tracker.category.Tracker, target: core.class.Doc, @@ -259,7 +258,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.NewSubIssue, icon: tracker.icon.Subissue, - keyBinding: [], input: 'focus', category: tracker.category.Tracker, target: tracker.class.Issue, @@ -285,7 +283,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.SetParent, icon: tracker.icon.Parent, - keyBinding: [], input: 'none', category: tracker.category.Tracker, target: tracker.class.Issue, @@ -312,7 +309,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.NewRelatedIssue, icon: tracker.icon.NewIssue, - keyBinding: [], input: 'focus', category: tracker.category.Tracker, target: core.class.Doc, @@ -336,7 +332,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.SetParent, icon: tracker.icon.Parent, - keyBinding: [], input: 'none', category: tracker.category.Tracker, target: tracker.class.Issue, @@ -582,7 +577,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.CopyIssueId, icon: view.icon.CopyId, - keyBinding: [], input: 'focus', category: tracker.category.Tracker, target: tracker.class.Issue, @@ -603,7 +597,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.CopyIssueTitle, icon: tracker.icon.CopyBranch, - keyBinding: [], input: 'focus', category: tracker.category.Tracker, target: tracker.class.Issue, @@ -624,7 +617,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.CopyIssueUrl, icon: view.icon.CopyLink, - keyBinding: [], input: 'focus', category: tracker.category.Tracker, target: tracker.class.Issue, @@ -642,7 +634,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: action: tracker.actionImpl.Move, label: tracker.string.MoveToProject, icon: view.icon.Move, - keyBinding: [], input: 'any', category: tracker.category.Tracker, target: tracker.class.Issue, @@ -665,7 +656,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.Relations, icon: tracker.icon.Relations, - keyBinding: [], input: 'focus', category: tracker.category.Tracker, target: tracker.class.Issue, @@ -691,7 +681,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.Duplicate, icon: tracker.icon.Duplicate, - keyBinding: [], input: 'focus', category: tracker.category.Tracker, target: tracker.class.Issue, @@ -736,7 +725,6 @@ export function createActions (builder: Builder, issuesId: string, componentsId: }, label: tracker.string.MapRelatedIssues, icon: tracker.icon.Relations, - keyBinding: [], input: 'none', category: tracker.category.Tracker, target: core.class.Space, diff --git a/models/workbench/src/index.ts b/models/workbench/src/index.ts index d34b25d364..253d5c0783 100644 --- a/models/workbench/src/index.ts +++ b/models/workbench/src/index.ts @@ -79,7 +79,6 @@ export function createModel (builder: Builder): void { }, label: getEmbeddedLabel('Server statistics'), icon: view.icon.Configure, - keyBinding: [], input: 'none', category: view.category.General, target: core.class.Doc, diff --git a/plugins/recruit-resources/src/index.ts b/plugins/recruit-resources/src/index.ts index 49ff9555b4..3bb1af6dd1 100644 --- a/plugins/recruit-resources/src/index.ts +++ b/plugins/recruit-resources/src/index.ts @@ -24,8 +24,9 @@ import { type RelatedDocument } from '@hcengineering/core' import { OK, Severity, Status, type Resources } from '@hcengineering/platform' -import { createQuery, type ObjectSearchResult } from '@hcengineering/presentation' +import { createQuery, getClient, type ObjectSearchResult } from '@hcengineering/presentation' import { type Applicant, type Candidate, type Vacancy } from '@hcengineering/recruit' +import contact from '@hcengineering/contact' import task from '@hcengineering/task' import { showPopup } from '@hcengineering/ui' import { type Filter } from '@hcengineering/view' @@ -316,6 +317,30 @@ export async function hideArchivedVacancies (value: any, query: DocumentQuery { + if (doc === undefined) return false + const client = getClient() + const applicants = Array.isArray(doc) ? (doc as Applicant[]) : ([doc] as Applicant[]) + const hierarchy = client.getHierarchy() + for (const app of applicants) { + if (!hierarchy.isDerived(app._class, recruit.class.Applicant)) return false + } + const ids = applicants.map((p) => p.attachedTo) + const res = await client.findAll( + contact.class.Channel, + { + provider: contact.channelProvider.Email, + attachedTo: { $in: ids } + }, + { projection: { _id: 1, attachedTo: 1 } } + ) + const set = new Set(res.map((p) => p.attachedTo)) + for (const val of ids) { + if (!set.has(val)) return false + } + return true +} + export default async (): Promise => ({ actionImpl: { CreateOpinion: createOpinion, @@ -385,7 +410,8 @@ export default async (): Promise => ({ GetObjectLinkFragment: getSequenceLink, GetIdObjectLinkFragment: getObjectLink, HideDoneState: hideDoneState, - HideArchivedVacancies: hideArchivedVacancies + HideArchivedVacancies: hideArchivedVacancies, + ApplicantHasEmail: applicantHasEmail }, resolver: { Location: resolveLocation