mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
Remove review Category (#1727)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
6c96af45d4
commit
f8e0e58a6e
@ -44,7 +44,7 @@ import { Applicant, Candidate, Candidates, Vacancy } from '@anticrm/recruit'
|
||||
import { KeyBinding } from '@anticrm/view'
|
||||
import recruit from './plugin'
|
||||
import { createReviewModel, reviewTableConfig, reviewTableOptions } from './review'
|
||||
import { TOpinion, TReview, TReviewCategory } from './review-model'
|
||||
import { TOpinion, TReview } from './review-model'
|
||||
|
||||
@Model(recruit.class.Vacancy, task.class.SpaceWithStates)
|
||||
@UX(recruit.string.Vacancy, recruit.icon.Vacancy)
|
||||
@ -123,7 +123,7 @@ export class TApplicant extends TTask implements Applicant {
|
||||
}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createModel(TVacancy, TCandidates, TCandidate, TApplicant, TReviewCategory, TReview, TOpinion)
|
||||
builder.createModel(TVacancy, TCandidates, TCandidate, TApplicant, TReview, TOpinion)
|
||||
|
||||
builder.mixin(recruit.class.Vacancy, core.class.Class, workbench.mixin.SpaceView, {
|
||||
view: {
|
||||
@ -156,14 +156,7 @@ export function createModel (builder: Builder): void {
|
||||
icon: recruit.icon.RecruitApplication,
|
||||
hidden: false,
|
||||
navigatorModel: {
|
||||
spaces: [
|
||||
{
|
||||
label: recruit.string.ReviewCategory,
|
||||
spaceClass: recruit.class.ReviewCategory,
|
||||
addSpaceLabel: recruit.string.CreateReviewCategory,
|
||||
createComponent: recruit.component.CreateReviewCategory
|
||||
}
|
||||
],
|
||||
spaces: [],
|
||||
specials: [
|
||||
{
|
||||
id: vacanciesId,
|
||||
@ -218,15 +211,19 @@ export function createModel (builder: Builder): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'upcoming',
|
||||
component: calendar.component.UpcomingEvents,
|
||||
id: 'reviews',
|
||||
component: calendar.component.Events,
|
||||
componentProps: {
|
||||
viewLabel: recruit.string.Reviews,
|
||||
viewIcon: recruit.icon.Review,
|
||||
_class: recruit.class.Review,
|
||||
options: reviewTableOptions,
|
||||
config: reviewTableConfig
|
||||
config: reviewTableConfig,
|
||||
createLabel: recruit.string.ReviewCreateLabel,
|
||||
createComponent: recruit.component.CreateReview
|
||||
},
|
||||
icon: calendar.icon.Calendar,
|
||||
label: calendar.string.UpcomingEvents,
|
||||
label: recruit.string.Reviews,
|
||||
position: 'event'
|
||||
}
|
||||
]
|
||||
@ -343,10 +340,6 @@ export function createModel (builder: Builder): void {
|
||||
editor: recruit.component.EditVacancy
|
||||
})
|
||||
|
||||
builder.mixin(recruit.class.ReviewCategory, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: recruit.component.EditReviewCategory
|
||||
})
|
||||
|
||||
builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.AttributePresenter, {
|
||||
presenter: recruit.component.ApplicationPresenter
|
||||
})
|
||||
@ -355,10 +348,6 @@ export function createModel (builder: Builder): void {
|
||||
presenter: recruit.component.VacancyPresenter
|
||||
})
|
||||
|
||||
builder.mixin(recruit.class.ReviewCategory, core.class.Class, view.mixin.AttributePresenter, {
|
||||
presenter: recruit.component.ReviewCategoryPresenter
|
||||
})
|
||||
|
||||
builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.ObjectValidator, {
|
||||
validator: recruit.validator.ApplicantValidator
|
||||
})
|
||||
|
@ -13,8 +13,10 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import core, { Doc, Ref, Space, TxOperations } from '@anticrm/core'
|
||||
import core, { Class, Doc, DOMAIN_TX, Ref, Space, TxOperations } from '@anticrm/core'
|
||||
import { createOrUpdate, MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
|
||||
import { DOMAIN_CALENDAR } from '@anticrm/model-calendar'
|
||||
import { DOMAIN_SPACE } from '@anticrm/model-core'
|
||||
import tags, { TagCategory } from '@anticrm/model-tags'
|
||||
import { createKanbanTemplate, createSequence } from '@anticrm/model-task'
|
||||
import { getCategories } from '@anticrm/skillset'
|
||||
@ -22,7 +24,31 @@ import { KanbanTemplate } from '@anticrm/task'
|
||||
import recruit from './plugin'
|
||||
|
||||
export const recruitOperation: MigrateOperation = {
|
||||
async migrate (client: MigrationClient): Promise<void> {},
|
||||
async migrate (client: MigrationClient): Promise<void> {
|
||||
await client.update(
|
||||
DOMAIN_CALENDAR,
|
||||
{
|
||||
_class: recruit.class.Review,
|
||||
space: { $nin: [recruit.space.Reviews] }
|
||||
},
|
||||
{
|
||||
space: recruit.space.Reviews
|
||||
}
|
||||
)
|
||||
const categories = await client.find(DOMAIN_SPACE, {
|
||||
_class: 'recruit:class:ReviewCategory' as Ref<Class<Doc>>
|
||||
})
|
||||
for (const cat of categories) {
|
||||
await client.delete(DOMAIN_SPACE, cat._id)
|
||||
}
|
||||
|
||||
const catTx = await client.find(DOMAIN_TX, {
|
||||
objectClass: 'recruit:class:ReviewCategory' as Ref<Class<Doc>>
|
||||
})
|
||||
for (const cat of catTx) {
|
||||
await client.delete(DOMAIN_TX, cat._id)
|
||||
}
|
||||
},
|
||||
async upgrade (client: MigrationUpgradeClient): Promise<void> {
|
||||
const tx = new TxOperations(client, core.account.System)
|
||||
await createDefaults(tx)
|
||||
@ -30,7 +56,7 @@ export const recruitOperation: MigrateOperation = {
|
||||
}
|
||||
|
||||
async function createDefaults (tx: TxOperations): Promise<void> {
|
||||
await createSpace(tx)
|
||||
await createSpaces(tx)
|
||||
|
||||
await createOrUpdate(
|
||||
tx,
|
||||
@ -66,44 +92,6 @@ async function createDefaults (tx: TxOperations): Promise<void> {
|
||||
await createSequence(tx, recruit.class.Opinion)
|
||||
await createSequence(tx, recruit.class.Applicant)
|
||||
await createDefaultKanbanTemplate(tx)
|
||||
await createReviewTemplates(tx)
|
||||
}
|
||||
|
||||
async function createReviewTemplates (tx: TxOperations): Promise<void> {
|
||||
if ((await tx.findOne(core.class.TxCreateDoc, { objectId: recruit.template.Interview })) === undefined) {
|
||||
await createKanbanTemplate(tx, {
|
||||
kanbanId: recruit.template.Interview,
|
||||
space: recruit.space.ReviewTemplates as Ref<Doc> as Ref<Space>,
|
||||
title: 'Interview',
|
||||
states: [
|
||||
{ color: 9, title: 'Prepare' },
|
||||
{ color: 10, title: 'Appointment' },
|
||||
{ color: 1, title: 'Opinions' }
|
||||
],
|
||||
doneStates: [
|
||||
{ isWon: true, title: 'Pass' },
|
||||
{ isWon: false, title: 'Failed' }
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
if ((await tx.findOne(core.class.TxCreateDoc, { objectId: recruit.template.Task })) === undefined) {
|
||||
await createKanbanTemplate(tx, {
|
||||
kanbanId: recruit.template.Task,
|
||||
space: recruit.space.ReviewTemplates as Ref<Doc> as Ref<Space>,
|
||||
title: 'Test task',
|
||||
states: [
|
||||
{ color: 9, title: 'Prepare' },
|
||||
{ color: 10, title: 'Assigned' },
|
||||
{ color: 1, title: 'Review' },
|
||||
{ color: 4, title: 'Opinions' }
|
||||
],
|
||||
doneStates: [
|
||||
{ isWon: true, title: 'Pass' },
|
||||
{ isWon: false, title: 'Failed' }
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function createDefaultKanbanTemplate (tx: TxOperations): Promise<Ref<KanbanTemplate>> {
|
||||
@ -129,7 +117,7 @@ async function createDefaultKanbanTemplate (tx: TxOperations): Promise<Ref<Kanba
|
||||
})
|
||||
}
|
||||
|
||||
async function createSpace (tx: TxOperations): Promise<void> {
|
||||
async function createSpaces (tx: TxOperations): Promise<void> {
|
||||
const current = await tx.findOne(core.class.Space, {
|
||||
_id: recruit.space.CandidatesPublic
|
||||
})
|
||||
@ -147,4 +135,22 @@ async function createSpace (tx: TxOperations): Promise<void> {
|
||||
recruit.space.CandidatesPublic
|
||||
)
|
||||
}
|
||||
|
||||
const currentReviews = await tx.findOne(core.class.Space, {
|
||||
_id: recruit.space.Reviews
|
||||
})
|
||||
if (currentReviews === undefined) {
|
||||
await tx.createDoc(
|
||||
core.class.Space,
|
||||
core.space.Space,
|
||||
{
|
||||
name: 'Reviews',
|
||||
description: 'Public reviews',
|
||||
private: true,
|
||||
members: [],
|
||||
archived: false
|
||||
},
|
||||
recruit.space.Reviews
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ export default mergeIds(recruitId, recruit, {
|
||||
ApplicationPresenter: '' as AnyComponent,
|
||||
ApplicationsPresenter: '' as AnyComponent,
|
||||
VacancyPresenter: '' as AnyComponent,
|
||||
ReviewCategoryPresenter: '' as AnyComponent,
|
||||
EditApplication: '' as AnyComponent,
|
||||
TemplatesIcon: '' as AnyComponent,
|
||||
Applications: '' as AnyComponent,
|
||||
@ -73,7 +72,6 @@ export default mergeIds(recruitId, recruit, {
|
||||
SkillsView: '' as AnyComponent,
|
||||
Vacancies: '' as AnyComponent,
|
||||
|
||||
CreateReviewCategory: '' as AnyComponent,
|
||||
CreateReview: '' as AnyComponent,
|
||||
Reviews: '' as AnyComponent,
|
||||
KanbanReviewCard: '' as AnyComponent,
|
||||
@ -86,8 +84,6 @@ export default mergeIds(recruitId, recruit, {
|
||||
},
|
||||
template: {
|
||||
DefaultVacancy: '' as Ref<KanbanTemplate>,
|
||||
|
||||
Interview: '' as Ref<KanbanTemplate>,
|
||||
Task: '' as Ref<KanbanTemplate>
|
||||
},
|
||||
completion: {
|
||||
|
@ -5,18 +5,11 @@ import attachment from '@anticrm/model-attachment'
|
||||
import calendar, { TEvent } from '@anticrm/model-calendar'
|
||||
import chunter from '@anticrm/model-chunter'
|
||||
import contact from '@anticrm/model-contact'
|
||||
import core, { TAttachedDoc, TSpace } from '@anticrm/model-core'
|
||||
import core, { TAttachedDoc } from '@anticrm/model-core'
|
||||
import task from '@anticrm/model-task'
|
||||
import { Candidate, Opinion, Review, ReviewCategory } from '@anticrm/recruit'
|
||||
import { Candidate, Opinion, Review } from '@anticrm/recruit'
|
||||
import recruit from './plugin'
|
||||
|
||||
@Model(recruit.class.ReviewCategory, core.class.Space)
|
||||
@UX(recruit.string.ReviewCategory, recruit.icon.Review)
|
||||
export class TReviewCategory extends TSpace implements ReviewCategory {
|
||||
@Prop(TypeString(), recruit.string.FullDescription)
|
||||
fullDescription?: string
|
||||
}
|
||||
|
||||
@Model(recruit.class.Review, calendar.class.Event)
|
||||
@UX(recruit.string.Review, recruit.icon.Review, recruit.string.ReviewShortLabel, 'number')
|
||||
export class TReview extends TEvent implements Review {
|
||||
|
@ -3,9 +3,7 @@ import { Builder } from '@anticrm/model'
|
||||
import calendar from '@anticrm/model-calendar'
|
||||
import contact from '@anticrm/model-contact'
|
||||
import core from '@anticrm/model-core'
|
||||
import { actionTemplates } from '@anticrm/model-task'
|
||||
import view, { createAction } from '@anticrm/model-view'
|
||||
import workbench from '@anticrm/model-workbench'
|
||||
import { Review } from '@anticrm/recruit'
|
||||
import { BuildModelKey } from '@anticrm/view'
|
||||
import recruit from './plugin'
|
||||
@ -35,14 +33,6 @@ export const reviewTableConfig: (BuildModelKey | string)[] = [
|
||||
]
|
||||
|
||||
export function createReviewModel (builder: Builder): void {
|
||||
builder.mixin(recruit.class.ReviewCategory, core.class.Class, workbench.mixin.SpaceView, {
|
||||
view: {
|
||||
class: recruit.class.Review,
|
||||
createItemDialog: recruit.component.CreateReview,
|
||||
createItemLabel: recruit.string.ReviewCreateLabel
|
||||
}
|
||||
})
|
||||
|
||||
builder.mixin(recruit.class.Review, core.class.Class, view.mixin.CollectionEditor, {
|
||||
editor: recruit.component.Reviews
|
||||
})
|
||||
@ -106,9 +96,6 @@ export function createReviewModel (builder: Builder): void {
|
||||
}
|
||||
})
|
||||
|
||||
createAction(builder, { ...actionTemplates.archiveSpace, target: recruit.class.ReviewCategory })
|
||||
createAction(builder, { ...actionTemplates.unarchiveSpace, target: recruit.class.ReviewCategory })
|
||||
|
||||
const reviewOptions: FindOptions<Review> = {
|
||||
lookup: {
|
||||
attachedTo: recruit.mixin.Candidate,
|
||||
|
@ -115,12 +115,7 @@
|
||||
</div>
|
||||
<div class="scroll">
|
||||
<div class="box">
|
||||
<ListView
|
||||
bind:this={list}
|
||||
count={objects.length}
|
||||
bind:selection
|
||||
on:click={(evt) => handleSelection(evt, evt.detail)}
|
||||
>
|
||||
<ListView bind:this={list} count={objects.length} bind:selection>
|
||||
<svelte:fragment slot="item" let:item>
|
||||
{@const person = objects[item]}
|
||||
<button
|
||||
|
@ -21,7 +21,6 @@
|
||||
"ModeMonth": "Month",
|
||||
"ModeYear": "Year",
|
||||
"Today": "Today",
|
||||
"UpcomingEvents": "Upcoming events",
|
||||
"TableView": "Table",
|
||||
"DueMinutes": "{minutes, plural, =0 {less than a minute} =1 {a minute} other {# minutes}}",
|
||||
"DueHours": "{hours, plural, =0 {less than an hour} =1 {1 hour} other {# hours}}",
|
||||
|
@ -21,7 +21,6 @@
|
||||
"ModeMonth": "Месяц",
|
||||
"ModeYear": "Год",
|
||||
"Today": "Сегодня",
|
||||
"UpcomingEvents": "Предстоящие события",
|
||||
"TableView": "Таблица",
|
||||
"DueMinutes": "{minutes, plural, =0 {меньше минуты} =1 {минута} other {# минут}}",
|
||||
"DueHours": "{hours, plural, =0 {меньше часа} =1 {1 час} other {# часы}}",
|
||||
|
@ -14,12 +14,21 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Event } from '@anticrm/calendar'
|
||||
import { EmployeeAccount } from '@anticrm/contact'
|
||||
import { Class, DocumentQuery, FindOptions, getCurrentAccount, Ref } from '@anticrm/core'
|
||||
import { Class, DocumentQuery, FindOptions, Ref } from '@anticrm/core'
|
||||
import { Asset, IntlString } from '@anticrm/platform'
|
||||
import { AnySvelteComponent, Icon, Label, SearchEdit, Tooltip } from '@anticrm/ui'
|
||||
import { Table } from '@anticrm/view-resources'
|
||||
import {
|
||||
AnyComponent,
|
||||
AnySvelteComponent,
|
||||
Button,
|
||||
Icon,
|
||||
IconAdd,
|
||||
Label,
|
||||
SearchEdit,
|
||||
showPopup,
|
||||
Tooltip
|
||||
} from '@anticrm/ui'
|
||||
import view from '@anticrm/view'
|
||||
import { TableBrowser } from '@anticrm/view-resources'
|
||||
import calendar from '../plugin'
|
||||
import CalendarView from './CalendarView.svelte'
|
||||
|
||||
@ -29,15 +38,17 @@
|
||||
export let baseMenuClass: Ref<Class<Event>> | undefined = undefined
|
||||
export let config: string[]
|
||||
|
||||
const currentUser = getCurrentAccount() as EmployeeAccount
|
||||
export let viewIcon: Asset = calendar.icon.Calendar
|
||||
export let viewLabel: IntlString = calendar.string.Events
|
||||
|
||||
export let createComponent: AnyComponent | undefined
|
||||
export let createLabel: IntlString | undefined
|
||||
|
||||
let search = ''
|
||||
let resultQuery: DocumentQuery<Event> = {}
|
||||
|
||||
function updateResultQuery (search: string): void {
|
||||
resultQuery = search === '' ? { ...query } : { ...query, $search: search }
|
||||
|
||||
resultQuery.participants = currentUser.employee
|
||||
}
|
||||
|
||||
$: updateResultQuery(search)
|
||||
@ -50,6 +61,19 @@
|
||||
}
|
||||
|
||||
$: viewlets = [
|
||||
{
|
||||
component: TableBrowser,
|
||||
icon: view.icon.Table,
|
||||
label: calendar.string.TableView,
|
||||
props: {
|
||||
_class,
|
||||
query: resultQuery,
|
||||
options,
|
||||
baseMenuClass,
|
||||
config,
|
||||
search
|
||||
}
|
||||
},
|
||||
{
|
||||
component: CalendarView,
|
||||
icon: calendar.icon.Calendar,
|
||||
@ -63,28 +87,22 @@
|
||||
config,
|
||||
search
|
||||
}
|
||||
},
|
||||
{
|
||||
component: Table,
|
||||
icon: view.icon.Table,
|
||||
label: calendar.string.TableView,
|
||||
props: {
|
||||
_class,
|
||||
query: resultQuery,
|
||||
options,
|
||||
baseMenuClass,
|
||||
config,
|
||||
search
|
||||
}
|
||||
}
|
||||
] as CalendarViewlet[]
|
||||
let selectedViewlet = 0
|
||||
|
||||
function showCreateDialog () {
|
||||
if (createComponent === undefined) {
|
||||
return
|
||||
}
|
||||
showPopup(createComponent, {}, 'top')
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="ac-header full">
|
||||
<div class="ac-header__wrap-title">
|
||||
<div class="ac-header__icon"><Icon icon={calendar.icon.Calendar} size={'small'} /></div>
|
||||
<span class="ac-header__title"><Label label={calendar.string.UpcomingEvents} /></span>
|
||||
<div class="ac-header__icon"><Icon icon={viewIcon} size={'small'} /></div>
|
||||
<span class="ac-header__title"><Label label={viewLabel} /></span>
|
||||
</div>
|
||||
|
||||
{#if viewlets.length > 1}
|
||||
@ -111,6 +129,7 @@
|
||||
updateResultQuery(search)
|
||||
}}
|
||||
/>
|
||||
<Button icon={IconAdd} label={createLabel} kind={'primary'} on:click={showCreateDialog} />
|
||||
</div>
|
||||
|
||||
{#if viewlets[selectedViewlet]}
|
@ -21,7 +21,7 @@ import SaveEventReminder from './components/SaveEventReminder.svelte'
|
||||
import DateTimePresenter from './components/DateTimePresenter.svelte'
|
||||
import DocReminder from './components/DocReminder.svelte'
|
||||
import PersonsPresenter from './components/PersonsPresenter.svelte'
|
||||
import UpcomingEvents from './components/UpcomingEvents.svelte'
|
||||
import Events from './components/Events.svelte'
|
||||
import ReminderPresenter from './components/ReminderPresenter.svelte'
|
||||
import ReminderViewlet from './components/activity/ReminderViewlet.svelte'
|
||||
import EditEvent from './components/EditEvent.svelte'
|
||||
@ -37,7 +37,7 @@ export default async (): Promise<Resources> => ({
|
||||
ReminderPresenter,
|
||||
PersonsPresenter,
|
||||
CalendarView,
|
||||
UpcomingEvents,
|
||||
Events,
|
||||
DateTimePresenter,
|
||||
DocReminder,
|
||||
RemindersPopup
|
||||
|
@ -33,7 +33,6 @@ export default mergeIds(calendarId, calendar, {
|
||||
ModeMonth: '' as IntlString,
|
||||
ModeYear: '' as IntlString,
|
||||
Today: '' as IntlString,
|
||||
UpcomingEvents: '' as IntlString,
|
||||
TableView: '' as IntlString,
|
||||
DueMinutes: '' as IntlString,
|
||||
DueHours: '' as IntlString,
|
||||
|
@ -82,7 +82,7 @@ const calendarPlugin = plugin(calendarId, {
|
||||
},
|
||||
component: {
|
||||
PersonsPresenter: '' as AnyComponent,
|
||||
UpcomingEvents: '' as AnyComponent,
|
||||
Events: '' as AnyComponent,
|
||||
DateTimePresenter: '' as AnyComponent,
|
||||
DocReminder: '' as AnyComponent,
|
||||
RemindersPopup: '' as AnyComponent
|
||||
|
@ -16,7 +16,7 @@
|
||||
<script lang="ts">
|
||||
import { Doc, DocumentQuery } from '@anticrm/core'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import { Button, Icon, IconAdd, Label, Scroller, SearchEdit, showPopup } from '@anticrm/ui'
|
||||
import { Button, Icon, IconAdd, Label, SearchEdit, showPopup } from '@anticrm/ui'
|
||||
import view, { Viewlet } from '@anticrm/view'
|
||||
import { ActionContext, TableBrowser } from '@anticrm/view-resources'
|
||||
import contact from '../plugin'
|
||||
@ -66,17 +66,15 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Scroller tableFade>
|
||||
{#await tableDescriptor then descr}
|
||||
{#if descr}
|
||||
<TableBrowser
|
||||
_class={contact.class.Contact}
|
||||
config={descr.config}
|
||||
options={descr.options}
|
||||
query={resultQuery}
|
||||
showNotification
|
||||
/>
|
||||
{/if}
|
||||
{/await}
|
||||
</Scroller>
|
||||
{#await tableDescriptor then descr}
|
||||
{#if descr}
|
||||
<TableBrowser
|
||||
_class={contact.class.Contact}
|
||||
config={descr.config}
|
||||
options={descr.options}
|
||||
query={resultQuery}
|
||||
showNotification
|
||||
/>
|
||||
{/if}
|
||||
{/await}
|
||||
</div>
|
||||
|
@ -12,9 +12,9 @@
|
||||
"VacancyPlaceholder": "Разработчик",
|
||||
"MakePrivate": "Сделать личным",
|
||||
"MakePrivateDescription": "Только пользователи могут видеть это",
|
||||
"CreateAnApplication": "Создать претендента",
|
||||
"CreateAnApplication": "Новый Претендент",
|
||||
"NoApplicationsForCandidate": "Нет претендентов для данного кандидата.",
|
||||
"CreateApplication": "Создать претендента",
|
||||
"CreateApplication": "Новый Претендент",
|
||||
"SelectVacancy": "Выбрать вакансию",
|
||||
"Candidate": "Кандидат",
|
||||
"CandidateCreateLabel": "Кандидата",
|
||||
@ -57,21 +57,21 @@
|
||||
"EditVacancy": "Редактировать",
|
||||
"FullDescription": "Детальное описание",
|
||||
|
||||
"CreateReviewCategory": "Создать категорию оценки",
|
||||
"CreateReviewCategory": "Создать категорию ревью",
|
||||
"ReviewCategoryName": "Имя категории*",
|
||||
"ReviewCategoryPlaceholder": "Интервью",
|
||||
"ReviewCategory": "Оценки",
|
||||
"ReviewCategory": "Ревью",
|
||||
"ReviewCategoryDescription": "Описание",
|
||||
"ThisReviewCategoryIsPrivate": "Эта категория личная",
|
||||
"CreateReview": "Запланировать оценку",
|
||||
"CreateReview": "Запланировать Ревью",
|
||||
"CreateReviewParams": "Запланировать {label}",
|
||||
"SelectReviewCategory": "выбрать категорию",
|
||||
"Reviews": "Оценки",
|
||||
"Review": "Оценка",
|
||||
"ReviewCreateLabel": "Оценку",
|
||||
"Reviews": "Ревью",
|
||||
"Review": "Ревью",
|
||||
"ReviewCreateLabel": "Ревью",
|
||||
"Opinions": "Мнения",
|
||||
"Opinion": "Мнение",
|
||||
"OpinionValue": "Оценка",
|
||||
"OpinionValue": "Значение",
|
||||
"OpinionShortLabel": "OPE",
|
||||
"ReviewShortLabel": "RVE",
|
||||
"StartDate": "Дата начала",
|
||||
@ -79,9 +79,9 @@
|
||||
"ReviewCategoryTitle":"Категория",
|
||||
"Verdict": "Вердикт",
|
||||
"OpinionSave": "Сохранить",
|
||||
"CandidateReviews": "Оценки кандидата",
|
||||
"NoReviewForCandidate": "Нет оценок",
|
||||
"CreateAnReview": "Добавить оценку",
|
||||
"CandidateReviews": "Ревью кандидата",
|
||||
"NoReviewForCandidate": "Нет ревью",
|
||||
"CreateAnReview": "Добавить Ревью",
|
||||
"CreateOpinion": "Добавить мнение",
|
||||
"OpinionValuePlaceholder": "10/10",
|
||||
"Participants": "Участники",
|
||||
|
@ -20,7 +20,7 @@
|
||||
import { Doc, DocumentQuery, FindOptions } from '@anticrm/core'
|
||||
import { Applicant } from '@anticrm/recruit'
|
||||
import task from '@anticrm/task'
|
||||
import { Button, Icon, IconAdd, Label, Scroller, SearchEdit, showPopup } from '@anticrm/ui'
|
||||
import { Button, Icon, IconAdd, Label, SearchEdit, showPopup } from '@anticrm/ui'
|
||||
import { BuildModelKey } from '@anticrm/view'
|
||||
import { TableBrowser } from '@anticrm/view-resources'
|
||||
import recruit from '../plugin'
|
||||
@ -82,6 +82,4 @@
|
||||
<Button icon={IconAdd} label={recruit.string.ApplicationCreateLabel} kind={'primary'} on:click={showCreateDialog} />
|
||||
</div>
|
||||
|
||||
<Scroller tableFade>
|
||||
<TableBrowser _class={recruit.class.Applicant} {config} {options} query={resultQuery} showNotification />
|
||||
</Scroller>
|
||||
<TableBrowser _class={recruit.class.Applicant} {config} {options} query={resultQuery} showNotification />
|
||||
|
@ -18,7 +18,7 @@
|
||||
import { Doc, DocumentQuery, Ref } from '@anticrm/core'
|
||||
import { createQuery, getClient } from '@anticrm/presentation'
|
||||
import tags, { selectedTagElements, TagCategory, TagElement } from '@anticrm/tags'
|
||||
import { Component, Icon, Label, Scroller, SearchEdit } from '@anticrm/ui'
|
||||
import { Component, Icon, Label, SearchEdit } from '@anticrm/ui'
|
||||
import view, { Viewlet } from '@anticrm/view'
|
||||
import { ActionContext, TableBrowser } from '@anticrm/view-resources'
|
||||
import recruit from '../plugin'
|
||||
@ -82,16 +82,14 @@
|
||||
mode: 'browser'
|
||||
}}
|
||||
/>
|
||||
<Scroller tableFade>
|
||||
{#await tableDescriptor then descr}
|
||||
{#if descr}
|
||||
<TableBrowser
|
||||
_class={recruit.mixin.Candidate}
|
||||
config={descr.config}
|
||||
options={descr.options}
|
||||
query={resultQuery}
|
||||
showNotification
|
||||
/>
|
||||
{/if}
|
||||
{/await}
|
||||
</Scroller>
|
||||
{#await tableDescriptor then descr}
|
||||
{#if descr}
|
||||
<TableBrowser
|
||||
_class={recruit.mixin.Candidate}
|
||||
config={descr.config}
|
||||
options={descr.options}
|
||||
query={resultQuery}
|
||||
showNotification
|
||||
/>
|
||||
{/if}
|
||||
{/await}
|
||||
|
@ -17,8 +17,7 @@
|
||||
import core, { Doc, DocumentQuery, Lookup, Ref } from '@anticrm/core'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
import { Vacancy } from '@anticrm/recruit'
|
||||
import { Button, getCurrentLocation, Icon, IconAdd, Label, navigate, Scroller, showPopup } from '@anticrm/ui'
|
||||
import { SearchEdit } from '@anticrm/ui'
|
||||
import { Button, getCurrentLocation, Icon, IconAdd, Label, navigate, SearchEdit, showPopup } from '@anticrm/ui'
|
||||
import { TableBrowser } from '@anticrm/view-resources'
|
||||
import recruit from '../plugin'
|
||||
import CreateVacancy from './CreateVacancy.svelte'
|
||||
@ -89,44 +88,42 @@
|
||||
/>
|
||||
<Button icon={IconAdd} label={recruit.string.VacancyCreateLabel} kind={'primary'} on:click={showCreateDialog} />
|
||||
</div>
|
||||
<Scroller tableFade>
|
||||
<TableBrowser
|
||||
_class={recruit.class.Vacancy}
|
||||
config={[
|
||||
{
|
||||
key: '',
|
||||
presenter: recruit.component.VacancyItemPresenter,
|
||||
label: recruit.string.Vacancy,
|
||||
sortingKey: 'name',
|
||||
props: { action }
|
||||
},
|
||||
{
|
||||
key: '',
|
||||
presenter: recruit.component.VacancyCountPresenter,
|
||||
label: recruit.string.Applications,
|
||||
props: { applications },
|
||||
sortingKey: '@applications',
|
||||
sortingFunction: applicationSorting
|
||||
},
|
||||
'$lookup.company',
|
||||
'location',
|
||||
'description',
|
||||
{
|
||||
key: '',
|
||||
presenter: recruit.component.VacancyModifiedPresenter,
|
||||
label: core.string.Modified,
|
||||
props: { applications },
|
||||
sortingKey: 'modifiedOn',
|
||||
sortingFunction: modifiedSorting
|
||||
}
|
||||
]}
|
||||
options={{
|
||||
lookup
|
||||
}}
|
||||
query={{
|
||||
...resultQuery,
|
||||
archived: false
|
||||
}}
|
||||
showNotification
|
||||
/>
|
||||
</Scroller>
|
||||
<TableBrowser
|
||||
_class={recruit.class.Vacancy}
|
||||
config={[
|
||||
{
|
||||
key: '',
|
||||
presenter: recruit.component.VacancyItemPresenter,
|
||||
label: recruit.string.Vacancy,
|
||||
sortingKey: 'name',
|
||||
props: { action }
|
||||
},
|
||||
{
|
||||
key: '',
|
||||
presenter: recruit.component.VacancyCountPresenter,
|
||||
label: recruit.string.Applications,
|
||||
props: { applications },
|
||||
sortingKey: '@applications',
|
||||
sortingFunction: applicationSorting
|
||||
},
|
||||
'$lookup.company',
|
||||
'location',
|
||||
'description',
|
||||
{
|
||||
key: '',
|
||||
presenter: recruit.component.VacancyModifiedPresenter,
|
||||
label: core.string.Modified,
|
||||
props: { applications },
|
||||
sortingKey: 'modifiedOn',
|
||||
sortingFunction: modifiedSorting
|
||||
}
|
||||
]}
|
||||
options={{
|
||||
lookup
|
||||
}}
|
||||
query={{
|
||||
...resultQuery,
|
||||
archived: false
|
||||
}}
|
||||
showNotification
|
||||
/>
|
||||
|
@ -21,14 +21,14 @@
|
||||
import { getResource, OK, Resource, Severity, Status } from '@anticrm/platform'
|
||||
import { Card, getClient, UserBox, UserBoxList } from '@anticrm/presentation'
|
||||
import type { Candidate, Review } from '@anticrm/recruit'
|
||||
import task, { SpaceWithStates } from '@anticrm/task'
|
||||
import task from '@anticrm/task'
|
||||
import { StyledTextBox } from '@anticrm/text-editor'
|
||||
import { DateRangePresenter, EditBox, Status as StatusControl } from '@anticrm/ui'
|
||||
import view from '@anticrm/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import recruit from '../../plugin'
|
||||
|
||||
export let space: Ref<SpaceWithStates>
|
||||
// export let space: Ref<SpaceWithStates>
|
||||
export let candidate: Ref<Person>
|
||||
|
||||
export let preserveCandidate = false
|
||||
@ -49,7 +49,7 @@
|
||||
attachedTo: candidate,
|
||||
attachedToClass: recruit.mixin.Candidate,
|
||||
_class: recruit.class.Review,
|
||||
space: space,
|
||||
space: recruit.space.Reviews,
|
||||
_id: generateId(),
|
||||
collection: 'reviews',
|
||||
modifiedOn: Date.now(),
|
||||
@ -147,11 +147,6 @@
|
||||
labelProps={{ label: spaceLabel }}
|
||||
okAction={createReview}
|
||||
canSave={status.severity === Severity.OK && title.trim().length > 0}
|
||||
spaceClass={recruit.class.ReviewCategory}
|
||||
spaceQuery={{ archived: false }}
|
||||
spaceLabel={recruit.string.ReviewCategory}
|
||||
spacePlaceholder={recruit.string.SelectReviewCategory}
|
||||
bind:space={doc.space}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
|
@ -1,61 +0,0 @@
|
||||
<!--
|
||||
// Copyright © 2020 Anticrm Platform Contributors.
|
||||
//
|
||||
// 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 core from '@anticrm/core'
|
||||
import { getClient, SpaceCreateCard } from '@anticrm/presentation'
|
||||
import { EditBox } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import recruit from '../../plugin'
|
||||
import Review from '../icons/Review.svelte'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let name: string = ''
|
||||
const description: string = ''
|
||||
|
||||
export function canClose (): boolean {
|
||||
return name === ''
|
||||
}
|
||||
|
||||
const client = getClient()
|
||||
|
||||
async function createReviewCategory () {
|
||||
await client.createDoc(recruit.class.ReviewCategory, core.space.Space, {
|
||||
name,
|
||||
description,
|
||||
private: false,
|
||||
archived: false,
|
||||
members: []
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<SpaceCreateCard
|
||||
label={recruit.string.CreateReviewCategory}
|
||||
okAction={createReviewCategory}
|
||||
canSave={!!name}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<EditBox
|
||||
label={recruit.string.ReviewCategoryName}
|
||||
bind:value={name}
|
||||
icon={Review}
|
||||
placeholder={recruit.string.ReviewCategoryPlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
</SpaceCreateCard>
|
@ -1,264 +0,0 @@
|
||||
<!--
|
||||
// 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 activity from '@anticrm/activity'
|
||||
import { Attachments } from '@anticrm/attachment-resources'
|
||||
import type { Ref } from '@anticrm/core'
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { AttributesBar, createQuery, getClient } from '@anticrm/presentation'
|
||||
import { ReviewCategory } from '@anticrm/recruit'
|
||||
import { TextEditor } from '@anticrm/text-editor'
|
||||
import { Component, EditBox, Grid, Icon, IconClose, Label, ToggleWithLabel } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import recruit from '../../plugin'
|
||||
|
||||
export let _id: Ref<ReviewCategory>
|
||||
|
||||
let object: ReviewCategory
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const client = getClient()
|
||||
|
||||
const query = createQuery()
|
||||
const clazz = client.getHierarchy().getClass(recruit.class.ReviewCategory)
|
||||
$: query.query(recruit.class.ReviewCategory, { _id }, (result) => {
|
||||
object = result[0]
|
||||
})
|
||||
|
||||
const tabs: IntlString[] = ['General' as IntlString, 'Members' as IntlString, 'Activity' as IntlString]
|
||||
let selected = 0
|
||||
let textEditor: TextEditor
|
||||
|
||||
function onChange (key: string, value: any): void {
|
||||
client.updateDoc(object._class, object.space, object._id, { [key]: value })
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="overlay"
|
||||
on:click={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
/>
|
||||
<div class="dialog-container">
|
||||
{#if object}
|
||||
<div class="flex-row-center header">
|
||||
<div class="flex-grow">
|
||||
<div class="flex">
|
||||
<div class="svg-medium flex-no-shrink">
|
||||
{#if clazz.icon}<Icon icon={clazz.icon} size={'medium'} />{/if}
|
||||
</div>
|
||||
<div class="flex-grow fs-title ml-2">
|
||||
{object.name}
|
||||
</div>
|
||||
</div>
|
||||
<div class="small-text">{object.description}</div>
|
||||
</div>
|
||||
<div
|
||||
class="tool"
|
||||
on:click={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<IconClose size={'small'} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-row-center subtitle">
|
||||
<AttributesBar {object} keys={[]} />
|
||||
</div>
|
||||
<div class="flex-stretch tab-container">
|
||||
{#each tabs as tab, i}
|
||||
<div
|
||||
class="flex-row-center tab"
|
||||
class:selected={i === selected}
|
||||
on:click={() => {
|
||||
selected = i
|
||||
}}
|
||||
>
|
||||
<Label label={tab} />
|
||||
</div>
|
||||
{/each}
|
||||
<div class="grow" />
|
||||
</div>
|
||||
<div class="scroll">
|
||||
<div class="flex-col box">
|
||||
{#if selected === 0}
|
||||
<Grid column={1} rowGap={1.5}>
|
||||
<EditBox
|
||||
label={recruit.string.ReviewCategoryName}
|
||||
bind:value={object.name}
|
||||
placeholder={recruit.string.ReviewCategoryPlaceholder}
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
on:change={() => {
|
||||
onChange('name', object.name)
|
||||
}}
|
||||
/>
|
||||
<EditBox
|
||||
label={recruit.string.Description}
|
||||
bind:value={object.description}
|
||||
placeholder={recruit.string.ReviewCategoryDescription}
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
on:change={() => {
|
||||
onChange('description', object.description)
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<div class="mt-10">
|
||||
<span class="title">Description</span>
|
||||
<div class="description-container">
|
||||
<TextEditor
|
||||
bind:this={textEditor}
|
||||
bind:content={object.fullDescription}
|
||||
on:blur={textEditor.submit}
|
||||
on:content={() => {
|
||||
onChange('fullDescription', object.fullDescription)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-14">
|
||||
<Attachments objectId={object._id} _class={object._class} space={object.space} />
|
||||
</div>
|
||||
{:else if selected === 1}
|
||||
<ToggleWithLabel
|
||||
label={recruit.string.ThisReviewCategoryIsPrivate}
|
||||
description={recruit.string.MakePrivateDescription}
|
||||
/>
|
||||
{:else if selected === 2}
|
||||
<Component is={activity.component.Activity} props={{ object, transparent: true }} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.dialog-container {
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
top: 32px;
|
||||
bottom: 1.25rem;
|
||||
left: 50%;
|
||||
right: 1rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100% - 32px - 1.25rem);
|
||||
background: var(--theme-bg-color);
|
||||
border-radius: 1.25rem;
|
||||
|
||||
.header {
|
||||
flex-shrink: 0;
|
||||
padding: 0 2rem 0 2.5rem;
|
||||
height: 4.5rem;
|
||||
border-bottom: 1px solid var(--theme-dialog-divider);
|
||||
|
||||
.tool {
|
||||
margin-left: 0.75rem;
|
||||
color: var(--theme-content-accent-color);
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: var(--theme-caption-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
flex-shrink: 0;
|
||||
padding: 0 2.5rem;
|
||||
height: 3.5rem;
|
||||
border-bottom: 1px solid var(--theme-dialog-divider);
|
||||
}
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
flex-shrink: 0;
|
||||
flex-wrap: nowrap;
|
||||
margin: 0 2.5rem;
|
||||
height: 4.5rem;
|
||||
border-bottom: 1px solid var(--theme-menu-divider);
|
||||
|
||||
.tab {
|
||||
height: 4.5rem;
|
||||
font-weight: 500;
|
||||
color: var(--theme-content-trans-color);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&.selected {
|
||||
border-top: 0.125rem solid transparent;
|
||||
border-bottom: 0.125rem solid var(--theme-caption-color);
|
||||
color: var(--theme-caption-color);
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
.tab + .tab {
|
||||
margin-left: 2.5rem;
|
||||
}
|
||||
.grow {
|
||||
min-width: 2.5rem;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll {
|
||||
flex-grow: 1;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
margin: 1rem 2rem;
|
||||
padding: 1.5rem 0.5rem;
|
||||
height: 100%;
|
||||
|
||||
.box {
|
||||
margin-right: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-right: 0.75rem;
|
||||
font-weight: 500;
|
||||
font-size: 1.25rem;
|
||||
color: var(--theme-caption-color);
|
||||
}
|
||||
|
||||
.description-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
overflow-y: auto;
|
||||
height: 100px;
|
||||
padding: 0px 16px;
|
||||
background-color: var(--theme-bg-accent-color);
|
||||
border: 1px solid var(--theme-bg-accent-color);
|
||||
border-top: 20px solid transparent;
|
||||
border-bottom: 20px solid transparent;
|
||||
border-radius: 0.75rem;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
</style>
|
@ -1,78 +0,0 @@
|
||||
<!--
|
||||
// Copyright © 2020 Anticrm Platform Contributors.
|
||||
//
|
||||
// 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 Company from '../icons/Company.svelte'
|
||||
import type { ReviewCategory } from '@anticrm/recruit'
|
||||
import { closePanel, closePopup, closeTooltip, getCurrentLocation, navigate } from '@anticrm/ui'
|
||||
|
||||
export let category: ReviewCategory
|
||||
</script>
|
||||
|
||||
<div class="flex-col h-full card-container">
|
||||
<div class="label">Review category</div>
|
||||
<div class="flex-center logo">
|
||||
<Company size={'large'} />
|
||||
</div>
|
||||
{#if category}
|
||||
<div
|
||||
class="name over-underline"
|
||||
on:click={() => {
|
||||
closeTooltip()
|
||||
closePopup()
|
||||
closePanel()
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[2] = category._id
|
||||
loc.path.length = 3
|
||||
navigate(loc)
|
||||
}}
|
||||
>
|
||||
{category.name}
|
||||
</div>
|
||||
<div class="description">{category.description ?? ''}</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.card-container {
|
||||
padding: 1rem 1.5rem 1.25rem;
|
||||
background-color: var(--theme-button-bg-enabled);
|
||||
border: 1px solid var(--theme-bg-accent-color);
|
||||
border-radius: 0.75rem;
|
||||
|
||||
.logo {
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
color: var(--primary-button-color);
|
||||
background-color: var(--primary-button-enabled);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.label {
|
||||
margin-bottom: 1.75rem;
|
||||
font-weight: 500;
|
||||
font-size: 0.625rem;
|
||||
color: var(--theme-content-dark-color);
|
||||
}
|
||||
.name {
|
||||
margin: 1rem 0 0.25rem;
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
color: var(--theme-caption-color);
|
||||
}
|
||||
.description {
|
||||
font-size: 0.75rem;
|
||||
color: var(--theme-content-dark-color);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,37 +0,0 @@
|
||||
<!--
|
||||
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||
// Copyright © 2021, 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 type { ReviewCategory } from '@anticrm/recruit'
|
||||
import { Icon } from '@anticrm/ui'
|
||||
import { showPanel } from '@anticrm/ui/src/panelup'
|
||||
import recruit from '../../plugin'
|
||||
|
||||
export let value: ReviewCategory
|
||||
export let inline: boolean = false
|
||||
|
||||
function show () {
|
||||
showPanel(recruit.component.EditReviewCategory, value._id, value._class, 'right')
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
<div class="flex-presenter" class:inline-presenter={inline} on:click={show}>
|
||||
<div class="icon">
|
||||
<Icon icon={recruit.icon.Vacancy} size={'small'} />
|
||||
</div>
|
||||
<span class="label">{value.name}</span>
|
||||
</div>
|
||||
{/if}
|
@ -33,13 +33,10 @@ import EditVacancy from './components/EditVacancy.svelte'
|
||||
import KanbanCard from './components/KanbanCard.svelte'
|
||||
import CreateOpinion from './components/review/CreateOpinion.svelte'
|
||||
import CreateReview from './components/review/CreateReview.svelte'
|
||||
import CreateReviewCategory from './components/review/CreateReviewCategory.svelte'
|
||||
import EditReview from './components/review/EditReview.svelte'
|
||||
import EditReviewCategory from './components/review/EditReviewCategory.svelte'
|
||||
import OpinionPresenter from './components/review/OpinionPresenter.svelte'
|
||||
import Opinions from './components/review/Opinions.svelte'
|
||||
import OpinionsPresenter from './components/review/OpinionsPresenter.svelte'
|
||||
import ReviewCategoryPresenter from './components/review/ReviewCategoryPresenter.svelte'
|
||||
import ReviewPresenter from './components/review/ReviewPresenter.svelte'
|
||||
import Reviews from './components/review/Reviews.svelte'
|
||||
import SkillsView from './components/SkillsView.svelte'
|
||||
@ -152,8 +149,6 @@ export default async (): Promise<Resources> => ({
|
||||
VacancyCountPresenter,
|
||||
VacancyModifiedPresenter,
|
||||
|
||||
CreateReviewCategory,
|
||||
EditReviewCategory,
|
||||
CreateReview,
|
||||
ReviewPresenter,
|
||||
EditReview,
|
||||
@ -161,7 +156,6 @@ export default async (): Promise<Resources> => ({
|
||||
Opinions,
|
||||
OpinionPresenter,
|
||||
OpinionsPresenter,
|
||||
ReviewCategoryPresenter,
|
||||
ApplicationsView,
|
||||
|
||||
NewCandidateHeader
|
||||
|
@ -133,7 +133,7 @@ const recruit = plugin(recruitId, {
|
||||
},
|
||||
space: {
|
||||
VacancyTemplates: '' as Ref<KanbanTemplateSpace>,
|
||||
ReviewTemplates: '' as Ref<KanbanTemplateSpace>
|
||||
Reviews: '' as Ref<Space>
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { IntlString, translate } from '@anticrm/platform'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
import { TagCategory, TagElement } from '@anticrm/tags'
|
||||
import { Button, Icon, Label, Scroller, SearchEdit, showPopup, IconAdd } from '@anticrm/ui'
|
||||
import { Button, Icon, IconAdd, Label, SearchEdit, showPopup } from '@anticrm/ui'
|
||||
import { TableBrowser } from '@anticrm/view-resources'
|
||||
import tags from '../plugin'
|
||||
import CategoryBar from './CategoryBar.svelte'
|
||||
@ -108,40 +108,38 @@
|
||||
updateResultQuery(search, category)
|
||||
}}
|
||||
/>
|
||||
<Scroller tableFade>
|
||||
<TableBrowser
|
||||
_class={tags.class.TagElement}
|
||||
config={[
|
||||
{
|
||||
key: '',
|
||||
label: item,
|
||||
presenter: tags.component.TagElementPresenter,
|
||||
props: { edit: true, keyTitle },
|
||||
sortingKey: 'title'
|
||||
},
|
||||
...(category === undefined
|
||||
? [
|
||||
{
|
||||
key: '$lookup.category',
|
||||
presenter: tags.component.CategoryPresenter,
|
||||
sortingKey: 'category',
|
||||
label: tags.string.CategoryLabel
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
key: '',
|
||||
presenter: tags.component.TagElementCountPresenter,
|
||||
label: item,
|
||||
props: { tagElements, label: item, onTag },
|
||||
sortingKey: '@tagCount',
|
||||
sortingFunction: countSorting
|
||||
},
|
||||
'description',
|
||||
'modifiedOn'
|
||||
]}
|
||||
options={opt}
|
||||
query={resultQuery}
|
||||
showNotification
|
||||
/>
|
||||
</Scroller>
|
||||
<TableBrowser
|
||||
_class={tags.class.TagElement}
|
||||
config={[
|
||||
{
|
||||
key: '',
|
||||
label: item,
|
||||
presenter: tags.component.TagElementPresenter,
|
||||
props: { edit: true, keyTitle },
|
||||
sortingKey: 'title'
|
||||
},
|
||||
...(category === undefined
|
||||
? [
|
||||
{
|
||||
key: '$lookup.category',
|
||||
presenter: tags.component.CategoryPresenter,
|
||||
sortingKey: 'category',
|
||||
label: tags.string.CategoryLabel
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
key: '',
|
||||
presenter: tags.component.TagElementCountPresenter,
|
||||
label: item,
|
||||
props: { tagElements, label: item, onTag },
|
||||
sortingKey: '@tagCount',
|
||||
sortingFunction: countSorting
|
||||
},
|
||||
'description',
|
||||
'modifiedOn'
|
||||
]}
|
||||
options={opt}
|
||||
query={resultQuery}
|
||||
showNotification
|
||||
/>
|
||||
|
@ -20,7 +20,7 @@
|
||||
import { createQuery, getClient } from '@anticrm/presentation'
|
||||
import tags, { selectedTagElements, TagCategory, TagElement } from '@anticrm/tags'
|
||||
import { DoneState, Task } from '@anticrm/task'
|
||||
import { Component, Icon, Label, Scroller, SearchEdit } from '@anticrm/ui'
|
||||
import { Component, Icon, Label, SearchEdit } from '@anticrm/ui'
|
||||
import { TableBrowser } from '@anticrm/view-resources'
|
||||
import task from '../plugin'
|
||||
|
||||
@ -99,31 +99,29 @@
|
||||
on:change={(evt) => updateCategory(evt.detail)}
|
||||
/>
|
||||
|
||||
<Scroller tableFade>
|
||||
<TableBrowser
|
||||
{_class}
|
||||
config={[
|
||||
'',
|
||||
'$lookup.attachedTo',
|
||||
'$lookup.assignee',
|
||||
'$lookup.state',
|
||||
'$lookup.doneState',
|
||||
{
|
||||
key: '',
|
||||
presenter: attachment.component.AttachmentsPresenter,
|
||||
label: attachment.string.Files,
|
||||
sortingKey: 'attachments'
|
||||
},
|
||||
{
|
||||
key: '',
|
||||
presenter: chunter.component.CommentsPresenter,
|
||||
label: chunter.string.Comments,
|
||||
sortingKey: 'comments'
|
||||
},
|
||||
'modifiedOn'
|
||||
]}
|
||||
options={taskOptions}
|
||||
query={resultQuery}
|
||||
showNotification
|
||||
/>
|
||||
</Scroller>
|
||||
<TableBrowser
|
||||
{_class}
|
||||
config={[
|
||||
'',
|
||||
'$lookup.attachedTo',
|
||||
'$lookup.assignee',
|
||||
'$lookup.state',
|
||||
'$lookup.doneState',
|
||||
{
|
||||
key: '',
|
||||
presenter: attachment.component.AttachmentsPresenter,
|
||||
label: attachment.string.Files,
|
||||
sortingKey: 'attachments'
|
||||
},
|
||||
{
|
||||
key: '',
|
||||
presenter: chunter.component.CommentsPresenter,
|
||||
label: chunter.string.Comments,
|
||||
sortingKey: 'comments'
|
||||
},
|
||||
'modifiedOn'
|
||||
]}
|
||||
options={taskOptions}
|
||||
query={resultQuery}
|
||||
showNotification
|
||||
/>
|
||||
|
@ -17,13 +17,12 @@
|
||||
import { Class, DocumentQuery, FindOptions, Ref, SortingOrder } from '@anticrm/core'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
import { DoneState, SpaceWithStates, State, Task } from '@anticrm/task'
|
||||
import { ScrollBox } from '@anticrm/ui'
|
||||
import Label from '@anticrm/ui/src/components/Label.svelte'
|
||||
import { TableBrowser } from '@anticrm/view-resources'
|
||||
import task from '../plugin'
|
||||
import Lost from './icons/Lost.svelte'
|
||||
import Won from './icons/Won.svelte'
|
||||
import StatesBar from './state/StatesBar.svelte'
|
||||
import task from '../plugin'
|
||||
|
||||
export let _class: Ref<Class<Task>>
|
||||
export let space: Ref<SpaceWithStates>
|
||||
@ -176,9 +175,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="statustableview-container">
|
||||
<ScrollBox vertical stretch noShift>
|
||||
<TableBrowser {_class} {query} config={resConfig} {options} showNotification />
|
||||
</ScrollBox>
|
||||
<TableBrowser {_class} {query} config={resConfig} {options} showNotification />
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -14,6 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { Class, Doc, DocumentQuery, FindOptions, Ref } from '@anticrm/core'
|
||||
import { Scroller } from '@anticrm/ui'
|
||||
import { BuildModelKey } from '@anticrm/view'
|
||||
import { onMount } from 'svelte'
|
||||
import { ActionContext } from '..'
|
||||
@ -50,26 +51,28 @@
|
||||
}}
|
||||
/>
|
||||
|
||||
<Table
|
||||
bind:this={table}
|
||||
{_class}
|
||||
{config}
|
||||
{options}
|
||||
{query}
|
||||
{showNotification}
|
||||
{baseMenuClass}
|
||||
{loadingProps}
|
||||
highlightRows={true}
|
||||
enableChecking
|
||||
checked={$selectionStore ?? []}
|
||||
selection={listProvider.current($focusStore)}
|
||||
on:row-focus={(evt) => {
|
||||
listProvider.updateFocus(evt.detail)
|
||||
}}
|
||||
on:content={(evt) => {
|
||||
listProvider.update(evt.detail)
|
||||
}}
|
||||
on:check={(evt) => {
|
||||
listProvider.updateSelection(evt.detail.docs, evt.detail.value)
|
||||
}}
|
||||
/>
|
||||
<Scroller tableFade>
|
||||
<Table
|
||||
bind:this={table}
|
||||
{_class}
|
||||
{config}
|
||||
{options}
|
||||
{query}
|
||||
{showNotification}
|
||||
{baseMenuClass}
|
||||
{loadingProps}
|
||||
highlightRows={true}
|
||||
enableChecking
|
||||
checked={$selectionStore ?? []}
|
||||
selection={listProvider.current($focusStore)}
|
||||
on:row-focus={(evt) => {
|
||||
listProvider.updateFocus(evt.detail)
|
||||
}}
|
||||
on:content={(evt) => {
|
||||
listProvider.update(evt.detail)
|
||||
}}
|
||||
on:check={(evt) => {
|
||||
listProvider.updateSelection(evt.detail.docs, evt.detail.value)
|
||||
}}
|
||||
/>
|
||||
</Scroller>
|
||||
|
@ -15,7 +15,6 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { Class, Doc, DocumentQuery, FindOptions, Ref, Space } from '@anticrm/core'
|
||||
import { Scroller } from '@anticrm/ui'
|
||||
import { TableBrowser } from '..'
|
||||
import ActionContext from './ActionContext.svelte'
|
||||
|
||||
@ -35,6 +34,4 @@
|
||||
mode: 'browser'
|
||||
}}
|
||||
/>
|
||||
<Scroller tableFade>
|
||||
<TableBrowser {_class} {config} {options} query={resultQuery} {baseMenuClass} showNotification />
|
||||
</Scroller>
|
||||
<TableBrowser {_class} {config} {options} query={resultQuery} {baseMenuClass} showNotification />
|
||||
|
@ -136,34 +136,20 @@ test.describe('recruit tests', () => {
|
||||
|
||||
await page.locator('[id="app-recruit\\:string\\:RecruitApplication"]').click()
|
||||
|
||||
await page.hover('text=Reviews')
|
||||
await page.click('[name="tooltip-recruit:string:CreateReviewCategory"]')
|
||||
await page.click('text=Reviews')
|
||||
|
||||
await page.fill('[placeholder="Interview"]', interviewId)
|
||||
await page.click('button:has-text("Create")')
|
||||
await page.locator(`text=${interviewId}`).click()
|
||||
|
||||
// Click button:has-text("Review")
|
||||
await page.click('button:has-text("Review")')
|
||||
// Click [placeholder="\ "]
|
||||
await page.click('[placeholder="Title"]')
|
||||
// Fill [placeholder="\ "]
|
||||
await page.fill('[placeholder="Title"]', 'Meet PEterson')
|
||||
// Click text=Location Company Company >> [placeholder="\ "]
|
||||
await page.click('[placeholder="Location"]')
|
||||
// Fill text=Location Company Company >> [placeholder="\ "]
|
||||
await page.fill('[placeholder="Location"]', 'NSK')
|
||||
// Click text=Company Company >> div
|
||||
// await page.click('text=Company Company >> div')
|
||||
// Click button:has-text("Apple")
|
||||
// await page.click('button:has-text("Apple")')
|
||||
// Click text=Candidate Not selected >> span
|
||||
await page.click('form button:has-text("Candidate")')
|
||||
// Click button:has-text("Andrey P.")
|
||||
await page.click('button:has-text("Andrey P.")')
|
||||
// Click text=Create
|
||||
await page.click('text=Create')
|
||||
|
||||
await page.click('[placeholder="Title"]')
|
||||
|
||||
await page.fill('[placeholder="Title"]', `Meet Peterson ${interviewId}`)
|
||||
|
||||
await page.click('[placeholder="Location"]')
|
||||
|
||||
await page.fill('[placeholder="Location"]', 'NSK')
|
||||
await page.click('form button:has-text("Candidate")')
|
||||
await page.click('button:has-text("Andrey P.")')
|
||||
await page.click('text=Create')
|
||||
await page.click('td:has-text("RVE-")')
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user