From 3b8690248baf5b5275106233c151fe58c9f33aec Mon Sep 17 00:00:00 2001 From: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> Date: Fri, 24 Jun 2022 10:21:13 +0600 Subject: [PATCH] Leaves schedule (#2135) Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> --- changelog.md | 4 + models/contact/src/plugin.ts | 1 - models/hr/package.json | 1 + models/hr/src/index.ts | 195 +++++++++++++- models/hr/src/plugin.ts | 18 +- packages/core/src/component.ts | 4 +- plugins/contact/src/index.ts | 1 + plugins/hr-assets/assets/icons.svg | 19 ++ plugins/hr-assets/lang/en.json | 17 +- plugins/hr-assets/lang/ru.json | 17 +- plugins/hr-assets/src/index.ts | 7 +- plugins/hr-resources/package.json | 3 + .../src/components/CreateRequest.svelte | 119 +++++++++ .../src/components/EditRequest.svelte | 55 ++++ .../src/components/RequestsPopup.svelte | 35 +++ .../src/components/Schedule.svelte | 94 +++++++ .../src/components/ScheduleRequests.svelte | 76 ++++++ .../src/components/ScheduleView.svelte | 244 ++++++++++++++++++ .../src/components/Structure.svelte | 16 +- plugins/hr-resources/src/index.ts | 10 +- plugins/hr-resources/src/plugin.ts | 8 +- plugins/hr/src/index.ts | 56 +++- 22 files changed, 960 insertions(+), 40 deletions(-) create mode 100644 plugins/hr-resources/src/components/CreateRequest.svelte create mode 100644 plugins/hr-resources/src/components/EditRequest.svelte create mode 100644 plugins/hr-resources/src/components/RequestsPopup.svelte create mode 100644 plugins/hr-resources/src/components/Schedule.svelte create mode 100644 plugins/hr-resources/src/components/ScheduleRequests.svelte create mode 100644 plugins/hr-resources/src/components/ScheduleView.svelte diff --git a/changelog.md b/changelog.md index 590b4b68a4..5249d996b4 100644 --- a/changelog.md +++ b/changelog.md @@ -11,6 +11,10 @@ Chunter: - Reactions on messages +HR: + +- Leaves schedule + ## 0.6.28 Core: diff --git a/models/contact/src/plugin.ts b/models/contact/src/plugin.ts index 2cf207e832..94ff921815 100644 --- a/models/contact/src/plugin.ts +++ b/models/contact/src/plugin.ts @@ -51,7 +51,6 @@ export default mergeIds(contactId, contact, { Location: '' as IntlString, Channel: '' as IntlString, ChannelProvider: '' as IntlString, - Employee: '' as IntlString, Value: '' as IntlString, Phone: '' as IntlString, PhonePlaceholder: '' as IntlString, diff --git a/models/hr/package.json b/models/hr/package.json index 23ef616680..40c065d53b 100644 --- a/models/hr/package.json +++ b/models/hr/package.json @@ -35,6 +35,7 @@ "@anticrm/model-workbench": "~0.6.1", "@anticrm/model-contact": "~0.6.1", "@anticrm/model-chunter": "~0.6.0", + "@anticrm/model-calendar": "~0.6.0", "@anticrm/model-attachment": "~0.6.0", "@anticrm/hr": "~0.6.0", "@anticrm/hr-resources": "~0.6.0", diff --git a/models/hr/src/index.ts b/models/hr/src/index.ts index 4c8bc74ec7..4163f97494 100644 --- a/models/hr/src/index.ts +++ b/models/hr/src/index.ts @@ -14,16 +14,35 @@ // import { Employee } from '@anticrm/contact' -import contact, { TEmployee, TEmployeeAccount } from '@anticrm/model-contact' -import { Arr, IndexKind, Ref } from '@anticrm/core' -import type { Department, DepartmentMember, Staff } from '@anticrm/hr' -import { Builder, Index, Mixin, Model, Prop, TypeRef, Collection, TypeString, UX, ArrOf } from '@anticrm/model' -import core, { TSpace } from '@anticrm/model-core' -import workbench from '@anticrm/model-workbench' -import hr from './plugin' -import view, { createAction } from '@anticrm/model-view' +import { Arr, Class, Domain, DOMAIN_MODEL, IndexKind, Markup, Ref, Timestamp } from '@anticrm/core' +import type { Department, DepartmentMember, Request, RequestType, Staff } from '@anticrm/hr' +import { + ArrOf, + Builder, + Collection, + Hidden, + Index, + Mixin, + Model, + Prop, + TypeDate, + TypeIntlString, + TypeMarkup, + TypeRef, + TypeString, + UX +} from '@anticrm/model' import attachment from '@anticrm/model-attachment' +import calendar from '@anticrm/model-calendar' import chunter from '@anticrm/model-chunter' +import contact, { TEmployee, TEmployeeAccount } from '@anticrm/model-contact' +import core, { TAttachedDoc, TDoc, TSpace } from '@anticrm/model-core' +import view, { createAction } from '@anticrm/model-view' +import workbench from '@anticrm/model-workbench' +import { Asset, IntlString } from '@anticrm/platform' +import hr from './plugin' + +export const DOMAIN_HR = 'hr' as Domain @Model(hr.class.Department, core.class.Space) @UX(hr.string.Department, hr.icon.Department) @@ -64,8 +83,51 @@ export class TStaff extends TEmployee implements Staff { department!: Ref } +@Model(hr.class.RequestType, core.class.Doc, DOMAIN_MODEL) +@UX(hr.string.RequestType) +export class TRequestType extends TDoc implements RequestType { + @Prop(TypeIntlString(), core.string.Name) + label!: IntlString + + icon!: Asset + value!: number + color!: number +} + +@Model(hr.class.Request, core.class.AttachedDoc, DOMAIN_HR) +@UX(hr.string.Request, hr.icon.PTO) +export class TRequest extends TAttachedDoc implements Request { + @Prop(TypeRef(hr.mixin.Staff), contact.string.Employee) + declare attachedTo: Ref + + declare attachedToClass: Ref> + + @Prop(TypeRef(hr.class.Department), hr.string.Department) + declare space: Ref + + @Prop(TypeRef(hr.class.RequestType), hr.string.RequestType) + @Hidden() + type!: Ref + + @Prop(Collection(chunter.class.Comment), chunter.string.Comments) + comments?: number + + @Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, undefined, attachment.string.Files) + attachments?: number + + @Prop(TypeMarkup(), core.string.Description) + @Index(IndexKind.FullText) + description!: Markup + + @Prop(TypeDate(false), calendar.string.Date) + date!: Timestamp + + @Prop(TypeDate(false), calendar.string.DueTo) + dueDate!: Timestamp +} + export function createModel (builder: Builder): void { - builder.createModel(TDepartment, TDepartmentMember, TStaff) + builder.createModel(TDepartment, TDepartmentMember, TRequest, TRequestType, TStaff) builder.createDoc( workbench.class.Application, @@ -82,6 +144,13 @@ export function createModel (builder: Builder): void { icon: hr.icon.Structure, label: hr.string.Structure, position: 'top' + }, + { + id: 'schedule', + component: hr.component.Schedule, + icon: calendar.icon.Calendar, + label: hr.string.Schedule, + position: 'top' } ], spaces: [] @@ -98,17 +167,103 @@ export function createModel (builder: Builder): void { editor: hr.component.EditDepartment }) + builder.mixin(hr.class.Request, core.class.Class, view.mixin.ObjectEditor, { + editor: hr.component.EditRequest + }) + builder.mixin(hr.class.DepartmentMember, core.class.Class, view.mixin.ArrayEditor, { editor: hr.component.DepartmentStaff }) + builder.createDoc( + hr.class.RequestType, + core.space.Model, + { + label: hr.string.Vacation, + icon: hr.icon.Vacation, + color: 2, + value: 0 + }, + hr.ids.Vacation + ) + + builder.createDoc( + hr.class.RequestType, + core.space.Model, + { + label: hr.string.Sick, + icon: hr.icon.Sick, + color: 11, + value: -1 + }, + hr.ids.Sick + ) + + builder.createDoc( + hr.class.RequestType, + core.space.Model, + { + label: hr.string.PTO, + icon: hr.icon.PTO, + color: 9, + value: -1 + }, + hr.ids.PTO + ) + + builder.createDoc( + hr.class.RequestType, + core.space.Model, + { + label: hr.string.PTO2, + icon: hr.icon.PTO, + color: 9, + value: -0.5 + }, + hr.ids.PTO2 + ) + + builder.createDoc( + hr.class.RequestType, + core.space.Model, + { + label: hr.string.Overtime, + icon: hr.icon.Overtime, + color: 5, + value: 1 + }, + hr.ids.Overtime + ) + + builder.createDoc( + hr.class.RequestType, + core.space.Model, + { + label: hr.string.Overtime2, + icon: hr.icon.Overtime, + color: 5, + value: 0.5 + }, + hr.ids.Overtime2 + ) + + builder.createDoc( + hr.class.RequestType, + core.space.Model, + { + label: hr.string.Remote, + icon: hr.icon.Remote, + color: 4, + value: 0 + }, + hr.ids.Remote + ) + createAction( builder, { action: view.actionImpl.ShowPanel, - actionProps: { - component: hr.component.EditDepartment - }, + actionProps: {}, label: view.string.Open, icon: view.icon.Open, keyBinding: ['e'], @@ -138,6 +293,22 @@ export function createModel (builder: Builder): void { }, hr.action.DeleteDepartment ) + + createAction( + builder, + { + action: view.actionImpl.ShowPanel, + actionProps: {}, + label: view.string.Open, + icon: view.icon.Open, + keyBinding: ['e'], + input: 'any', + category: hr.category.HR, + target: hr.class.Request, + context: { mode: 'context', application: hr.app.HR, group: 'top' } + }, + hr.action.EditRequest + ) } export { hrOperation } from './migration' diff --git a/models/hr/src/plugin.ts b/models/hr/src/plugin.ts index 1c952f37c1..39f07c5821 100644 --- a/models/hr/src/plugin.ts +++ b/models/hr/src/plugin.ts @@ -23,19 +23,31 @@ import { Action, ActionCategory } from '@anticrm/view' export default mergeIds(hrId, hr, { string: { HRApplication: '' as IntlString, - Departments: '' as IntlString + Departments: '' as IntlString, + Request: '' as IntlString, + Vacation: '' as IntlString, + Sick: '' as IntlString, + PTO: '' as IntlString, + PTO2: '' as IntlString, + Remote: '' as IntlString, + Overtime: '' as IntlString, + Overtime2: '' as IntlString }, component: { Structure: '' as AnyComponent, EditDepartment: '' as AnyComponent, DepartmentStaff: '' as AnyComponent, - DepartmentEditor: '' as AnyComponent + DepartmentEditor: '' as AnyComponent, + Schedule: '' as AnyComponent, + EditRequest: '' as AnyComponent }, category: { HR: '' as Ref }, action: { EditDepartment: '' as Ref, - DeleteDepartment: '' as Ref + DeleteDepartment: '' as Ref, + EditRequest: '' as Ref, + DeleteRequest: '' as Ref } }) diff --git a/packages/core/src/component.ts b/packages/core/src/component.ts index 2c5c0b29d8..55632901e0 100644 --- a/packages/core/src/component.ts +++ b/packages/core/src/component.ts @@ -133,7 +133,7 @@ export default plugin(coreId, { Array: '' as IntlString, Bag: '' as IntlString, Name: '' as IntlString, - Description: '' as IntlString, - Enum: '' as IntlString + Enum: '' as IntlString, + Description: '' as IntlString } }) diff --git a/plugins/contact/src/index.ts b/plugins/contact/src/index.ts index 50bbc611ac..7bc18b2fbe 100644 --- a/plugins/contact/src/index.ts +++ b/plugins/contact/src/index.ts @@ -213,6 +213,7 @@ const contactPlugin = plugin(contactId, { string: { PersonAlreadyExists: '' as IntlString, Person: '' as IntlString, + Employee: '' as IntlString, CreateOrganization: '' as IntlString }, viewlet: { diff --git a/plugins/hr-assets/assets/icons.svg b/plugins/hr-assets/assets/icons.svg index 358f0131a9..5458e1174e 100644 --- a/plugins/hr-assets/assets/icons.svg +++ b/plugins/hr-assets/assets/icons.svg @@ -10,4 +10,23 @@ + + + + + + + + + + + + + + + + + + + diff --git a/plugins/hr-assets/lang/en.json b/plugins/hr-assets/lang/en.json index a15cecd9e0..7dc06767fe 100644 --- a/plugins/hr-assets/lang/en.json +++ b/plugins/hr-assets/lang/en.json @@ -15,6 +15,21 @@ "MoveStaff": "Employee transfer", "MoveStaffDescr": "Do you want to transfer employee from {current} to {department}", "Departments": "Departments", - "AddEmployee": "Add employee" + "ShowEmployees": "Show employees", + "AddEmployee": "Add employee", + "Schedule": "Schedule", + "RequestType": "Type", + "CreateRequest": "Create {type}", + "Today": "Today", + "NoEmployeesInDepartment": "There are no employees in the selected department", + "Vacation": "Vacation", + "Sick": "Sick", + "PTO": "PTO", + "Remote": "Remote", + "Overtime": "Overtime", + "PTO2": "PTO/2", + "Overtime2": "Overtime/2", + "EditRequest": "Edit {type}", + "Request": "Request" } } \ No newline at end of file diff --git a/plugins/hr-assets/lang/ru.json b/plugins/hr-assets/lang/ru.json index bd5df8993f..8e459ef19e 100644 --- a/plugins/hr-assets/lang/ru.json +++ b/plugins/hr-assets/lang/ru.json @@ -15,6 +15,21 @@ "MoveStaff": "Перевод сотрудника", "MoveStaffDescr": "Вы действительно хотите перевести сотрудника из {current} в {department}", "Departments": "Департаменты", - "AddEmployee": "Добавить сотрудника" + "ShowEmployees": "Просмотреть сотрудников", + "AddEmployee": "Добавить сотрудника", + "Schedule": "График", + "RequestType": "Тип", + "CreateRequest": "Создать {type}", + "Today": "Сегодня", + "NoEmployeesInDepartment": "Нет сотрудников в выбранном департаменте", + "Vacation": "Отпуск", + "Sick": "Больничный", + "PTO": "PTO", + "Remote": "Удаленно", + "Overtime": "Переработка", + "PTO2": "PTO/2", + "Overtime2": "Переработка/2", + "EditRequest": "Редактировать {type}", + "Request": "Запрос" } } \ No newline at end of file diff --git a/plugins/hr-assets/src/index.ts b/plugins/hr-assets/src/index.ts index d1c99fb549..f68a56f6cb 100644 --- a/plugins/hr-assets/src/index.ts +++ b/plugins/hr-assets/src/index.ts @@ -20,7 +20,12 @@ const icons = require('../assets/icons.svg') as string // eslint-disable-line loadMetadata(hr.icon, { HR: `${icons}#hr`, Department: `${icons}#department`, - Structure: `${icons}#structure` + Structure: `${icons}#structure`, + Vacation: `${icons}#vacation`, + Sick: `${icons}#sick`, + PTO: `${icons}#pto`, + Overtime: `${icons}#overtime`, + Remote: `${icons}#remote` }) addStringsLoader(hrId, async (lang: string) => await import(`../lang/${lang}.json`)) diff --git a/plugins/hr-resources/package.json b/plugins/hr-resources/package.json index ae4cb55e4e..4171ee1e32 100644 --- a/plugins/hr-resources/package.json +++ b/plugins/hr-resources/package.json @@ -32,6 +32,7 @@ "dependencies": { "@anticrm/platform": "~0.6.6", "svelte": "^3.47", + "@anticrm/calendar": "~0.6.0", "@anticrm/hr": "~0.6.0", "@anticrm/ui": "~0.6.0", "@anticrm/presentation": "~0.6.2", @@ -41,6 +42,8 @@ "@anticrm/view": "~0.6.0", "@anticrm/view-resources": "~0.6.0", "@anticrm/contact-resources": "~0.6.0", + "@anticrm/attachment-resources": "~0.6.0", + "@anticrm/text-editor": "~0.6.0", "@anticrm/setting": "~0.6.1", "@anticrm/attachment": "~0.6.1" } diff --git a/plugins/hr-resources/src/components/CreateRequest.svelte b/plugins/hr-resources/src/components/CreateRequest.svelte new file mode 100644 index 0000000000..47f061a561 --- /dev/null +++ b/plugins/hr-resources/src/components/CreateRequest.svelte @@ -0,0 +1,119 @@ + + + + { + dispatch('close') + }} +> + { + return { id: p._id, label: p.label } + })} + placeholder={hr.string.RequestType} + label={hr.string.RequestType} + on:selected={(e) => typeSelected(e.detail)} + /> + + + + + + +