ats automation (#4515)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2024-02-05 14:47:52 +06:00 committed by GitHub
parent 697fb2732c
commit 896ac1172b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
53 changed files with 748 additions and 74 deletions

View File

@ -308,6 +308,9 @@ dependencies:
'@rush-temp/model-server-telegram':
specifier: file:./projects/model-server-telegram.tgz
version: file:projects/model-server-telegram.tgz(svelte@4.2.5)(typescript@5.2.2)
'@rush-temp/model-server-templates':
specifier: file:./projects/model-server-templates.tgz
version: file:projects/model-server-templates.tgz(svelte@4.2.5)(typescript@5.2.2)
'@rush-temp/model-server-tracker':
specifier: file:./projects/model-server-tracker.tgz
version: file:projects/model-server-tracker.tgz(svelte@4.2.5)(typescript@5.2.2)
@ -533,6 +536,9 @@ dependencies:
'@rush-temp/server-telegram-resources':
specifier: file:./projects/server-telegram-resources.tgz
version: file:projects/server-telegram-resources.tgz(@types/node@16.11.68)(esbuild@0.16.17)(svelte@4.2.5)(ts-node@10.9.1)
'@rush-temp/server-templates':
specifier: file:./projects/server-templates.tgz
version: file:projects/server-templates.tgz(esbuild@0.16.17)(svelte@4.2.5)(ts-node@10.9.1)
'@rush-temp/server-token':
specifier: file:./projects/server-token.tgz
version: file:projects/server-token.tgz(esbuild@0.16.17)(svelte@4.2.5)(ts-node@10.9.1)
@ -18562,7 +18568,7 @@ packages:
dev: false
file:projects/model-all.tgz(svelte@4.2.5)(typescript@5.2.2):
resolution: {integrity: sha512-PEl4zAGjvSsQ5stSRUuj2PYcZ0BdWTkxyaJNP63dbX4U6QA5sf7BuXamJRgETTD74jA40pGRXUAMnprS6t9z4w==, tarball: file:projects/model-all.tgz}
resolution: {integrity: sha512-rRoP0AGubenpWEnLgCxmsp24ap6T59CCi32i2svNsX3v3DqcSLMCD/m921cLLDtoLvrp7FEXEFzvA5G3sInS4w==, tarball: file:projects/model-all.tgz}
id: file:projects/model-all.tgz
name: '@rush-temp/model-all'
version: 0.0.0
@ -19010,7 +19016,7 @@ packages:
dev: false
file:projects/model-server-contact.tgz(svelte@4.2.5)(typescript@5.2.2):
resolution: {integrity: sha512-d8ktsQb+9GnNT/Oc4b1KZxR0zxWhJcTzngYoD5R2396PyGo1WlPWSDyg7/ZwfW3VPuRUmFK4kQN9rvx5shqr1A==, tarball: file:projects/model-server-contact.tgz}
resolution: {integrity: sha512-vlsuafmQmf1ZBTgFnJs9jL2awlyHh/ErdTV2P2bUXXsYkBdA9XWHVAYZn+oi0Rd3id5j3DDGrDwN5NiR0U6+tQ==, tarball: file:projects/model-server-contact.tgz}
id: file:projects/model-server-contact.tgz
name: '@rush-temp/model-server-contact'
version: 0.0.0
@ -19220,7 +19226,7 @@ packages:
dev: false
file:projects/model-server-setting.tgz(svelte@4.2.5)(typescript@5.2.2):
resolution: {integrity: sha512-yVGC8ZWVTm3yOqKVta+BEaIkp42ZSpNbiUtjNJKUbn+3ExMzBt5BoCNxFnuZbcYpbgBGtVQ+ZJF0rflo+92ZEg==, tarball: file:projects/model-server-setting.tgz}
resolution: {integrity: sha512-sGvikiJYi3Q+I7SjeOSNmNnQALpeEMW338oLYIHWPqsdC5yK+mNBl3G62qx4RE5YCnQiT04QpGABEgUhoUK5ug==, tarball: file:projects/model-server-setting.tgz}
id: file:projects/model-server-setting.tgz
name: '@rush-temp/model-server-setting'
version: 0.0.0
@ -19283,7 +19289,7 @@ packages:
dev: false
file:projects/model-server-telegram.tgz(svelte@4.2.5)(typescript@5.2.2):
resolution: {integrity: sha512-0SFtpXukJznjjaLURWNNb3OUK8cLTYAGeFgUWte5oijmuDHcyPiFqvaCFPwyX8BTn+PL284jVnCy56HQGVv/lw==, tarball: file:projects/model-server-telegram.tgz}
resolution: {integrity: sha512-vsMfQWsKyRmKNuWnrTGt7XazrucPqAnK9lug4EqYvHeNht1p0ghjmypsTI1bZU72wJnnfGmuE24kHFqG7/Jumw==, tarball: file:projects/model-server-telegram.tgz}
id: file:projects/model-server-telegram.tgz
name: '@rush-temp/model-server-telegram'
version: 0.0.0
@ -19303,6 +19309,27 @@ packages:
- typescript
dev: false
file:projects/model-server-templates.tgz(svelte@4.2.5)(typescript@5.2.2):
resolution: {integrity: sha512-OSVMWQCabgesTAbFc/TTbs9dzlu5ZqXRbm682xc1C0C0Z2rXDmonFYV7RYELMc5Jf39Kctnne4edqHZWcj3BtQ==, tarball: file:projects/model-server-templates.tgz}
id: file:projects/model-server-templates.tgz
name: '@rush-temp/model-server-templates'
version: 0.0.0
dependencies:
'@typescript-eslint/eslint-plugin': 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.54.0)(typescript@5.2.2)
'@typescript-eslint/parser': 6.11.0(eslint@8.54.0)(typescript@5.2.2)
eslint: 8.54.0
eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.11.0)(eslint-plugin-import@2.28.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.54.0)(typescript@5.2.2)
eslint-plugin-import: 2.28.1(eslint@8.54.0)
eslint-plugin-n: 15.7.0(eslint@8.54.0)
eslint-plugin-promise: 6.1.1(eslint@8.54.0)
prettier: 3.1.0
prettier-plugin-svelte: 3.1.0(prettier@3.1.0)(svelte@4.2.5)
transitivePeerDependencies:
- supports-color
- svelte
- typescript
dev: false
file:projects/model-server-tracker.tgz(svelte@4.2.5)(typescript@5.2.2):
resolution: {integrity: sha512-R7x6XRRSUS6b/pi3Xh01bA5iNCSAOYBy4l0E8/J6SrAG0K0v2565iEEc5FjZll3RWe+vVsA5GFeoIvJkgg+rpQ==, tarball: file:projects/model-server-tracker.tgz}
id: file:projects/model-server-tracker.tgz
@ -20928,7 +20955,7 @@ packages:
dev: false
file:projects/server-contact.tgz(esbuild@0.16.17)(svelte@4.2.5)(ts-node@10.9.1):
resolution: {integrity: sha512-9uEmb9dproJeJoIM9tEknpiF6SmB3mUuYJSjJZBPsqVvckSPSiWhntDUEk2P6rVk1VDKr02Sxo8Ao9BBoHjBrA==, tarball: file:projects/server-contact.tgz}
resolution: {integrity: sha512-tFf4IQRLfSksCwdSdgf/UqHqUHEueA2Umyru2R1UB39sxiDA4tgzkYJg6NiJ9FYYQaGZfkkg1iHiNww4raIasw==, tarball: file:projects/server-contact.tgz}
id: file:projects/server-contact.tgz
name: '@rush-temp/server-contact'
version: 0.0.0
@ -21507,7 +21534,7 @@ packages:
dev: false
file:projects/server-setting.tgz(esbuild@0.16.17)(svelte@4.2.5)(ts-node@10.9.1):
resolution: {integrity: sha512-B1xZXUDrJjE6nRBumLMBkG0EGa7MSTSspMKcFNn1RUYeSQVj9K5EMQbuGHVdUyHDPoWy5h+BgYHdT7k/pkw87A==, tarball: file:projects/server-setting.tgz}
resolution: {integrity: sha512-BhdjSgGhI6B3T3YrKwfbHkn7wBc25CexZhqYAyo+yOPudt3BgKjaYsaEpWq0amLm82i4i0lzPB3YTh6Um/1yPA==, tarball: file:projects/server-setting.tgz}
id: file:projects/server-setting.tgz
name: '@rush-temp/server-setting'
version: 0.0.0
@ -21667,7 +21694,7 @@ packages:
dev: false
file:projects/server-telegram-resources.tgz(@types/node@16.11.68)(esbuild@0.16.17)(svelte@4.2.5)(ts-node@10.9.1):
resolution: {integrity: sha512-VhNEvKhlJ+YLFb/sQZcpq2wbO2MIy9rjAupK3a1UVtNSLjxQQdGG28/sBtzolxfqewS+iRFPdV5R5LxO31ocdg==, tarball: file:projects/server-telegram-resources.tgz}
resolution: {integrity: sha512-0xrMPAORRu6sTt0VKvmvv2I+6fy7kdMd4eU9LVKZZiNySzl9ar+9dLvVofzdP9pAZzndqeH89EjbIdi0WsIIeg==, tarball: file:projects/server-telegram-resources.tgz}
id: file:projects/server-telegram-resources.tgz
name: '@rush-temp/server-telegram-resources'
version: 0.0.0
@ -21699,7 +21726,7 @@ packages:
dev: false
file:projects/server-telegram.tgz(esbuild@0.16.17)(svelte@4.2.5)(ts-node@10.9.1):
resolution: {integrity: sha512-BA7dhLmV5p7UwD5wNpJD4Lfog13uVZy9cF6GDCsjGqodLUutP38zwFOEjLMmdC6bruxnS0PpH4N62VTxqGY8Ig==, tarball: file:projects/server-telegram.tgz}
resolution: {integrity: sha512-q7nsFwdvFCQw4bXA/Lb3bi2w5xtpJAzOZSra+pWwY+ZJMX1i2Dvo8LqevRwR/1vHALDFhQPsud/dipoJMnBFZw==, tarball: file:projects/server-telegram.tgz}
id: file:projects/server-telegram.tgz
name: '@rush-temp/server-telegram'
version: 0.0.0
@ -21730,6 +21757,38 @@ packages:
- ts-node
dev: false
file:projects/server-templates.tgz(esbuild@0.16.17)(svelte@4.2.5)(ts-node@10.9.1):
resolution: {integrity: sha512-wFkwKZjd1eEPQ0sdZdZQnrAZxzUH0f3B5Ml/hVMtI8f5jqYJlGGZNMt0ivQuKDEA5cLQosGVs1kVUxenDHG88w==, tarball: file:projects/server-templates.tgz}
id: file:projects/server-templates.tgz
name: '@rush-temp/server-templates'
version: 0.0.0
dependencies:
'@types/jest': 29.5.5
'@types/node': 16.11.68
'@typescript-eslint/eslint-plugin': 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.54.0)(typescript@5.2.2)
'@typescript-eslint/parser': 6.11.0(eslint@8.54.0)(typescript@5.2.2)
eslint: 8.54.0
eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.11.0)(eslint-plugin-import@2.28.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.54.0)(typescript@5.2.2)
eslint-plugin-import: 2.28.1(eslint@8.54.0)
eslint-plugin-n: 15.7.0(eslint@8.54.0)
eslint-plugin-promise: 6.1.1(eslint@8.54.0)
jest: 29.7.0(@types/node@16.11.68)(ts-node@10.9.1)
prettier: 3.1.0
prettier-plugin-svelte: 3.1.0(prettier@3.1.0)(svelte@4.2.5)
ts-jest: 29.1.1(esbuild@0.16.17)(jest@29.7.0)(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
- '@babel/core'
- '@jest/types'
- babel-jest
- babel-plugin-macros
- esbuild
- node-notifier
- supports-color
- svelte
- ts-node
dev: false
file:projects/server-token.tgz(esbuild@0.16.17)(svelte@4.2.5)(ts-node@10.9.1):
resolution: {integrity: sha512-VMRRUJ7aTTj5u0lL05bAJQ05MiAoP6uljsDeaR+rMNV0JkR21W0IWNgJznLh50da74Zwwcx9tfrRhBvhFuejIA==, tarball: file:projects/server-token.tgz}
id: file:projects/server-token.tgz

View File

@ -50,6 +50,7 @@
"@hcengineering/model-server-recruit": "^0.6.0",
"@hcengineering/model-server-lead": "^0.6.0",
"@hcengineering/model-server-inventory": "^0.6.0",
"@hcengineering/model-server-templates": "^0.6.0",
"@hcengineering/model-activity": "^0.6.0",
"@hcengineering/model-attachment": "^0.6.0",
"@hcengineering/model-gmail": "^0.6.0",

View File

@ -46,10 +46,11 @@ import { serverLeadId, createModel as serverLeadModel } from '@hcengineering/mod
import { serverNotificationId, createModel as serverNotificationModel } from '@hcengineering/model-server-notification'
import { serverRecruitId, createModel as serverRecruitModel } from '@hcengineering/model-server-recruit'
import { serverRequestId, createModel as serverRequestModel } from '@hcengineering/model-server-request'
import { createModel as serveSettingModel, serverSettingId } from '@hcengineering/model-server-setting'
import { serverSettingId, createModel as serveSettingModel } from '@hcengineering/model-server-setting'
import { serverTagsId, createModel as serverTagsModel } from '@hcengineering/model-server-tags'
import { serverTaskId, createModel as serverTaskModel } from '@hcengineering/model-server-task'
import { serverTelegramId, createModel as serverTelegramModel } from '@hcengineering/model-server-telegram'
import { serverTemplatesId, createModel as serverTemplatesModel } from '@hcengineering/model-server-templates'
import { serverTrackerId, createModel as serverTrackerModel } from '@hcengineering/model-server-tracker'
import { serverViewId, createModel as serverViewModel } from '@hcengineering/model-server-view'
import setting, { settingId, createModel as settingModel } from '@hcengineering/model-setting'
@ -284,6 +285,7 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[
[serverCalendarModel, serverCalendarId],
[serverRecruitModel, serverRecruitId],
[serverGmailModel, serverGmailId],
[serverTemplatesModel, serverTemplatesId],
[serverTelegramModel, serverTelegramId],
[serverHrModel, serverHrId],
[serverNotificationModel, serverNotificationId],

View File

@ -30,6 +30,8 @@
"@hcengineering/platform": "^0.6.9",
"@hcengineering/server-contact": "^0.6.1",
"@hcengineering/server-core": "^0.6.1",
"@hcengineering/templates": "^0.6.7",
"@hcengineering/server-templates": "^0.6.0",
"@hcengineering/contact": "^0.6.20",
"@hcengineering/server-notification": "^0.6.1"
}

View File

@ -21,6 +21,8 @@ import core from '@hcengineering/core'
import serverContact from '@hcengineering/server-contact'
import serverCore from '@hcengineering/server-core'
import serverNotification from '@hcengineering/server-notification'
import serverTemplates from '@hcengineering/server-templates'
import templates from '@hcengineering/templates'
export { serverContactId } from '@hcengineering/server-contact'
export function createModel (builder: Builder): void {
@ -75,4 +77,58 @@ export function createModel (builder: Builder): void {
_class: core.class.TxUpdateDoc
}
})
builder.mixin(
contact.templateField.CurrentEmployeeName,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverContact.function.GetCurrentEmployeeName
}
)
builder.mixin(
contact.templateField.CurrentEmployeeEmail,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverContact.function.GetCurrentEmployeeEmail
}
)
builder.mixin(
contact.templateField.ContactName,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverContact.function.GetContactName
}
)
builder.mixin(
contact.templateField.CurrentEmployeePosition,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverContact.function.GetCurrentEmployeePosition
}
)
builder.mixin(
contact.templateField.ContactFirstName,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverContact.function.GetContactFirstName
}
)
builder.mixin(
contact.templateField.ContactLastName,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverContact.function.GetContactLastName
}
)
}

View File

@ -30,6 +30,8 @@
"@hcengineering/platform": "^0.6.9",
"@hcengineering/setting": "^0.6.11",
"@hcengineering/server-notification": "^0.6.1",
"@hcengineering/templates": "^0.6.7",
"@hcengineering/server-templates": "^0.6.0",
"@hcengineering/server-setting": "^0.6.0",
"@hcengineering/server-core": "^0.6.1"
}

View File

@ -20,6 +20,8 @@ import core from '@hcengineering/core'
import serverNotification from '@hcengineering/server-notification'
import serverSetting from '@hcengineering/server-setting'
import setting from '@hcengineering/setting'
import serverTemplates from '@hcengineering/server-templates'
import templates from '@hcengineering/templates'
export { serverSettingId } from '@hcengineering/server-setting'
@ -31,4 +33,35 @@ export function createModel (builder: Builder): void {
builder.mixin(setting.class.Integration, core.class.Class, serverNotification.mixin.TextPresenter, {
presenter: serverSetting.function.IntegrationTextPresenter
})
builder.mixin(setting.templateField.Value, templates.class.TemplateField, serverTemplates.mixin.ServerTemplateField, {
serverFunc: serverSetting.function.GetValue
})
builder.mixin(
setting.templateField.OwnerFirstName,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverSetting.function.GetFirstName
}
)
builder.mixin(
setting.templateField.OwnerLastName,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverSetting.function.GetLastName
}
)
builder.mixin(
setting.templateField.OwnerPosition,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverSetting.function.GetOwnerPosition
}
)
}

View File

@ -33,6 +33,8 @@
"@hcengineering/server-core": "^0.6.1",
"@hcengineering/telegram": "^0.6.14",
"@hcengineering/notification": "^0.6.16",
"@hcengineering/templates": "^0.6.7",
"@hcengineering/server-templates": "^0.6.0",
"@hcengineering/server-notification": "^0.6.1"
}
}

View File

@ -22,6 +22,8 @@ import serverTelegram from '@hcengineering/server-telegram'
import telegram from '@hcengineering/telegram'
import notification from '@hcengineering/notification'
import serverNotification from '@hcengineering/server-notification'
import serverTemplates from '@hcengineering/server-templates'
import templates from '@hcengineering/templates'
export { serverTelegramId } from '@hcengineering/server-telegram'
@ -52,4 +54,22 @@ export function createModel (builder: Builder): void {
func: serverTelegram.function.IsIncomingMessage
}
)
builder.mixin(
telegram.templateField.CurrentEmployeeTelegram,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverTelegram.function.GetCurrentEmployeeTG
}
)
builder.mixin(
telegram.templateField.IntegrationOwnerTG,
templates.class.TemplateField,
serverTemplates.mixin.ServerTemplateField,
{
serverFunc: serverTelegram.function.GetIntegrationOwnerTG
}
)
}

View File

@ -0,0 +1,7 @@
module.exports = {
extends: ['./node_modules/@hcengineering/platform-rig/profiles/model/eslint.config.json'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
}
}

View File

@ -0,0 +1,4 @@
*
!/lib/**
!CHANGELOG.md
/lib/**/__tests__/

View File

@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
"rigPackageName": "@hcengineering/platform-rig",
"rigProfile": "model"
}

View File

@ -0,0 +1,36 @@
{
"name": "@hcengineering/model-server-templates",
"version": "0.6.0",
"main": "lib/index.js",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "tsc",
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"lint": "eslint src",
"format": "format src"
},
"template": "@hcengineering/model-package",
"devDependencies": {
"@hcengineering/platform-rig": "^0.6.0",
"@typescript-eslint/eslint-plugin": "^6.11.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-n": "^15.4.0",
"eslint": "^8.54.0",
"@typescript-eslint/parser": "^6.11.0",
"eslint-config-standard-with-typescript": "^40.0.0",
"prettier": "^3.1.0",
"prettier-plugin-svelte": "^3.1.0"
},
"dependencies": {
"@hcengineering/core": "^0.6.28",
"@hcengineering/model": "^0.6.7",
"@hcengineering/platform": "^0.6.9",
"@hcengineering/templates": "^0.6.7",
"@hcengineering/model-templates": "^0.6.0",
"@hcengineering/server-templates": "^0.6.0",
"@hcengineering/server-core": "^0.6.1"
}
}

View File

@ -0,0 +1,31 @@
//
// Copyright © 2024 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.
//
import { Mixin, type Builder } from '@hcengineering/model'
import { TTemplateField } from '@hcengineering/model-templates'
import { type Resource } from '@hcengineering/platform'
import serverTemplates, { type TemplateFieldServerFunc } from '@hcengineering/server-templates'
import templates, { type TemplateField } from '@hcengineering/templates'
@Mixin(serverTemplates.mixin.ServerTemplateField, templates.class.TemplateField)
export class TServerTemplateField extends TTemplateField implements TemplateField {
serverFunc!: Resource<TemplateFieldServerFunc>
}
export { serverTemplatesId } from '@hcengineering/server-templates'
export function createModel (builder: Builder): void {
builder.createModel(TServerTemplateField)
}

View File

@ -0,0 +1,9 @@
{
"extends": "./node_modules/@hcengineering/platform-rig/profiles/model/tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib",
"tsBuildInfoFile": ".build/build.tsbuildinfo"
}
}

View File

@ -90,7 +90,7 @@
--global-ui-hover-highlight-BackgroundColor: #A5BDFF40;
--global-surface-01-BackgroundColor: #F8F9FA;
--global-surface-01-BorderColor: #DDE1E9;
--global-surface-02-BackgroundColor: #19202E;
--global-surface-02-BackgroundColor: #FFFFFF;
--global-surface-02-BorderColor: #EBEEF2;
--global-surface-03-hover-BackgroundColor: #F8F9FA;
--global-subtle-ui-BorderColor: #1530720D;

View File

@ -6,11 +6,19 @@
"Save": "Save",
"Publish": "Publish",
"SaveDraft": "Save draft",
"Minutes": "{minutes, plural, =0 {less than a minute ago} =1 {a minute ago} other {# minutes ago}}",
"Hours": "{hours, plural, =0 {less than an hour ago} =1 {an hour ago} other {# hours ago}}",
"Days": "{days, plural, =0 {today} =1 {yesterday} other {# days ago}}",
"Months": "{months, plural, =0 {this month} =1 {a month ago} other {# months ago}}",
"Years": "{years, plural, =0 {this year} =1 {a year ago} other {# years ago}}",
"MinutesAgo": "{minutes, plural, =0 {less than a minute ago} =1 {a minute ago} other {# minutes ago}}",
"HoursAgo": "{hours, plural, =0 {less than an hour ago} =1 {an hour ago} other {# hours ago}}",
"DaysAgo": "{days, plural, =0 {today} =1 {yesterday} other {# days ago}}",
"MonthsAgo": "{months, plural, =0 {this month} =1 {a month ago} other {# months ago}}",
"YearsAgo": "{years, plural, =0 {this year} =1 {a year ago} other {# years ago}}",
"Minutes": "{minutes, plural, =0 {less than a minute} =1 {a minute} other {# minutes}}",
"Hours": "{hours, plural, =0 {less than an hour} =1 {an hour} other {# hours}}",
"Days": "{days, plural, =0 {today} =1 {1 day} other {# days }}",
"Weeks": "{weeks, plural, =0 {this week} =1 {1 week} other {# weeks}}",
"Months": "{months, plural, =0 {this month} =1 {1 month} other {# months}}",
"Years": "{years, plural, =0 {this year} =1 {a year} other {# years}}",
"Before": "Before",
"After": "After",
"MinutesShort": "{value}m",
"HoursShort": "{value}h",
"DaysShort": "{value}d",
@ -43,9 +51,13 @@
"MinutesBefore": "{minutes, plural, =1 {a minute before} other {# minutes before}}",
"HoursBefore": "{hours, plural, =1 {an hour before} other {# hours before}}",
"DaysBefore": "{days, plural, =1 {a day before} other {# days before}}",
"WeeksBefore": "{weeks, plural, =1 {a week before} other {# weeks before}}",
"MonthsBefore": "{months, plural, =1 {a months before} other {# months before}}",
"MinutesAfter": "{minutes, plural, =1 {in a minute} other {in # minutes}}",
"HoursAfter": "{hours, plural, =1 {in an hour} other {in # hours}}",
"DaysAfter": "{days, plural, =1 {in a day} other {in # days}}",
"WeeksAfter": "{weeks, plural, =1 {in a day} other {in # weeks}}",
"MonthsAfter": "{months, plural, =1 {in a month} other {in # months}}",
"NoActionsDefined": "No actions applicable",
"Incoming": "Incoming",
"HoursLabel": "Hours",

View File

@ -6,11 +6,19 @@
"Save": "Сохранить",
"Publish": "Опубликовать",
"SaveDraft": "Сохранить черновик",
"Minutes": "{minutes, plural, =0 {меньше минуты назад} =1 {минуту назад} one {# минуту назад} few {# минуты назад} other {# минут назад}}",
"Hours": "{hours, plural, =0 {меньше часа назад} =1 {час назад} one {# час назад} few {# часа назад} other {# часов назад}}",
"Days": "{days, plural, =0 {сегодня} =1 {вчера} one {# день назад} few {# дня назад} other {# дней назад}}",
"Months": "{months, plural, =0 {в этом месяце} =1 {месяц назад} one {# месяц назад} few {# месяца назад} other {# месяцев назад}}",
"Years": "{years, plural, =0 {в этом году} =1 {год назад} one {# год назад} few {# год назад} other {# лет назад}}",
"MinutesAgo": "{minutes, plural, =0 {меньше минуты назад} =1 {минуту назад} one {# минуту назад} few {# минуты назад} other {# минут назад}}",
"HoursAgo": "{hours, plural, =0 {меньше часа назад} =1 {час назад} one {# час назад} few {# часа назад} other {# часов назад}}",
"DaysAgo": "{days, plural, =0 {сегодня} =1 {вчера} one {# день назад} few {# дня назад} other {# дней назад}}",
"MonthsAgo": "{months, plural, =0 {в этом месяце} =1 {месяц назад} one {# месяц назад} few {# месяца назад} other {# месяцев назад}}",
"YearsAgo": "{years, plural, =0 {в этом году} =1 {год назад} one {# год назад} few {# год назад} other {# лет назад}}",
"Minutes": "{minutes, plural, =0 {меньше минуты} one {# минуту} few {# минуты} other {# минут}}",
"Hours": "{hours, plural, =0 {меньше часа} one {# час} few {# часа} other {# часов}}",
"Days": "{days, plural, =0 {сегодня} one {# день} few {# дня} other {# дней}}",
"Weeks": "{weeks, plural, =0 {меньше недели} one {# неделя} few {# недели} other {# недель}}",
"Months": "{months, plural, =0 {меньше месяца} one {# месяц} few {# месяца} other {# месяцев}}",
"Years": "{years, plural, =0 {меньше года} one {# год} few {# года} other {# лет}}",
"Before": "За",
"After": "Через",
"MinutesShort": "{value}м",
"HoursShort": "{value}ч",
"DaysShort": "{value}д",
@ -43,9 +51,13 @@
"MinutesBefore": "{minutes, plural, =1 {за минуту} one {за # минуту} few {за # минуты} other {за # минут}}",
"HoursBefore": "{hours, plural, =1 {за час} one {за # час} few {за # часа} other {за # часов}}",
"DaysBefore": "{days, plural, =1 {за день} one {за # день} few {за # дня} other {за # дней}}",
"WeeksBefore": "{weeks, plural, =1 {за неделю} one {за # неделю} few {за # недели} other {за # недель}}",
"MonthsBefore": "{months, plural, =1 {за месяц} one {за # месяц} few {за # месяца} other {за # месяцев}}",
"MinutesAfter": "{minutes, plural, =1 {через минуту} one {через # минуту} few {через # минуты} other {через # минут}}",
"HoursAfter": "{hours, plural, =1 {через час} one {через # час} few {через # часа} other {через # часов}}",
"DaysAfter": "{days, plural, =1 {через день} one {через # день} few {через # дня} other {через # дней}}",
"WeeksAfter": "{weeks, plural, =1 {через неделю} one {через # неделю} few {через # недели} other {через # недель}}",
"MonthsAfter": "{months, plural, =1 {через месяц} one {через # месяц} few {через # месяца} other {через # месяцев}}",
"NoActionsDefined": "Нет доступных действий",
"Incoming": "Входящие",
"HoursLabel": "Часы",

View File

@ -41,15 +41,15 @@
let passed = now - value
if (passed < 0) passed = 0
if (passed < HOUR) {
time = await translate(ui.string.Minutes, { minutes: Math.floor(passed / MINUTE) }, $themeStore.language)
time = await translate(ui.string.MinutesAgo, { minutes: Math.floor(passed / MINUTE) }, $themeStore.language)
} else if (passed < DAY) {
time = await translate(ui.string.Hours, { hours: Math.floor(passed / HOUR) }, $themeStore.language)
time = await translate(ui.string.HoursAgo, { hours: Math.floor(passed / HOUR) }, $themeStore.language)
} else if (passed < MONTH) {
time = await translate(ui.string.Days, { days: Math.floor(passed / DAY) }, $themeStore.language)
time = await translate(ui.string.DaysAgo, { days: Math.floor(passed / DAY) }, $themeStore.language)
} else if (passed < YEAR) {
time = await translate(ui.string.Months, { months: calculateMonthsPassed(now, value) }, $themeStore.language)
time = await translate(ui.string.MonthsAgo, { months: calculateMonthsPassed(now, value) }, $themeStore.language)
} else {
time = await translate(ui.string.Years, { years: Math.floor(passed / YEAR) }, $themeStore.language)
time = await translate(ui.string.YearsAgo, { years: Math.floor(passed / YEAR) }, $themeStore.language)
}
}

View File

@ -31,11 +31,19 @@ export const uis = plugin(uiId, {
Save: '' as IntlString,
Publish: '' as IntlString,
SaveDraft: '' as IntlString,
MinutesAgo: '' as IntlString,
HoursAgo: '' as IntlString,
DaysAgo: '' as IntlString,
MonthsAgo: '' as IntlString,
YearsAgo: '' as IntlString,
Minutes: '' as IntlString,
Hours: '' as IntlString,
Days: '' as IntlString,
Weeks: '' as IntlString,
Months: '' as IntlString,
Years: '' as IntlString,
Before: '' as IntlString,
After: '' as IntlString,
MinutesShort: '' as IntlString,
HoursShort: '' as IntlString,
DaysShort: '' as IntlString,
@ -64,9 +72,13 @@ export const uis = plugin(uiId, {
MinutesBefore: '' as IntlString,
HoursBefore: '' as IntlString,
DaysBefore: '' as IntlString,
WeeksBefore: '' as IntlString,
MonthsBefore: '' as IntlString,
MinutesAfter: '' as IntlString,
HoursAfter: '' as IntlString,
DaysAfter: '' as IntlString,
WeeksAfter: '' as IntlString,
MonthsAfter: '' as IntlString,
NoActionsDefined: '' as IntlString,
Incoming: '' as IntlString,
HoursLabel: '' as IntlString,

View File

@ -71,7 +71,7 @@
{#if value}
{#if statusLabel}
<div class="inline-flex items-center clear-mins">
<div class="inline-flex items-center clear-mins w-full">
<PersonElement
{value}
{name}

View File

@ -20,8 +20,6 @@ import gmail, { gmailId } from '@hcengineering/gmail'
export default mergeIds(gmailId, gmail, {
string: {
From: '' as IntlString,
To: '' as IntlString,
Copy: '' as IntlString,
MessagesSelected: '' as IntlString,
PublishSelected: '' as IntlString,

View File

@ -15,7 +15,7 @@
import { ChannelItem } from '@hcengineering/contact'
import type { Account, AttachedDoc, Class, Doc, Ref, Space, Timestamp } from '@hcengineering/core'
import type { Plugin } from '@hcengineering/platform'
import type { IntlString, Plugin } from '@hcengineering/platform'
import { Metadata, plugin } from '@hcengineering/platform'
import { NotificationType } from '@hcengineering/notification'
import type { Handler, IntegrationType } from '@hcengineering/setting'
@ -87,6 +87,10 @@ export default plugin(gmailId, {
NewMessages: '' as AnyComponent,
Configure: '' as AnyComponent
},
string: {
From: '' as IntlString,
To: '' as IntlString
},
integrationType: {
Gmail: '' as Ref<IntegrationType>
},

View File

@ -327,7 +327,7 @@
{/if}
</div>
<div bind:this={navigator[2].element} class="flex-col">
<div bind:this={navigator[2].element} class="flex-col gap">
<ComponentExtensions extension={task.extensions.ProjectEditorExtension} props={{ type }} />
</div>
@ -346,3 +346,9 @@
</div>
</div>
{/if}
<style lang="scss">
.gap {
gap: var(--spacing-4);
}
</style>

View File

@ -15,6 +15,7 @@
"Field": "Field",
"TemplateCategory": "Template group",
"CreateTemplateCategory": "Create group",
"Copy": "Copy"
"Copy": "Copy",
"Template": "Template"
}
}

View File

@ -15,6 +15,7 @@
"Field": "Поле",
"TemplateCategory": "Группа шаблонов",
"CreateTemplateCategory": "Создать группу",
"Copy": "Копировать"
"Copy": "Копировать",
"Template": "Шаблон"
}
}

View File

@ -0,0 +1,26 @@
<!--
// Copyright © 2024 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 { TextEditorHandler } from '@hcengineering/text-editor'
import TemplatePopup from './TemplatePopup.svelte'
export let editor: TextEditorHandler
async function dispatchItem (e: CustomEvent): Promise<void> {
editor.insertTemplate(e.detail.title, e.detail.message)
}
</script>
a<TemplatePopup on:template={dispatchItem} />

View File

@ -16,13 +16,12 @@
<script lang="ts">
import { createQuery } from '@hcengineering/presentation'
import { MessageTemplate, TemplateCategory } from '@hcengineering/templates'
import { TextEditorHandler } from '@hcengineering/text-editor'
import { closePopup, deviceOptionsStore, EditWithIcon, IconSearch } from '@hcengineering/ui'
import { groupBy } from '@hcengineering/view-resources'
import templates from '../plugin'
import { getTemplateDataProvider } from '../utils'
import { createEventDispatcher } from 'svelte'
export let editor: TextEditorHandler
let items: MessageTemplate[] = []
let groups: TemplateCategory[] = []
@ -46,11 +45,21 @@
let selected = 0
const dispatch = createEventDispatcher()
const provider = getTemplateDataProvider()
async function dispatchItem (item: MessageTemplate): Promise<void> {
const message = await provider.fillTemplate(item.message)
editor.insertTemplate(item.title, message)
closePopup()
dispatch('template', {
_id: item._id,
title: item.title,
message
})
dispatch('close', {
_id: item._id,
title: item.title,
message
})
}
export function onKeyDown (ev: KeyboardEvent) {

View File

@ -18,20 +18,22 @@ import { type Resources } from '@hcengineering/platform'
import Templates from './components/Templates.svelte'
import { type TextEditorHandler } from '@hcengineering/text-editor'
import { showPopup } from '@hcengineering/ui'
import TemplatePopup from './components/TemplatePopup.svelte'
import EditorTemplatePopup from './components/EditorTemplatePopup.svelte'
import CreateTemplateCategory from './components/CreateTemplateCategory.svelte'
import TemplatePopup from './components/TemplatePopup.svelte'
import Move from './components/Move.svelte'
import Copy from './components/Copy.svelte'
import EditGroup from './components/EditGroup.svelte'
import { getTemplateDataProvider } from './utils'
function ShowTemplates (element: HTMLElement, editor: TextEditorHandler): void {
showPopup(TemplatePopup, { editor }, element)
showPopup(EditorTemplatePopup, { editor }, element)
}
export default async (): Promise<Resources> => ({
component: {
Templates,
TemplatePopup,
CreateTemplateCategory,
Move,
Copy,

View File

@ -2,14 +2,13 @@ import { type Class, type Doc, generateId, type Ref } from '@hcengineering/core'
import { getResource } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation'
import templates, {
templateFieldRegexp,
type TemplateData,
type TemplateDataProvider,
type TemplateField,
type TemplateFieldCategory
} from '@hcengineering/templates'
const fieldRegexp = /\$\{(\S+?)}/gi
const templateData = new Map<Ref<TemplateFieldCategory>, TemplateData[]>()
class TemplateDataProviderImpl implements TemplateDataProvider {
@ -32,7 +31,7 @@ class TemplateDataProviderImpl implements TemplateDataProvider {
async fillTemplate (message: string): Promise<string> {
while (true) {
const matched = fieldRegexp.exec(message)
const matched = templateFieldRegexp.exec(message)
if (matched === null) return message
const client = getClient()
const field = await client.findOne(templates.class.TemplateField, { _id: matched[1] as Ref<TemplateField> })
@ -41,7 +40,7 @@ class TemplateDataProviderImpl implements TemplateDataProvider {
const result = await f(this)
if (result !== undefined) {
message = message.replaceAll(matched[0], result)
fieldRegexp.lastIndex = 0
templateFieldRegexp.lastIndex = 0
}
}
}

View File

@ -16,6 +16,7 @@
import type { Class, Doc, Ref, Space } from '@hcengineering/core'
import type { IntlString, Plugin, Resource } from '@hcengineering/platform'
import { Asset, plugin } from '@hcengineering/platform'
import { AnyComponent } from '@hcengineering/ui'
/**
* @public
@ -70,6 +71,8 @@ export interface TemplateField extends Doc {
func: Resource<TemplateFieldFunc>
}
export const templateFieldRegexp = /\$\{(\S+?)}/gi
/**
* @public
*/
@ -82,6 +85,12 @@ export default plugin(templatesId, {
TemplateField: '' as Ref<Class<TemplateField>>,
TemplateFieldCategory: '' as Ref<Class<TemplateFieldCategory>>
},
component: {
TemplatePopup: '' as AnyComponent
},
string: {
Template: '' as IntlString
},
space: {
Templates: '' as Ref<TemplateCategory>
},

View File

@ -199,11 +199,6 @@
"NoDescription": "No description",
"SearchIssue": "Search for task...",
"DurMinutes": "{minutes, plural, =0 {less than a minute} =1 {a minute} other {# minutes}}",
"DurHours": "{hours, plural, =0 {less than an hour} =1 {an hour} other {# hours}}",
"DurDays": "{days, plural, =0 {today} =1 {1 day} other {# days }}",
"DurMonths": "{months, plural, =0 {this month} =1 {1 month} other {# months}}",
"DurYears": "{years, plural, =0 {this year} =1 {a year} other {# years}}",
"StatusHistory": "State History",
"NewSubIssue": "Add sub-issue...",
"AddLabel": "Add label",

View File

@ -199,11 +199,6 @@
"NoDescription": "Нет описания",
"SearchIssue": "Поиск задачи...",
"DurMinutes": "{minutes, plural, =0 {меньше минуты} one {# минуту} few {# минуты} other {# минут}}",
"DurHours": "{hours, plural, =0 {меньше часа} one {# час} few {# часа} other {# часов}}",
"DurDays": "{days, plural, =0 {сегодня} one {# день} few {# дня} other {# дней }}",
"DurMonths": "{months, plural, =0 {меньше месяца} one {# месяц} few {# месяца} other {# месяцев}}",
"DurYears": "{years, plural, =0 {меньше года} one {# год} few {# года} other {# лет}}",
"StatusHistory": "История состояний",
"NewSubIssue": "Добавить под-задачу...",
"AddLabel": "Добавить метку",

View File

@ -14,8 +14,7 @@
-->
<script lang="ts">
import { translate } from '@hcengineering/platform'
import tracker from '../../plugin'
import { DAY, HOUR, MINUTE, MONTH, YEAR, themeStore } from '@hcengineering/ui'
import ui, { DAY, HOUR, MINUTE, MONTH, YEAR, themeStore } from '@hcengineering/ui'
export let value: number
@ -24,15 +23,15 @@
async function formatTime (passed: number) {
if (passed < 0) passed = 0
if (passed < HOUR) {
time = await translate(tracker.string.DurMinutes, { minutes: Math.floor(passed / MINUTE) }, $themeStore.language)
time = await translate(ui.string.Minutes, { minutes: Math.floor(passed / MINUTE) }, $themeStore.language)
} else if (passed < DAY) {
time = await translate(tracker.string.DurHours, { hours: Math.floor(passed / HOUR) }, $themeStore.language)
time = await translate(ui.string.Hours, { hours: Math.floor(passed / HOUR) }, $themeStore.language)
} else if (passed < MONTH) {
time = await translate(tracker.string.DurDays, { days: Math.floor(passed / DAY) }, $themeStore.language)
time = await translate(ui.string.Days, { days: Math.floor(passed / DAY) }, $themeStore.language)
} else if (passed < YEAR) {
time = await translate(tracker.string.DurMonths, { months: Math.floor(passed / MONTH) }, $themeStore.language)
time = await translate(ui.string.Months, { months: Math.floor(passed / MONTH) }, $themeStore.language)
} else {
time = await translate(tracker.string.DurYears, { years: Math.floor(passed / YEAR) }, $themeStore.language)
time = await translate(ui.string.Years, { years: Math.floor(passed / YEAR) }, $themeStore.language)
}
}

View File

@ -236,11 +236,6 @@ export default mergeIds(trackerId, tracker, {
Blocks: '' as IntlString,
Related: '' as IntlString,
DurMinutes: '' as IntlString,
DurHours: '' as IntlString,
DurDays: '' as IntlString,
DurMonths: '' as IntlString,
DurYears: '' as IntlString,
StatusHistory: '' as IntlString,
AddLabel: '' as IntlString,

View File

@ -996,6 +996,16 @@
"projectFolder": "models/templates",
"shouldPublish": false
},
{
"packageName": "@hcengineering/server-templates",
"projectFolder": "server-plugins/templates",
"shouldPublish": false
},
{
"packageName": "@hcengineering/model-server-templates",
"projectFolder": "models/server-templates",
"shouldPublish": false
},
{
"packageName": "@hcengineering/model-text-editor",
"projectFolder": "models/text-editor",

View File

@ -21,7 +21,12 @@ import contact, {
Person,
contactId,
getName,
formatContactName
formatContactName,
PersonAccount,
formatName,
getLastName,
getFirstName,
Employee
} from '@hcengineering/contact'
import { Ref, Class, Doc, Tx, TxRemoveDoc, TxUpdateDoc, concatLink, Hierarchy } from '@hcengineering/core'
import notification, { Collaborators } from '@hcengineering/notification'
@ -174,6 +179,76 @@ export function contactNameProvider (hierarchy: Hierarchy, props: Record<string,
return formatContactName(hierarchy, _class, props.name ?? '')
}
export async function getCurrentEmployeeName (control: TriggerControl, context: Record<string, Doc>): Promise<string> {
const account = await control.modelDb.findOne(contact.class.PersonAccount, {
_id: control.txFactory.account as Ref<PersonAccount>
})
if (account === undefined) return ''
const employee = (await control.findAll(contact.class.Person, { _id: account.person }))[0]
return employee !== undefined ? formatName(employee.name) : ''
}
export async function getCurrentEmployeeEmail (control: TriggerControl, context: Record<string, Doc>): Promise<string> {
const account = await control.modelDb.findOne(contact.class.PersonAccount, {
_id: control.txFactory.account as Ref<PersonAccount>
})
if (account === undefined) return ''
return account.email
}
export async function getCurrentEmployeePosition (
control: TriggerControl,
context: Record<string, Doc>
): Promise<string | undefined> {
const account = await control.modelDb.findOne(contact.class.PersonAccount, {
_id: control.txFactory.account as Ref<PersonAccount>
})
if (account === undefined) return ''
const employee = (await control.findAll(contact.mixin.Employee, { _id: account.person as Ref<Employee> }))[0]
if (employee !== undefined) {
return employee.position ?? ''
}
}
export async function getContactName (
control: TriggerControl,
context: Record<string, Doc>
): Promise<string | undefined> {
const value = context[contact.class.Contact] as Contact
if (value === undefined) return
if (control.hierarchy.isDerived(value._class, contact.class.Person)) {
return getName(control.hierarchy, value)
} else {
return value.name
}
}
export async function getContactLastName (
control: TriggerControl,
context: Record<string, Doc>
): Promise<string | undefined> {
const value = context[contact.class.Contact] as Contact
if (value === undefined) return
if (control.hierarchy.isDerived(value._class, contact.class.Person)) {
return getLastName(value.name)
} else {
return ''
}
}
export async function getContactFirstName (
control: TriggerControl,
context: Record<string, Doc>
): Promise<string | undefined> {
const value = context[contact.class.Contact] as Contact
if (value === undefined) return
if (control.hierarchy.isDerived(value._class, contact.class.Person)) {
return getFirstName(value.name)
} else {
return value.name
}
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export default async () => ({
trigger: {
@ -185,6 +260,12 @@ export default async () => ({
PersonTextPresenter: personTextPresenter,
OrganizationHTMLPresenter: organizationHTMLPresenter,
OrganizationTextPresenter: organizationTextPresenter,
ContactNameProvider: contactNameProvider
ContactNameProvider: contactNameProvider,
GetCurrentEmployeeName: getCurrentEmployeeName,
GetCurrentEmployeeEmail: getCurrentEmployeeEmail,
GetContactName: getContactName,
GetCurrentEmployeePosition: getCurrentEmployeePosition,
GetContactFirstName: getContactFirstName,
GetContactLastName: getContactLastName
}
})

View File

@ -31,6 +31,7 @@
},
"dependencies": {
"@hcengineering/server-notification": "^0.6.1",
"@hcengineering/server-templates": "^0.6.0",
"@hcengineering/platform": "^0.6.9",
"@hcengineering/server-core": "^0.6.1"
}

View File

@ -18,6 +18,7 @@ import type { Plugin, Resource } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import type { TriggerFunc, SearchPresenterProvider } from '@hcengineering/server-core'
import { Presenter } from '@hcengineering/server-notification'
import { TemplateFieldServerFunc } from '@hcengineering/server-templates'
/**
* @public
@ -38,6 +39,12 @@ export default plugin(serverContactId, {
OrganizationHTMLPresenter: '' as Resource<Presenter>,
OrganizationTextPresenter: '' as Resource<Presenter>,
ContactNameProvider: '' as Resource<SearchPresenterProvider>
ContactNameProvider: '' as Resource<SearchPresenterProvider>,
GetCurrentEmployeeName: '' as Resource<TemplateFieldServerFunc>,
GetCurrentEmployeeEmail: '' as Resource<TemplateFieldServerFunc>,
GetContactName: '' as Resource<TemplateFieldServerFunc>,
GetCurrentEmployeePosition: '' as Resource<TemplateFieldServerFunc>,
GetContactFirstName: '' as Resource<TemplateFieldServerFunc>,
GetContactLastName: '' as Resource<TemplateFieldServerFunc>
}
})

View File

@ -13,7 +13,8 @@
// limitations under the License.
//
import { Doc } from '@hcengineering/core'
import contact, { Person, PersonAccount, getFirstName, getLastName } from '@hcengineering/contact'
import { Account, Doc, Ref } from '@hcengineering/core'
import { translate } from '@hcengineering/platform'
import type { TriggerControl } from '@hcengineering/server-core'
import setting, { Integration } from '@hcengineering/setting'
@ -36,10 +37,68 @@ export async function integrationTextPresenter (doc: Doc, control: TriggerContro
return `${label} (${integration.value})`
}
export async function getValue (control: TriggerControl, context: Record<string, Doc>): Promise<string | undefined> {
const value = context[setting.class.Integration] as Integration
if (value === undefined) return
return value.value
}
async function getEmployee (control: TriggerControl, _id: Ref<Account>): Promise<Person | undefined> {
const employeeAccount = (
await control.modelDb.findAll(contact.class.PersonAccount, {
_id: _id as Ref<PersonAccount>
})
)[0]
if (employeeAccount !== undefined) {
const employee = (
await control.findAll(contact.class.Person, {
_id: employeeAccount.person
})
)[0]
return employee
}
}
export async function getOwnerFirstName (
control: TriggerControl,
context: Record<string, Doc>
): Promise<string | undefined> {
const value = context[setting.class.Integration] as Integration
if (value === undefined) return
const employee = await getEmployee(control, value.modifiedBy)
return employee != null ? getFirstName(employee.name) : undefined
}
export async function getOwnerLastName (
control: TriggerControl,
context: Record<string, Doc>
): Promise<string | undefined> {
const value = context[setting.class.Integration] as Integration
if (value === undefined) return
const employee = await getEmployee(control, value.modifiedBy)
return employee != null ? getLastName(employee.name) : undefined
}
export async function getOwnerPosition (
control: TriggerControl,
context: Record<string, Doc>
): Promise<string | undefined> {
const value = context[setting.class.Integration] as Integration
if (value === undefined) return
const employee = await getEmployee(control, value.modifiedBy)
if (employee !== undefined) {
return control.hierarchy.as(employee, contact.mixin.Employee)?.position ?? undefined
}
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export default async () => ({
function: {
IntegrationHTMLPresenter: integrationHTMLPresenter,
IntegrationTextPresenter: integrationTextPresenter
IntegrationTextPresenter: integrationTextPresenter,
GetValue: getValue,
GetFirstName: getFirstName,
GetLastName: getLastName,
GetOwnerPosition: getOwnerPosition
}
})

View File

@ -31,6 +31,7 @@
},
"dependencies": {
"@hcengineering/core": "^0.6.28",
"@hcengineering/server-templates": "^0.6.0",
"@hcengineering/platform": "^0.6.9",
"@hcengineering/server-notification": "^0.6.1",
"@hcengineering/server-core": "^0.6.1"

View File

@ -16,6 +16,7 @@
import type { Plugin, Resource } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import { Presenter } from '@hcengineering/server-notification'
import { TemplateFieldServerFunc } from '@hcengineering/server-templates'
/**
* @public
@ -28,6 +29,10 @@ export const serverSettingId = 'server-setting' as Plugin
export default plugin(serverSettingId, {
function: {
IntegrationHTMLPresenter: '' as Resource<Presenter>,
IntegrationTextPresenter: '' as Resource<Presenter>
IntegrationTextPresenter: '' as Resource<Presenter>,
GetValue: '' as Resource<TemplateFieldServerFunc>,
GetFirstName: '' as Resource<TemplateFieldServerFunc>,
GetLastName: '' as Resource<TemplateFieldServerFunc>,
GetOwnerPosition: '' as Resource<TemplateFieldServerFunc>
}
})

View File

@ -34,6 +34,7 @@
"@hcengineering/server-core": "^0.6.1",
"@hcengineering/contact": "^0.6.20",
"@hcengineering/notification": "^0.6.16",
"@hcengineering/telegram": "^0.6.14"
"@hcengineering/telegram": "^0.6.14",
"@hcengineering/setting": "^0.6.11"
}
}

View File

@ -13,7 +13,7 @@
// limitations under the License.
//
import contact, { Channel } from '@hcengineering/contact'
import contact, { Channel, ChannelProvider, Contact, Employee, PersonAccount } from '@hcengineering/contact'
import {
Account,
Class,
@ -30,6 +30,7 @@ import {
import { TriggerControl } from '@hcengineering/server-core'
import telegram, { TelegramMessage } from '@hcengineering/telegram'
import notification, { NotificationType } from '@hcengineering/notification'
import setting, { Integration } from '@hcengineering/setting'
/**
* @public
@ -129,6 +130,51 @@ export async function IsIncomingMessage (
return message.incoming && message.sendOn > (doc.createdOn ?? doc.modifiedOn)
}
export async function GetCurrentEmployeeTG (
control: TriggerControl,
context: Record<string, Doc>
): Promise<string | undefined> {
const account = await control.modelDb.findOne(contact.class.PersonAccount, {
_id: control.txFactory.account as Ref<PersonAccount>
})
if (account === undefined) return
const employee = (await control.findAll(contact.mixin.Employee, { _id: account.person as Ref<Employee> }))[0]
if (employee !== undefined) {
return await getContactChannel(control, employee, contact.channelProvider.Telegram)
}
}
export async function GetIntegrationOwnerTG (
control: TriggerControl,
context: Record<string, Doc>
): Promise<string | undefined> {
const value = context[setting.class.Integration] as Integration
if (value === undefined) return
const account = await control.modelDb.findOne(contact.class.PersonAccount, {
_id: value.modifiedBy as Ref<PersonAccount>
})
if (account === undefined) return
const employee = (await control.findAll(contact.mixin.Employee, { _id: account.person as Ref<Employee> }))[0]
if (employee !== undefined) {
return await getContactChannel(control, employee, contact.channelProvider.Telegram)
}
}
async function getContactChannel (
control: TriggerControl,
value: Contact,
provider: Ref<ChannelProvider>
): Promise<string | undefined> {
if (value === undefined) return
const res = (
await control.findAll(contact.class.Channel, {
attachedTo: value._id,
provider
})
)[0]
return res?.value ?? ''
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export default async () => ({
trigger: {
@ -136,6 +182,8 @@ export default async () => ({
},
function: {
IsIncomingMessage,
FindMessages
FindMessages,
GetCurrentEmployeeTG,
GetIntegrationOwnerTG
}
})

View File

@ -32,6 +32,7 @@
"dependencies": {
"@hcengineering/core": "^0.6.28",
"@hcengineering/platform": "^0.6.9",
"@hcengineering/server-templates": "^0.6.0",
"@hcengineering/server-notification": "^0.6.1",
"@hcengineering/server-core": "^0.6.1"
}

View File

@ -18,6 +18,7 @@ import type { Plugin, Resource } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import { ObjectDDParticipantFunc, TriggerFunc } from '@hcengineering/server-core'
import { TypeMatchFunc } from '@hcengineering/server-notification'
import { TemplateFieldServerFunc } from '@hcengineering/server-templates'
/**
* @public
@ -33,6 +34,8 @@ export default plugin(serverTelegramId, {
},
function: {
IsIncomingMessage: '' as TypeMatchFunc,
FindMessages: '' as Resource<ObjectDDParticipantFunc>
FindMessages: '' as Resource<ObjectDDParticipantFunc>,
GetCurrentEmployeeTG: '' as Resource<TemplateFieldServerFunc>,
GetIntegrationOwnerTG: '' as Resource<TemplateFieldServerFunc>
}
})

View File

@ -0,0 +1,7 @@
module.exports = {
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
}
}

View File

@ -0,0 +1,4 @@
*
!/lib/**
!CHANGELOG.md
/lib/**/__tests__/

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
"rigPackageName": "@hcengineering/platform-rig"
}

View File

@ -0,0 +1,7 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
roots: ["./src"],
coverageReporters: ["text-summary", "html"]
}

View File

@ -0,0 +1,38 @@
{
"name": "@hcengineering/server-templates",
"version": "0.6.0",
"main": "lib/index.js",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "tsc",
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"lint": "eslint src",
"format": "format src",
"test": "jest --passWithNoTests --silent"
},
"devDependencies": {
"@hcengineering/platform-rig": "^0.6.0",
"@types/node": "~16.11.12",
"@typescript-eslint/eslint-plugin": "^6.11.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-n": "^15.4.0",
"eslint": "^8.54.0",
"@typescript-eslint/parser": "^6.11.0",
"eslint-config-standard-with-typescript": "^40.0.0",
"prettier": "^3.1.0",
"typescript": "^5.2.2",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"@types/jest": "^29.5.5",
"prettier-plugin-svelte": "^3.1.0"
},
"dependencies": {
"@hcengineering/core": "^0.6.28",
"@hcengineering/server-core": "^0.6.1",
"@hcengineering/platform": "^0.6.9",
"@hcengineering/templates": "^0.6.7"
}
}

View File

@ -0,0 +1,44 @@
//
// 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.
//
import { Ref, Mixin, Doc } from '@hcengineering/core'
import type { Plugin, Resource } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import { type TriggerControl } from '@hcengineering/server-core'
import { TemplateField } from '@hcengineering/templates'
export type TemplateFieldServerFunc = (
control: TriggerControl,
context: Record<string, Doc>
) => Promise<string | undefined>
export interface ServerTemplateField extends TemplateField {
serverFunc: Resource<TemplateFieldServerFunc>
}
/**
* @public
*/
export const serverTemplatesId = 'server-templates' as Plugin
/**
* @public
*/
export default plugin(serverTemplatesId, {
mixin: {
ServerTemplateField: '' as Ref<Mixin<ServerTemplateField>>
}
})

View File

@ -0,0 +1,9 @@
{
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib",
"tsBuildInfoFile": ".build/build.tsbuildinfo"
}
}