From 294d6c5732c1e5a39b6e8090c19068768a728d55 Mon Sep 17 00:00:00 2001 From: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> Date: Thu, 17 Mar 2022 15:39:57 +0600 Subject: [PATCH] Vacancy company organization (#1155) Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> --- dev/generator/src/recruit.ts | 1 - dev/tool/src/importer.ts | 1 - models/contact/src/index.ts | 4 + models/contact/src/plugin.ts | 4 +- models/recruit/src/index.ts | 7 +- models/recruit/src/review-model.ts | 5 +- packages/ui/img/google.svg | 23 ------ packages/ui/img/tesla.svg | 25 ------ packages/ui/src/components/Dropdown.svelte | 15 ++-- .../ui/src/components/DropdownPopup.svelte | 26 +++++-- packages/ui/src/index.ts | 1 + packages/ui/src/types.ts | 3 +- .../src/components/OrganizationEditor.svelte | 78 +++++++++++++++++++ .../components/OrganizationSelector.svelte | 58 ++++++++++++++ plugins/contact-resources/src/index.ts | 5 +- plugins/contact-resources/src/plugin.ts | 1 + .../src/components/CreateVacancy.svelte | 13 ++-- .../src/components/Vacancies.svelte | 13 +++- .../review/CreateReviewCategory.svelte | 13 ++-- plugins/recruit/src/index.ts | 5 +- 20 files changed, 213 insertions(+), 88 deletions(-) delete mode 100644 packages/ui/img/google.svg delete mode 100644 packages/ui/img/tesla.svg create mode 100644 plugins/contact-resources/src/components/OrganizationEditor.svelte create mode 100644 plugins/contact-resources/src/components/OrganizationSelector.svelte diff --git a/dev/generator/src/recruit.ts b/dev/generator/src/recruit.ts index a7930bf276..4aff1560c2 100644 --- a/dev/generator/src/recruit.ts +++ b/dev/generator/src/recruit.ts @@ -86,7 +86,6 @@ async function genVacansyApplicants ( description: faker.lorem.sentences(2), fullDescription: faker.lorem.sentences(10), location: faker.address.city(), - company: faker.company.companyName(), members: accountIds, private: false, archived: false diff --git a/dev/tool/src/importer.ts b/dev/tool/src/importer.ts index b3d7930757..43f3d32ec1 100644 --- a/dev/tool/src/importer.ts +++ b/dev/tool/src/importer.ts @@ -237,7 +237,6 @@ async function createUpdateVacancy (client: TxOperations, statuses: any): Promis description: '', fullDescription: '', location: '', - company: '', members: [], archived: false, private: false diff --git a/models/contact/src/index.ts b/models/contact/src/index.ts index 0374058147..f59a7b6ea3 100644 --- a/models/contact/src/index.ts +++ b/models/contact/src/index.ts @@ -165,6 +165,10 @@ export function createModel (builder: Builder): void { editor: contact.component.EditOrganization }) + builder.mixin(contact.class.Organization, core.class.Class, view.mixin.AttributeEditor, { + editor: contact.component.OrganizationEditor + }) + builder.mixin(contact.class.Channel, core.class.Class, view.mixin.AttributePresenter, { presenter: contact.component.ChannelsPresenter }) diff --git a/models/contact/src/plugin.ts b/models/contact/src/plugin.ts index 6a2448378f..90b5a09b97 100644 --- a/models/contact/src/plugin.ts +++ b/models/contact/src/plugin.ts @@ -34,7 +34,8 @@ export default mergeIds(contactId, contact, { CreateOrganizations: '' as AnyComponent, OrganizationPresenter: '' as AnyComponent, Contacts: '' as AnyComponent, - EmployeeAccountPresenter: '' as AnyComponent + EmployeeAccountPresenter: '' as AnyComponent, + OrganizationEditor: '' as AnyComponent }, string: { Persons: '' as IntlString, @@ -47,7 +48,6 @@ export default mergeIds(contactId, contact, { Channel: '' as IntlString, ChannelProvider: '' as IntlString, Person: '' as IntlString, - Organization: '' as IntlString, Employee: '' as IntlString, Value: '' as IntlString, Phone: '' as IntlString, diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 78b7ee5faf..771590b13c 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -13,7 +13,7 @@ // limitations under the License. // -import type { Employee } from '@anticrm/contact' +import type { Employee, Organization } from '@anticrm/contact' import { Doc, FindOptions, IndexKind, Lookup, Ref, Timestamp } from '@anticrm/core' import { Builder, @@ -60,9 +60,8 @@ export class TVacancy extends TSpaceWithStates implements Vacancy { @Index(IndexKind.FullText) location?: string - @Prop(TypeString(), recruit.string.Company, contact.icon.Company) - @Index(IndexKind.FullText) - company?: string + @Prop(TypeRef(contact.class.Organization), recruit.string.Company, contact.icon.Company) + company?: Ref<Organization> @Prop(Collection(chunter.class.Comment), chunter.string.Comments) comments?: number diff --git a/models/recruit/src/review-model.ts b/models/recruit/src/review-model.ts index 71c7c8d14c..13d77c7bc2 100644 --- a/models/recruit/src/review-model.ts +++ b/models/recruit/src/review-model.ts @@ -1,4 +1,4 @@ -import { Employee } from '@anticrm/contact' +import { Employee, Organization } from '@anticrm/contact' import { Domain, IndexKind, Ref, Timestamp } from '@anticrm/core' import { Collection, Index, Model, Prop, TypeDate, TypeMarkup, TypeRef, TypeString, UX } from '@anticrm/model' import attachment from '@anticrm/model-attachment' @@ -14,6 +14,9 @@ import recruit from './plugin' export class TReviewCategory extends TSpaceWithStates implements ReviewCategory { @Prop(TypeString(), recruit.string.FullDescription) fullDescription?: string + + @Prop(TypeRef(contact.class.Organization), recruit.string.Company, contact.icon.Company) + company?: Ref<Organization> } @Model(recruit.class.Review, task.class.Task) diff --git a/packages/ui/img/google.svg b/packages/ui/img/google.svg deleted file mode 100644 index d165497322..0000000000 --- a/packages/ui/img/google.svg +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 23.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> -<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" - viewBox="0 0 36 36" style="enable-background:new 0 0 36 36;" xml:space="preserve"> -<style type="text/css"> - .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#B82C2E;} - .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#6FA94C;} - .st2{fill-rule:evenodd;clip-rule:evenodd;fill:#687EB9;} - .st3{fill-rule:evenodd;clip-rule:evenodd;fill:#E6C12D;} -</style> -<g> - <path class="st0" d="M4.9,11.3c0.6-1.3,1.5-2.5,2.5-3.6c2.3-2.4,5.1-3.9,8.4-4.5c4.6-0.7,8.7,0.4,12.3,3.4c0.2,0.2,0.3,0.3,0,0.5 - c-1.3,1.2-2.5,2.5-3.7,3.7c-0.1,0.1-0.2,0.3-0.4,0.1c-3.1-2.9-8.2-2.8-11.6,0.3c-1.1,1.1-2,2.3-2.5,3.8c-0.1-0.1-0.2-0.1-0.2-0.2 - C8,13.7,6.5,12.5,4.9,11.3z"/> - <path class="st1" d="M9.8,20.9c0.4,1.1,1,2.2,1.8,3.1c2.1,2.3,4.7,3.3,7.9,3c1.5-0.2,2.8-0.6,4-1.4c0.1,0.1,0.2,0.2,0.4,0.3 - c1.5,1.1,2.9,2.3,4.4,3.4c-1.6,1.5-3.5,2.5-5.6,3.1c-5,1.3-9.6,0.5-13.7-2.8c-1.7-1.3-3-3-4-4.9C6.5,23.4,8.2,22.2,9.8,20.9z"/> - <path class="st2" d="M28.2,29.4c-1.5-1.1-2.9-2.3-4.4-3.4c-0.1-0.1-0.2-0.2-0.4-0.3c1-0.8,1.8-1.6,2.3-2.8c0.2-0.4,0.4-0.9,0.5-1.4 - c0.1-0.3,0.1-0.5-0.3-0.5c-2.4,0-4.8,0-7.2,0c-0.5,0-0.5,0-0.5-0.5c0-1.6,0-3.3,0-4.9c0-0.3,0.1-0.4,0.4-0.4c4.5,0,8.9,0,13.4,0 - c0.2,0,0.4,0,0.4,0.3c0.6,3.9,0.1,7.6-1.9,11.1C29.9,27.6,29.2,28.6,28.2,29.4z"/> - <path class="st3" d="M9.8,20.9c-1.6,1.3-3.3,2.5-4.9,3.8c-0.8-1.5-1.3-3.1-1.5-4.7c-0.4-2.9,0-5.6,1.3-8.3c0.1-0.1,0.2-0.3,0.2-0.4 - c1.6,1.2,3.1,2.4,4.7,3.6C9.7,14.9,9.8,15,9.8,15C9.2,17,9.2,18.9,9.8,20.9z"/> -</g> -</svg> diff --git a/packages/ui/img/tesla.svg b/packages/ui/img/tesla.svg deleted file mode 100644 index 6eac18dd43..0000000000 --- a/packages/ui/img/tesla.svg +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 23.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> -<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" - viewBox="0 0 36 36" style="enable-background:new 0 0 36 36;" xml:space="preserve"> -<style type="text/css"> - .st0{fill:url(#SVGID_1_);} - .st1{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_2_);} -</style> -<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="14.3791" y1="-2.5354" x2="21.6209" y2="38.5354"> - <stop offset="5.076140e-03" style="stop-color:#C52229"/> - <stop offset="1" style="stop-color:#802022"/> -</linearGradient> -<rect class="st0" width="36" height="36"/> -<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="18" y1="6.2743" x2="18" y2="29.7257"> - <stop offset="0" style="stop-color:#FFFFFF"/> - <stop offset="0.5066" style="stop-color:#FDFDFD"/> - <stop offset="0.7696" style="stop-color:#F5F5F5"/> - <stop offset="0.9763" style="stop-color:#E8E8E8"/> - <stop offset="1" style="stop-color:#E6E6E6"/> -</linearGradient> -<path class="st1" d="M7.3,9.8c2.8-1.1,7.4-1.3,9.4-1.2l1.3,1.6l1.3-1.6c2-0.1,6.6,0.1,9.4,1.2c-0.4,0.7-2.1,1.8-3,2 - c-0.1-1.4-2.1-1.7-4-1.7L18,29.7l-3.7-19.7c-2,0-4,0.3-4,1.7C9.4,11.6,7.7,10.5,7.3,9.8L7.3,9.8z M6,7.8l0.7,1.1 - c2.7-1,5.9-1.4,9.3-1.5c1.3,0,2.6,0,3.9,0c3.4,0.1,6.6,0.6,9.3,1.5L30,7.8c-3.2-1.1-6.6-1.4-10-1.5c-1.3,0-2.6,0-4,0 - C12.6,6.4,9.2,6.7,6,7.8L6,7.8z"/> -</svg> diff --git a/packages/ui/src/components/Dropdown.svelte b/packages/ui/src/components/Dropdown.svelte index a62b81115b..27f041232c 100644 --- a/packages/ui/src/components/Dropdown.svelte +++ b/packages/ui/src/components/Dropdown.svelte @@ -24,13 +24,10 @@ import DropdownPopup from './DropdownPopup.svelte' import Add from './icons/Add.svelte' - import tesla from '../../img/tesla.svg' - import google from '../../img/google.svg' - export let icon: Asset | AnySvelteComponent = Add export let label: IntlString - export let placeholder: string - export let items: ListItem[] = [{ item: tesla, label: 'Tesla' }, { item: google, label: 'Google' }] + export let placeholder: IntlString + export let items: ListItem[] = [] export let selected: ListItem | undefined = undefined export let show: boolean = false @@ -51,7 +48,7 @@ btn.focus() if (!opened) { opened = true - showPopup(DropdownPopup, { title: label, items }, container, (result) => { + showPopup(DropdownPopup, { title: label, items, icon }, container, (result) => { if (result) selected = result opened = false }) @@ -59,8 +56,8 @@ }} > <div class="flex-center focused-button btn" class:selected bind:this={btn} tabindex={0} on:focus={() => container.click()}> - {#if selected} - <img src={selected.item} alt={selected.label} /> + {#if selected && selected.image} + <img src={selected.image} alt={selected.label} /> {:else} {#if typeof (icon) === 'string'} <Icon {icon} size={'small'} /> @@ -73,7 +70,7 @@ <div class="selectUser"> <div class="title"><Label {label} /></div> <div class="caption-color" class:empty={selected ? false : true}> - {#if selected}{selected.label}{:else}{placeholder}{/if} + {#if selected}{selected.label}{:else}<Label label={placeholder} />{/if} </div> </div> </div> diff --git a/packages/ui/src/components/DropdownPopup.svelte b/packages/ui/src/components/DropdownPopup.svelte index a279b7e3c0..7cd6e224b7 100644 --- a/packages/ui/src/components/DropdownPopup.svelte +++ b/packages/ui/src/components/DropdownPopup.svelte @@ -13,16 +13,18 @@ // limitations under the License. --> <script lang="ts"> - import type { IntlString } from '@anticrm/platform' + import type { Asset, IntlString } from '@anticrm/platform' import { createEventDispatcher } from 'svelte' import Label from './Label.svelte' import EditWithIcon from './EditWithIcon.svelte' import IconSearch from './icons/Search.svelte' - import type { ListItem } from '../types' + import type { AnySvelteComponent, ListItem } from '../types' import plugin from '../plugin' + import Icon from './Icon.svelte' export let title: IntlString | undefined = undefined + export let icon: Asset | AnySvelteComponent export let caption: IntlString = plugin.string.Suggested export let items: ListItem[] export let header: boolean = true @@ -52,8 +54,16 @@ <div class="ap-box"> {#each items.filter((x) => x.label.toLowerCase().includes(search.toLowerCase())) as item} <button class="ap-menuItem" on:click={() => { dispatch('close', item) }}> - <div class="flex-center img"> - <img src={item.item} alt={item.label} /> + <div class="flex-center img" class:image={item.image}> + {#if item.image} + <img src={item.image} alt={item.label} /> + {:else} + {#if typeof (icon) === 'string'} + <Icon {icon} size={'small'} /> + {:else} + <svelte:component this={icon} size={'small'} /> + {/if} + {/if} </div> <div class="flex-grow caption-color">{item.label}</div> </button> @@ -66,12 +76,18 @@ <style lang="scss"> .img { margin-right: .75rem; + flex-shrink: 0; width: 2.25rem; height: 2.25rem; color: var(--theme-caption-color); + background-color: transparent; + border: 1px solid var(--theme-card-divider); border-radius: .5rem; + outline: none; overflow: hidden; - + } + .image { + border-color: transparent; img { max-width: fit-content; } } </style> diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 76e7649704..088ff84141 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -61,6 +61,7 @@ export { default as CircleButton } from './components/CircleButton.svelte' export { default as Link } from './components/Link.svelte' export { default as TimeSince } from './components/TimeSince.svelte' export { default as Dropdown } from './components/Dropdown.svelte' +export { default as DropdownPopup } from './components/DropdownPopup.svelte' export { default as DropdownLabels } from './components/DropdownLabels.svelte' export { default as ShowMore } from './components/ShowMore.svelte' export { default as Menu } from './components/Menu.svelte' diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts index b260a18bc9..03dcb0fcbb 100644 --- a/packages/ui/src/types.ts +++ b/packages/ui/src/types.ts @@ -77,8 +77,9 @@ export interface LabelAndProps { } export interface ListItem { - item: any | undefined + _id: string label: string + image?: string } export interface DropdownTextItem { diff --git a/plugins/contact-resources/src/components/OrganizationEditor.svelte b/plugins/contact-resources/src/components/OrganizationEditor.svelte new file mode 100644 index 0000000000..1f308de5a7 --- /dev/null +++ b/plugins/contact-resources/src/components/OrganizationEditor.svelte @@ -0,0 +1,78 @@ +<!-- +// 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 { Organization } from '@anticrm/contact' + import { Ref } from '@anticrm/core' + import { IntlString } from '@anticrm/platform' + import { createQuery } from '@anticrm/presentation' + import { DropdownPopup, Label, showPopup } from '@anticrm/ui' + import { ListItem } from '@anticrm/ui/src/types' + import contact from '../plugin' + import Company from './icons/Company.svelte' + + export let value: Ref<Organization> | undefined + export let label: IntlString = contact.string.Organization + export let onChange: (value: any) => void + + const query = createQuery() + + query.query(contact.class.Organization, {}, (res) => { + items = res.map((org) => { + return { + _id: org._id, + label: org.name, + image: 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<Organization> + } + onChange(value) + } + + let opened: boolean = false + const icon = Company + let container: HTMLElement + +</script> + +<div class="caption-color cursor-pointer" bind:this={container} class:empty={selected === undefined} on:click|preventDefault={() => { + if (!opened) { + opened = true + showPopup(DropdownPopup, { title: label, items, icon }, container, (result) => { + if (result) setValue(result) + opened = false + }) + } +}}> + {#if selected}{selected.label}{:else}<Label {label} />{/if} +</div> + +<style lang="scss"> + .empty { color: var(--theme-content-trans-color); } +</style> diff --git a/plugins/contact-resources/src/components/OrganizationSelector.svelte b/plugins/contact-resources/src/components/OrganizationSelector.svelte new file mode 100644 index 0000000000..f5e9d2d9e0 --- /dev/null +++ b/plugins/contact-resources/src/components/OrganizationSelector.svelte @@ -0,0 +1,58 @@ +<!-- +// 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 { Organization } from '@anticrm/contact' + import { Ref } from '@anticrm/core' + import { IntlString } from '@anticrm/platform' + import { createQuery } from '@anticrm/presentation' + import { Dropdown } from '@anticrm/ui' + import { ListItem } from '@anticrm/ui/src/types' + import contact from '../plugin' + import Company from './icons/Company.svelte' + + export let value: Ref<Organization> | undefined + export let label: IntlString = contact.string.Organization + + const query = createQuery() + + query.query(contact.class.Organization, {}, (res) => { + items = res.map((org) => { + return { + _id: org._id, + label: org.name, + image: org.avatar + } + }) + if (value !== undefined) { + selected = items.find((p) => p._id === value) + } + }) + + let items: ListItem[] = [] + let selected: ListItem | undefined + + $: setValue(selected) + + function setValue (selected: ListItem | undefined): void { + if (selected === undefined) { + value = undefined + } else { + value = selected._id as Ref<Organization> + } + } +</script> + +<Dropdown icon={Company} label={label} placeholder={label} {items} bind:selected /> \ No newline at end of file diff --git a/plugins/contact-resources/src/index.ts b/plugins/contact-resources/src/index.ts index 5d19c2c90b..5d396c7d94 100644 --- a/plugins/contact-resources/src/index.ts +++ b/plugins/contact-resources/src/index.ts @@ -35,8 +35,10 @@ import PersonPresenter from './components/PersonPresenter.svelte' import SocialEditor from './components/SocialEditor.svelte' import contact from './plugin' import EmployeeAccountPresenter from './components/EmployeeAccountPresenter.svelte' +import OrganizationEditor from './components/OrganizationEditor.svelte' +import OrganizationSelector from './components/OrganizationSelector.svelte' -export { Channels, ChannelsEditor, ContactPresenter, ChannelsView } +export { Channels, ChannelsEditor, ContactPresenter, ChannelsView, OrganizationSelector } async function queryContact (_class: Ref<Class<Contact>>, client: Client, search: string): Promise<ObjectSearchResult[]> { return (await client.findAll(_class, { name: { $like: `%${search}%` } }, { limit: 200 })).map(e => ({ @@ -51,6 +53,7 @@ async function queryContact (_class: Ref<Class<Contact>>, client: Client, search export default async (): Promise<Resources> => ({ component: { + OrganizationEditor, ContactPresenter, PersonPresenter, OrganizationPresenter, diff --git a/plugins/contact-resources/src/plugin.ts b/plugins/contact-resources/src/plugin.ts index f61bf6b776..39e2611e76 100644 --- a/plugins/contact-resources/src/plugin.ts +++ b/plugins/contact-resources/src/plugin.ts @@ -32,6 +32,7 @@ export default mergeIds(contactId, contact, { PersonsNamePlaceholder: '' as IntlString, CreateOrganizations: '' as IntlString, Organizations: '' as IntlString, + Organization: '' as IntlString, SelectFolder: '' as IntlString, OrganizationsFolder: '' as IntlString, PersonsFolder: '' as IntlString, diff --git a/plugins/recruit-resources/src/components/CreateVacancy.svelte b/plugins/recruit-resources/src/components/CreateVacancy.svelte index 9d742bbd12..1df885efa1 100644 --- a/plugins/recruit-resources/src/components/CreateVacancy.svelte +++ b/plugins/recruit-resources/src/components/CreateVacancy.svelte @@ -14,13 +14,14 @@ --> <script lang="ts"> + import { Organization } from '@anticrm/contact' import core, { Ref } from '@anticrm/core' - import { getClient, SpaceCreateCard } from '@anticrm/presentation' - import task, { createKanban, KanbanTemplate } from '@anticrm/task' - import { Component, Dropdown, EditBox, Grid } from '@anticrm/ui' + import { getClient,SpaceCreateCard } from '@anticrm/presentation' + import task, { createKanban,KanbanTemplate } from '@anticrm/task' + import { Component,EditBox,Grid } from '@anticrm/ui' import { createEventDispatcher } from 'svelte' import recruit from '../plugin' - import Company from './icons/Company.svelte' + import { OrganizationSelector } from '@anticrm/contact-resources' import Vacancy from './icons/Vacancy.svelte' const dispatch = createEventDispatcher() @@ -28,6 +29,7 @@ let name: string = '' const description: string = '' let templateId: Ref<KanbanTemplate> | undefined + let company: Ref<Organization> | undefined export function canClose (): boolean { return name === '' && templateId !== undefined @@ -45,6 +47,7 @@ description, private: false, archived: false, + company, members: [] }) @@ -60,7 +63,7 @@ > <Grid column={1} rowGap={1.5}> <EditBox label={recruit.string.VacancyName} bind:value={name} icon={Vacancy} placeholder={recruit.string.VacancyPlaceholder} maxWidth={'16rem'} focus/> - <Dropdown icon={Company} label={recruit.string.Company} placeholder={'Company'} /> + <OrganizationSelector bind:value={company} label={recruit.string.Company} /> <Component is={task.component.KanbanTemplateSelector} props={{ folders: [recruit.space.VacancyTemplates], diff --git a/plugins/recruit-resources/src/components/Vacancies.svelte b/plugins/recruit-resources/src/components/Vacancies.svelte index 65a322e79d..806fae3cc8 100644 --- a/plugins/recruit-resources/src/components/Vacancies.svelte +++ b/plugins/recruit-resources/src/components/Vacancies.svelte @@ -13,7 +13,8 @@ // limitations under the License. --> <script lang="ts"> - import core, { Doc, DocumentQuery, Ref } from '@anticrm/core' + import contact from '@anticrm/contact' + import core, { Doc, DocumentQuery, Lookup, Ref } from '@anticrm/core' import { createQuery } from '@anticrm/presentation' import { Applicant, Vacancy } from '@anticrm/recruit' import { Button, getCurrentLocation, Icon, Label, navigate, Scroller, showPopup, IconAdd } from '@anticrm/ui' @@ -88,6 +89,10 @@ ) } + const lookup = { + company: contact.class.Organization + } as Lookup<Doc> + function showCreateDialog (ev: Event) { showPopup(CreateVacancy, { space: recruit.space.CandidatesPublic }, ev.target as HTMLElement) } @@ -127,7 +132,7 @@ sortingKey: '@applications', sortingFunction: applicationSorting }, - 'company', + '$lookup.company', 'location', 'description', { @@ -139,7 +144,9 @@ sortingFunction: modifiedSorting } ]} - options={{}} + options={{ + lookup + }} query={{ ...vacancyQuery, archived: false diff --git a/plugins/recruit-resources/src/components/review/CreateReviewCategory.svelte b/plugins/recruit-resources/src/components/review/CreateReviewCategory.svelte index 50e9c35aa8..2995fdfa52 100644 --- a/plugins/recruit-resources/src/components/review/CreateReviewCategory.svelte +++ b/plugins/recruit-resources/src/components/review/CreateReviewCategory.svelte @@ -15,19 +15,21 @@ <script lang="ts"> import core, { Ref } from '@anticrm/core' - import { getClient, SpaceCreateCard } from '@anticrm/presentation' - import task, { createKanban, KanbanTemplate } from '@anticrm/task' - import { Component, Dropdown, EditBox, Grid } from '@anticrm/ui' + import { getClient,SpaceCreateCard } from '@anticrm/presentation' + import task,{ createKanban,KanbanTemplate } from '@anticrm/task' + import { Component,EditBox,Grid } from '@anticrm/ui' import { createEventDispatcher } from 'svelte' import recruit from '../../plugin' - import Company from '../icons/Company.svelte' import Review from '../icons/Review.svelte' + import { Organization } from '@anticrm/contact' + import { OrganizationSelector } from '@anticrm/contact-resources' const dispatch = createEventDispatcher() let name: string = '' const description: string = '' let templateId: Ref<KanbanTemplate> | undefined + let company: Ref<Organization> | undefined export function canClose (): boolean { return name === '' && templateId !== undefined @@ -45,6 +47,7 @@ description, private: false, archived: false, + company, members: [] }) @@ -60,7 +63,7 @@ > <Grid column={1} rowGap={1.5}> <EditBox label={recruit.string.ReviewCategoryName} bind:value={name} icon={Review} placeholder={recruit.string.ReviewCategoryPlaceholder} maxWidth={'16rem'} focus/> - <Dropdown icon={Company} label={recruit.string.Company} placeholder={'Company'} /> + <OrganizationSelector bind:value={company} label={recruit.string.Company} /> <Component is={task.component.KanbanTemplateSelector} props={{ folders: [recruit.space.ReviewTemplates], diff --git a/plugins/recruit/src/index.ts b/plugins/recruit/src/index.ts index 9d45a66c21..cfcc496ea1 100644 --- a/plugins/recruit/src/index.ts +++ b/plugins/recruit/src/index.ts @@ -13,7 +13,7 @@ // limitations under the License. // -import type { Employee, Person } from '@anticrm/contact' +import type { Employee, Organization, Person } from '@anticrm/contact' import type { AttachedDoc, Class, Doc, Mixin, Ref, Space, Timestamp } from '@anticrm/core' import type { Asset, Plugin } from '@anticrm/platform' import { plugin } from '@anticrm/platform' @@ -28,7 +28,7 @@ export interface Vacancy extends SpaceWithStates { attachments?: number dueTo?: Timestamp location?: string - company?: string + company?: Ref<Organization> } /** @@ -37,6 +37,7 @@ export interface Vacancy extends SpaceWithStates { export interface ReviewCategory extends SpaceWithStates { fullDescription?: string attachments?: number + company?: Ref<Organization> } /**