diff --git a/models/contact/src/index.ts b/models/contact/src/index.ts index d5ae6dcfe1..7197e4e78c 100644 --- a/models/contact/src/index.ts +++ b/models/contact/src/index.ts @@ -364,6 +364,10 @@ export function createModel (builder: Builder): void { presenter: contact.component.PersonPresenter }) + builder.mixin(core.class.Account, core.class.Class, view.mixin.ArrayEditor, { + inlineEditor: contact.component.AccountArrayEditor + }) + builder.mixin(core.class.Account, core.class.Class, view.mixin.AttributePresenter, { presenter: contact.component.EmployeeAccountPresenter }) @@ -388,9 +392,13 @@ export function createModel (builder: Builder): void { filters: ['_class', 'city', 'modifiedOn'] }) - builder.mixin(contact.class.Contact, core.class.Class, setting.mixin.Editable, {}) + builder.mixin(contact.class.Contact, core.class.Class, setting.mixin.Editable, { + value: true + }) - builder.mixin(contact.class.Member, core.class.Class, setting.mixin.Editable, {}) + builder.mixin(contact.class.Member, core.class.Class, setting.mixin.Editable, { + value: true + }) builder.createDoc( presentation.class.ObjectSearchCategory, diff --git a/models/contact/src/plugin.ts b/models/contact/src/plugin.ts index c9dcf29872..28b57cad60 100644 --- a/models/contact/src/plugin.ts +++ b/models/contact/src/plugin.ts @@ -41,7 +41,8 @@ export default mergeIds(contactId, contact, { EditMember: '' as AnyComponent, EmployeeArrayEditor: '' as AnyComponent, EmployeeEditor: '' as AnyComponent, - CreateEmployee: '' as AnyComponent + CreateEmployee: '' as AnyComponent, + AccountArrayEditor: '' as AnyComponent }, string: { Persons: '' as IntlString, diff --git a/models/core/src/component.ts b/models/core/src/component.ts index 6b4567baeb..080bbde1b9 100644 --- a/models/core/src/component.ts +++ b/models/core/src/component.ts @@ -21,6 +21,7 @@ export default mergeIds(coreId, core, { Private: '' as IntlString, Archived: '' as IntlString, ClassLabel: '' as IntlString, - ClassPropertyLabel: '' as IntlString + ClassPropertyLabel: '' as IntlString, + Members: '' as IntlString } }) diff --git a/models/core/src/security.ts b/models/core/src/security.ts index d8a02ea13d..25a4470c86 100644 --- a/models/core/src/security.ts +++ b/models/core/src/security.ts @@ -14,7 +14,7 @@ // import { Account, AccountRole, Arr, Domain, DOMAIN_MODEL, IndexKind, Ref, Space } from '@anticrm/core' -import { Index, Model, Prop, TypeBoolean, TypeString, UX } from '@anticrm/model' +import { ArrOf, Index, Model, Prop, TypeBoolean, TypeRef, TypeString, UX } from '@anticrm/model' import core from './component' import { TDoc } from './core' @@ -39,6 +39,7 @@ export class TSpace extends TDoc implements Space { @Prop(TypeBoolean(), core.string.Archived) archived!: boolean + @Prop(ArrOf(TypeRef(core.class.Account)), core.string.Members) members!: Arr> } diff --git a/models/inventory/src/index.ts b/models/inventory/src/index.ts index a94ea21f01..e3aff6922b 100644 --- a/models/inventory/src/index.ts +++ b/models/inventory/src/index.ts @@ -95,7 +95,9 @@ export function createModel (builder: Builder): void { editor: inventory.component.EditProduct }) - builder.mixin(inventory.class.Product, core.class.Class, setting.mixin.Editable, {}) + builder.mixin(inventory.class.Product, core.class.Class, setting.mixin.Editable, { + value: true + }) builder.createDoc( view.class.Viewlet, diff --git a/models/lead/src/index.ts b/models/lead/src/index.ts index 595b136aed..4891f8bc3d 100644 --- a/models/lead/src/index.ts +++ b/models/lead/src/index.ts @@ -93,7 +93,9 @@ export function createModel (builder: Builder): void { editor: lead.component.EditFunnel }) - builder.mixin(lead.class.Lead, core.class.Class, setting.mixin.Editable, {}) + builder.mixin(lead.class.Lead, core.class.Class, setting.mixin.Editable, { + value: true + }) builder.createDoc( workbench.class.Application, diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 0d5a91270f..7b7f450e21 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -16,6 +16,7 @@ import type { Employee, Organization } from '@anticrm/contact' import { Doc, FindOptions, IndexKind, Lookup, Ref, Timestamp } from '@anticrm/core' import { + ArrOf, Builder, Collection, Index, @@ -32,17 +33,17 @@ import { import attachment from '@anticrm/model-attachment' import calendar from '@anticrm/model-calendar' import chunter from '@anticrm/model-chunter' -import contact, { TPerson } from '@anticrm/model-contact' +import contact, { TOrganization, TPerson } from '@anticrm/model-contact' import core, { TSpace } from '@anticrm/model-core' import presentation from '@anticrm/model-presentation' import tags from '@anticrm/model-tags' -import task, { TSpaceWithStates, TTask, actionTemplates } from '@anticrm/model-task' -import view, { createAction, actionTemplates as viewTemplates } from '@anticrm/model-view' +import task, { actionTemplates, TSpaceWithStates, TTask } from '@anticrm/model-task' +import view, { actionTemplates as viewTemplates, createAction } from '@anticrm/model-view' import workbench, { Application, createNavigateAction } from '@anticrm/model-workbench' import { IntlString } from '@anticrm/platform' -import { Applicant, Candidate, Candidates, recruitId, Vacancy } from '@anticrm/recruit' -import { KeyBinding } from '@anticrm/view' +import { Applicant, Candidate, Candidates, recruitId, Vacancy, VacancyList } from '@anticrm/recruit' import setting from '@anticrm/setting' +import { KeyBinding } from '@anticrm/view' import recruit from './plugin' import { createReviewModel, reviewTableConfig, reviewTableOptions } from './review' import { TOpinion, TReview } from './review-model' @@ -69,6 +70,9 @@ export class TVacancy extends TSpaceWithStates implements Vacancy { @Prop(Collection(chunter.class.Comment), chunter.string.Comments) comments?: number + + @Prop(Collection(chunter.class.Backlink), chunter.string.Comments) + relations!: number } @Model(recruit.class.Candidates, core.class.Space) @@ -102,6 +106,13 @@ export class TCandidate extends TPerson implements Candidate { reviews?: number } +@Mixin(recruit.mixin.VacancyList, contact.class.Organization) +@UX(recruit.string.VacancyList, recruit.icon.RecruitApplication, undefined, 'name') +export class TVacancyList extends TOrganization implements VacancyList { + @Prop(ArrOf(TypeRef(recruit.class.Vacancy)), recruit.string.Vacancies) + vacancies!: number +} + @Model(recruit.class.Applicant, task.class.Task) @UX(recruit.string.Application, recruit.icon.Application, recruit.string.ApplicationShort, 'number') export class TApplicant extends TTask implements Applicant { @@ -126,7 +137,7 @@ export class TApplicant extends TTask implements Applicant { } export function createModel (builder: Builder): void { - builder.createModel(TVacancy, TCandidates, TCandidate, TApplicant, TReview, TOpinion) + builder.createModel(TVacancy, TCandidates, TCandidate, TApplicant, TReview, TOpinion, TVacancyList) builder.mixin(recruit.class.Vacancy, core.class.Class, workbench.mixin.SpaceView, { view: { @@ -140,13 +151,24 @@ export function createModel (builder: Builder): void { editor: recruit.component.Applications }) + builder.mixin(recruit.class.Vacancy, core.class.Class, view.mixin.ArrayEditor, { + editor: recruit.component.VacancyList + }) + builder.mixin(recruit.mixin.Candidate, core.class.Mixin, view.mixin.ObjectFactory, { component: recruit.component.CreateCandidate }) - builder.mixin(recruit.class.Applicant, core.class.Class, setting.mixin.Editable, {}) + builder.mixin(recruit.class.Applicant, core.class.Class, setting.mixin.Editable, { + value: true + }) - builder.mixin(recruit.class.Vacancy, core.class.Class, setting.mixin.Editable, {}) + builder.mixin(recruit.class.Vacancy, core.class.Class, setting.mixin.Editable, { + value: true + }) + builder.mixin(recruit.mixin.VacancyList, core.class.Class, setting.mixin.Editable, { + value: false + }) const vacanciesId = 'vacancies' const talentsId = 'talents' diff --git a/models/recruit/src/migration.ts b/models/recruit/src/migration.ts index 876ba9101e..c60c6cfbcb 100644 --- a/models/recruit/src/migration.ts +++ b/models/recruit/src/migration.ts @@ -13,11 +13,15 @@ // limitations under the License. // +import { Organization } from '@anticrm/contact' import core, { Doc, Ref, Space, TxOperations } from '@anticrm/core' import { createOrUpdate, MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model' import { DOMAIN_CALENDAR } from '@anticrm/model-calendar' +import contact, { DOMAIN_CONTACT } from '@anticrm/model-contact' +import { DOMAIN_SPACE } from '@anticrm/model-core' import tags, { TagCategory } from '@anticrm/model-tags' import { createKanbanTemplate, createSequence } from '@anticrm/model-task' +import { Vacancy } from '@anticrm/recruit' import { getCategories } from '@anticrm/skillset' import { KanbanTemplate } from '@anticrm/task' import recruit from './plugin' @@ -34,6 +38,33 @@ export const recruitOperation: MigrateOperation = { space: recruit.space.Reviews } ) + + const vacancies = await client.find( + DOMAIN_SPACE, + { _class: recruit.class.Vacancy, company: { $exists: true } }, + { projection: { _id: 1, company: 1 } } + ) + + const orgIds = Array.from(vacancies.map((it) => it.company)) + .filter((it) => it != null) + .filter((it, idx, arr) => arr.indexOf(it) === idx) as Ref[] + const orgs = await client.find(DOMAIN_CONTACT, { + _class: contact.class.Organization, + _id: { $in: orgIds } + }) + for (const o of orgs) { + if ((o as any)[recruit.mixin.VacancyList] === undefined) { + await client.update( + DOMAIN_CONTACT, + { _id: o._id }, + { + [recruit.mixin.VacancyList]: { + vacancies: vacancies.filter((it) => it.company === o._id).reduce((a) => a + 1, 0) + } + } + ) + } + } }, async upgrade (client: MigrationUpgradeClient): Promise { const tx = new TxOperations(client, core.account.System) diff --git a/models/recruit/src/plugin.ts b/models/recruit/src/plugin.ts index bb4a83b495..c6bb307b9b 100644 --- a/models/recruit/src/plugin.ts +++ b/models/recruit/src/plugin.ts @@ -56,7 +56,8 @@ export default mergeIds(recruitId, recruit, { GotoSkills: '' as IntlString, GotoAssigned: '' as IntlString, GotoApplicants: '' as IntlString, - GotoRecruitApplication: '' as IntlString + GotoRecruitApplication: '' as IntlString, + VacancyList: '' as IntlString }, validator: { ApplicantValidator: '' as Resource<(doc: T, client: Client) => Promise> @@ -81,7 +82,8 @@ export default mergeIds(recruitId, recruit, { Opinions: '' as AnyComponent, OpinionPresenter: '' as AnyComponent, NewCandidateHeader: '' as AnyComponent, - ApplicantFilter: '' as AnyComponent + ApplicantFilter: '' as AnyComponent, + VacancyList: '' as AnyComponent }, template: { DefaultVacancy: '' as Ref, diff --git a/models/server-recruit/src/index.ts b/models/server-recruit/src/index.ts index d0c360d1ed..fb6b467f4b 100644 --- a/models/server-recruit/src/index.ts +++ b/models/server-recruit/src/index.ts @@ -19,6 +19,7 @@ import core from '@anticrm/core' import recruit from '@anticrm/recruit' import view from '@anticrm/view' import serverRecruit from '@anticrm/server-recruit' +import serverCore from '@anticrm/server-core' export function createModel (builder: Builder): void { builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.HTMLPresenter, { @@ -36,4 +37,8 @@ export function createModel (builder: Builder): void { builder.mixin(recruit.class.Vacancy, core.class.Class, view.mixin.TextPresenter, { presenter: serverRecruit.function.VacancyTextPresenter }) + + builder.createDoc(serverCore.class.Trigger, core.space.Model, { + trigger: serverRecruit.trigger.OnVacancyUpdate + }) } diff --git a/models/setting/src/index.ts b/models/setting/src/index.ts index 188e9712af..b33dd16770 100644 --- a/models/setting/src/index.ts +++ b/models/setting/src/index.ts @@ -71,7 +71,9 @@ export class TIntegrationType extends TDoc implements IntegrationType { } @Mixin(setting.mixin.Editable, core.class.Class) -export class TEditable extends TClass implements Editable {} +export class TEditable extends TClass implements Editable { + value!: boolean +} @Mixin(setting.mixin.UserMixin, core.class.Class) export class TUserMixin extends TClass implements UserMixin {} @@ -332,6 +334,8 @@ export function createModel (builder: Builder): void { }, setting.action.DeleteMixin ) + + // builder.mixin(core.class.Space, core.class.Class, setting.mixin.Editable, {}) } export { settingOperation } from './migration' diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index 5615bfcd58..f007df7dd1 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -567,7 +567,9 @@ export function createModel (builder: Builder): void { presenter: tracker.component.SprintTitlePresenter }) - builder.mixin(tracker.class.Issue, core.class.Class, setting.mixin.Editable, {}) + builder.mixin(tracker.class.Issue, core.class.Class, setting.mixin.Editable, { + value: true + }) builder.mixin(tracker.class.TypeProjectStatus, core.class.Class, view.mixin.AttributeEditor, { inlineEditor: tracker.component.ProjectStatusEditor diff --git a/packages/core/lang/en.json b/packages/core/lang/en.json index 6a0009ead6..c1fb4dd278 100644 --- a/packages/core/lang/en.json +++ b/packages/core/lang/en.json @@ -24,6 +24,7 @@ "Collection": "Collection", "Array": "Array", "Bag": "Bag", - "Enum": "Enum" + "Enum": "Enum", + "Members": "Members" } } diff --git a/packages/core/lang/ru.json b/packages/core/lang/ru.json index 3c87ee36cc..fc3bdc03ae 100644 --- a/packages/core/lang/ru.json +++ b/packages/core/lang/ru.json @@ -24,6 +24,7 @@ "Collection": "Коллекция", "Array": "Массив", "Bag": "Bag", - "Enum": "Справочник" + "Enum": "Справочник", + "Members": "Участники" } } \ No newline at end of file diff --git a/packages/core/src/classes.ts b/packages/core/src/classes.ts index 5b995d3bbe..cb3dc8794b 100644 --- a/packages/core/src/classes.ts +++ b/packages/core/src/classes.ts @@ -14,7 +14,7 @@ // limitations under the License. // -import type { IntlString, Asset } from '@anticrm/platform' +import type { Asset, IntlString } from '@anticrm/platform' /** * @public diff --git a/packages/presentation/lang/ru.json b/packages/presentation/lang/ru.json index 7e64a92258..63f02d40ca 100644 --- a/packages/presentation/lang/ru.json +++ b/packages/presentation/lang/ru.json @@ -18,7 +18,7 @@ "Spaces": "Пространства", "Unassigned": "Не назначен", "CreateMore": "Создать еще", - "NumberMembers": "{count, plural, =0 {нет участников} =1 {1 участник} other {# участника}}", + "NumberMembers": "{count, plural, =0 {нет участников} =1 {1 участник} =2 {2 участника} =3 {3 участника} =4 {4 участника} other {# участников}}", "NumberSpaces": "{count, plural, =0 {В} =1 {В 1 месте} other {В # местах}}", "InThis": "В этом {space}", "NoMatchesInThis": "В этом {space} совпадения не обнаружены", diff --git a/packages/presentation/src/components/EmployeeBox.svelte b/packages/presentation/src/components/EmployeeBox.svelte index cf7f836f5e..4b763179a4 100644 --- a/packages/presentation/src/components/EmployeeBox.svelte +++ b/packages/presentation/src/components/EmployeeBox.svelte @@ -38,6 +38,7 @@ export let width: string | undefined = undefined export let focusIndex = -1 export let showTooltip: LabelAndProps | undefined = undefined + export let showNavigate = true diff --git a/packages/presentation/src/components/UserBox.svelte b/packages/presentation/src/components/UserBox.svelte index 066155fbca..7feb74b7a4 100644 --- a/packages/presentation/src/components/UserBox.svelte +++ b/packages/presentation/src/components/UserBox.svelte @@ -16,17 +16,23 @@
- diff --git a/packages/theme/styles/dialogs.scss b/packages/theme/styles/dialogs.scss index 31e042ccb2..a4d8fefc0e 100644 --- a/packages/theme/styles/dialogs.scss +++ b/packages/theme/styles/dialogs.scss @@ -132,9 +132,9 @@ } &.dialog { - width: 40rem; + width: 45rem; height: max-content; - max-width: 40rem; + max-width: 60rem; max-height: calc(100vh - 2rem); .antiCard-header { diff --git a/packages/ui/src/components/ActionIcon.svelte b/packages/ui/src/components/ActionIcon.svelte index 759dceeeb9..65851711bc 100644 --- a/packages/ui/src/components/ActionIcon.svelte +++ b/packages/ui/src/components/ActionIcon.svelte @@ -32,7 +32,7 @@ class="button {size}" use:tooltip={{ label, direction, props: labelProps }} tabindex="0" - on:click|stopPropagation={action} + on:click|stopPropagation|preventDefault={action} >
diff --git a/packages/ui/src/components/icons/Open.svelte b/packages/ui/src/components/icons/Open.svelte new file mode 100644 index 0000000000..521e55b4ac --- /dev/null +++ b/packages/ui/src/components/icons/Open.svelte @@ -0,0 +1,11 @@ + + + + + + diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 9abd334164..ed1fef9b19 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -132,6 +132,7 @@ export { default as IconDetails } from './components/icons/Details.svelte' export { default as IconDetailsFilled } from './components/icons/DetailsFilled.svelte' export { default as IconScale } from './components/icons/Scale.svelte' export { default as IconScaleFull } from './components/icons/ScaleFull.svelte' +export { default as IconOpen } from './components/icons/Open.svelte' export { default as PanelInstance } from './components/PanelInstance.svelte' export { default as Panel } from './components/Panel.svelte' diff --git a/plugins/contact-resources/src/components/AccountArrayEditor.svelte b/plugins/contact-resources/src/components/AccountArrayEditor.svelte new file mode 100644 index 0000000000..fa7524e6c2 --- /dev/null +++ b/plugins/contact-resources/src/components/AccountArrayEditor.svelte @@ -0,0 +1,41 @@ + + + diff --git a/plugins/contact-resources/src/components/EmployeeEditor.svelte b/plugins/contact-resources/src/components/EmployeeEditor.svelte index 597fc40dd5..649c3107f1 100644 --- a/plugins/contact-resources/src/components/EmployeeEditor.svelte +++ b/plugins/contact-resources/src/components/EmployeeEditor.svelte @@ -44,6 +44,8 @@ {size} {justify} {width} + allowDeselect + titleDeselect={contact.string.Cancel} bind:value on:change={(e) => onChange(e.detail)} /> diff --git a/plugins/contact-resources/src/components/OrganizationEditor.svelte b/plugins/contact-resources/src/components/OrganizationEditor.svelte index 3a1444e329..8b6d20b1cd 100644 --- a/plugins/contact-resources/src/components/OrganizationEditor.svelte +++ b/plugins/contact-resources/src/components/OrganizationEditor.svelte @@ -16,12 +16,9 @@ import { Organization } from '@anticrm/contact' import { Ref } from '@anticrm/core' import { IntlString } from '@anticrm/platform' - import { createQuery } from '@anticrm/presentation' - import { DropdownPopup, Label, showPopup, Button } from '@anticrm/ui' + import { UserBox } from '@anticrm/presentation' import type { ButtonKind, ButtonSize } from '@anticrm/ui' - import { ListItem } from '@anticrm/ui/src/types' import contact from '../plugin' - import Company from './icons/Company.svelte' export let value: Ref | undefined export let label: IntlString = contact.string.Organization @@ -29,80 +26,21 @@ export let kind: ButtonKind = 'no-border' export let size: ButtonSize = 'small' - export let justify: 'left' | 'center' = 'center' + export let justify: 'left' | 'center' = 'left' export let width: string | undefined = 'min-content' - - const query = createQuery() - - query.query(contact.class.Organization, {}, (res) => { - items = res.map((org) => { - return { - _id: org._id, - label: org.name, - image: org.avatar === null ? undefined : org.avatar - } - }) - if (value !== undefined) { - selected = items.find((p) => p._id === value) - } - }) - - let items: ListItem[] = [] - let selected: ListItem | undefined - - function setValue (res: ListItem | undefined): void { - selected = res - if (selected === undefined) { - value = undefined - } else { - value = selected._id as Ref - } - onChange(value) - } - - let opened: boolean = false - const icon = Company - let tool: HTMLElement -
- - - +/> diff --git a/plugins/contact-resources/src/components/OrganizationSelector.svelte b/plugins/contact-resources/src/components/OrganizationSelector.svelte deleted file mode 100644 index 6631e28d37..0000000000 --- a/plugins/contact-resources/src/components/OrganizationSelector.svelte +++ /dev/null @@ -1,84 +0,0 @@ - - - - diff --git a/plugins/contact-resources/src/index.ts b/plugins/contact-resources/src/index.ts index 10f3951c5d..6dea0bcea6 100644 --- a/plugins/contact-resources/src/index.ts +++ b/plugins/contact-resources/src/index.ts @@ -37,6 +37,7 @@ import EditOrganization from './components/EditOrganization.svelte' import EditPerson from './components/EditPerson.svelte' import EmployeeAccountPresenter from './components/EmployeeAccountPresenter.svelte' import EmployeeArrayEditor from './components/EmployeeArrayEditor.svelte' +import AccountArrayEditor from './components/AccountArrayEditor.svelte' import EmployeeBrowser from './components/EmployeeBrowser.svelte' import EmployeeEditor from './components/EmployeeEditor.svelte' import EmployeePresenter from './components/EmployeePresenter.svelte' @@ -44,7 +45,6 @@ import MemberPresenter from './components/MemberPresenter.svelte' import Members from './components/Members.svelte' import OrganizationEditor from './components/OrganizationEditor.svelte' import OrganizationPresenter from './components/OrganizationPresenter.svelte' -import OrganizationSelector from './components/OrganizationSelector.svelte' import PersonEditor from './components/PersonEditor.svelte' import PersonPresenter from './components/PersonPresenter.svelte' import SocialEditor from './components/SocialEditor.svelte' @@ -55,7 +55,6 @@ export { ChannelsEditor, ContactPresenter, ChannelsView, - OrganizationSelector, ChannelsDropdown, EmployeePresenter, PersonPresenter, @@ -144,7 +143,8 @@ export default async (): Promise => ({ EditMember, EmployeeArrayEditor, EmployeeEditor, - CreateEmployee + CreateEmployee, + AccountArrayEditor }, completion: { EmployeeQuery: async ( diff --git a/plugins/recruit-assets/lang/en.json b/plugins/recruit-assets/lang/en.json index c98625daf7..07fb39931a 100644 --- a/plugins/recruit-assets/lang/en.json +++ b/plugins/recruit-assets/lang/en.json @@ -92,7 +92,9 @@ "CopyLink": "Copy link", "HasActiveApplicant":"Active Only", "HasNoActiveApplicant": "No Active", - "NoneApplications": "None" + "NoneApplications": "None", + "RelatedIssues": "Related issues", + "VacancyList": "Vacancies" }, "status": { "TalentRequired": "Please select talent", diff --git a/plugins/recruit-assets/lang/ru.json b/plugins/recruit-assets/lang/ru.json index 4177e378eb..44b862a05d 100644 --- a/plugins/recruit-assets/lang/ru.json +++ b/plugins/recruit-assets/lang/ru.json @@ -94,7 +94,9 @@ "CopyLink": "Копировать ссылку", "HasActiveApplicant":"Только активные", "HasNoActiveApplicant": "Не активные", - "NoneApplications": "Отсутствуют" + "NoneApplications": "Отсутствуют", + "RelatedIssues": "Связанные задачи", + "VacancyList": "Вакансии" }, "status": { "TalentRequired": "Пожалуйста выберите таланта", diff --git a/plugins/recruit-resources/package.json b/plugins/recruit-resources/package.json index 9ed7c16148..105a46344a 100644 --- a/plugins/recruit-resources/package.json +++ b/plugins/recruit-resources/package.json @@ -56,6 +56,7 @@ "@anticrm/rekoni": "~0.6.0", "@anticrm/notification": "~0.6.0", "@anticrm/tags": "~0.6.2", - "@anticrm/calendar": "~0.6.0" + "@anticrm/calendar": "~0.6.0", + "@anticrm/tracker": "~0.6.0" } } diff --git a/plugins/recruit-resources/src/components/CreateVacancy.svelte b/plugins/recruit-resources/src/components/CreateVacancy.svelte index c9bf21bcd9..ce191c12bb 100644 --- a/plugins/recruit-resources/src/components/CreateVacancy.svelte +++ b/plugins/recruit-resources/src/components/CreateVacancy.svelte @@ -28,7 +28,8 @@ let name: string = '' const description: string = '' let templateId: Ref | undefined - let company: Ref | undefined + export let company: Ref | undefined + export let preserveCompany: boolean = false export function canClose (): boolean { return name === '' && templateId !== undefined @@ -87,12 +88,15 @@ _class={contact.class.Organization} label={recruit.string.Company} placeholder={recruit.string.Company} + justify={'left'} bind:value={company} allowDeselect titleDeselect={recruit.string.UnAssignCompany} kind={'no-border'} size={'small'} icon={Company} + readonly={preserveCompany} + showNavigate={false} create={{ component: contact.component.CreateOrganization, label: contact.string.CreateOrganization }} /> {#if object} @@ -79,8 +81,8 @@
@@ -130,7 +132,41 @@ space={object.space} attachments={object.attachments ?? 0} /> - - + + +
+
+
+ +
+ + +
+
+
+
+ { + isCreateIssue = false + }} + /> +
+
{/if} diff --git a/plugins/recruit-resources/src/components/VacancyList.svelte b/plugins/recruit-resources/src/components/VacancyList.svelte new file mode 100644 index 0000000000..db58c62835 --- /dev/null +++ b/plugins/recruit-resources/src/components/VacancyList.svelte @@ -0,0 +1,79 @@ + + + +
+
+
+ +
+ + +
+ {#if (vacancies ?? 0) > 0} + + {:else} +
+
+ +
+ + + + +
+ {/if} + diff --git a/plugins/recruit-resources/src/components/review/CreateReview.svelte b/plugins/recruit-resources/src/components/review/CreateReview.svelte index 9269bed895..33d89c3c19 100644 --- a/plugins/recruit-resources/src/components/review/CreateReview.svelte +++ b/plugins/recruit-resources/src/components/review/CreateReview.svelte @@ -16,7 +16,6 @@ import calendar from '@anticrm/calendar' import type { Contact, EmployeeAccount, Organization, Person } from '@anticrm/contact' import contact from '@anticrm/contact' - import { OrganizationSelector } from '@anticrm/contact-resources' import { Account, Class, Client, Doc, generateId, getCurrentAccount, Ref } from '@anticrm/core' import { getResource, OK, Resource, Severity, Status } from '@anticrm/platform' import { Card, getClient, UserBox, UserBoxList } from '@anticrm/presentation' @@ -171,7 +170,13 @@ create={{ component: recruit.component.CreateCandidate, label: recruit.string.CreateTalent }} /> {/if} - + (object.attachedToClass, { _id: object.attachedTo }) + candidate = + object?.attachedTo !== undefined + ? await client.findOne(object.attachedToClass, { _id: object.attachedTo }) + : undefined } $: updateSelected(object) diff --git a/plugins/recruit-resources/src/index.ts b/plugins/recruit-resources/src/index.ts index 04b5cd4a24..3d9581e30c 100644 --- a/plugins/recruit-resources/src/index.ts +++ b/plugins/recruit-resources/src/index.ts @@ -51,6 +51,7 @@ import VacancyModifiedPresenter from './components/VacancyModifiedPresenter.svel import VacancyPresenter from './components/VacancyPresenter.svelte' import recruit from './plugin' import { copyToClipboard, getApplicationTitle } from './utils' +import VacancyList from './components/VacancyList.svelte' async function createOpinion (object: Doc): Promise { showPopup(CreateOpinion, { space: object.space, review: object._id }) @@ -287,7 +288,9 @@ export default async (): Promise => ({ NewCandidateHeader, - ApplicantFilter + ApplicantFilter, + + VacancyList }, completion: { ApplicationQuery: async ( diff --git a/plugins/recruit-resources/src/plugin.ts b/plugins/recruit-resources/src/plugin.ts index 6dc88f9139..c45c673b21 100644 --- a/plugins/recruit-resources/src/plugin.ts +++ b/plugins/recruit-resources/src/plugin.ts @@ -105,7 +105,8 @@ export default mergeIds(recruitId, recruit, { FullDescription: '' as IntlString, HasActiveApplicant: '' as IntlString, HasNoActiveApplicant: '' as IntlString, - NoneApplications: '' as IntlString + NoneApplications: '' as IntlString, + RelatedIssues: '' as IntlString }, space: { CandidatesPublic: '' as Ref diff --git a/plugins/recruit/src/index.ts b/plugins/recruit/src/index.ts index d12ce8e6b1..c778e43c78 100644 --- a/plugins/recruit/src/index.ts +++ b/plugins/recruit/src/index.ts @@ -32,6 +32,13 @@ export interface Vacancy extends SpaceWithStates { company?: Ref } +/** + * @public + */ +export interface VacancyList extends Organization { + vacancies: number +} + /** * @public */ @@ -105,7 +112,8 @@ const recruit = plugin(recruitId, { Opinion: '' as Ref> }, mixin: { - Candidate: '' as Ref> + Candidate: '' as Ref>, + VacancyList: '' as Ref> }, component: { EditVacancy: '' as AnyComponent diff --git a/plugins/setting-resources/src/components/ClassHierarchy.svelte b/plugins/setting-resources/src/components/ClassHierarchy.svelte index e42e2ddaf7..096dbed4b6 100644 --- a/plugins/setting-resources/src/components/ClassHierarchy.svelte +++ b/plugins/setting-resources/src/components/ClassHierarchy.svelte @@ -36,7 +36,8 @@ cls.extends === _class && !cls.hidden && [ClassifierKind.CLASS, ClassifierKind.MIXIN].includes(cls.kind) && - cls.label !== undefined + cls.label !== undefined && + (!hierarchy.hasMixin(cls, settings.mixin.Editable) || hierarchy.as(cls, settings.mixin.Editable).value) ) { result.push(clazz) } diff --git a/plugins/setting-resources/src/components/ClassSetting.svelte b/plugins/setting-resources/src/components/ClassSetting.svelte index b4c86ea9b2..e496a79871 100644 --- a/plugins/setting-resources/src/components/ClassSetting.svelte +++ b/plugins/setting-resources/src/components/ClassSetting.svelte @@ -37,7 +37,12 @@ let classes: Ref>[] = [] clQuery.query(core.class.Class, {}, (res) => { classes = res - .filter((p) => hierarchy.hasMixin(p, setting.mixin.Editable) && !hierarchy.hasMixin(p, setting.mixin.UserMixin)) + .filter( + (p) => + hierarchy.hasMixin(p, setting.mixin.Editable) && + hierarchy.as(p, setting.mixin.Editable).value && + !hierarchy.hasMixin(p, setting.mixin.UserMixin) + ) .map((p) => p._id) }) diff --git a/plugins/setting-resources/src/components/CreateMixin.svelte b/plugins/setting-resources/src/components/CreateMixin.svelte index deb990d6bb..ba4aa70f88 100644 --- a/plugins/setting-resources/src/components/CreateMixin.svelte +++ b/plugins/setting-resources/src/components/CreateMixin.svelte @@ -34,7 +34,9 @@ icon: value.icon } const id = await client.createDoc(core.class.Mixin, core.space.Model, data) - await client.createMixin(id, core.class.Mixin, core.space.Model, setting.mixin.Editable, {}) + await client.createMixin(id, core.class.Mixin, core.space.Model, setting.mixin.Editable, { + value: true + }) await client.createMixin(id, core.class.Mixin, core.space.Model, setting.mixin.UserMixin, {}) dispatch('close') } diff --git a/plugins/setting/src/index.ts b/plugins/setting/src/index.ts index 9f18df13e3..10c3fe454f 100644 --- a/plugins/setting/src/index.ts +++ b/plugins/setting/src/index.ts @@ -47,7 +47,9 @@ export interface Integration extends Doc { /** * @public */ -export interface Editable extends Class {} +export interface Editable extends Class { + value: boolean // true is editable, false is not +} /** * @public diff --git a/plugins/tracker-resources/src/components/CreateIssue.svelte b/plugins/tracker-resources/src/components/CreateIssue.svelte index 0157fd0516..d6f7e92a4f 100644 --- a/plugins/tracker-resources/src/components/CreateIssue.svelte +++ b/plugins/tracker-resources/src/components/CreateIssue.svelte @@ -336,58 +336,60 @@ placeholder={tracker.string.IssueDescriptionPlaceholder} /> - {#if issueStatuses} -
- + {#if issueStatuses} +
+ (object.status = detail)} + /> +
+ (object.status = detail)} + justify="center" + on:change={({ detail }) => (object.priority = detail)} /> -
- (object.priority = detail)} - /> - (object.assignee = detail)} - /> - { - addTagRef(evt.detail) - }} - on:delete={(evt) => { - labels = labels.filter((it) => it._id !== evt.detail) - }} - /> - - - - {#if object.dueDate !== null} - + (object.assignee = detail)} + /> + { + addTagRef(evt.detail) + }} + on:delete={(evt) => { + labels = labels.filter((it) => it._id !== evt.detail) + }} + /> + + + + {#if object.dueDate !== null} + + {/if} + {:else} + {/if} - - {:else} - - {/if} + +