mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
parent
1a57aad78e
commit
0e6c458bfe
@ -1033,24 +1033,6 @@ export function createModel (builder: Builder): void {
|
|||||||
},
|
},
|
||||||
recruit.action.MoveApplicant
|
recruit.action.MoveApplicant
|
||||||
)
|
)
|
||||||
|
|
||||||
createAction(
|
|
||||||
builder,
|
|
||||||
{
|
|
||||||
label: recruit.string.RecognizeAttachment,
|
|
||||||
action: recruit.actionImpl.MoveApplicant,
|
|
||||||
icon: view.icon.Move,
|
|
||||||
input: 'any',
|
|
||||||
category: view.category.General,
|
|
||||||
target: recruit.class.Applicant,
|
|
||||||
context: {
|
|
||||||
mode: ['context', 'browser'],
|
|
||||||
group: 'tools'
|
|
||||||
},
|
|
||||||
override: [task.action.Move]
|
|
||||||
},
|
|
||||||
recruit.action.MoveApplicant
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { recruitOperation } from './migration'
|
export { recruitOperation } from './migration'
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import type { Client, Doc, Ref } from '@hcengineering/core'
|
import type { Client, Doc, Ref } from '@hcengineering/core'
|
||||||
import { ObjectSearchCategory, ObjectSearchFactory } from '@hcengineering/model-presentation'
|
|
||||||
import type { IntlString, Resource, Status } from '@hcengineering/platform'
|
import type { IntlString, Resource, Status } from '@hcengineering/platform'
|
||||||
import { mergeIds } from '@hcengineering/platform'
|
import { mergeIds } from '@hcengineering/platform'
|
||||||
import { recruitId } from '@hcengineering/recruit'
|
import { recruitId } from '@hcengineering/recruit'
|
||||||
@ -51,7 +50,6 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
TalentPools: '' as IntlString,
|
TalentPools: '' as IntlString,
|
||||||
SearchApplication: '' as IntlString,
|
SearchApplication: '' as IntlString,
|
||||||
SearchVacancy: '' as IntlString,
|
SearchVacancy: '' as IntlString,
|
||||||
Application: '' as IntlString,
|
|
||||||
AssignedRecruiter: '' as IntlString,
|
AssignedRecruiter: '' as IntlString,
|
||||||
Due: '' as IntlString,
|
Due: '' as IntlString,
|
||||||
Source: '' as IntlString,
|
Source: '' as IntlString,
|
||||||
@ -63,8 +61,7 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
GotoAssigned: '' as IntlString,
|
GotoAssigned: '' as IntlString,
|
||||||
GotoApplicants: '' as IntlString,
|
GotoApplicants: '' as IntlString,
|
||||||
GotoRecruitApplication: '' as IntlString,
|
GotoRecruitApplication: '' as IntlString,
|
||||||
VacancyList: '' as IntlString,
|
VacancyList: '' as IntlString
|
||||||
RecognizeAttachment: '' as IntlString
|
|
||||||
},
|
},
|
||||||
validator: {
|
validator: {
|
||||||
ApplicantValidator: '' as Resource<<T extends Doc>(doc: T, client: Client) => Promise<Status>>
|
ApplicantValidator: '' as Resource<<T extends Doc>(doc: T, client: Client) => Promise<Status>>
|
||||||
@ -100,12 +97,6 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
DefaultVacancy: '' as Ref<KanbanTemplate>,
|
DefaultVacancy: '' as Ref<KanbanTemplate>,
|
||||||
Task: '' as Ref<KanbanTemplate>
|
Task: '' as Ref<KanbanTemplate>
|
||||||
},
|
},
|
||||||
completion: {
|
|
||||||
ApplicationQuery: '' as Resource<ObjectSearchFactory>,
|
|
||||||
ApplicationCategory: '' as Ref<ObjectSearchCategory>,
|
|
||||||
VacancyCategory: '' as Ref<ObjectSearchCategory>,
|
|
||||||
VacancyQuery: '' as Resource<ObjectSearchFactory>
|
|
||||||
},
|
|
||||||
viewlet: {
|
viewlet: {
|
||||||
TableCandidate: '' as Ref<Viewlet>,
|
TableCandidate: '' as Ref<Viewlet>,
|
||||||
TableVacancy: '' as Ref<Viewlet>,
|
TableVacancy: '' as Ref<Viewlet>,
|
||||||
|
@ -7,7 +7,7 @@ import chunter from '@hcengineering/model-chunter'
|
|||||||
import contact from '@hcengineering/model-contact'
|
import contact from '@hcengineering/model-contact'
|
||||||
import core, { TAttachedDoc } from '@hcengineering/model-core'
|
import core, { TAttachedDoc } from '@hcengineering/model-core'
|
||||||
import task from '@hcengineering/model-task'
|
import task from '@hcengineering/model-task'
|
||||||
import { Candidate, Opinion, Review } from '@hcengineering/recruit'
|
import { Applicant, Candidate, Opinion, Review } from '@hcengineering/recruit'
|
||||||
import recruit from './plugin'
|
import recruit from './plugin'
|
||||||
|
|
||||||
@Model(recruit.class.Review, calendar.class.Event)
|
@Model(recruit.class.Review, calendar.class.Event)
|
||||||
@ -24,6 +24,9 @@ export class TReview extends TEvent implements Review {
|
|||||||
@Index(IndexKind.FullText)
|
@Index(IndexKind.FullText)
|
||||||
verdict!: string
|
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 })
|
@Prop(TypeRef(contact.class.Organization), recruit.string.Company, { icon: contact.icon.Company })
|
||||||
company?: Ref<Organization>
|
company?: Ref<Organization>
|
||||||
|
|
||||||
|
@ -105,7 +105,8 @@
|
|||||||
"Score": "Score",
|
"Score": "Score",
|
||||||
"Match": "Match",
|
"Match": "Match",
|
||||||
"PerformMatch": "Match",
|
"PerformMatch": "Match",
|
||||||
"MoveApplication": "Move to another vacancy"
|
"MoveApplication": "Move to another vacancy",
|
||||||
|
"SearchVacancy": "Search vacancy..."
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"TalentRequired": "Please select talent",
|
"TalentRequired": "Please select talent",
|
||||||
|
@ -107,7 +107,8 @@
|
|||||||
"Score": "Оценка",
|
"Score": "Оценка",
|
||||||
"Match": "Совпадение",
|
"Match": "Совпадение",
|
||||||
"PerformMatch": "Сопоставить",
|
"PerformMatch": "Сопоставить",
|
||||||
"MoveApplication": "Поменять Вакансию"
|
"MoveApplication": "Поменять Вакансию",
|
||||||
|
"SearchVacancy": "Найти вакансию..."
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"TalentRequired": "Пожалуйста выберите таланта",
|
"TalentRequired": "Пожалуйста выберите таланта",
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<Table
|
<Table
|
||||||
_class={recruit.class.Applicant}
|
_class={recruit.class.Applicant}
|
||||||
config={['', '$lookup.space.name', 'state', 'doneState']}
|
config={['', '$lookup.space.name', '$lookup.space.company', 'state', 'doneState']}
|
||||||
query={{ attachedTo: value._id }}
|
query={{ attachedTo: value._id }}
|
||||||
loadingProps={{ length: value.applications ?? 0 }}
|
loadingProps={{ length: value.applications ?? 0 }}
|
||||||
/>
|
/>
|
||||||
|
@ -60,7 +60,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</Scroller>
|
</Scroller>
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<Reviews objectId={candidate._id} reviews={candidate.reviews ?? 0} label={recruit.string.TalentReviews} />
|
<Reviews
|
||||||
|
objectId={candidate._id}
|
||||||
|
reviews={candidate.reviews ?? 0}
|
||||||
|
label={recruit.string.TalentReviews}
|
||||||
|
application={object?._id}
|
||||||
|
company={vacancy?.company}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
@ -16,14 +16,15 @@
|
|||||||
import calendar from '@hcengineering/calendar'
|
import calendar from '@hcengineering/calendar'
|
||||||
import type { Contact, EmployeeAccount, Organization, Person } from '@hcengineering/contact'
|
import type { Contact, EmployeeAccount, Organization, Person } from '@hcengineering/contact'
|
||||||
import contact from '@hcengineering/contact'
|
import contact from '@hcengineering/contact'
|
||||||
import { Account, Class, Client, Doc, generateId, getCurrentAccount, Ref, DateRangeMode } from '@hcengineering/core'
|
import { Account, Class, Client, DateRangeMode, Doc, generateId, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||||
import { getResource, OK, Resource, Severity, Status } from '@hcengineering/platform'
|
import { getResource, OK, Resource, Severity, Status } from '@hcengineering/platform'
|
||||||
import { Card, getClient, UserBox, UserBoxList } from '@hcengineering/presentation'
|
import { Card, getClient, UserBox, UserBoxList } from '@hcengineering/presentation'
|
||||||
import type { Candidate, Review } from '@hcengineering/recruit'
|
import type { Applicant, Candidate, Review } from '@hcengineering/recruit'
|
||||||
import task from '@hcengineering/task'
|
import task from '@hcengineering/task'
|
||||||
import { StyledTextArea } from '@hcengineering/text-editor'
|
import { StyledTextArea } from '@hcengineering/text-editor'
|
||||||
import { DateRangePresenter, EditBox, Status as StatusControl } from '@hcengineering/ui'
|
import { DateRangePresenter, EditBox, Status as StatusControl } from '@hcengineering/ui'
|
||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
|
import { ObjectSearchBox } from '@hcengineering/view-resources'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import recruit from '../../plugin'
|
import recruit from '../../plugin'
|
||||||
|
|
||||||
@ -46,7 +47,9 @@
|
|||||||
let startDate: number = initDate.getTime()
|
let startDate: number = initDate.getTime()
|
||||||
let dueDate: number = initDate.getTime() + 30 * 60 * 1000
|
let dueDate: number = initDate.getTime() + 30 * 60 * 1000
|
||||||
let location: string = ''
|
let location: string = ''
|
||||||
let company: Ref<Organization> | undefined = undefined
|
|
||||||
|
export let company: Ref<Organization> | undefined = undefined
|
||||||
|
export let application: Ref<Applicant> | undefined = undefined
|
||||||
|
|
||||||
const doc: Review = {
|
const doc: Review = {
|
||||||
number: 0,
|
number: 0,
|
||||||
@ -61,6 +64,7 @@
|
|||||||
date: 0,
|
date: 0,
|
||||||
dueDate: undefined,
|
dueDate: undefined,
|
||||||
description,
|
description,
|
||||||
|
application,
|
||||||
company,
|
company,
|
||||||
verdict: '',
|
verdict: '',
|
||||||
title,
|
title,
|
||||||
@ -106,6 +110,7 @@
|
|||||||
title,
|
title,
|
||||||
participants: doc.participants,
|
participants: doc.participants,
|
||||||
company,
|
company,
|
||||||
|
application,
|
||||||
location
|
location
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -169,6 +174,19 @@
|
|||||||
label={recruit.string.Company}
|
label={recruit.string.Company}
|
||||||
kind={'no-border'}
|
kind={'no-border'}
|
||||||
size={'small'}
|
size={'small'}
|
||||||
|
showNavigate={false}
|
||||||
|
create={{ component: contact.component.CreateOrganization, label: contact.string.CreateOrganization }}
|
||||||
|
/>
|
||||||
|
<ObjectSearchBox
|
||||||
|
_class={recruit.class.Applicant}
|
||||||
|
bind:value={application}
|
||||||
|
label={recruit.string.Application}
|
||||||
|
placeholder={recruit.string.ApplicationCreateLabel}
|
||||||
|
kind={'no-border'}
|
||||||
|
searchField={'number'}
|
||||||
|
size={'small'}
|
||||||
|
showNavigate={false}
|
||||||
|
allowCategory={[recruit.completion.ApplicationCategory]}
|
||||||
/>
|
/>
|
||||||
<DateRangePresenter
|
<DateRangePresenter
|
||||||
bind:value={startDate}
|
bind:value={startDate}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
import { FullDescriptionBox } from '@hcengineering/text-editor'
|
import { FullDescriptionBox } from '@hcengineering/text-editor'
|
||||||
import { EditBox, Grid, showPanel } from '@hcengineering/ui'
|
import { EditBox, Grid, showPanel } from '@hcengineering/ui'
|
||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
|
import { ObjectPresenter } from '@hcengineering/view-resources'
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
import recruit from '../../plugin'
|
import recruit from '../../plugin'
|
||||||
|
|
||||||
@ -67,14 +68,16 @@
|
|||||||
if (rawTitle !== object.title) client.update(object, { title: rawTitle })
|
if (rawTitle !== object.title) client.update(object, { title: rawTitle })
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
class="clear-mins"
|
class="clear-mins flex-row-center"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
if (candidate !== undefined) {
|
if (candidate !== undefined) {
|
||||||
showPanel(view.component.EditDoc, candidate._id, Hierarchy.mixinOrClass(candidate), 'content')
|
showPanel(view.component.EditDoc, candidate._id, Hierarchy.mixinOrClass(candidate), 'content')
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<ObjectPresenter _class={recruit.class.Applicant} bind:objectId={object.application} />
|
||||||
<UserBox
|
<UserBox
|
||||||
readonly
|
readonly
|
||||||
_class={contact.class.Person}
|
_class={contact.class.Person}
|
||||||
@ -85,6 +88,7 @@
|
|||||||
size={'x-large'}
|
size={'x-large'}
|
||||||
justify={'left'}
|
justify={'left'}
|
||||||
width={'100%'}
|
width={'100%'}
|
||||||
|
showNavigate={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -13,11 +13,12 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Doc, Ref } from '@hcengineering/core'
|
|
||||||
import core from '@hcengineering/core'
|
|
||||||
import { IntlString } from '@hcengineering/platform'
|
|
||||||
import calendar from '@hcengineering/calendar'
|
import calendar from '@hcengineering/calendar'
|
||||||
import { Button, IconAdd, Label, showPopup, resizeObserver, Scroller } from '@hcengineering/ui'
|
import { Organization } from '@hcengineering/contact'
|
||||||
|
import { DateRangeMode, Doc, FindOptions, Ref } from '@hcengineering/core'
|
||||||
|
import { IntlString } from '@hcengineering/platform'
|
||||||
|
import { Applicant, Review } from '@hcengineering/recruit'
|
||||||
|
import { Button, DatePresenter, IconAdd, Label, resizeObserver, showPopup } from '@hcengineering/ui'
|
||||||
import { Table } from '@hcengineering/view-resources'
|
import { Table } from '@hcengineering/view-resources'
|
||||||
import recruit from '../../plugin'
|
import recruit from '../../plugin'
|
||||||
import FileDuo from '../icons/FileDuo.svelte'
|
import FileDuo from '../icons/FileDuo.svelte'
|
||||||
@ -26,11 +27,27 @@
|
|||||||
export let objectId: Ref<Doc>
|
export let objectId: Ref<Doc>
|
||||||
export let reviews: number
|
export let reviews: number
|
||||||
export let label: IntlString = recruit.string.Reviews
|
export let label: IntlString = recruit.string.Reviews
|
||||||
|
export let application: Ref<Applicant> | undefined
|
||||||
|
export let company: Ref<Organization> | undefined
|
||||||
|
|
||||||
const createApp = (): void => {
|
const createApp = (): void => {
|
||||||
showPopup(CreateReview, { candidate: objectId, preserveCandidate: true }, 'top')
|
showPopup(
|
||||||
|
CreateReview,
|
||||||
|
{
|
||||||
|
candidate: objectId,
|
||||||
|
preserveCandidate: true,
|
||||||
|
application,
|
||||||
|
company
|
||||||
|
},
|
||||||
|
'top'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
let wSection: number
|
let wSection: number
|
||||||
|
const options: FindOptions<Review> = {
|
||||||
|
lookup: {
|
||||||
|
application: recruit.class.Applicant
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="antiSection" use:resizeObserver={(element) => (wSection = element.clientWidth)}>
|
<div class="antiSection" use:resizeObserver={(element) => (wSection = element.clientWidth)}>
|
||||||
@ -41,12 +58,12 @@
|
|||||||
<Button icon={IconAdd} kind={'transparent'} shape={'circle'} on:click={createApp} />
|
<Button icon={IconAdd} kind={'transparent'} shape={'circle'} on:click={createApp} />
|
||||||
</div>
|
</div>
|
||||||
{#if reviews > 0}
|
{#if reviews > 0}
|
||||||
{#if wSection < 640}
|
|
||||||
<Scroller horizontal>
|
|
||||||
<Table
|
<Table
|
||||||
_class={recruit.class.Review}
|
_class={recruit.class.Review}
|
||||||
config={[
|
config={[
|
||||||
'',
|
'',
|
||||||
|
'$lookup.application',
|
||||||
|
'company',
|
||||||
'verdict',
|
'verdict',
|
||||||
{
|
{
|
||||||
key: '',
|
key: '',
|
||||||
@ -55,44 +72,20 @@
|
|||||||
sortingKey: 'opinions'
|
sortingKey: 'opinions'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '',
|
key: 'date',
|
||||||
presenter: calendar.component.DateTimePresenter,
|
presenter: DatePresenter,
|
||||||
label: calendar.string.Date,
|
label: calendar.string.Date,
|
||||||
sortingKey: 'date'
|
sortingKey: 'date',
|
||||||
|
props: {
|
||||||
|
editable: false,
|
||||||
|
mode: DateRangeMode.DATE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
options={{
|
{options}
|
||||||
lookup: {
|
|
||||||
space: core.class.Space
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
query={{ attachedTo: objectId }}
|
query={{ attachedTo: objectId }}
|
||||||
loadingProps={{ length: reviews }}
|
loadingProps={{ length: reviews }}
|
||||||
/>
|
/>
|
||||||
</Scroller>
|
|
||||||
{:else}
|
|
||||||
<Table
|
|
||||||
_class={recruit.class.Review}
|
|
||||||
config={[
|
|
||||||
'',
|
|
||||||
'verdict',
|
|
||||||
{
|
|
||||||
key: '',
|
|
||||||
presenter: recruit.component.OpinionsPresenter,
|
|
||||||
label: recruit.string.Opinions,
|
|
||||||
sortingKey: 'opinions'
|
|
||||||
},
|
|
||||||
{ key: '', presenter: calendar.component.DateTimePresenter, label: calendar.string.Date, sortingKey: 'date' }
|
|
||||||
]}
|
|
||||||
options={{
|
|
||||||
lookup: {
|
|
||||||
space: core.class.Space
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
query={{ attachedTo: objectId }}
|
|
||||||
loadingProps={{ length: reviews }}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
{:else}
|
{:else}
|
||||||
<div class="antiSection-empty solid flex-col-center mt-3">
|
<div class="antiSection-empty solid flex-col-center mt-3">
|
||||||
<div class="caption-color">
|
<div class="caption-color">
|
||||||
@ -101,6 +94,7 @@
|
|||||||
<span class="dark-color mt-2">
|
<span class="dark-color mt-2">
|
||||||
<Label label={recruit.string.NoReviewForCandidate} />
|
<Label label={recruit.string.NoReviewForCandidate} />
|
||||||
</span>
|
</span>
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<span class="over-underline content-accent-color" on:click={createApp}>
|
<span class="over-underline content-accent-color" on:click={createApp}>
|
||||||
<Label label={recruit.string.CreateAnReview} />
|
<Label label={recruit.string.CreateAnReview} />
|
||||||
</span>
|
</span>
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
import { Client, Doc, Ref, Space } from '@hcengineering/core'
|
import { Client, Doc, Ref, Space } from '@hcengineering/core'
|
||||||
import type { IntlString, Resource, StatusCode } from '@hcengineering/platform'
|
import type { IntlString, Resource, StatusCode } from '@hcengineering/platform'
|
||||||
import { mergeIds } from '@hcengineering/platform'
|
import { mergeIds } from '@hcengineering/platform'
|
||||||
|
import { ObjectSearchCategory, ObjectSearchFactory } from '@hcengineering/presentation'
|
||||||
import recruit, { recruitId } from '@hcengineering/recruit'
|
import recruit, { recruitId } from '@hcengineering/recruit'
|
||||||
import { TagCategory } from '@hcengineering/tags'
|
import { TagCategory } from '@hcengineering/tags'
|
||||||
import { AnyComponent } from '@hcengineering/ui'
|
import { AnyComponent } from '@hcengineering/ui'
|
||||||
@ -118,7 +119,8 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
Score: '' as IntlString,
|
Score: '' as IntlString,
|
||||||
Match: '' as IntlString,
|
Match: '' as IntlString,
|
||||||
PerformMatch: '' as IntlString,
|
PerformMatch: '' as IntlString,
|
||||||
MoveApplication: '' as IntlString
|
MoveApplication: '' as IntlString,
|
||||||
|
Application: '' as IntlString
|
||||||
},
|
},
|
||||||
space: {
|
space: {
|
||||||
CandidatesPublic: '' as Ref<Space>
|
CandidatesPublic: '' as Ref<Space>
|
||||||
@ -127,6 +129,12 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
Other: '' as Ref<TagCategory>,
|
Other: '' as Ref<TagCategory>,
|
||||||
Category: '' as Ref<TagCategory>
|
Category: '' as Ref<TagCategory>
|
||||||
},
|
},
|
||||||
|
completion: {
|
||||||
|
ApplicationQuery: '' as Resource<ObjectSearchFactory>,
|
||||||
|
ApplicationCategory: '' as Ref<ObjectSearchCategory>,
|
||||||
|
VacancyCategory: '' as Ref<ObjectSearchCategory>,
|
||||||
|
VacancyQuery: '' as Resource<ObjectSearchFactory>
|
||||||
|
},
|
||||||
component: {
|
component: {
|
||||||
VacancyItemPresenter: '' as AnyComponent,
|
VacancyItemPresenter: '' as AnyComponent,
|
||||||
VacancyCountPresenter: '' as AnyComponent,
|
VacancyCountPresenter: '' as AnyComponent,
|
||||||
|
@ -111,6 +111,8 @@ export interface Review extends Event {
|
|||||||
|
|
||||||
verdict: string
|
verdict: string
|
||||||
|
|
||||||
|
application?: Ref<Applicant>
|
||||||
|
|
||||||
company?: Ref<Organization>
|
company?: Ref<Organization>
|
||||||
|
|
||||||
opinions?: number
|
opinions?: number
|
||||||
|
169
plugins/view-resources/src/components/ObjectSearchBox.svelte
Normal file
169
plugins/view-resources/src/components/ObjectSearchBox.svelte
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||||
|
// Copyright © 2021 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 { Class, Doc, DocumentQuery, FindOptions, Hierarchy, Ref } from '@hcengineering/core'
|
||||||
|
import { Asset, IntlString } from '@hcengineering/platform'
|
||||||
|
import presentation, {
|
||||||
|
getClient,
|
||||||
|
ObjectCreate,
|
||||||
|
ObjectSearchCategory,
|
||||||
|
ObjectSearchPopup,
|
||||||
|
ObjectSearchResult
|
||||||
|
} from '@hcengineering/presentation'
|
||||||
|
import {
|
||||||
|
ActionIcon,
|
||||||
|
AnySvelteComponent,
|
||||||
|
Button,
|
||||||
|
ButtonKind,
|
||||||
|
ButtonSize,
|
||||||
|
getEventPositionElement,
|
||||||
|
getFocusManager,
|
||||||
|
Icon,
|
||||||
|
IconOpen,
|
||||||
|
Label,
|
||||||
|
LabelAndProps,
|
||||||
|
showPanel,
|
||||||
|
showPopup
|
||||||
|
} from '@hcengineering/ui'
|
||||||
|
import view from '@hcengineering/view'
|
||||||
|
import { createEventDispatcher } from 'svelte'
|
||||||
|
import ObjectPresenter from './ObjectPresenter.svelte'
|
||||||
|
|
||||||
|
export let _class: Ref<Class<Doc>>
|
||||||
|
export let excluded: Ref<Doc>[] | undefined = undefined
|
||||||
|
export let options: FindOptions<Doc> | undefined = undefined
|
||||||
|
export let docQuery: DocumentQuery<Doc> | undefined = undefined
|
||||||
|
export let label: IntlString
|
||||||
|
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
||||||
|
export let placeholder: IntlString = presentation.string.Search
|
||||||
|
export let value: Ref<Doc> | null | undefined
|
||||||
|
export let allowDeselect = false
|
||||||
|
export let titleDeselect: IntlString | undefined = undefined
|
||||||
|
export let readonly = false
|
||||||
|
export let kind: ButtonKind = 'no-border'
|
||||||
|
export let size: ButtonSize = 'small'
|
||||||
|
export let justify: 'left' | 'center' = 'center'
|
||||||
|
export let width: string | undefined = undefined
|
||||||
|
export let focusIndex = -1
|
||||||
|
export let showTooltip: LabelAndProps | undefined = undefined
|
||||||
|
export let showNavigate = true
|
||||||
|
export let id: string | undefined = undefined
|
||||||
|
export let searchField: string = 'name'
|
||||||
|
export let docProps: Record<string, any> = {}
|
||||||
|
export let allowCategory: Ref<ObjectSearchCategory>[] | undefined
|
||||||
|
|
||||||
|
export let create: ObjectCreate | undefined = undefined
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
let selected: Doc | undefined
|
||||||
|
let container: HTMLElement
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
|
async function updateSelected (value: Ref<Doc> | null | undefined) {
|
||||||
|
selected = value ? await client.findOne(_class, { _id: value }) : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
$: updateSelected(value)
|
||||||
|
|
||||||
|
const mgr = getFocusManager()
|
||||||
|
|
||||||
|
const _click = (ev: MouseEvent): void => {
|
||||||
|
if (!readonly) {
|
||||||
|
showPopup(
|
||||||
|
ObjectSearchPopup,
|
||||||
|
{
|
||||||
|
_class,
|
||||||
|
options,
|
||||||
|
docQuery,
|
||||||
|
ignoreObjects: excluded ?? [],
|
||||||
|
icon,
|
||||||
|
allowDeselect,
|
||||||
|
selected: value,
|
||||||
|
titleDeselect,
|
||||||
|
placeholder,
|
||||||
|
create,
|
||||||
|
searchField,
|
||||||
|
docProps,
|
||||||
|
allowCategory
|
||||||
|
},
|
||||||
|
!$$slots.content ? container : getEventPositionElement(ev),
|
||||||
|
(result: ObjectSearchResult) => {
|
||||||
|
if (result === null) {
|
||||||
|
value = null
|
||||||
|
selected = undefined
|
||||||
|
dispatch('change', null)
|
||||||
|
} else if (result !== undefined && result.doc._id !== value) {
|
||||||
|
value = result.doc._id
|
||||||
|
dispatch('change', value)
|
||||||
|
}
|
||||||
|
mgr?.setFocusPos(focusIndex)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: hideIcon = size === 'x-large' || (size === 'large' && kind !== 'link')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div {id} bind:this={container} class="min-w-0" class:w-full={width === '100%'} class:h-full={$$slots.content}>
|
||||||
|
{#if $$slots.content}
|
||||||
|
<div class="w-full h-full flex-streatch" on:click={_click}>
|
||||||
|
<slot name="content" />
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<Button {focusIndex} width={width ?? 'min-content'} {size} {kind} {justify} {showTooltip} on:click={_click}>
|
||||||
|
<span slot="content" class="overflow-label flex-grow" class:flex-between={showNavigate && selected}>
|
||||||
|
<div
|
||||||
|
class="disabled flex-row-center"
|
||||||
|
style:width={showNavigate && selected
|
||||||
|
? `calc(${width ?? 'min-content'} - 1.5rem)`
|
||||||
|
: `${width ?? 'min-content'}`}
|
||||||
|
>
|
||||||
|
{#if selected}
|
||||||
|
<ObjectPresenter
|
||||||
|
objectId={selected._id}
|
||||||
|
_class={selected._class}
|
||||||
|
value={selected}
|
||||||
|
props={{ ...docProps, isInteractive: false, inline: true, size: 'x-small' }}
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<div class="flex-row-center">
|
||||||
|
{#if icon}
|
||||||
|
<Icon {icon} size={kind === 'link' ? 'small' : size} />
|
||||||
|
{/if}
|
||||||
|
<div class="ml-2">
|
||||||
|
<Label {label} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{#if selected && showNavigate}
|
||||||
|
<ActionIcon
|
||||||
|
icon={IconOpen}
|
||||||
|
size={'small'}
|
||||||
|
action={() => {
|
||||||
|
if (selected) {
|
||||||
|
showPanel(view.component.EditDoc, selected._id, Hierarchy.mixinOrClass(selected), 'content')
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
@ -94,6 +94,7 @@ export { default as LinkPresenter } from './components/LinkPresenter.svelte'
|
|||||||
export { default as List } from './components/list/List.svelte'
|
export { default as List } from './components/list/List.svelte'
|
||||||
export { default as ContextMenu } from './components/Menu.svelte'
|
export { default as ContextMenu } from './components/Menu.svelte'
|
||||||
export { default as ObjectBox } from './components/ObjectBox.svelte'
|
export { default as ObjectBox } from './components/ObjectBox.svelte'
|
||||||
|
export { default as ObjectSearchBox } from './components/ObjectSearchBox.svelte'
|
||||||
export { default as ObjectPresenter } from './components/ObjectPresenter.svelte'
|
export { default as ObjectPresenter } from './components/ObjectPresenter.svelte'
|
||||||
export { default as TableBrowser } from './components/TableBrowser.svelte'
|
export { default as TableBrowser } from './components/TableBrowser.svelte'
|
||||||
export { default as ValueSelector } from './components/ValueSelector.svelte'
|
export { default as ValueSelector } from './components/ValueSelector.svelte'
|
||||||
|
Loading…
Reference in New Issue
Block a user