mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-26 04:23:58 +03:00
Rework reviews (#1156)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
c37d6b8e0e
commit
a4af938871
@ -13,6 +13,9 @@ specifiers:
|
|||||||
'@rush-temp/attachment': file:./projects/attachment.tgz
|
'@rush-temp/attachment': file:./projects/attachment.tgz
|
||||||
'@rush-temp/attachment-assets': file:./projects/attachment-assets.tgz
|
'@rush-temp/attachment-assets': file:./projects/attachment-assets.tgz
|
||||||
'@rush-temp/attachment-resources': file:./projects/attachment-resources.tgz
|
'@rush-temp/attachment-resources': file:./projects/attachment-resources.tgz
|
||||||
|
'@rush-temp/calendar': file:./projects/calendar.tgz
|
||||||
|
'@rush-temp/calendar-assets': file:./projects/calendar-assets.tgz
|
||||||
|
'@rush-temp/calendar-resources': file:./projects/calendar-resources.tgz
|
||||||
'@rush-temp/chunter': file:./projects/chunter.tgz
|
'@rush-temp/chunter': file:./projects/chunter.tgz
|
||||||
'@rush-temp/chunter-assets': file:./projects/chunter-assets.tgz
|
'@rush-temp/chunter-assets': file:./projects/chunter-assets.tgz
|
||||||
'@rush-temp/chunter-resources': file:./projects/chunter-resources.tgz
|
'@rush-temp/chunter-resources': file:./projects/chunter-resources.tgz
|
||||||
@ -50,6 +53,7 @@ specifiers:
|
|||||||
'@rush-temp/model-activity': file:./projects/model-activity.tgz
|
'@rush-temp/model-activity': file:./projects/model-activity.tgz
|
||||||
'@rush-temp/model-all': file:./projects/model-all.tgz
|
'@rush-temp/model-all': file:./projects/model-all.tgz
|
||||||
'@rush-temp/model-attachment': file:./projects/model-attachment.tgz
|
'@rush-temp/model-attachment': file:./projects/model-attachment.tgz
|
||||||
|
'@rush-temp/model-calendar': file:./projects/model-calendar.tgz
|
||||||
'@rush-temp/model-chunter': file:./projects/model-chunter.tgz
|
'@rush-temp/model-chunter': file:./projects/model-chunter.tgz
|
||||||
'@rush-temp/model-contact': file:./projects/model-contact.tgz
|
'@rush-temp/model-contact': file:./projects/model-contact.tgz
|
||||||
'@rush-temp/model-core': file:./projects/model-core.tgz
|
'@rush-temp/model-core': file:./projects/model-core.tgz
|
||||||
@ -167,7 +171,6 @@ specifiers:
|
|||||||
'@types/koa__cors': ^3.0.3
|
'@types/koa__cors': ^3.0.3
|
||||||
'@types/mime-types': ~2.1.1
|
'@types/mime-types': ~2.1.1
|
||||||
'@types/minio': ~7.0.11
|
'@types/minio': ~7.0.11
|
||||||
'@types/node': ~16.11.12
|
|
||||||
'@types/pdfkit': ~0.12.3
|
'@types/pdfkit': ~0.12.3
|
||||||
'@types/prosemirror-model': ~1.16.0
|
'@types/prosemirror-model': ~1.16.0
|
||||||
'@types/request': ~2.48.8
|
'@types/request': ~2.48.8
|
||||||
@ -257,6 +260,9 @@ dependencies:
|
|||||||
'@rush-temp/attachment': file:projects/attachment.tgz
|
'@rush-temp/attachment': file:projects/attachment.tgz
|
||||||
'@rush-temp/attachment-assets': file:projects/attachment-assets.tgz_typescript@4.5.4
|
'@rush-temp/attachment-assets': file:projects/attachment-assets.tgz_typescript@4.5.4
|
||||||
'@rush-temp/attachment-resources': file:projects/attachment-resources.tgz_096c09b0b673a57c275d9767a12070b1
|
'@rush-temp/attachment-resources': file:projects/attachment-resources.tgz_096c09b0b673a57c275d9767a12070b1
|
||||||
|
'@rush-temp/calendar': file:projects/calendar.tgz
|
||||||
|
'@rush-temp/calendar-assets': file:projects/calendar-assets.tgz_typescript@4.5.4
|
||||||
|
'@rush-temp/calendar-resources': file:projects/calendar-resources.tgz_096c09b0b673a57c275d9767a12070b1
|
||||||
'@rush-temp/chunter': file:projects/chunter.tgz
|
'@rush-temp/chunter': file:projects/chunter.tgz
|
||||||
'@rush-temp/chunter-assets': file:projects/chunter-assets.tgz_typescript@4.5.4
|
'@rush-temp/chunter-assets': file:projects/chunter-assets.tgz_typescript@4.5.4
|
||||||
'@rush-temp/chunter-resources': file:projects/chunter-resources.tgz_096c09b0b673a57c275d9767a12070b1
|
'@rush-temp/chunter-resources': file:projects/chunter-resources.tgz_096c09b0b673a57c275d9767a12070b1
|
||||||
@ -269,11 +275,11 @@ dependencies:
|
|||||||
'@rush-temp/core': file:projects/core.tgz
|
'@rush-temp/core': file:projects/core.tgz
|
||||||
'@rush-temp/dev-account': file:projects/dev-account.tgz
|
'@rush-temp/dev-account': file:projects/dev-account.tgz
|
||||||
'@rush-temp/dev-client-resources': file:projects/dev-client-resources.tgz
|
'@rush-temp/dev-client-resources': file:projects/dev-client-resources.tgz
|
||||||
'@rush-temp/dev-server': file:projects/dev-server.tgz_@types+node@16.11.14
|
'@rush-temp/dev-server': file:projects/dev-server.tgz
|
||||||
'@rush-temp/dev-storage': file:projects/dev-storage.tgz
|
'@rush-temp/dev-storage': file:projects/dev-storage.tgz
|
||||||
'@rush-temp/devmodel': file:projects/devmodel.tgz_typescript@4.5.4
|
'@rush-temp/devmodel': file:projects/devmodel.tgz_typescript@4.5.4
|
||||||
'@rush-temp/devmodel-resources': file:projects/devmodel-resources.tgz_6cae74ea501386c76c405ad0408e0339
|
'@rush-temp/devmodel-resources': file:projects/devmodel-resources.tgz_6cae74ea501386c76c405ad0408e0339
|
||||||
'@rush-temp/elastic': file:projects/elastic.tgz_@types+node@16.11.14
|
'@rush-temp/elastic': file:projects/elastic.tgz
|
||||||
'@rush-temp/front': file:projects/front.tgz
|
'@rush-temp/front': file:projects/front.tgz
|
||||||
'@rush-temp/generator': file:projects/generator.tgz
|
'@rush-temp/generator': file:projects/generator.tgz
|
||||||
'@rush-temp/gmail': file:projects/gmail.tgz
|
'@rush-temp/gmail': file:projects/gmail.tgz
|
||||||
@ -294,6 +300,7 @@ dependencies:
|
|||||||
'@rush-temp/model-activity': file:projects/model-activity.tgz_typescript@4.5.4
|
'@rush-temp/model-activity': file:projects/model-activity.tgz_typescript@4.5.4
|
||||||
'@rush-temp/model-all': file:projects/model-all.tgz_typescript@4.5.4
|
'@rush-temp/model-all': file:projects/model-all.tgz_typescript@4.5.4
|
||||||
'@rush-temp/model-attachment': file:projects/model-attachment.tgz_typescript@4.5.4
|
'@rush-temp/model-attachment': file:projects/model-attachment.tgz_typescript@4.5.4
|
||||||
|
'@rush-temp/model-calendar': file:projects/model-calendar.tgz_typescript@4.5.4
|
||||||
'@rush-temp/model-chunter': file:projects/model-chunter.tgz_typescript@4.5.4
|
'@rush-temp/model-chunter': file:projects/model-chunter.tgz_typescript@4.5.4
|
||||||
'@rush-temp/model-contact': file:projects/model-contact.tgz_typescript@4.5.4
|
'@rush-temp/model-contact': file:projects/model-contact.tgz_typescript@4.5.4
|
||||||
'@rush-temp/model-core': file:projects/model-core.tgz_typescript@4.5.4
|
'@rush-temp/model-core': file:projects/model-core.tgz_typescript@4.5.4
|
||||||
@ -411,7 +418,6 @@ dependencies:
|
|||||||
'@types/koa__cors': 3.1.0
|
'@types/koa__cors': 3.1.0
|
||||||
'@types/mime-types': 2.1.1
|
'@types/mime-types': 2.1.1
|
||||||
'@types/minio': 7.0.11
|
'@types/minio': 7.0.11
|
||||||
'@types/node': 16.11.14
|
|
||||||
'@types/pdfkit': 0.12.3
|
'@types/pdfkit': 0.12.3
|
||||||
'@types/prosemirror-model': 1.16.0
|
'@types/prosemirror-model': 1.16.0
|
||||||
'@types/request': 2.48.8
|
'@types/request': 2.48.8
|
||||||
@ -478,7 +484,7 @@ dependencies:
|
|||||||
svgo-loader: 3.0.0
|
svgo-loader: 3.0.0
|
||||||
toposort: 2.0.2
|
toposort: 2.0.2
|
||||||
ts-loader: 9.2.6_typescript@4.5.4+webpack@5.65.0
|
ts-loader: 9.2.6_typescript@4.5.4+webpack@5.65.0
|
||||||
ts-node: 10.5.0_5d12c2add188ff0e728b4ade3dacd39b
|
ts-node: 10.5.0_typescript@4.5.4
|
||||||
typescript: 4.5.4
|
typescript: 4.5.4
|
||||||
uuid: 8.3.2
|
uuid: 8.3.2
|
||||||
webpack: 5.65.0_9def3870c80213359789f9191dbd286a
|
webpack: 5.65.0_9def3870c80213359789f9191dbd286a
|
||||||
@ -8563,7 +8569,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
import-cwd: 3.0.0
|
import-cwd: 3.0.0
|
||||||
lilconfig: 2.0.4
|
lilconfig: 2.0.4
|
||||||
ts-node: 10.5.0_5d12c2add188ff0e728b4ade3dacd39b
|
ts-node: 10.5.0_typescript@4.5.4
|
||||||
yaml: 1.10.2
|
yaml: 1.10.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@ -10452,6 +10458,36 @@ packages:
|
|||||||
yn: 3.1.1
|
yn: 3.1.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/ts-node/10.5.0_typescript@4.5.4:
|
||||||
|
resolution: {integrity: sha512-6kEJKwVxAJ35W4akuiysfKwKmjkbYxwQMTBaAxo9KKAx/Yd26mPUyhGz3ji+EsJoAgrLqVsYHNuuYwQe22lbtw==}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
'@swc/core': '>=1.2.50'
|
||||||
|
'@swc/wasm': '>=1.2.50'
|
||||||
|
'@types/node': '*'
|
||||||
|
typescript: '>=2.7'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@swc/core':
|
||||||
|
optional: true
|
||||||
|
'@swc/wasm':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@cspotcode/source-map-support': 0.7.0
|
||||||
|
'@tsconfig/node10': 1.0.8
|
||||||
|
'@tsconfig/node12': 1.0.9
|
||||||
|
'@tsconfig/node14': 1.0.1
|
||||||
|
'@tsconfig/node16': 1.0.2
|
||||||
|
acorn: 8.6.0
|
||||||
|
acorn-walk: 8.2.0
|
||||||
|
arg: 4.1.3
|
||||||
|
create-require: 1.1.1
|
||||||
|
diff: 4.0.2
|
||||||
|
make-error: 1.3.6
|
||||||
|
typescript: 4.5.4
|
||||||
|
v8-compile-cache-lib: 3.0.0
|
||||||
|
yn: 3.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/tsconfig-paths/3.12.0:
|
/tsconfig-paths/3.12.0:
|
||||||
resolution: {integrity: sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==}
|
resolution: {integrity: sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -11416,6 +11452,83 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
file:projects/calendar-assets.tgz_typescript@4.5.4:
|
||||||
|
resolution: {integrity: sha512-muyoJ0EuKPUpsAEL1bLgdR90OqIoohgdfUFDwyWP1qmtAe9k1my76bJSIiU1JSfybyssHYiR8jpM/SuIonWg3Q==, tarball: file:projects/calendar-assets.tgz}
|
||||||
|
id: file:projects/calendar-assets.tgz
|
||||||
|
name: '@rush-temp/calendar-assets'
|
||||||
|
version: 0.0.0
|
||||||
|
dependencies:
|
||||||
|
'@rushstack/heft': 0.41.8
|
||||||
|
'@types/heft-jest': 1.0.2
|
||||||
|
'@types/node': 16.11.14
|
||||||
|
'@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237
|
||||||
|
'@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4
|
||||||
|
eslint: 7.32.0
|
||||||
|
eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a
|
||||||
|
eslint-plugin-import: 2.25.3_eslint@7.32.0
|
||||||
|
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||||
|
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
||||||
|
prettier: 2.5.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
- typescript
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
file:projects/calendar-resources.tgz_096c09b0b673a57c275d9767a12070b1:
|
||||||
|
resolution: {integrity: sha512-UZIMmHCGB+XoLDkyP1A/+ot4oc0POAPYCVOtiPI3vQtVWuTIPquMM4pPX3HxkvfpWqblXburuJx3j18rfA5Mgw==, tarball: file:projects/calendar-resources.tgz}
|
||||||
|
id: file:projects/calendar-resources.tgz
|
||||||
|
name: '@rush-temp/calendar-resources'
|
||||||
|
version: 0.0.0
|
||||||
|
dependencies:
|
||||||
|
'@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237
|
||||||
|
'@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4
|
||||||
|
eslint: 7.32.0
|
||||||
|
eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a
|
||||||
|
eslint-plugin-import: 2.25.3_eslint@7.32.0
|
||||||
|
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||||
|
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
||||||
|
eslint-plugin-svelte3: 3.2.1_eslint@7.32.0+svelte@3.44.3
|
||||||
|
prettier: 2.5.1
|
||||||
|
prettier-plugin-svelte: 2.5.1_prettier@2.5.1+svelte@3.44.3
|
||||||
|
sass: 1.45.0
|
||||||
|
svelte: 3.44.3
|
||||||
|
svelte-check: 2.3.0_4374c622c67ed7479ff0e44c29d09bce
|
||||||
|
svelte-loader: 3.1.2_svelte@3.44.3
|
||||||
|
svelte-preprocess: 4.10.3_14d64cad431e31f100de7363af24a44f
|
||||||
|
typescript: 4.5.4
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@babel/core'
|
||||||
|
- coffeescript
|
||||||
|
- less
|
||||||
|
- node-sass
|
||||||
|
- postcss
|
||||||
|
- postcss-load-config
|
||||||
|
- pug
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
file:projects/calendar.tgz:
|
||||||
|
resolution: {integrity: sha512-mN4GfaHpyGzuLV59eFw3c3R6p2r4ewEumsIhzyifgeXaXSD9Bnm06LG5LvFgF5G5TmDquUFcIq88w3Zzd20cQA==, tarball: file:projects/calendar.tgz}
|
||||||
|
name: '@rush-temp/calendar'
|
||||||
|
version: 0.0.0
|
||||||
|
dependencies:
|
||||||
|
'@rushstack/heft': 0.41.8
|
||||||
|
'@types/heft-jest': 1.0.2
|
||||||
|
'@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237
|
||||||
|
'@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4
|
||||||
|
eslint: 7.32.0
|
||||||
|
eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a
|
||||||
|
eslint-plugin-import: 2.25.3_eslint@7.32.0
|
||||||
|
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||||
|
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
||||||
|
prettier: 2.5.1
|
||||||
|
typescript: 4.5.4
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: false
|
||||||
|
|
||||||
file:projects/chunter-assets.tgz_typescript@4.5.4:
|
file:projects/chunter-assets.tgz_typescript@4.5.4:
|
||||||
resolution: {integrity: sha512-2EQgdQ62vXKYpX9iOtOaCRt1GZliFiJpPPBZbOMHjaeWLye+/zYXlffkBbjVUSfR894cBlrtZBVRapjJU2T3uA==, tarball: file:projects/chunter-assets.tgz}
|
resolution: {integrity: sha512-2EQgdQ62vXKYpX9iOtOaCRt1GZliFiJpPPBZbOMHjaeWLye+/zYXlffkBbjVUSfR894cBlrtZBVRapjJU2T3uA==, tarball: file:projects/chunter-assets.tgz}
|
||||||
id: file:projects/chunter-assets.tgz
|
id: file:projects/chunter-assets.tgz
|
||||||
@ -11713,9 +11826,8 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/dev-server.tgz_@types+node@16.11.14:
|
file:projects/dev-server.tgz:
|
||||||
resolution: {integrity: sha512-pv0DpcojPAreq3xXTnbl3Rj2UwEy97zRPmXU2lJsM0pKc6dVpmicD+/Bq4laIWx5qhvzfLurbwjBV4/0mLeuYw==, tarball: file:projects/dev-server.tgz}
|
resolution: {integrity: sha512-pv0DpcojPAreq3xXTnbl3Rj2UwEy97zRPmXU2lJsM0pKc6dVpmicD+/Bq4laIWx5qhvzfLurbwjBV4/0mLeuYw==, tarball: file:projects/dev-server.tgz}
|
||||||
id: file:projects/dev-server.tgz
|
|
||||||
name: '@rush-temp/dev-server'
|
name: '@rush-temp/dev-server'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -11730,7 +11842,7 @@ packages:
|
|||||||
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
||||||
jwt-simple: 0.5.6
|
jwt-simple: 0.5.6
|
||||||
prettier: 2.5.1
|
prettier: 2.5.1
|
||||||
ts-node: 10.5.0_5d12c2add188ff0e728b4ade3dacd39b
|
ts-node: 10.5.0_typescript@4.5.4
|
||||||
typescript: 4.5.4
|
typescript: 4.5.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@swc/core'
|
- '@swc/core'
|
||||||
@ -11815,9 +11927,8 @@ packages:
|
|||||||
- typescript
|
- typescript
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/elastic.tgz_@types+node@16.11.14:
|
file:projects/elastic.tgz:
|
||||||
resolution: {integrity: sha512-CF8tie/n08Slnvw40pFZnaS4j/2JPQzs2xAxakNqpokb5x3ci9e0z2gzXNB6otQElk1NxW69QDHqNme+jHqWPA==, tarball: file:projects/elastic.tgz}
|
resolution: {integrity: sha512-CF8tie/n08Slnvw40pFZnaS4j/2JPQzs2xAxakNqpokb5x3ci9e0z2gzXNB6otQElk1NxW69QDHqNme+jHqWPA==, tarball: file:projects/elastic.tgz}
|
||||||
id: file:projects/elastic.tgz
|
|
||||||
name: '@rush-temp/elastic'
|
name: '@rush-temp/elastic'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -11832,7 +11943,7 @@ packages:
|
|||||||
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||||
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
||||||
prettier: 2.5.1
|
prettier: 2.5.1
|
||||||
ts-node: 10.5.0_5d12c2add188ff0e728b4ade3dacd39b
|
ts-node: 10.5.0_typescript@4.5.4
|
||||||
typescript: 4.5.4
|
typescript: 4.5.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@swc/core'
|
- '@swc/core'
|
||||||
@ -12305,7 +12416,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/model-all.tgz_typescript@4.5.4:
|
file:projects/model-all.tgz_typescript@4.5.4:
|
||||||
resolution: {integrity: sha512-Jll+Wp4p6/OjdvtbTqAGKbMUkOoAai5Se2+CSIOteRB6dDTgtlwy95fzQv2o5RHIBBiQXLQ2Csb8KgAluzTJ6w==, tarball: file:projects/model-all.tgz}
|
resolution: {integrity: sha512-LprNHSPgySvlj/zl9bkeSZ7Uh1wWyPPkQBW6knjBBD3cizpFpxPGBrSQnhDe/RP0uj6azKRYWWUcAPFOYe4TvQ==, tarball: file:projects/model-all.tgz}
|
||||||
id: file:projects/model-all.tgz
|
id: file:projects/model-all.tgz
|
||||||
name: '@rush-temp/model-all'
|
name: '@rush-temp/model-all'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
@ -12350,6 +12461,27 @@ packages:
|
|||||||
- typescript
|
- typescript
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
file:projects/model-calendar.tgz_typescript@4.5.4:
|
||||||
|
resolution: {integrity: sha512-sI97CjbxdgK1qWGDrBViWm65NY+vwFzt1s94cGheRJP8CL/GqJNuaSyrJv0pqjfZgK6Z3IkcUq2ZUSSHwD+1gQ==, tarball: file:projects/model-calendar.tgz}
|
||||||
|
id: file:projects/model-calendar.tgz
|
||||||
|
name: '@rush-temp/model-calendar'
|
||||||
|
version: 0.0.0
|
||||||
|
dependencies:
|
||||||
|
'@rushstack/heft': 0.41.8
|
||||||
|
'@types/heft-jest': 1.0.2
|
||||||
|
'@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237
|
||||||
|
'@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4
|
||||||
|
eslint: 7.32.0
|
||||||
|
eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a
|
||||||
|
eslint-plugin-import: 2.25.3_eslint@7.32.0
|
||||||
|
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||||
|
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
||||||
|
prettier: 2.5.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
- typescript
|
||||||
|
dev: false
|
||||||
|
|
||||||
file:projects/model-chunter.tgz_typescript@4.5.4:
|
file:projects/model-chunter.tgz_typescript@4.5.4:
|
||||||
resolution: {integrity: sha512-bbKuovYnIkpRkU0YhE2x6UEx2gvwKM/OkCj7SH4rQhVR3vjdWisBd0/P71NsNdfcdR7Hl4fhHSNVZfW6KNNPog==, tarball: file:projects/model-chunter.tgz}
|
resolution: {integrity: sha512-bbKuovYnIkpRkU0YhE2x6UEx2gvwKM/OkCj7SH4rQhVR3vjdWisBd0/P71NsNdfcdR7Hl4fhHSNVZfW6KNNPog==, tarball: file:projects/model-chunter.tgz}
|
||||||
id: file:projects/model-chunter.tgz
|
id: file:projects/model-chunter.tgz
|
||||||
@ -12540,7 +12672,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/model-recruit.tgz_typescript@4.5.4:
|
file:projects/model-recruit.tgz_typescript@4.5.4:
|
||||||
resolution: {integrity: sha512-t2mSCyFnB+YfsxFuAu0J8hNVhM+GP5SjiVevMe8tft+dCyyLeMpAJxTdEKkvRx6jV6yyxyPUmqZMAQCmm/pvuA==, tarball: file:projects/model-recruit.tgz}
|
resolution: {integrity: sha512-TtzOJVyFh5KY3RmQUTUUqeemhDDo/14R1RRrbQ7FoYun9yl+lv5b00OUuIbZ4rtYSJQLhiJaXFbZbxHl6pr3mA==, tarball: file:projects/model-recruit.tgz}
|
||||||
id: file:projects/model-recruit.tgz
|
id: file:projects/model-recruit.tgz
|
||||||
name: '@rush-temp/model-recruit'
|
name: '@rush-temp/model-recruit'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
@ -13235,7 +13367,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/prod.tgz_a07ec81d4d975778878ca12202ea119e:
|
file:projects/prod.tgz_a07ec81d4d975778878ca12202ea119e:
|
||||||
resolution: {integrity: sha512-R0Y2btm9DPFvRRGYAGC6ilCIcE5t+p2trcdARVBxyi+tH4XwcXZSt0NJJe+57vpiwkCV8hYPa2fI+Eul1wdrpQ==, tarball: file:projects/prod.tgz}
|
resolution: {integrity: sha512-mxkGGtPp108JHMkmnEgKKPNVrihu3xVv1wZqY/HTWhZ+v8Ct5RG92+Yg6NBhEsLmqCBBPTAHY/JapGi1oF9bWg==, tarball: file:projects/prod.tgz}
|
||||||
id: file:projects/prod.tgz
|
id: file:projects/prod.tgz
|
||||||
name: '@rush-temp/prod'
|
name: '@rush-temp/prod'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
@ -13329,7 +13461,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/recruit-resources.tgz_096c09b0b673a57c275d9767a12070b1:
|
file:projects/recruit-resources.tgz_096c09b0b673a57c275d9767a12070b1:
|
||||||
resolution: {integrity: sha512-EexKsB2ZRQ/VxlTABy5b5g3MLR51+549IMWW4g6+Xb/ZR6MZKCT6ocWPRgULW64EO3CTOJ37nIlXijj6Z/fPKw==, tarball: file:projects/recruit-resources.tgz}
|
resolution: {integrity: sha512-nvxkMBBQ9fPzCtIIQbUOlLaV+4wulVAKLg2iBOR5RuEiKZK/kwItpbzv0u6mS5Vb7/yFRp0GsRM+G7rv1tiGfg==, tarball: file:projects/recruit-resources.tgz}
|
||||||
id: file:projects/recruit-resources.tgz
|
id: file:projects/recruit-resources.tgz
|
||||||
name: '@rush-temp/recruit-resources'
|
name: '@rush-temp/recruit-resources'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
@ -13366,7 +13498,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/recruit.tgz:
|
file:projects/recruit.tgz:
|
||||||
resolution: {integrity: sha512-wAgHbMEy+KVBNhYTiPdcBnN0O7BAsfxLMxK/gcjM1pkqeLbCzJ/SpRNMFpC2K0/TU+qsPqCzK3zx0VSvFXH05A==, tarball: file:projects/recruit.tgz}
|
resolution: {integrity: sha512-VAcfan3RLB0bq8DYryIS1waf0EiSSjbd1mdyq0IqMvlp9b8OBUGf0mOCfHDhkno9C4nf9fN8kCUDk9y82LfjZg==, tarball: file:projects/recruit.tgz}
|
||||||
name: '@rush-temp/recruit'
|
name: '@rush-temp/recruit'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -82,7 +82,7 @@ services:
|
|||||||
- mongodb
|
- mongodb
|
||||||
- elastic
|
- elastic
|
||||||
- minio
|
- minio
|
||||||
- apm-server
|
# - apm-server
|
||||||
ports:
|
ports:
|
||||||
- 3333:3333
|
- 3333:3333
|
||||||
environment:
|
environment:
|
||||||
@ -94,41 +94,41 @@ services:
|
|||||||
- MINIO_ENDPOINT=minio
|
- MINIO_ENDPOINT=minio
|
||||||
- MINIO_ACCESS_KEY=minioadmin
|
- MINIO_ACCESS_KEY=minioadmin
|
||||||
- MINIO_SECRET_KEY=minioadmin
|
- MINIO_SECRET_KEY=minioadmin
|
||||||
- APM_SERVER_URL=http://apm-server:8200
|
# - APM_SERVER_URL=http://apm-server:8200
|
||||||
apm-server:
|
# apm-server:
|
||||||
image: docker.elastic.co/apm/apm-server:7.14.2
|
# image: docker.elastic.co/apm/apm-server:7.14.2
|
||||||
depends_on:
|
# depends_on:
|
||||||
- "elastic"
|
# - "elastic"
|
||||||
- "kibana"
|
# - "kibana"
|
||||||
cap_add: ["CHOWN", "DAC_OVERRIDE", "SETGID", "SETUID"]
|
# cap_add: ["CHOWN", "DAC_OVERRIDE", "SETGID", "SETUID"]
|
||||||
cap_drop: ["ALL"]
|
# cap_drop: ["ALL"]
|
||||||
ports:
|
# ports:
|
||||||
- 8200:8200
|
# - 8200:8200
|
||||||
command: |
|
# command: |
|
||||||
apm-server -e
|
# apm-server -e
|
||||||
-E apm-server.rum.enabled=true
|
# -E apm-server.rum.enabled=true
|
||||||
-E setup.kibana.host=kibana:5601
|
# -E setup.kibana.host=kibana:5601
|
||||||
-E setup.template.settings.index.number_of_replicas=0
|
# -E setup.template.settings.index.number_of_replicas=0
|
||||||
-E apm-server.kibana.enabled=true
|
# -E apm-server.kibana.enabled=true
|
||||||
-E apm-server.kibana.host=kibana:5601
|
# -E apm-server.kibana.host=kibana:5601
|
||||||
-E output.elasticsearch.hosts=["elastic:9200"]
|
# -E output.elasticsearch.hosts=["elastic:9200"]
|
||||||
healthcheck:
|
# healthcheck:
|
||||||
interval: 10s
|
# interval: 10s
|
||||||
retries: 12
|
# retries: 12
|
||||||
test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:8200/
|
# test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:8200/
|
||||||
kibana:
|
# kibana:
|
||||||
image: docker.elastic.co/kibana/kibana:7.14.2
|
# image: docker.elastic.co/kibana/kibana:7.14.2
|
||||||
depends_on:
|
# depends_on:
|
||||||
- "elastic"
|
# - "elastic"
|
||||||
environment:
|
# environment:
|
||||||
ELASTICSEARCH_URL: http://elastic:9200
|
# ELASTICSEARCH_URL: http://elastic:9200
|
||||||
ELASTICSEARCH_HOSTS: http://elastic:9200
|
# ELASTICSEARCH_HOSTS: http://elastic:9200
|
||||||
ports:
|
# ports:
|
||||||
- 5601:5601
|
# - 5601:5601
|
||||||
healthcheck:
|
# healthcheck:
|
||||||
interval: 10s
|
# interval: 10s
|
||||||
retries: 20
|
# retries: 20
|
||||||
test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:5601/api/status
|
# test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:5601/api/status
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
db:
|
db:
|
||||||
|
@ -119,6 +119,9 @@
|
|||||||
"@anticrm/server-recruit": "~0.6.0",
|
"@anticrm/server-recruit": "~0.6.0",
|
||||||
"@anticrm/server-recruit-resources": "~0.6.0",
|
"@anticrm/server-recruit-resources": "~0.6.0",
|
||||||
"@anticrm/server-task": "~0.6.0",
|
"@anticrm/server-task": "~0.6.0",
|
||||||
"@anticrm/server-task-resources": "~0.6.0"
|
"@anticrm/server-task-resources": "~0.6.0",
|
||||||
|
"@anticrm/calendar": "~0.6.0",
|
||||||
|
"@anticrm/calendar-assets": "~0.6.0",
|
||||||
|
"@anticrm/calendar-resources": "~0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import { inventoryId } from '@anticrm/inventory'
|
|||||||
import { templatesId } from '@anticrm/templates'
|
import { templatesId } from '@anticrm/templates'
|
||||||
import { notificationId } from '@anticrm/notification'
|
import { notificationId } from '@anticrm/notification'
|
||||||
import { tagsId } from '@anticrm/tags'
|
import { tagsId } from '@anticrm/tags'
|
||||||
|
import { calendarId } from '@anticrm/calendar'
|
||||||
import rekoni from '@anticrm/rekoni'
|
import rekoni from '@anticrm/rekoni'
|
||||||
|
|
||||||
import '@anticrm/login-assets'
|
import '@anticrm/login-assets'
|
||||||
@ -54,6 +55,7 @@ import '@anticrm/inventory-assets'
|
|||||||
import '@anticrm/templates-assets'
|
import '@anticrm/templates-assets'
|
||||||
import '@anticrm/notification-assets'
|
import '@anticrm/notification-assets'
|
||||||
import '@anticrm/tags-assets'
|
import '@anticrm/tags-assets'
|
||||||
|
import '@anticrm/calendar-assets'
|
||||||
|
|
||||||
import { setMetadata } from '@anticrm/platform'
|
import { setMetadata } from '@anticrm/platform'
|
||||||
export async function configurePlatform() {
|
export async function configurePlatform() {
|
||||||
@ -95,4 +97,5 @@ export async function configurePlatform() {
|
|||||||
addLocation(templatesId, () => import(/* webpackChunkName: "templates" */ '@anticrm/templates-resources'))
|
addLocation(templatesId, () => import(/* webpackChunkName: "templates" */ '@anticrm/templates-resources'))
|
||||||
addLocation(notificationId, () => import(/* webpackChunkName: "notification" */ '@anticrm/notification-resources'))
|
addLocation(notificationId, () => import(/* webpackChunkName: "notification" */ '@anticrm/notification-resources'))
|
||||||
addLocation(tagsId, () => import(/* webpackChunkName: "tags" */ '@anticrm/tags-resources'))
|
addLocation(tagsId, () => import(/* webpackChunkName: "tags" */ '@anticrm/tags-resources'))
|
||||||
|
addLocation(calendarId, () => import(/* webpackChunkName: "calendar" */ '@anticrm/calendar-resources'))
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
"@anticrm/model-notification": "~0.6.0",
|
"@anticrm/model-notification": "~0.6.0",
|
||||||
"@anticrm/model-text-editor": "~0.6.0",
|
"@anticrm/model-text-editor": "~0.6.0",
|
||||||
"@anticrm/core": "~0.6.16",
|
"@anticrm/core": "~0.6.16",
|
||||||
"@anticrm/model-tags": "~0.6.0"
|
"@anticrm/model-tags": "~0.6.0",
|
||||||
|
"@anticrm/model-calendar": "~0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ import { createModel as viewModel } from '@anticrm/model-view'
|
|||||||
import { createModel as workbenchModel } from '@anticrm/model-workbench'
|
import { createModel as workbenchModel } from '@anticrm/model-workbench'
|
||||||
import { createModel as notificationModel } from '@anticrm/model-notification'
|
import { createModel as notificationModel } from '@anticrm/model-notification'
|
||||||
import { createModel as tagsModel } from '@anticrm/model-tags'
|
import { createModel as tagsModel } from '@anticrm/model-tags'
|
||||||
|
import { createModel as calendarModel } from '@anticrm/model-calendar'
|
||||||
|
|
||||||
export const version: Data<Version> = jsonVersion as Data<Version>
|
export const version: Data<Version> = jsonVersion as Data<Version>
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ const builders = [
|
|||||||
serverNotificationModel,
|
serverNotificationModel,
|
||||||
serveSettingModel,
|
serveSettingModel,
|
||||||
tagsModel,
|
tagsModel,
|
||||||
|
calendarModel,
|
||||||
serverChunterModel,
|
serverChunterModel,
|
||||||
serverInventoryModel,
|
serverInventoryModel,
|
||||||
serverLeadModel,
|
serverLeadModel,
|
||||||
|
7
models/calendar/.eslintrc.js
Normal file
7
models/calendar/.eslintrc.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: ['./node_modules/@anticrm/model-rig/profiles/default/config/eslint.config.json'],
|
||||||
|
parserOptions: {
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
project: './tsconfig.json'
|
||||||
|
}
|
||||||
|
}
|
4
models/calendar/.npmignore
Normal file
4
models/calendar/.npmignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
*
|
||||||
|
!/lib/**
|
||||||
|
!CHANGELOG.md
|
||||||
|
/lib/**/__tests__/
|
18
models/calendar/config/rig.json
Normal file
18
models/calendar/config/rig.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// The "rig.json" file directs tools to look for their config files in an external package.
|
||||||
|
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Required) The name of the rig package to inherit from.
|
||||||
|
* It should be an NPM package name with the "-rig" suffix.
|
||||||
|
*/
|
||||||
|
"rigPackageName": "@anticrm/model-rig"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Optional) Selects a config profile from the rig package. The name must consist of
|
||||||
|
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
|
||||||
|
* If omitted, then the "default" profile will be used."
|
||||||
|
*/
|
||||||
|
// "rigProfile": "your-profile-name"
|
||||||
|
}
|
46
models/calendar/package.json
Normal file
46
models/calendar/package.json
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"name": "@anticrm/model-calendar",
|
||||||
|
"version": "0.6.0",
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"author": "Anticrm Platform Contributors",
|
||||||
|
"license": "EPL-2.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "heft build",
|
||||||
|
"build:watch": "tsc",
|
||||||
|
"lint:fix": "eslint --fix src",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"format": "prettier --write src && eslint --fix src"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@anticrm/model-rig": "~0.6.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||||
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
"eslint-plugin-promise": "^5.1.1",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"@types/heft-jest": "^1.0.2",
|
||||||
|
"@typescript-eslint/parser": "^5.4.0",
|
||||||
|
"eslint-config-standard-with-typescript": "^21.0.1",
|
||||||
|
"prettier": "^2.4.1",
|
||||||
|
"@rushstack/heft": "^0.41.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@anticrm/core": "~0.6.11",
|
||||||
|
"@anticrm/model": "~0.6.0",
|
||||||
|
"@anticrm/ui": "~0.6.0",
|
||||||
|
"@anticrm/view": "~0.6.0",
|
||||||
|
"@anticrm/model-attachment": "~0.6.0",
|
||||||
|
"@anticrm/model-task": "~0.6.0",
|
||||||
|
"@anticrm/calendar": "~0.6.0",
|
||||||
|
"@anticrm/calendar-resources": "~0.6.0",
|
||||||
|
"@anticrm/platform": "~0.6.5",
|
||||||
|
"@anticrm/model-core": "~0.6.0",
|
||||||
|
"@anticrm/model-view": "~0.6.0",
|
||||||
|
"@anticrm/model-workbench": "~0.6.1",
|
||||||
|
"@anticrm/activity": "~0.6.0",
|
||||||
|
"@anticrm/workbench": "~0.6.1",
|
||||||
|
"@anticrm/model-chunter": "~0.6.0",
|
||||||
|
"@anticrm/model-contact": "~0.6.1",
|
||||||
|
"@anticrm/contact": "~0.6.5"
|
||||||
|
}
|
||||||
|
}
|
90
models/calendar/src/index.ts
Normal file
90
models/calendar/src/index.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// Copyright © 2020, 2021 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { Calendar, Event } from '@anticrm/calendar'
|
||||||
|
import { Employee } from '@anticrm/contact'
|
||||||
|
import type { Domain, Markup, Ref, Timestamp } from '@anticrm/core'
|
||||||
|
import { IndexKind } from '@anticrm/core'
|
||||||
|
import { Builder, Collection, Index, Model, Prop, TypeDate, TypeMarkup, TypeString, UX } from '@anticrm/model'
|
||||||
|
import attachment from '@anticrm/model-attachment'
|
||||||
|
import chunter from '@anticrm/model-chunter'
|
||||||
|
import contact from '@anticrm/model-contact'
|
||||||
|
import core, { TAttachedDoc } from '@anticrm/model-core'
|
||||||
|
import { TSpaceWithStates } from '@anticrm/model-task'
|
||||||
|
import workbench from '@anticrm/model-workbench'
|
||||||
|
import calendar from './plugin'
|
||||||
|
|
||||||
|
export * from '@anticrm/calendar'
|
||||||
|
|
||||||
|
export const DOMAIN_CALENDAR = 'calendar' as Domain
|
||||||
|
|
||||||
|
@Model(calendar.class.Calendar, core.class.Space)
|
||||||
|
@UX(calendar.string.Calendar, calendar.icon.Calendar)
|
||||||
|
export class TCalendar extends TSpaceWithStates implements Calendar {}
|
||||||
|
|
||||||
|
@Model(calendar.class.Event, core.class.AttachedDoc, DOMAIN_CALENDAR)
|
||||||
|
export class TEvent extends TAttachedDoc implements Event {
|
||||||
|
@Prop(TypeString(), calendar.string.Title)
|
||||||
|
@Index(IndexKind.FullText)
|
||||||
|
title!: string
|
||||||
|
|
||||||
|
@Prop(TypeString(), calendar.string.EventNumber)
|
||||||
|
number!: number
|
||||||
|
|
||||||
|
@Prop(TypeMarkup(), calendar.string.Description)
|
||||||
|
@Index(IndexKind.FullText)
|
||||||
|
description!: Markup
|
||||||
|
|
||||||
|
@Prop(TypeString(), calendar.string.Location, calendar.icon.Location)
|
||||||
|
@Index(IndexKind.FullText)
|
||||||
|
location?: string
|
||||||
|
|
||||||
|
@Prop(TypeDate(true), calendar.string.Date)
|
||||||
|
date!: Timestamp
|
||||||
|
|
||||||
|
@Prop(TypeDate(true), calendar.string.DueTo)
|
||||||
|
dueDate!: Timestamp
|
||||||
|
|
||||||
|
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments)
|
||||||
|
attachments?: number
|
||||||
|
|
||||||
|
@Prop(Collection(chunter.class.Comment), chunter.string.Comments)
|
||||||
|
comments?: number
|
||||||
|
|
||||||
|
@Prop(Collection(contact.class.Employee), calendar.string.Participants)
|
||||||
|
participants!: Ref<Employee>[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createModel (builder: Builder): void {
|
||||||
|
builder.createModel(TCalendar, TEvent)
|
||||||
|
|
||||||
|
builder.createDoc(workbench.class.Application, core.space.Model, {
|
||||||
|
label: calendar.string.ApplicationLabelCalendar,
|
||||||
|
icon: calendar.icon.Calendar,
|
||||||
|
hidden: true,
|
||||||
|
navigatorModel: {
|
||||||
|
spaces: [
|
||||||
|
{
|
||||||
|
label: calendar.string.Calendars,
|
||||||
|
spaceClass: calendar.class.Calendar,
|
||||||
|
addSpaceLabel: calendar.string.CreateCalendar,
|
||||||
|
createComponent: calendar.component.CreateCalendar
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}, calendar.app.Calendar)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default calendar
|
31
models/calendar/src/plugin.ts
Normal file
31
models/calendar/src/plugin.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { calendarId } from '@anticrm/calendar'
|
||||||
|
import calendar from '@anticrm/calendar-resources/src/plugin'
|
||||||
|
import type { IntlString } from '@anticrm/platform'
|
||||||
|
import { mergeIds } from '@anticrm/platform'
|
||||||
|
import { AnyComponent } from '@anticrm/ui'
|
||||||
|
|
||||||
|
export default mergeIds(calendarId, calendar, {
|
||||||
|
component: {
|
||||||
|
CreateCalendar: '' as AnyComponent
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
ApplicationLabelCalendar: '' as IntlString
|
||||||
|
},
|
||||||
|
space: {
|
||||||
|
}
|
||||||
|
})
|
8
models/calendar/tsconfig.json
Normal file
8
models/calendar/tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"extends": "./node_modules/@anticrm/model-rig/profiles/default/tsconfig.json",
|
||||||
|
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "./src",
|
||||||
|
"outDir": "./lib",
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@ export default mergeIds(coreId, core, {
|
|||||||
Name: '' as IntlString,
|
Name: '' as IntlString,
|
||||||
Description: '' as IntlString,
|
Description: '' as IntlString,
|
||||||
Private: '' as IntlString,
|
Private: '' as IntlString,
|
||||||
Archived: '' as IntlString
|
Archived: '' as IntlString,
|
||||||
|
ClassLabel: '' as IntlString
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -24,7 +24,7 @@ import {
|
|||||||
Timestamp,
|
Timestamp,
|
||||||
Type, Version
|
Type, Version
|
||||||
} from '@anticrm/core'
|
} from '@anticrm/core'
|
||||||
import { Index, Model, Prop, TypeRef, TypeString, TypeTimestamp } from '@anticrm/model'
|
import { Index, Model, Prop, TypeIntlString, TypeRef, TypeString, TypeTimestamp } from '@anticrm/model'
|
||||||
import type { IntlString } from '@anticrm/platform'
|
import type { IntlString } from '@anticrm/platform'
|
||||||
import core from './component'
|
import core from './component'
|
||||||
|
|
||||||
@ -70,7 +70,10 @@ export class TAttachedDoc extends TDoc implements AttachedDoc {
|
|||||||
@Model(core.class.Class, core.class.Doc, DOMAIN_MODEL)
|
@Model(core.class.Class, core.class.Doc, DOMAIN_MODEL)
|
||||||
export class TClass extends TDoc implements Class<Obj> {
|
export class TClass extends TDoc implements Class<Obj> {
|
||||||
kind!: ClassifierKind
|
kind!: ClassifierKind
|
||||||
|
|
||||||
|
@Prop(TypeIntlString(), core.string.ClassLabel)
|
||||||
label!: IntlString
|
label!: IntlString
|
||||||
|
|
||||||
extends!: Ref<Class<Obj>>
|
extends!: Ref<Class<Obj>>
|
||||||
domain!: Domain
|
domain!: Domain
|
||||||
}
|
}
|
||||||
@ -101,6 +104,9 @@ export class TType extends TObj implements Type<any> {
|
|||||||
@Model(core.class.TypeString, core.class.Type)
|
@Model(core.class.TypeString, core.class.Type)
|
||||||
export class TTypeString extends TType {}
|
export class TTypeString extends TType {}
|
||||||
|
|
||||||
|
@Model(core.class.TypeIntlString, core.class.Type)
|
||||||
|
export class TTypeIntlString extends TType {}
|
||||||
|
|
||||||
@Model(core.class.TypeNumber, core.class.Type)
|
@Model(core.class.TypeNumber, core.class.Type)
|
||||||
export class TTypeNumber extends TType {}
|
export class TTypeNumber extends TType {}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import {
|
|||||||
TRefTo,
|
TRefTo,
|
||||||
TType,
|
TType,
|
||||||
TTypeBoolean,
|
TTypeBoolean,
|
||||||
TTypeDate, TTypeMarkup, TTypeNumber, TTypeString, TTypeTimestamp,
|
TTypeDate, TTypeIntlString, TTypeMarkup, TTypeNumber, TTypeString, TTypeTimestamp,
|
||||||
TVersion
|
TVersion
|
||||||
} from './core'
|
} from './core'
|
||||||
import { TAccount, TSpace } from './security'
|
import { TAccount, TSpace } from './security'
|
||||||
@ -80,6 +80,7 @@ export function createModel (builder: Builder): void {
|
|||||||
TTypeDate,
|
TTypeDate,
|
||||||
TArrOf,
|
TArrOf,
|
||||||
TVersion,
|
TVersion,
|
||||||
TTypeNumber
|
TTypeNumber,
|
||||||
|
TTypeIntlString
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
"@anticrm/model-task": "~0.6.0",
|
"@anticrm/model-task": "~0.6.0",
|
||||||
"@anticrm/workbench": "~0.6.1",
|
"@anticrm/workbench": "~0.6.1",
|
||||||
"@anticrm/model-presentation": "~0.6.0",
|
"@anticrm/model-presentation": "~0.6.0",
|
||||||
|
"@anticrm/model-calendar": "~0.6.0",
|
||||||
"@anticrm/model-tags": "~0.6.0",
|
"@anticrm/model-tags": "~0.6.0",
|
||||||
"@anticrm/skillset": "^0.6.0"
|
"@anticrm/skillset": "^0.6.0"
|
||||||
}
|
}
|
||||||
|
@ -303,6 +303,10 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: recruit.component.VacancyPresenter
|
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, {
|
builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.ObjectValidator, {
|
||||||
validator: recruit.validator.ApplicantValidator
|
validator: recruit.validator.ApplicantValidator
|
||||||
})
|
})
|
||||||
@ -366,6 +370,14 @@ export function createModel (builder: Builder): void {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.createDoc(view.class.ActionTarget, core.space.Model, {
|
||||||
|
target: recruit.class.ReviewCategory,
|
||||||
|
action: task.action.UnarchiveSpace,
|
||||||
|
query: {
|
||||||
|
archived: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
builder.createDoc(
|
builder.createDoc(
|
||||||
view.class.Action,
|
view.class.Action,
|
||||||
core.space.Model,
|
core.space.Model,
|
||||||
|
@ -17,6 +17,7 @@ import { Person } from '@anticrm/contact'
|
|||||||
import core, { AttachedDoc, Class, Doc, DocumentQuery, DOMAIN_TX, MixinData, Ref, TxCollectionCUD, TxCreateDoc, TxMixin, TxOperations, TxUpdateDoc } from '@anticrm/core'
|
import core, { AttachedDoc, Class, Doc, DocumentQuery, DOMAIN_TX, MixinData, Ref, TxCollectionCUD, TxCreateDoc, TxMixin, TxOperations, TxUpdateDoc } from '@anticrm/core'
|
||||||
import { createOrUpdate, MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
|
import { createOrUpdate, MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
|
||||||
import { DOMAIN_ATTACHMENT } from '@anticrm/model-attachment'
|
import { DOMAIN_ATTACHMENT } from '@anticrm/model-attachment'
|
||||||
|
import { DOMAIN_CALENDAR } from '@anticrm/model-calendar'
|
||||||
import { DOMAIN_COMMENT } from '@anticrm/model-chunter'
|
import { DOMAIN_COMMENT } from '@anticrm/model-chunter'
|
||||||
import contact, { DOMAIN_CONTACT } from '@anticrm/model-contact'
|
import contact, { DOMAIN_CONTACT } from '@anticrm/model-contact'
|
||||||
import tags, { DOMAIN_TAGS, TagCategory, TagElement } from '@anticrm/model-tags'
|
import tags, { DOMAIN_TAGS, TagCategory, TagElement } from '@anticrm/model-tags'
|
||||||
@ -157,6 +158,25 @@ export const recruitOperation: MigrateOperation = {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Migrate reviews
|
||||||
|
|
||||||
|
await client.update(DOMAIN_TASK, {
|
||||||
|
_class: recruit.class.Review
|
||||||
|
}, {
|
||||||
|
$rename: {
|
||||||
|
startDate: 'date'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await client.update(DOMAIN_TASK, {
|
||||||
|
_class: recruit.class.Review,
|
||||||
|
title: { $exists: false }
|
||||||
|
}, {
|
||||||
|
title: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
await client.move(DOMAIN_TASK, { _class: recruit.class.Review }, DOMAIN_CALENDAR)
|
||||||
},
|
},
|
||||||
async upgrade (client: MigrationUpgradeClient): Promise<void> {
|
async upgrade (client: MigrationUpgradeClient): Promise<void> {
|
||||||
const tx = new TxOperations(client, core.account.System)
|
const tx = new TxOperations(client, core.account.System)
|
||||||
|
@ -61,6 +61,7 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
ApplicationPresenter: '' as AnyComponent,
|
ApplicationPresenter: '' as AnyComponent,
|
||||||
ApplicationsPresenter: '' as AnyComponent,
|
ApplicationsPresenter: '' as AnyComponent,
|
||||||
VacancyPresenter: '' as AnyComponent,
|
VacancyPresenter: '' as AnyComponent,
|
||||||
|
ReviewCategoryPresenter: '' as AnyComponent,
|
||||||
EditApplication: '' as AnyComponent,
|
EditApplication: '' as AnyComponent,
|
||||||
TemplatesIcon: '' as AnyComponent,
|
TemplatesIcon: '' as AnyComponent,
|
||||||
Applications: '' as AnyComponent,
|
Applications: '' as AnyComponent,
|
||||||
|
@ -1,67 +1,38 @@
|
|||||||
import { Employee, Organization } from '@anticrm/contact'
|
import { Organization } from '@anticrm/contact'
|
||||||
import { Domain, IndexKind, Ref, Timestamp } from '@anticrm/core'
|
import { Domain, IndexKind, Ref } from '@anticrm/core'
|
||||||
import { Collection, Index, Model, Prop, TypeDate, TypeMarkup, TypeRef, TypeString, UX } from '@anticrm/model'
|
import { Collection, Index, Model, Prop, TypeMarkup, TypeRef, TypeString, UX } from '@anticrm/model'
|
||||||
import attachment from '@anticrm/model-attachment'
|
import attachment from '@anticrm/model-attachment'
|
||||||
|
import calendar, { TEvent } from '@anticrm/model-calendar'
|
||||||
import chunter from '@anticrm/model-chunter'
|
import chunter from '@anticrm/model-chunter'
|
||||||
import contact from '@anticrm/model-contact'
|
import contact from '@anticrm/model-contact'
|
||||||
import core, { TAttachedDoc } from '@anticrm/model-core'
|
import core, { TAttachedDoc, TSpace } from '@anticrm/model-core'
|
||||||
import task, { TSpaceWithStates, TTask } from '@anticrm/model-task'
|
import task from '@anticrm/model-task'
|
||||||
import { Candidate, Opinion, Review, ReviewCategory } from '@anticrm/recruit'
|
import { Candidate, Opinion, Review, ReviewCategory } from '@anticrm/recruit'
|
||||||
import recruit from './plugin'
|
import recruit from './plugin'
|
||||||
|
|
||||||
@Model(recruit.class.ReviewCategory, task.class.SpaceWithStates)
|
@Model(recruit.class.ReviewCategory, core.class.Space)
|
||||||
@UX(recruit.string.ReviewCategory, recruit.icon.Review)
|
@UX(recruit.string.ReviewCategory, recruit.icon.Review)
|
||||||
export class TReviewCategory extends TSpaceWithStates implements ReviewCategory {
|
export class TReviewCategory extends TSpace implements ReviewCategory {
|
||||||
@Prop(TypeString(), recruit.string.FullDescription)
|
@Prop(TypeString(), recruit.string.FullDescription)
|
||||||
fullDescription?: string
|
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 {
|
||||||
|
// We need to declare, to provide property with label
|
||||||
|
@Prop(TypeRef(recruit.mixin.Candidate), recruit.string.Candidate)
|
||||||
|
declare attachedTo: Ref<Candidate>
|
||||||
|
|
||||||
|
@Prop(TypeString(), recruit.string.Verdict)
|
||||||
|
@Index(IndexKind.FullText)
|
||||||
|
verdict!: string
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Organization), recruit.string.Company, contact.icon.Company)
|
@Prop(TypeRef(contact.class.Organization), recruit.string.Company, contact.icon.Company)
|
||||||
company?: Ref<Organization>
|
company?: Ref<Organization>
|
||||||
}
|
|
||||||
|
|
||||||
@Model(recruit.class.Review, task.class.Task)
|
|
||||||
@UX(recruit.string.Review, recruit.icon.Review, recruit.string.ReviewShortLabel, 'number')
|
|
||||||
export class TReview extends TTask implements Review {
|
|
||||||
// We need to declare, to provide property with label
|
|
||||||
@Prop(TypeRef(recruit.class.Applicant), recruit.string.Candidate)
|
|
||||||
declare attachedTo: Ref<Candidate>
|
|
||||||
|
|
||||||
@Prop(TypeRef(contact.class.Employee), recruit.string.AssignedRecruiter)
|
|
||||||
declare assignee: Ref<Employee> | null
|
|
||||||
|
|
||||||
@Prop(TypeMarkup(), recruit.string.Description)
|
|
||||||
@Index(IndexKind.FullText)
|
|
||||||
description!: string
|
|
||||||
|
|
||||||
@Index(IndexKind.FullText)
|
|
||||||
@Prop(TypeMarkup(), recruit.string.Verdict)
|
|
||||||
verdict!: string
|
|
||||||
|
|
||||||
@Index(IndexKind.FullText)
|
|
||||||
@Prop(TypeString(), recruit.string.Location, recruit.icon.Location)
|
|
||||||
location?: string
|
|
||||||
|
|
||||||
@Index(IndexKind.FullText)
|
|
||||||
@Prop(TypeString(), recruit.string.Company, contact.icon.Company)
|
|
||||||
company?: string
|
|
||||||
|
|
||||||
@Prop(TypeDate(), recruit.string.StartDate)
|
|
||||||
startDate!: Timestamp | null
|
|
||||||
|
|
||||||
@Prop(TypeDate(), recruit.string.DueDate)
|
|
||||||
dueDate!: Timestamp | null
|
|
||||||
|
|
||||||
@Prop(Collection(recruit.class.Opinion), recruit.string.Opinions)
|
@Prop(Collection(recruit.class.Opinion), recruit.string.Opinions)
|
||||||
opinions?: number
|
opinions?: number
|
||||||
|
|
||||||
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments)
|
|
||||||
attachments?: number
|
|
||||||
|
|
||||||
@Prop(Collection(chunter.class.Comment), chunter.string.Comments)
|
|
||||||
comments?: number
|
|
||||||
|
|
||||||
@Prop(Collection(contact.class.Employee), recruit.string.Participants)
|
|
||||||
participants!: Ref<Employee>[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Model(recruit.class.Opinion, core.class.AttachedDoc, 'recruit' as Domain)
|
@Model(recruit.class.Opinion, core.class.AttachedDoc, 'recruit' as Domain)
|
||||||
|
@ -6,6 +6,7 @@ import task from '@anticrm/model-task'
|
|||||||
import view from '@anticrm/model-view'
|
import view from '@anticrm/model-view'
|
||||||
import workbench from '@anticrm/model-workbench'
|
import workbench from '@anticrm/model-workbench'
|
||||||
import recruit from './plugin'
|
import recruit from './plugin'
|
||||||
|
import calendar from '@anticrm/model-calendar'
|
||||||
|
|
||||||
export function createReviewModel (builder: Builder): void {
|
export function createReviewModel (builder: Builder): void {
|
||||||
builder.mixin(recruit.class.ReviewCategory, core.class.Class, workbench.mixin.SpaceView, {
|
builder.mixin(recruit.class.ReviewCategory, core.class.Class, workbench.mixin.SpaceView, {
|
||||||
@ -21,11 +22,21 @@ export function createReviewModel (builder: Builder): void {
|
|||||||
})
|
})
|
||||||
|
|
||||||
createTableViewlet(builder)
|
createTableViewlet(builder)
|
||||||
createKanbanViewlet(builder)
|
|
||||||
createStatusTableViewlet(builder)
|
|
||||||
|
|
||||||
builder.mixin(recruit.class.Review, core.class.Class, task.mixin.KanbanCard, {
|
builder.createDoc(
|
||||||
card: recruit.component.KanbanReviewCard
|
view.class.Action,
|
||||||
|
core.space.Model,
|
||||||
|
{
|
||||||
|
label: recruit.string.CreateOpinion,
|
||||||
|
icon: recruit.icon.Create,
|
||||||
|
action: recruit.actionImpl.CreateOpinion
|
||||||
|
},
|
||||||
|
recruit.action.CreateOpinion
|
||||||
|
)
|
||||||
|
|
||||||
|
builder.createDoc(view.class.ActionTarget, core.space.Model, {
|
||||||
|
target: recruit.class.Review,
|
||||||
|
action: recruit.action.CreateOpinion
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.mixin(recruit.class.Review, core.class.Class, view.mixin.ObjectEditor, {
|
builder.mixin(recruit.class.Review, core.class.Class, view.mixin.ObjectEditor, {
|
||||||
@ -63,17 +74,6 @@ export function createReviewModel (builder: Builder): void {
|
|||||||
action: recruit.action.CreateReview
|
action: recruit.action.CreateReview
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.createDoc(
|
|
||||||
task.class.KanbanTemplateSpace,
|
|
||||||
core.space.Model,
|
|
||||||
{
|
|
||||||
name: recruit.string.ReviewCategory,
|
|
||||||
description: task.string.ManageStatusesWithin,
|
|
||||||
icon: recruit.component.TemplatesIcon
|
|
||||||
},
|
|
||||||
recruit.space.ReviewTemplates
|
|
||||||
)
|
|
||||||
|
|
||||||
builder.createDoc(view.class.ActionTarget, core.space.Model, {
|
builder.createDoc(view.class.ActionTarget, core.space.Model, {
|
||||||
target: recruit.class.ReviewCategory,
|
target: recruit.class.ReviewCategory,
|
||||||
action: task.action.ArchiveSpace,
|
action: task.action.ArchiveSpace,
|
||||||
@ -82,69 +82,6 @@ export function createReviewModel (builder: Builder): void {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function createStatusTableViewlet (builder: Builder): void {
|
|
||||||
builder.createDoc(view.class.Viewlet, core.space.Model, {
|
|
||||||
attachTo: recruit.class.Review,
|
|
||||||
descriptor: task.viewlet.StatusTable,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
||||||
options: {
|
|
||||||
lookup: {
|
|
||||||
attachedTo: recruit.mixin.Candidate,
|
|
||||||
state: task.class.State,
|
|
||||||
assignee: contact.class.Employee,
|
|
||||||
doneState: task.class.DoneState,
|
|
||||||
participants: contact.class.Employee
|
|
||||||
}
|
|
||||||
} as FindOptions<Doc>,
|
|
||||||
config: [
|
|
||||||
'',
|
|
||||||
'$lookup.attachedTo',
|
|
||||||
{ key: '$lookup.participants', presenter: recruit.component.PersonsPresenter, label: recruit.string.Participants, sortingKey: '$lookup.participants' },
|
|
||||||
// 'location',
|
|
||||||
'company',
|
|
||||||
'dueDate',
|
|
||||||
{ key: '', presenter: recruit.component.OpinionsPresenter, label: recruit.string.Opinions, sortingKey: 'opinions' },
|
|
||||||
'$lookup.state',
|
|
||||||
'$lookup.doneState',
|
|
||||||
// { presenter: attachment.component.AttachmentsPresenter, label: attachment.string.Files, sortingKey: 'attachments' },
|
|
||||||
// { presenter: chunter.component.CommentsPresenter, label: chunter.string.Comments, sortingKey: 'comments' },
|
|
||||||
'modifiedOn'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
builder.createDoc(
|
|
||||||
view.class.Action,
|
|
||||||
core.space.Model,
|
|
||||||
{
|
|
||||||
label: recruit.string.CreateOpinion,
|
|
||||||
icon: recruit.icon.Create,
|
|
||||||
action: recruit.actionImpl.CreateOpinion
|
|
||||||
},
|
|
||||||
recruit.action.CreateOpinion
|
|
||||||
)
|
|
||||||
|
|
||||||
builder.createDoc(view.class.ActionTarget, core.space.Model, {
|
|
||||||
target: recruit.class.Review,
|
|
||||||
action: recruit.action.CreateOpinion
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function createKanbanViewlet (builder: Builder): void {
|
|
||||||
builder.createDoc(view.class.Viewlet, core.space.Model, {
|
|
||||||
attachTo: recruit.class.Review,
|
|
||||||
descriptor: task.viewlet.Kanban,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
||||||
options: {
|
|
||||||
lookup: {
|
|
||||||
attachedTo: recruit.mixin.Candidate,
|
|
||||||
state: task.class.State,
|
|
||||||
assignee: contact.class.Employee,
|
|
||||||
participants: contact.class.Employee
|
|
||||||
}
|
|
||||||
} as FindOptions<Doc>,
|
|
||||||
config: ['$lookup.attachedTo', '$lookup.state', '$lookup.participants', '$lookup.assignee']
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function createTableViewlet (builder: Builder): void {
|
function createTableViewlet (builder: Builder): void {
|
||||||
builder.createDoc(view.class.Viewlet, core.space.Model, {
|
builder.createDoc(view.class.Viewlet, core.space.Model, {
|
||||||
@ -154,22 +91,20 @@ function createTableViewlet (builder: Builder): void {
|
|||||||
options: {
|
options: {
|
||||||
lookup: {
|
lookup: {
|
||||||
attachedTo: recruit.mixin.Candidate,
|
attachedTo: recruit.mixin.Candidate,
|
||||||
state: task.class.State,
|
participants: contact.class.Employee,
|
||||||
assignee: contact.class.Employee,
|
company: contact.class.Organization
|
||||||
doneState: task.class.DoneState,
|
|
||||||
participants: contact.class.Employee
|
|
||||||
}
|
}
|
||||||
} as FindOptions<Doc>,
|
} as FindOptions<Doc>,
|
||||||
config: [
|
config: [
|
||||||
'',
|
'',
|
||||||
|
'title',
|
||||||
'$lookup.attachedTo',
|
'$lookup.attachedTo',
|
||||||
{ key: '$lookup.participants', presenter: recruit.component.PersonsPresenter, label: recruit.string.Participants, sortingKey: '$lookup.participants' },
|
'verdict',
|
||||||
// 'location',
|
|
||||||
'company',
|
|
||||||
'dueDate',
|
|
||||||
{ key: '', presenter: recruit.component.OpinionsPresenter, label: recruit.string.Opinions, sortingKey: 'opinions' },
|
{ key: '', presenter: recruit.component.OpinionsPresenter, label: recruit.string.Opinions, sortingKey: 'opinions' },
|
||||||
'$lookup.state',
|
{ key: '$lookup.participants', presenter: calendar.component.PersonsPresenter, label: calendar.string.Participants, sortingKey: '$lookup.participants' },
|
||||||
'$lookup.doneState',
|
'$lookup.company',
|
||||||
|
'date',
|
||||||
|
'dueDate',
|
||||||
// { presenter: attachment.component.AttachmentsPresenter, label: attachment.string.Files, sortingKey: 'attachments' },
|
// { presenter: attachment.component.AttachmentsPresenter, label: attachment.string.Files, sortingKey: 'attachments' },
|
||||||
// { presenter: chunter.component.CommentsPresenter, label: chunter.string.Comments, sortingKey: 'comments' },
|
// { presenter: chunter.component.CommentsPresenter, label: chunter.string.Comments, sortingKey: 'comments' },
|
||||||
'modifiedOn'
|
'modifiedOn'
|
||||||
|
@ -142,6 +142,10 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: view.component.StringPresenter
|
presenter: view.component.StringPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.mixin(core.class.TypeIntlString, core.class.Class, view.mixin.AttributePresenter, {
|
||||||
|
presenter: view.component.IntlStringPresenter
|
||||||
|
})
|
||||||
|
|
||||||
builder.mixin(core.class.TypeNumber, core.class.Class, view.mixin.AttributeEditor, {
|
builder.mixin(core.class.TypeNumber, core.class.Class, view.mixin.AttributeEditor, {
|
||||||
editor: view.component.NumberEditor
|
editor: view.component.NumberEditor
|
||||||
})
|
})
|
||||||
|
@ -31,6 +31,7 @@ export default mergeIds(viewId, view, {
|
|||||||
component: {
|
component: {
|
||||||
StringEditor: '' as AnyComponent,
|
StringEditor: '' as AnyComponent,
|
||||||
StringPresenter: '' as AnyComponent,
|
StringPresenter: '' as AnyComponent,
|
||||||
|
IntlStringPresenter: '' as AnyComponent,
|
||||||
NumberEditor: '' as AnyComponent,
|
NumberEditor: '' as AnyComponent,
|
||||||
NumberPresenter: '' as AnyComponent,
|
NumberPresenter: '' as AnyComponent,
|
||||||
HTMLPresenter: '' as AnyComponent,
|
HTMLPresenter: '' as AnyComponent,
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
"Description": "Description",
|
"Description": "Description",
|
||||||
"Private": "Private",
|
"Private": "Private",
|
||||||
"Archived": "Archived"
|
"Archived": "Archived",
|
||||||
|
"ClassLabel": "Label"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"Name": "Название",
|
"Name": "Название",
|
||||||
"Description": "Описание",
|
"Description": "Описание",
|
||||||
"Private": "Личный",
|
"Private": "Личный",
|
||||||
"Archived": "Архивный"
|
"Archived": "Архивный",
|
||||||
|
"ClassLabel": "Тип"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,6 +31,11 @@ export type PrimitiveType = number | string | boolean | undefined | Ref<Doc>
|
|||||||
*/
|
*/
|
||||||
export type Timestamp = number
|
export type Timestamp = number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export type Markup = string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -160,6 +165,15 @@ export type AttachedData<T extends AttachedDoc> = Omit<T, keyof AttachedDoc>
|
|||||||
|
|
||||||
// T Y P E S
|
// T Y P E S
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface TypeDate extends Type<Date> {
|
||||||
|
// If not set to true, will be false
|
||||||
|
withTime?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
|
@ -44,6 +44,7 @@ export default plugin(coreId, {
|
|||||||
Space: '' as Ref<Class<Space>>,
|
Space: '' as Ref<Class<Space>>,
|
||||||
Account: '' as Ref<Class<Account>>,
|
Account: '' as Ref<Class<Account>>,
|
||||||
TypeString: '' as Ref<Class<Type<string>>>,
|
TypeString: '' as Ref<Class<Type<string>>>,
|
||||||
|
TypeIntlString: '' as Ref<Class<Type<IntlString>>>,
|
||||||
TypeNumber: '' as Ref<Class<Type<string>>>,
|
TypeNumber: '' as Ref<Class<Type<string>>>,
|
||||||
TypeMarkup: '' as Ref<Class<Type<string>>>,
|
TypeMarkup: '' as Ref<Class<Type<string>>>,
|
||||||
TypeBoolean: '' as Ref<Class<Type<boolean>>>,
|
TypeBoolean: '' as Ref<Class<Type<boolean>>>,
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import core, {
|
import core, {
|
||||||
Account, ArrOf as TypeArrOf, AttachedDoc, Attribute, Class, Classifier, ClassifierKind, Collection as TypeCollection, Data, Doc, Domain, generateId, IndexKind, Interface, Mixin as IMixin, MixinUpdate, Obj, PropertyType, Ref, RefTo, Space, Tx, TxCreateDoc, TxFactory, TxProcessor, Type
|
Account, ArrOf as TypeArrOf, AttachedDoc, Attribute, Class, Classifier, ClassifierKind, Collection as TypeCollection, Data, Doc, Domain, generateId, IndexKind, Interface, Markup, Mixin as IMixin, MixinUpdate, Obj, PropertyType, Ref, RefTo, Space, Timestamp, Tx, TxCreateDoc, TxFactory, TxProcessor, Type, TypeDate as TypeDateType
|
||||||
} from '@anticrm/core'
|
} from '@anticrm/core'
|
||||||
import type { Asset, IntlString } from '@anticrm/platform'
|
import type { Asset, IntlString } from '@anticrm/platform'
|
||||||
import toposort from 'toposort'
|
import toposort from 'toposort'
|
||||||
@ -331,36 +331,43 @@ export function TypeString (): Type<string> {
|
|||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export function TypeNumber (): Type<string> {
|
export function TypeNumber (): Type<number> {
|
||||||
return { _class: core.class.TypeNumber, label: 'TypeNumber' as IntlString }
|
return { _class: core.class.TypeNumber, label: 'TypeNumber' as IntlString }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export function TypeMarkup (): Type<string> {
|
export function TypeMarkup (): Type<Markup> {
|
||||||
return { _class: core.class.TypeMarkup, label: 'TypeMarkup' as IntlString }
|
return { _class: core.class.TypeMarkup, label: 'TypeMarkup' as IntlString }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export function TypeBoolean (): Type<string> {
|
export function TypeIntlString (): Type<IntlString> {
|
||||||
|
return { _class: core.class.TypeIntlString, label: 'TypeIntlString' as IntlString }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export function TypeBoolean (): Type<boolean> {
|
||||||
return { _class: core.class.TypeBoolean, label: 'TypeBoolean' as IntlString }
|
return { _class: core.class.TypeBoolean, label: 'TypeBoolean' as IntlString }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export function TypeTimestamp (): Type<string> {
|
export function TypeTimestamp (): Type<Timestamp> {
|
||||||
return { _class: core.class.TypeTimestamp, label: 'TypeTimestamp' as IntlString }
|
return { _class: core.class.TypeTimestamp, label: 'TypeTimestamp' as IntlString }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export function TypeDate (): Type<string> {
|
export function TypeDate (withTime?: boolean): TypeDateType {
|
||||||
return { _class: core.class.TypeDate, label: 'TypeDate' as IntlString }
|
return { _class: core.class.TypeDate, label: 'TypeDate' as IntlString, withTime }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
placeholder={attribute?.label}
|
placeholder={attribute?.label}
|
||||||
{maxWidth}
|
{maxWidth}
|
||||||
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
|
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
|
||||||
|
attributeType={attribute.type}
|
||||||
space={object.space}
|
space={object.space}
|
||||||
{onChange}
|
{onChange}
|
||||||
{focus}
|
{focus}
|
||||||
@ -94,6 +95,7 @@
|
|||||||
placeholder={attribute?.label}
|
placeholder={attribute?.label}
|
||||||
{maxWidth}
|
{maxWidth}
|
||||||
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
|
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
|
||||||
|
attributeType={attribute.type}
|
||||||
space={object.space}
|
space={object.space}
|
||||||
{onChange}
|
{onChange}
|
||||||
{focus}
|
{focus}
|
||||||
@ -105,6 +107,7 @@
|
|||||||
this={instance}
|
this={instance}
|
||||||
{maxWidth}
|
{maxWidth}
|
||||||
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
|
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
|
||||||
|
attributeType={attribute.type}
|
||||||
space={object.space}
|
space={object.space}
|
||||||
{onChange}
|
{onChange}
|
||||||
{focus}
|
{focus}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
export let labelProps: any | undefined = undefined
|
export let labelProps: any | undefined = undefined
|
||||||
export let okAction: () => void
|
export let okAction: () => void
|
||||||
export let canSave: boolean = false
|
export let canSave: boolean = false
|
||||||
|
export let size: 'small'| 'medium' = 'small'
|
||||||
|
|
||||||
export let okLabel: IntlString = presentation.string.Create
|
export let okLabel: IntlString = presentation.string.Create
|
||||||
export let cancelLabel: IntlString = presentation.string.Cancel
|
export let cancelLabel: IntlString = presentation.string.Cancel
|
||||||
@ -40,7 +41,7 @@
|
|||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="antiCard" on:submit|preventDefault={ () => {} }>
|
<form class="antiCard" class:w-2125rem={size === 'small'} class:w-4125rem={size === 'medium'} on:submit|preventDefault={ () => {} }>
|
||||||
<div class="antiCard-header">
|
<div class="antiCard-header">
|
||||||
<div class="antiCard-header__title"><Label {label} params={labelProps ?? {}} /></div>
|
<div class="antiCard-header__title"><Label {label} params={labelProps ?? {}} /></div>
|
||||||
{#if $$slots.error}
|
{#if $$slots.error}
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
export let show: boolean = false
|
export let show: boolean = false
|
||||||
export let allowDeselect = false
|
export let allowDeselect = false
|
||||||
export let titleDeselect: IntlString | undefined = undefined
|
export let titleDeselect: IntlString | undefined = undefined
|
||||||
|
export let readonly = false
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
@ -69,7 +70,7 @@
|
|||||||
<div class="antiSelect" bind:this={container}
|
<div class="antiSelect" bind:this={container}
|
||||||
on:click|preventDefault={() => {
|
on:click|preventDefault={() => {
|
||||||
btn.focus()
|
btn.focus()
|
||||||
if (!opened) {
|
if (!opened && !readonly) {
|
||||||
opened = true
|
opened = true
|
||||||
showPopup(UsersPopup, { _class, title, caption, allowDeselect, selected: value, titleDeselect }, container, (result) => {
|
showPopup(UsersPopup, { _class, title, caption, allowDeselect, selected: value, titleDeselect }, container, (result) => {
|
||||||
if (result === null) {
|
if (result === null) {
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#each persons as person}
|
{#each persons as person}
|
||||||
<div class="antiComponentBox flex-center">
|
<div class="antiComponentBox flex-center margin_025 antiComponentBoxFocused">
|
||||||
<UserInfo value={person} size={'medium'} />
|
<UserInfo value={person} size={'medium'} />
|
||||||
<div class="ml-1">
|
<div class="ml-1">
|
||||||
<ActionIcon icon={IconClose} size={'small'} action={() => removePerson(person)} />
|
<ActionIcon icon={IconClose} size={'small'} action={() => removePerson(person)} />
|
||||||
@ -104,4 +104,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
.margin_025 {
|
||||||
|
margin: 0.25rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IntlString } from '@anticrm/platform'
|
import { IntlString } from '@anticrm/platform'
|
||||||
import presentation, { MessageViewer } from '@anticrm/presentation'
|
import presentation, { MessageViewer } from '@anticrm/presentation'
|
||||||
import { ActionIcon, IconCheck, IconClose, IconEdit } from '@anticrm/ui'
|
import { ActionIcon, IconCheck, IconClose, IconEdit, Label } from '@anticrm/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import textEditorPlugin from '../plugin'
|
import textEditorPlugin from '../plugin'
|
||||||
import StyledTextEditor from './StyledTextEditor.svelte'
|
import StyledTextEditor from './StyledTextEditor.svelte'
|
||||||
|
|
||||||
|
export let label: IntlString | undefined = undefined
|
||||||
export let content: string
|
export let content: string
|
||||||
export let placeholder: IntlString = textEditorPlugin.string.EditorPlaceholder
|
export let placeholder: IntlString = textEditorPlugin.string.EditorPlaceholder
|
||||||
|
|
||||||
|
export let emphasized = false
|
||||||
|
export let alwaysEdit = false
|
||||||
|
export let showButtons = true
|
||||||
|
|
||||||
let rawValue: string
|
let rawValue: string
|
||||||
|
|
||||||
const Mode = {
|
const Mode = {
|
||||||
@ -22,18 +28,41 @@
|
|||||||
textEditor.submit()
|
textEditor.submit()
|
||||||
}
|
}
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
let focused = false
|
||||||
|
|
||||||
|
let needFocus = false
|
||||||
|
|
||||||
|
$: if (textEditor && needFocus) {
|
||||||
|
textEditor.focus()
|
||||||
|
needFocus = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="antiComponent styled-box">
|
<div class="antiComponent styled-box" class:emphasized class:emphasized-focus={(mode === Mode.Edit || alwaysEdit) && focused} on:click={() => {
|
||||||
{#if mode !== Mode.View}
|
if (alwaysEdit && focused) {
|
||||||
|
textEditor?.focus()
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
{#if label}
|
||||||
|
<div class="label"><Label {label} /></div>
|
||||||
|
{/if}
|
||||||
|
{#if mode !== Mode.View || alwaysEdit}
|
||||||
<StyledTextEditor
|
<StyledTextEditor
|
||||||
{placeholder}
|
{placeholder}
|
||||||
|
{showButtons}
|
||||||
bind:content={rawValue}
|
bind:content={rawValue}
|
||||||
bind:this={textEditor}
|
bind:this={textEditor}
|
||||||
|
on:focus={() => {
|
||||||
|
focused = true
|
||||||
|
}}
|
||||||
|
on:blur={() => {
|
||||||
|
focused = false
|
||||||
|
}}
|
||||||
on:value={(evt) => {
|
on:value={(evt) => {
|
||||||
rawValue = evt.detail
|
rawValue = evt.detail
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{#if !alwaysEdit}
|
||||||
<div class="flex flex-reverse flex-grow">
|
<div class="flex flex-reverse flex-grow">
|
||||||
<div class="ml-2">
|
<div class="ml-2">
|
||||||
<!-- disabled={rawValue.trim().length === 0} -->
|
<!-- disabled={rawValue.trim().length === 0} -->
|
||||||
@ -59,6 +88,7 @@
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
</StyledTextEditor>
|
</StyledTextEditor>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="text">
|
<div class="text">
|
||||||
@ -66,28 +96,58 @@
|
|||||||
<MessageViewer message={content} />
|
<MessageViewer message={content} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-reverse">
|
{#if !alwaysEdit}
|
||||||
<ActionIcon
|
<div class="flex flex-reverse">
|
||||||
size={'medium'}
|
<ActionIcon
|
||||||
icon={IconEdit}
|
size={'medium'}
|
||||||
direction={'top'}
|
icon={IconEdit}
|
||||||
label={textEditorPlugin.string.Edit}
|
direction={'top'}
|
||||||
action={() => {
|
label={textEditorPlugin.string.Edit}
|
||||||
rawValue = content ?? ''
|
action={() => {
|
||||||
mode = Mode.Edit
|
rawValue = content ?? ''
|
||||||
}}
|
needFocus = true
|
||||||
/>
|
mode = Mode.Edit
|
||||||
</div>
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.styled-box {
|
.styled-box {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
padding-bottom: 0.25rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
opacity: 0.3;
|
||||||
|
transition: top 200ms;
|
||||||
|
pointer-events: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.emphasized .emphasized-focus + .label {
|
||||||
|
top: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.emphasized {
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: var(--theme-bg-accent-color);
|
||||||
|
border: 1px solid var(--theme-bg-accent-hover);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
&.emphasized-focus {
|
||||||
|
background-color: var(--theme-bg-focused-color);
|
||||||
|
border-color: var(--theme-bg-focused-border);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.text {
|
.text {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
line-height: 150%;
|
line-height: 150%;
|
||||||
|
|
||||||
|
.nolabel {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -27,12 +27,16 @@
|
|||||||
|
|
||||||
export let content: string = ''
|
export let content: string = ''
|
||||||
export let placeholder: IntlString = textEditorPlugin.string.EditorPlaceholder
|
export let placeholder: IntlString = textEditorPlugin.string.EditorPlaceholder
|
||||||
|
export let showButtons = true
|
||||||
|
|
||||||
let textEditor: TextEditor
|
let textEditor: TextEditor
|
||||||
|
|
||||||
export function submit (): void {
|
export function submit (): void {
|
||||||
textEditor.submit()
|
textEditor.submit()
|
||||||
}
|
}
|
||||||
|
export function focus (): void {
|
||||||
|
textEditor.focus()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="ref-container">
|
<div class="ref-container">
|
||||||
@ -50,15 +54,16 @@
|
|||||||
textEditor.clear()
|
textEditor.clear()
|
||||||
}}
|
}}
|
||||||
on:blur
|
on:blur
|
||||||
|
on:focus
|
||||||
supportSubmit={false}
|
supportSubmit={false}
|
||||||
/>
|
/>
|
||||||
</ScrollBox>
|
</ScrollBox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons">
|
<div class="buttons" class:shown={showButtons}>
|
||||||
<div class="tool"><TextStyle size={'large'} /></div>
|
<div class="tool"><TextStyle size={'large'} /></div>
|
||||||
<div class="tool"><Emoji size={'large'}/></div>
|
<div class="tool"><Emoji size={'large'} /></div>
|
||||||
<div class="tool"><GIF size={'large'}/></div>
|
<div class="tool"><GIF size={'large'} /></div>
|
||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
@ -72,6 +77,14 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 4.5rem;
|
min-height: 4.5rem;
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shown {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
.textInput {
|
.textInput {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -53,6 +53,15 @@
|
|||||||
export function insertText (text: string): void {
|
export function insertText (text: string): void {
|
||||||
editor.commands.insertContent(text as HTMLContent)
|
editor.commands.insertContent(text as HTMLContent)
|
||||||
}
|
}
|
||||||
|
let needFocus = false
|
||||||
|
export function focus (): void {
|
||||||
|
needFocus = true
|
||||||
|
}
|
||||||
|
|
||||||
|
$: if (editor && needFocus) {
|
||||||
|
editor.commands.focus()
|
||||||
|
needFocus = false
|
||||||
|
}
|
||||||
|
|
||||||
const Handle = Extension.create({
|
const Handle = Extension.create({
|
||||||
addKeyboardShortcuts () {
|
addKeyboardShortcuts () {
|
||||||
@ -98,6 +107,9 @@
|
|||||||
onBlur: () => {
|
onBlur: () => {
|
||||||
dispatch('blur', editor.getHTML())
|
dispatch('blur', editor.getHTML())
|
||||||
},
|
},
|
||||||
|
onFocus: () => {
|
||||||
|
dispatch('focus', editor.getHTML())
|
||||||
|
},
|
||||||
onUpdate: () => {
|
onUpdate: () => {
|
||||||
content = editor.getHTML()
|
content = editor.getHTML()
|
||||||
dispatch('value', content)
|
dispatch('value', content)
|
||||||
|
@ -417,12 +417,14 @@
|
|||||||
|
|
||||||
// Basic component view.
|
// Basic component view.
|
||||||
.antiComponentBox {
|
.antiComponentBox {
|
||||||
margin: 0.25rem;
|
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
background-color: var(--theme-button-bg-focused);
|
background-color: var(--theme-bg-accent-color);
|
||||||
border: 1px solid var(--theme-button-border-enabled);
|
border: 1px solid var(--theme-button-border-enabled);
|
||||||
border-radius: .75rem;
|
border-radius: .75rem;
|
||||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, .2);
|
|
||||||
|
&.antiComponentBoxFocused {
|
||||||
|
background-color: var(--theme-button-bg-focused);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select */
|
/* Select */
|
||||||
|
@ -70,13 +70,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Cards */
|
/* Cards */
|
||||||
.antiCard {
|
.antiCard {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 21.25rem;
|
|
||||||
min-width: 21.25rem;
|
|
||||||
max-width: 21.25rem;
|
|
||||||
background-color: var(--theme-card-bg);
|
background-color: var(--theme-card-bg);
|
||||||
border-radius: 1.25rem;
|
border-radius: 1.25rem;
|
||||||
box-shadow: var(--theme-card-shadow);
|
box-shadow: var(--theme-card-shadow);
|
||||||
|
@ -28,12 +28,12 @@
|
|||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
const getNow = (): Date => {
|
const getNow = (): Date => {
|
||||||
let tempDate = new Date(Date.now())
|
const tempDate = new Date(Date.now())
|
||||||
return new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())
|
return new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())
|
||||||
}
|
}
|
||||||
let today: Date = getNow()
|
const today: Date = getNow()
|
||||||
let todayString: string
|
let todayString: string
|
||||||
async function todayStr() {
|
async function todayStr () {
|
||||||
todayString = await translate(ui.string.Today, {})
|
todayString = await translate(ui.string.Today, {})
|
||||||
}
|
}
|
||||||
todayStr()
|
todayStr()
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
export let withTime: boolean = false
|
export let withTime: boolean = false
|
||||||
|
|
||||||
const { currentLanguage } = getContext('lang')
|
const { currentLanguage } = getContext('lang')
|
||||||
let inter: boolean = (currentLanguage === 'ru') ?? false
|
const inter: boolean = (currentLanguage === 'ru') ?? false
|
||||||
|
|
||||||
const zeroLead = (n: number): string => {
|
const zeroLead = (n: number): string => {
|
||||||
if (n < 10) return '0' + n.toString()
|
if (n < 10) return '0' + n.toString()
|
||||||
|
7
plugins/calendar-assets/.eslintrc.js
Normal file
7
plugins/calendar-assets/.eslintrc.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: ['./node_modules/@anticrm/platform-rig/profiles/default/config/eslint.config.json'],
|
||||||
|
parserOptions: {
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
project: './tsconfig.json'
|
||||||
|
}
|
||||||
|
}
|
9
plugins/calendar-assets/assets/icons.svg
Normal file
9
plugins/calendar-assets/assets/icons.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||||
|
<symbol id="calendar" viewBox="0 0 24 24">
|
||||||
|
<path d="M19.5,5h-2.1V4.5c0-0.3-0.2-0.5-0.5-0.5s-0.5,0.2-0.5,0.5V5H8.1V4.5C8.1,4.2,7.9,4,7.6,4S7.1,4.2,7.1,4.5V5H5 C4.2,5,3.5,5.7,3.5,6.5V19c0,0.8,0.7,1.5,1.5,1.5h14.5c0.8,0,1.5-0.7,1.5-1.5V6.5C21,5.7,20.3,5,19.5,5z M5,6h2.1v0.5 c0,0.3,0.2,0.5,0.5,0.5s0.5-0.2,0.5-0.5V6h8.3v0.5c0,0.3,0.2,0.5,0.5,0.5s0.5-0.2,0.5-0.5V6h2.1C19.7,6,20,6.3,20,6.5v3.1H4.5V6.5 C4.5,6.3,4.7,6,5,6z M19.5,19.5H5c-0.3,0-0.5-0.2-0.5-0.5v-8.3H20V19C20,19.2,19.7,19.5,19.5,19.5z" />
|
||||||
|
</symbol>
|
||||||
|
<symbol id="location" viewBox="0 0 16 16">
|
||||||
|
<path d="M8,4.6c-1.5,0-2.6,1.2-2.6,2.6S6.5,9.9,8,9.9s2.6-1.2,2.6-2.6S9.5,4.6,8,4.6z M8,8.9c-0.9,0-1.6-0.7-1.6-1.6 c0-0.9,0.7-1.6,1.6-1.6s1.6,0.7,1.6,1.6C9.6,8.2,8.9,8.9,8,8.9z"/>
|
||||||
|
<path d="M8,1.8c-3,0-5.5,2.5-5.5,5.5c0,1.9,0.9,3.4,2,4.5c1.1,1.1,2.3,1.8,2.9,2.1c0.4,0.2,0.9,0.2,1.3,0c0.6-0.3,1.8-1,2.9-2.1 c1.1-1.1,2-2.6,2-4.5C13.5,4.3,11,1.8,8,1.8z M10.8,11.1c-1,1-2.1,1.7-2.6,2c-0.1,0.1-0.2,0.1-0.3,0c-0.6-0.3-1.7-1-2.6-2 c-1-1-1.7-2.3-1.7-3.8c0-2.5,2-4.5,4.5-4.5s4.5,2,4.5,4.5C12.5,8.8,11.7,10.1,10.8,11.1z"/>
|
||||||
|
</symbol>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
18
plugins/calendar-assets/config/rig.json
Normal file
18
plugins/calendar-assets/config/rig.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// The "rig.json" file directs tools to look for their config files in an external package.
|
||||||
|
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Required) The name of the rig package to inherit from.
|
||||||
|
* It should be an NPM package name with the "-rig" suffix.
|
||||||
|
*/
|
||||||
|
"rigPackageName": "@anticrm/platform-rig"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Optional) Selects a config profile from the rig package. The name must consist of
|
||||||
|
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
|
||||||
|
* If omitted, then the "default" profile will be used."
|
||||||
|
*/
|
||||||
|
// "rigProfile": "your-profile-name"
|
||||||
|
}
|
17
plugins/calendar-assets/lang/en.json
Normal file
17
plugins/calendar-assets/lang/en.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"string": {
|
||||||
|
"ApplicationLabelCalendar": "Calendar",
|
||||||
|
"Calendars": "Calendars",
|
||||||
|
"Participants": "Participants",
|
||||||
|
"NoParticipants": "No participants added",
|
||||||
|
"PersonsLabel": "{name}",
|
||||||
|
"AddDescription": "Add description",
|
||||||
|
"Date": "Date",
|
||||||
|
"DueTo": "Due date",
|
||||||
|
"Description": "Description",
|
||||||
|
"Title": "Title",
|
||||||
|
"Location": "Location",
|
||||||
|
"Company": "Company",
|
||||||
|
"CreateCalendar": "Create Calendar"
|
||||||
|
}
|
||||||
|
}
|
17
plugins/calendar-assets/lang/ru.json
Normal file
17
plugins/calendar-assets/lang/ru.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"string": {
|
||||||
|
"ApplicationLabelCalendar": "Календарь",
|
||||||
|
"Calendars": "Календари",
|
||||||
|
"Participants": "Участники",
|
||||||
|
"NoParticipants": "Участники не добавлены",
|
||||||
|
"PersonsLabel": "{name}",
|
||||||
|
"AddDescription": "Добавить описание",
|
||||||
|
"Date": "Дата",
|
||||||
|
"DueTo": "Дата конца",
|
||||||
|
"Description": "Описание",
|
||||||
|
"Title": "Название",
|
||||||
|
"Location": "Местоположение",
|
||||||
|
"Company": "Компания",
|
||||||
|
"CreateCalendar": "Новый Калеедарь"
|
||||||
|
}
|
||||||
|
}
|
33
plugins/calendar-assets/package.json
Normal file
33
plugins/calendar-assets/package.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "@anticrm/calendar-assets",
|
||||||
|
"version": "0.6.0",
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"author": "Anticrm Platform Contributors",
|
||||||
|
"license": "EPL-2.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "heft build",
|
||||||
|
"build:docs": "",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"lint:fix": "eslint --fix src",
|
||||||
|
"format": "prettier --write src && eslint --fix src",
|
||||||
|
"build:watch": "tsc"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@anticrm/platform-rig": "~0.6.0",
|
||||||
|
"@types/heft-jest": "^1.0.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||||
|
"@typescript-eslint/parser": "^5.4.0",
|
||||||
|
"eslint-config-standard-with-typescript": "^21.0.1",
|
||||||
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-plugin-promise": "^5.1.1",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"prettier": "^2.4.1",
|
||||||
|
"@rushstack/heft": "^0.41.1",
|
||||||
|
"@types/node": "^16.4.10"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@anticrm/platform": "~0.6.5",
|
||||||
|
"@anticrm/calendar": "~0.6.0"
|
||||||
|
}
|
||||||
|
}
|
25
plugins/calendar-assets/src/index.ts
Normal file
25
plugins/calendar-assets/src/index.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { addStringsLoader, loadMetadata } from '@anticrm/platform'
|
||||||
|
import calendar, { calendarId } from '@anticrm/calendar'
|
||||||
|
|
||||||
|
const icons = require('../assets/icons.svg') as string // eslint-disable-line
|
||||||
|
loadMetadata(calendar.icon, {
|
||||||
|
Calendar: `${icons}#calendar`,
|
||||||
|
Location: `${icons}#location`
|
||||||
|
})
|
||||||
|
|
||||||
|
addStringsLoader(calendarId, async (lang: string) => await import(`../lang/${lang}.json`))
|
15
plugins/calendar-assets/tsconfig.json
Normal file
15
plugins/calendar-assets/tsconfig.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "esnext",
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "./lib",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
7
plugins/calendar-resources/.eslintrc.js
Normal file
7
plugins/calendar-resources/.eslintrc.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: ['./node_modules/@anticrm/platform-rig/profiles/ui/config/eslint.config.json'],
|
||||||
|
parserOptions: { tsconfigRootDir: __dirname },
|
||||||
|
settings: {
|
||||||
|
'svelte3/ignore-styles': () => true
|
||||||
|
}
|
||||||
|
}
|
BIN
plugins/calendar-resources/img/avatar.png
Normal file
BIN
plugins/calendar-resources/img/avatar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
47
plugins/calendar-resources/package.json
Normal file
47
plugins/calendar-resources/package.json
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "@anticrm/calendar-resources",
|
||||||
|
"version": "0.6.0",
|
||||||
|
"main": "src/index.ts",
|
||||||
|
"author": "Anticrm Platform Contributors",
|
||||||
|
"license": "EPL-2.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "echo 'no build for ui'",
|
||||||
|
"build:docs": "api-extractor run --local",
|
||||||
|
"lint": "svelte-check && eslint",
|
||||||
|
"lint:fix": "eslint --fix src",
|
||||||
|
"format": "prettier --write --plugin-search-dir=. src && eslint --fix src",
|
||||||
|
"svelte-check": "svelte-check"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"svelte-loader": "^3.1.2",
|
||||||
|
"sass": "^1.37.5",
|
||||||
|
"svelte-preprocess": "^4.10.3",
|
||||||
|
"@anticrm/platform-rig": "~0.6.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||||
|
"@typescript-eslint/parser": "^5.4.0",
|
||||||
|
"eslint-config-standard-with-typescript": "^21.0.1",
|
||||||
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-plugin-promise": "^5.1.1",
|
||||||
|
"eslint-plugin-svelte3": "~3.2.1",
|
||||||
|
"prettier-plugin-svelte": "^2.2.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"prettier": "^2.4.1",
|
||||||
|
"svelte-check": "^2.2.10",
|
||||||
|
"typescript": "^4.3.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@anticrm/core": "~0.6.11",
|
||||||
|
"@anticrm/platform": "~0.6.5",
|
||||||
|
"@anticrm/ui": "~0.6.0",
|
||||||
|
"@anticrm/presentation": "~0.6.2",
|
||||||
|
"@anticrm/calendar": "~0.6.0",
|
||||||
|
"svelte": "^3.37.0",
|
||||||
|
"@anticrm/text-editor": "~0.6.0",
|
||||||
|
"@anticrm/contact": "~0.6.2",
|
||||||
|
"@anticrm/contact-resources": "~0.6.0",
|
||||||
|
"@anticrm/view-resources": "~0.6.0",
|
||||||
|
"@anticrm/view": "~0.6.0",
|
||||||
|
"@anticrm/workbench": "~0.6.1"
|
||||||
|
}
|
||||||
|
}
|
5
plugins/calendar-resources/postcss.config.js
Normal file
5
plugins/calendar-resources/postcss.config.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
require('autoprefixer')
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
<!--
|
||||||
|
// 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 { formatName, Person } from '@anticrm/contact'
|
||||||
|
import { Hierarchy } from '@anticrm/core'
|
||||||
|
import { Avatar } from '@anticrm/presentation'
|
||||||
|
import calendar from '../plugin'
|
||||||
|
import { showPanel, Tooltip } from '@anticrm/ui'
|
||||||
|
import view from '@anticrm/view'
|
||||||
|
|
||||||
|
export let value: Person | Person[]
|
||||||
|
export let inline: boolean = false
|
||||||
|
|
||||||
|
let persons: Person[] = []
|
||||||
|
$: persons = Array.isArray(value) ? value : [value]
|
||||||
|
|
||||||
|
async function onClick (p: Person) {
|
||||||
|
showPanel(view.component.EditDoc, p._id, Hierarchy.mixinOrClass(p), 'full')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if value}
|
||||||
|
<div class='flex persons'>
|
||||||
|
{#each persons as p}
|
||||||
|
<Tooltip label={calendar.string.PersonsLabel} props={{ name: formatName(p.name) }}>
|
||||||
|
<div class="flex-presenter" class:inline-presenter={inline} on:click={() => onClick(p)}>
|
||||||
|
<div class="icon">
|
||||||
|
<Avatar size={'x-small'} avatar={p.avatar} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<style lang="scss">
|
||||||
|
.persons {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, min-content);
|
||||||
|
.icon {
|
||||||
|
margin: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
24
plugins/calendar-resources/src/index.ts
Normal file
24
plugins/calendar-resources/src/index.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { Resources } from '@anticrm/platform'
|
||||||
|
|
||||||
|
import PersonsPresenter from './components/PersonsPresenter.svelte'
|
||||||
|
|
||||||
|
export default async (): Promise<Resources> => ({
|
||||||
|
component: {
|
||||||
|
PersonsPresenter
|
||||||
|
}
|
||||||
|
})
|
24
plugins/calendar-resources/src/plugin.ts
Normal file
24
plugins/calendar-resources/src/plugin.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
import calendar, { calendarId } from '@anticrm/calendar'
|
||||||
|
import { mergeIds } from '@anticrm/platform'
|
||||||
|
|
||||||
|
export default mergeIds(calendarId, calendar, {
|
||||||
|
component: {
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
}
|
||||||
|
})
|
5
plugins/calendar-resources/svelte.config.js
Normal file
5
plugins/calendar-resources/svelte.config.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const sveltePreprocess = require('svelte-preprocess')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
preprocess: sveltePreprocess()
|
||||||
|
};
|
15
plugins/calendar-resources/tsconfig.json
Normal file
15
plugins/calendar-resources/tsconfig.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "esnext",
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "./lib",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
7
plugins/calendar/.eslintrc.js
Normal file
7
plugins/calendar/.eslintrc.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: ['./node_modules/@anticrm/platform-rig/profiles/default/config/eslint.config.json'],
|
||||||
|
parserOptions: {
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
project: './tsconfig.json'
|
||||||
|
}
|
||||||
|
}
|
4
plugins/calendar/.npmignore
Normal file
4
plugins/calendar/.npmignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
*
|
||||||
|
!/lib/**
|
||||||
|
!CHANGELOG.md
|
||||||
|
/lib/**/__tests__/
|
18
plugins/calendar/config/rig.json
Normal file
18
plugins/calendar/config/rig.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// The "rig.json" file directs tools to look for their config files in an external package.
|
||||||
|
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Required) The name of the rig package to inherit from.
|
||||||
|
* It should be an NPM package name with the "-rig" suffix.
|
||||||
|
*/
|
||||||
|
"rigPackageName": "@anticrm/platform-rig"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Optional) Selects a config profile from the rig package. The name must consist of
|
||||||
|
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
|
||||||
|
* If omitted, then the "default" profile will be used."
|
||||||
|
*/
|
||||||
|
// "rigProfile": "your-profile-name"
|
||||||
|
}
|
34
plugins/calendar/package.json
Normal file
34
plugins/calendar/package.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "@anticrm/calendar",
|
||||||
|
"version": "0.6.0",
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"author": "Anticrm Platform Contributors",
|
||||||
|
"license": "EPL-2.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "heft build",
|
||||||
|
"build:watch": "tsc",
|
||||||
|
"lint:fix": "eslint --fix src",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"format": "prettier --write src && eslint --fix src"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@anticrm/platform-rig": "~0.6.0",
|
||||||
|
"@types/heft-jest": "^1.0.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||||
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
"eslint-plugin-promise": "^5.1.1",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"@typescript-eslint/parser": "^5.4.0",
|
||||||
|
"eslint-config-standard-with-typescript": "^21.0.1",
|
||||||
|
"prettier": "^2.4.1",
|
||||||
|
"@rushstack/heft": "^0.41.1",
|
||||||
|
"typescript": "^4.3.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@anticrm/platform": "~0.6.5",
|
||||||
|
"@anticrm/ui": "~0.6.0",
|
||||||
|
"@anticrm/core": "~0.6.11",
|
||||||
|
"@anticrm/contact": "~0.6.5"
|
||||||
|
}
|
||||||
|
}
|
90
plugins/calendar/src/index.ts
Normal file
90
plugins/calendar/src/index.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Copyright © 2022 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License. You may
|
||||||
|
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
//
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { Employee } from '@anticrm/contact'
|
||||||
|
import type { AttachedDoc, Class, Doc, Markup, Ref, Space, Timestamp } from '@anticrm/core'
|
||||||
|
import type { Asset, IntlString, Plugin } from '@anticrm/platform'
|
||||||
|
import { plugin } from '@anticrm/platform'
|
||||||
|
import { AnyComponent } from '@anticrm/ui'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface Calendar extends Space {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface Event extends AttachedDoc {
|
||||||
|
title: string
|
||||||
|
number: number
|
||||||
|
description: Markup
|
||||||
|
|
||||||
|
location?: string
|
||||||
|
|
||||||
|
// Event scheduled date
|
||||||
|
date: Timestamp
|
||||||
|
|
||||||
|
// Event due date for long events.
|
||||||
|
dueDate?: Timestamp
|
||||||
|
|
||||||
|
attachments?: number
|
||||||
|
comments?: number
|
||||||
|
|
||||||
|
participants?: Ref<Employee>[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export const calendarId = 'calendar' as Plugin
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
const calendarPlugin = plugin(calendarId, {
|
||||||
|
class: {
|
||||||
|
Calendar: '' as Ref<Class<Calendar>>,
|
||||||
|
Event: '' as Ref<Class<Event>>
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
Calendar: '' as Asset,
|
||||||
|
Location: '' as Asset
|
||||||
|
},
|
||||||
|
space: {
|
||||||
|
// Space for all personal events.
|
||||||
|
PersonalEvents: '' as Ref<Space>
|
||||||
|
},
|
||||||
|
app: {
|
||||||
|
Calendar: '' as Ref<Doc>
|
||||||
|
},
|
||||||
|
component: {
|
||||||
|
PersonsPresenter: '' as AnyComponent
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
Title: '' as IntlString,
|
||||||
|
Calendar: '' as IntlString,
|
||||||
|
Description: '' as IntlString,
|
||||||
|
Date: '' as IntlString,
|
||||||
|
DueTo: '' as IntlString,
|
||||||
|
Calendars: '' as IntlString,
|
||||||
|
CreateCalendar: '' as IntlString,
|
||||||
|
Location: '' as IntlString,
|
||||||
|
Participants: '' as IntlString,
|
||||||
|
NoParticipants: '' as IntlString,
|
||||||
|
PersonsLabel: '' as IntlString,
|
||||||
|
EventNumber: '' as IntlString
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default calendarPlugin
|
9
plugins/calendar/tsconfig.json
Normal file
9
plugins/calendar/tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "./node_modules/@anticrm/platform-rig/profiles/default/tsconfig.json",
|
||||||
|
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "./src",
|
||||||
|
"outDir": "./lib",
|
||||||
|
"lib": ["esnext", "dom"]
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@
|
|||||||
import { createQuery } from '@anticrm/presentation'
|
import { createQuery } from '@anticrm/presentation'
|
||||||
import { Dropdown } from '@anticrm/ui'
|
import { Dropdown } from '@anticrm/ui'
|
||||||
import { ListItem } from '@anticrm/ui/src/types'
|
import { ListItem } from '@anticrm/ui/src/types'
|
||||||
|
import { createEventDispatcher } from 'svelte'
|
||||||
import contact from '../plugin'
|
import contact from '../plugin'
|
||||||
import Company from './icons/Company.svelte'
|
import Company from './icons/Company.svelte'
|
||||||
|
|
||||||
@ -27,6 +28,7 @@
|
|||||||
export let label: IntlString = contact.string.Organization
|
export let label: IntlString = contact.string.Organization
|
||||||
|
|
||||||
const query = createQuery()
|
const query = createQuery()
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
query.query(contact.class.Organization, {}, (res) => {
|
query.query(contact.class.Organization, {}, (res) => {
|
||||||
items = res.map((org) => {
|
items = res.map((org) => {
|
||||||
@ -52,6 +54,7 @@
|
|||||||
} else {
|
} else {
|
||||||
value = selected._id as Ref<Organization>
|
value = selected._id as Ref<Organization>
|
||||||
}
|
}
|
||||||
|
dispatch('change', value)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
"ReviewCategory": "Reviews",
|
"ReviewCategory": "Reviews",
|
||||||
"ReviewCategoryDescription": "Description",
|
"ReviewCategoryDescription": "Description",
|
||||||
"ThisReviewCategoryIsPrivate": "This category is private",
|
"ThisReviewCategoryIsPrivate": "This category is private",
|
||||||
"CreateReview": "Create review",
|
"CreateReview": "Schedule {label}",
|
||||||
"SelectReviewCategory": "select category",
|
"SelectReviewCategory": "select category",
|
||||||
"Reviews": "Reviews",
|
"Reviews": "Reviews",
|
||||||
"Review": "Review",
|
"Review": "Review",
|
||||||
@ -84,7 +84,8 @@
|
|||||||
"OpinionValuePlaceholder": "10/10",
|
"OpinionValuePlaceholder": "10/10",
|
||||||
"Participants": "Participants",
|
"Participants": "Participants",
|
||||||
"NoParticipants": "No participants added",
|
"NoParticipants": "No participants added",
|
||||||
"PersonsLabel": "{name}"
|
"PersonsLabel": "{name}",
|
||||||
|
"AddDescription": "Add description"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"CandidateRequired": "Please select candidate",
|
"CandidateRequired": "Please select candidate",
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
"ReviewCategory": "Оценки",
|
"ReviewCategory": "Оценки",
|
||||||
"ReviewCategoryDescription": "Описание",
|
"ReviewCategoryDescription": "Описание",
|
||||||
"ThisReviewCategoryIsPrivate": "Эта категория личная",
|
"ThisReviewCategoryIsPrivate": "Эта категория личная",
|
||||||
"CreateReview": "Запланировать оценку",
|
"CreateReview": "Запланировать {label}",
|
||||||
"SelectReviewCategory": "выбрать категорию",
|
"SelectReviewCategory": "выбрать категорию",
|
||||||
"Reviews": "Оценки",
|
"Reviews": "Оценки",
|
||||||
"Review": "Оценка",
|
"Review": "Оценка",
|
||||||
@ -85,7 +85,8 @@
|
|||||||
"OpinionValuePlaceholder": "10/10",
|
"OpinionValuePlaceholder": "10/10",
|
||||||
"Participants": "Участники",
|
"Participants": "Участники",
|
||||||
"NoParticipants": "Участники не добавлены",
|
"NoParticipants": "Участники не добавлены",
|
||||||
"PersonsLabel": "{name}"
|
"PersonsLabel": "{name}",
|
||||||
|
"AddDescription": "Add description"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"CandidateRequired": "Пожалуйста выберите кандидата",
|
"CandidateRequired": "Пожалуйста выберите кандидата",
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
"@anticrm/contact-resources": "~0.6.0",
|
"@anticrm/contact-resources": "~0.6.0",
|
||||||
"@anticrm/rekoni": "~0.6.0",
|
"@anticrm/rekoni": "~0.6.0",
|
||||||
"@anticrm/notification": "~0.6.0",
|
"@anticrm/notification": "~0.6.0",
|
||||||
"@anticrm/tags": "~0.6.0"
|
"@anticrm/tags": "~0.6.0",
|
||||||
|
"@anticrm/calendar": "~0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,36 +13,36 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Contact, Employee, Person } from '@anticrm/contact'
|
import type { Contact, Organization, Person } from '@anticrm/contact'
|
||||||
import contact from '@anticrm/contact'
|
import contact from '@anticrm/contact'
|
||||||
import { Account, Class, Client, Doc, generateId, Ref, SortingOrder } from '@anticrm/core'
|
import { OrganizationSelector } from '@anticrm/contact-resources'
|
||||||
|
import { Account, Class, Client, Doc, generateId, Ref } from '@anticrm/core'
|
||||||
import { getResource, OK, Resource, Severity, Status } from '@anticrm/platform'
|
import { getResource, OK, Resource, Severity, Status } from '@anticrm/platform'
|
||||||
import { Card, getClient, UserBox } from '@anticrm/presentation'
|
import { Card, getClient, UserBox } from '@anticrm/presentation'
|
||||||
import type { Candidate, Review } from '@anticrm/recruit'
|
import type { Candidate, Review } from '@anticrm/recruit'
|
||||||
import task, { calcRank, SpaceWithStates, State } from '@anticrm/task'
|
import task, { SpaceWithStates } from '@anticrm/task'
|
||||||
import { Grid, Status as StatusControl } from '@anticrm/ui'
|
import { StyledTextBox } from '@anticrm/text-editor'
|
||||||
import {DatePicker} from '@anticrm/ui'
|
import { DatePicker, Grid, Status as StatusControl, StylishEdit } from '@anticrm/ui'
|
||||||
import view from '@anticrm/view'
|
import view from '@anticrm/view'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import recruit from '../../plugin'
|
import recruit from '../../plugin'
|
||||||
|
|
||||||
export let space: Ref<SpaceWithStates>
|
export let space: Ref<SpaceWithStates>
|
||||||
export let candidate: Ref<Person>
|
export let candidate: Ref<Person>
|
||||||
export let assignee: Ref<Employee>
|
|
||||||
|
|
||||||
export let preserveCandidate = false
|
export let preserveCandidate = false
|
||||||
|
|
||||||
let status: Status = OK
|
let status: Status = OK
|
||||||
|
|
||||||
|
let title: string = ''
|
||||||
|
let description: string = ''
|
||||||
let startDate: Date = new Date()
|
let startDate: Date = new Date()
|
||||||
let dueDate: Date = new Date()
|
let dueDate: Date = new Date()
|
||||||
|
let location: string = ''
|
||||||
|
let company: Ref<Organization> | undefined = undefined
|
||||||
|
|
||||||
const doc: Review = {
|
const doc: Review = {
|
||||||
state: '' as Ref<State>,
|
|
||||||
doneState: null,
|
|
||||||
number: 0,
|
number: 0,
|
||||||
assignee: assignee,
|
|
||||||
rank: '',
|
|
||||||
attachedTo: candidate,
|
attachedTo: candidate,
|
||||||
attachedToClass: recruit.mixin.Candidate,
|
attachedToClass: recruit.mixin.Candidate,
|
||||||
_class: recruit.class.Review,
|
_class: recruit.class.Review,
|
||||||
@ -51,10 +51,12 @@
|
|||||||
collection: 'reviews',
|
collection: 'reviews',
|
||||||
modifiedOn: Date.now(),
|
modifiedOn: Date.now(),
|
||||||
modifiedBy: '' as Ref<Account>,
|
modifiedBy: '' as Ref<Account>,
|
||||||
startDate: null,
|
date: 0,
|
||||||
dueDate: null,
|
dueDate: undefined,
|
||||||
description: '',
|
description,
|
||||||
verdict: ''
|
company,
|
||||||
|
verdict: '',
|
||||||
|
title
|
||||||
}
|
}
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
@ -62,9 +64,17 @@
|
|||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
|
|
||||||
export function canClose (): boolean {
|
export function canClose (): boolean {
|
||||||
return candidate === undefined && assignee === undefined
|
return candidate === undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let spaceLabel: string = ''
|
||||||
|
|
||||||
|
$: client.findOne(recruit.class.ReviewCategory, { _id: doc.space }).then((res) => {
|
||||||
|
if (res !== undefined) {
|
||||||
|
spaceLabel = res.name
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
async function createReview () {
|
async function createReview () {
|
||||||
const state = await client.findOne(task.class.State, { space: doc.space })
|
const state = await client.findOne(task.class.State, { space: doc.space })
|
||||||
if (state === undefined) {
|
if (state === undefined) {
|
||||||
@ -75,11 +85,6 @@
|
|||||||
throw new Error('sequence object not found')
|
throw new Error('sequence object not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastOne = await client.findOne(
|
|
||||||
recruit.class.Review,
|
|
||||||
{ state: state._id },
|
|
||||||
{ sort: { rank: SortingOrder.Descending } }
|
|
||||||
)
|
|
||||||
const incResult = await client.update(sequence, { $inc: { sequence: 1 } }, true)
|
const incResult = await client.update(sequence, { $inc: { sequence: 1 } }, true)
|
||||||
|
|
||||||
const candidateInstance = await client.findOne(contact.class.Person, { _id: doc.attachedTo as Ref<Person> })
|
const candidateInstance = await client.findOne(contact.class.Person, { _id: doc.attachedTo as Ref<Person> })
|
||||||
@ -87,24 +92,25 @@
|
|||||||
throw new Error('contact not found')
|
throw new Error('contact not found')
|
||||||
}
|
}
|
||||||
if (!client.getHierarchy().hasMixin(candidateInstance, recruit.mixin.Candidate)) {
|
if (!client.getHierarchy().hasMixin(candidateInstance, recruit.mixin.Candidate)) {
|
||||||
await client.createMixin<Contact, Candidate>(candidateInstance._id, candidateInstance._class, candidateInstance.space, recruit.mixin.Candidate, {})
|
await client.createMixin<Contact, Candidate>(
|
||||||
|
candidateInstance._id,
|
||||||
|
candidateInstance._class,
|
||||||
|
candidateInstance.space,
|
||||||
|
recruit.mixin.Candidate,
|
||||||
|
{}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
await client.addCollection(
|
await client.addCollection(recruit.class.Review, doc.space, doc.attachedTo, doc.attachedToClass, 'reviews', {
|
||||||
recruit.class.Review,
|
number: (incResult as any).object.sequence,
|
||||||
doc.space, doc.attachedTo, doc.attachedToClass, 'reviews',
|
date: startDate?.getTime() ?? null,
|
||||||
{
|
dueDate: dueDate?.getTime() ?? null,
|
||||||
state: state._id,
|
description,
|
||||||
doneState: null,
|
verdict: '',
|
||||||
number: (incResult as any).object.sequence,
|
title,
|
||||||
assignee: doc.assignee,
|
company,
|
||||||
rank: calcRank(lastOne, undefined),
|
location
|
||||||
startDate: startDate?.getTime() ?? null,
|
})
|
||||||
dueDate: dueDate?.getTime() ?? null,
|
|
||||||
description: '',
|
|
||||||
verdict: ''
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function invokeValidate (
|
async function invokeValidate (
|
||||||
@ -130,9 +136,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Card
|
<Card
|
||||||
|
size={'medium'}
|
||||||
label={recruit.string.CreateReview}
|
label={recruit.string.CreateReview}
|
||||||
|
labelProps={{ label: spaceLabel }}
|
||||||
okAction={createReview}
|
okAction={createReview}
|
||||||
canSave={status.severity === Severity.OK}
|
canSave={status.severity === Severity.OK && title.trim().length > 0}
|
||||||
spaceClass={recruit.class.ReviewCategory}
|
spaceClass={recruit.class.ReviewCategory}
|
||||||
spaceQuery={{ archived: false }}
|
spaceQuery={{ archived: false }}
|
||||||
spaceLabel={recruit.string.ReviewCategory}
|
spaceLabel={recruit.string.ReviewCategory}
|
||||||
@ -143,19 +151,38 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StatusControl slot="error" {status} />
|
<StatusControl slot="error" {status} />
|
||||||
|
|
||||||
<Grid column={1} rowGap={1.75}>
|
<Grid column={1} rowGap={1.75}>
|
||||||
{#if !preserveCandidate}
|
<Grid column={!preserveCandidate ? 2 : 1}>
|
||||||
<UserBox _class={contact.class.Person} title={recruit.string.Candidate} caption={recruit.string.Candidates} bind:value={doc.attachedTo} />
|
<StylishEdit bind:value={title} label={recruit.string.Title} />
|
||||||
{/if}
|
{#if !preserveCandidate}
|
||||||
<UserBox
|
<div class="antiComponentBox">
|
||||||
_class={contact.class.Employee}
|
<UserBox
|
||||||
title={recruit.string.AssignRecruiter}
|
_class={contact.class.Person}
|
||||||
caption={recruit.string.Recruiters}
|
title={recruit.string.Candidate}
|
||||||
bind:value={doc.assignee}
|
caption={recruit.string.Candidates}
|
||||||
allowDeselect
|
bind:value={doc.attachedTo}
|
||||||
titleDeselect={recruit.string.UnAssignRecruiter}
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</Grid>
|
||||||
|
<StyledTextBox
|
||||||
|
emphasized
|
||||||
|
showButtons={false}
|
||||||
|
bind:content={description}
|
||||||
|
label={recruit.string.Description}
|
||||||
|
alwaysEdit
|
||||||
|
placeholder={recruit.string.AddDescription}
|
||||||
/>
|
/>
|
||||||
<DatePicker title={recruit.string.StartDate} bind:value={startDate} withTime />
|
<Grid column={2}>
|
||||||
<DatePicker title={recruit.string.DueDate} bind:value={dueDate} withTime />
|
<StylishEdit bind:value={location} label={recruit.string.Location} />
|
||||||
|
<OrganizationSelector bind:value={company} label={recruit.string.Company} />
|
||||||
|
</Grid>
|
||||||
|
<div class="antiComponentBox">
|
||||||
|
<DatePicker title={recruit.string.StartDate} bind:value={startDate} withTime />
|
||||||
|
</div>
|
||||||
|
<div class="antiComponentBox">
|
||||||
|
<DatePicker title={recruit.string.DueDate} bind:value={dueDate} withTime />
|
||||||
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -14,44 +14,32 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import core, { Ref } from '@anticrm/core'
|
import core from '@anticrm/core'
|
||||||
import { getClient,SpaceCreateCard } from '@anticrm/presentation'
|
import { getClient, SpaceCreateCard } from '@anticrm/presentation'
|
||||||
import task,{ createKanban,KanbanTemplate } from '@anticrm/task'
|
import { EditBox, Grid } from '@anticrm/ui'
|
||||||
import { Component,EditBox,Grid } from '@anticrm/ui'
|
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import recruit from '../../plugin'
|
import recruit from '../../plugin'
|
||||||
import Review from '../icons/Review.svelte'
|
import Review from '../icons/Review.svelte'
|
||||||
import { Organization } from '@anticrm/contact'
|
|
||||||
import { OrganizationSelector } from '@anticrm/contact-resources'
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let name: string = ''
|
let name: string = ''
|
||||||
const description: string = ''
|
const description: string = ''
|
||||||
let templateId: Ref<KanbanTemplate> | undefined
|
|
||||||
let company: Ref<Organization> | undefined
|
|
||||||
|
|
||||||
export function canClose (): boolean {
|
export function canClose (): boolean {
|
||||||
return name === '' && templateId !== undefined
|
return name === ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
async function createReviewCategory () {
|
async function createReviewCategory () {
|
||||||
if (templateId !== undefined && await client.findOne(task.class.KanbanTemplate, { _id: templateId }) === undefined) {
|
await client.createDoc(recruit.class.ReviewCategory, core.space.Space, {
|
||||||
throw Error(`Failed to find target kanban template: ${templateId}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const id = await client.createDoc(recruit.class.ReviewCategory, core.space.Space, {
|
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
private: false,
|
private: false,
|
||||||
archived: false,
|
archived: false,
|
||||||
company,
|
|
||||||
members: []
|
members: []
|
||||||
})
|
})
|
||||||
|
|
||||||
await createKanban(client, id, templateId)
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -63,13 +51,5 @@
|
|||||||
>
|
>
|
||||||
<Grid column={1} rowGap={1.5}>
|
<Grid column={1} rowGap={1.5}>
|
||||||
<EditBox label={recruit.string.ReviewCategoryName} bind:value={name} icon={Review} placeholder={recruit.string.ReviewCategoryPlaceholder} maxWidth={'16rem'} focus/>
|
<EditBox label={recruit.string.ReviewCategoryName} bind:value={name} icon={Review} placeholder={recruit.string.ReviewCategoryPlaceholder} maxWidth={'16rem'} focus/>
|
||||||
<OrganizationSelector bind:value={company} label={recruit.string.Company} />
|
|
||||||
|
|
||||||
<Component is={task.component.KanbanTemplateSelector} props={{
|
|
||||||
folders: [recruit.space.ReviewTemplates],
|
|
||||||
template: templateId
|
|
||||||
}} on:change={(evt) => {
|
|
||||||
templateId = evt.detail
|
|
||||||
}}/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</SpaceCreateCard>
|
</SpaceCreateCard>
|
||||||
|
@ -14,117 +14,111 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact from '@anticrm/contact'
|
import calendar from '@anticrm/calendar'
|
||||||
import { createQuery, getClient, UserBoxList } from '@anticrm/presentation'
|
import contact, { Contact } from '@anticrm/contact'
|
||||||
import type { Candidate, Review, ReviewCategory } from '@anticrm/recruit'
|
import { OrganizationSelector } from '@anticrm/contact-resources'
|
||||||
|
import { getClient, UserBox, UserBoxList, UserInfo } from '@anticrm/presentation'
|
||||||
|
import type { Review } from '@anticrm/recruit'
|
||||||
import { StyledTextBox } from '@anticrm/text-editor'
|
import { StyledTextBox } from '@anticrm/text-editor'
|
||||||
import { EditBox, Grid, Label } from '@anticrm/ui'
|
import { Grid, Label, showPanel, StylishEdit } from '@anticrm/ui'
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
import recruit from '../../plugin'
|
import recruit from '../../plugin'
|
||||||
import CandidateCard from '../CandidateCard.svelte'
|
import view from '@anticrm/view'
|
||||||
import ExpandRightDouble from '../icons/ExpandRightDouble.svelte'
|
|
||||||
import ReviewCategoryCard from './ReviewCategoryCard.svelte'
|
|
||||||
|
|
||||||
export let object: Review
|
export let object: Review
|
||||||
let candidate: Candidate
|
|
||||||
|
|
||||||
let reviewCategory: ReviewCategory
|
|
||||||
|
|
||||||
const candidateQuery = createQuery()
|
|
||||||
$: if (object !== undefined) {
|
|
||||||
candidateQuery.query(recruit.mixin.Candidate, { _id: object.attachedTo }, (result) => {
|
|
||||||
candidate = result[0]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const reviewCategoryQuery = createQuery()
|
|
||||||
$: if (candidate !== undefined) {
|
|
||||||
reviewCategoryQuery.query(recruit.class.ReviewCategory, { _id: object.space }, (result) => {
|
|
||||||
reviewCategory = result[0]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
dispatch('open', {
|
dispatch('open', {
|
||||||
ignoreKeys: ['location', 'company', 'number', 'comments', 'startDate', 'description', 'verdict']
|
ignoreKeys: ['number', 'comments', 'title', 'description', 'verdict']
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let candidate: Contact | undefined = undefined
|
||||||
|
|
||||||
|
async function updateSelected (object: Review) {
|
||||||
|
candidate = await client.findOne<Contact>(object.attachedToClass, { _id: object.attachedTo })
|
||||||
|
}
|
||||||
|
|
||||||
|
$: updateSelected(object)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if object !== undefined && candidate !== undefined}
|
{#if object !== undefined}
|
||||||
<div class="flex-between">
|
<div class="mb-2">
|
||||||
<div class="card"><CandidateCard {candidate} /></div>
|
<div class="mb-2">
|
||||||
<div class="arrows"><ExpandRightDouble /></div>
|
<Grid column={2}>
|
||||||
<div class="card"><ReviewCategoryCard category={reviewCategory} /></div>
|
<StylishEdit
|
||||||
</div>
|
label={calendar.string.Title}
|
||||||
|
bind:value={object.title}
|
||||||
<div class="mt-6 mb-2">
|
on:change={() => client.update(object, { title: object.title })}
|
||||||
<Grid column={2}>
|
/>
|
||||||
<EditBox
|
<div class="antiComponentBox over-underline" on:click={() => {
|
||||||
label={recruit.string.Company}
|
if (candidate !== undefined) {
|
||||||
bind:value={object.company}
|
showPanel(view.component.EditDoc, candidate._id, candidate._class, 'full')
|
||||||
icon={contact.icon.Company}
|
}
|
||||||
placeholder={recruit.string.Company}
|
}}>
|
||||||
maxWidth="39rem"
|
<UserBox
|
||||||
focus
|
readonly
|
||||||
on:change={() => client.update(object, { company: object.company })}
|
_class={contact.class.Person}
|
||||||
|
title={recruit.string.Candidate}
|
||||||
|
caption={recruit.string.Candidates}
|
||||||
|
value={object.attachedTo}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 mb-2">
|
||||||
|
<StyledTextBox
|
||||||
|
label={recruit.string.Description}
|
||||||
|
emphasized
|
||||||
|
content={object.description}
|
||||||
|
on:value={(evt) => {
|
||||||
|
console.log(evt.detail)
|
||||||
|
client.update(object, { description: evt.detail })
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<EditBox
|
</div>
|
||||||
label={recruit.string.Location}
|
|
||||||
|
<Grid column={2}>
|
||||||
|
<StylishEdit
|
||||||
|
label={calendar.string.Location}
|
||||||
bind:value={object.location}
|
bind:value={object.location}
|
||||||
icon={recruit.icon.Location}
|
|
||||||
placeholder={recruit.string.Location}
|
|
||||||
maxWidth="39rem"
|
|
||||||
focus
|
|
||||||
on:change={() => client.update(object, { location: object.location })}
|
on:change={() => client.update(object, { location: object.location })}
|
||||||
/>
|
/>
|
||||||
|
<div class="antiComponentBox">
|
||||||
|
<OrganizationSelector
|
||||||
|
bind:value={object.company}
|
||||||
|
label={recruit.string.Company}
|
||||||
|
on:change={() => client.update(object, { company: object.company })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
<div class="flex-row">
|
<div class="flex-row">
|
||||||
<div class="mt-4 mb-2">
|
<div class="mt-4 mb-2">
|
||||||
<Label label={recruit.string.Participants} />
|
<Label label={calendar.string.Participants} />
|
||||||
</div>
|
</div>
|
||||||
<UserBoxList
|
<UserBoxList
|
||||||
_class={contact.class.Employee}
|
_class={contact.class.Employee}
|
||||||
items={object.participants}
|
items={object.participants}
|
||||||
title={recruit.string.Participants}
|
title={calendar.string.Participants}
|
||||||
on:open={(evt) => {
|
on:open={(evt) => {
|
||||||
client.update(object, { $push: { participants: evt.detail._id } })
|
client.update(object, { $push: { participants: evt.detail._id } })
|
||||||
}}
|
}}
|
||||||
on:delete={(evt) => {
|
on:delete={(evt) => {
|
||||||
client.update(object, { $pull: { participants: evt.detail._id } })
|
client.update(object, { $pull: { participants: evt.detail._id } })
|
||||||
}}
|
}}
|
||||||
noItems={recruit.string.NoParticipants}
|
noItems={calendar.string.NoParticipants}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4 mb-1">
|
<StylishEdit
|
||||||
<Label label={recruit.string.Description} />
|
label={recruit.string.Verdict}
|
||||||
</div>
|
bind:value={object.verdict}
|
||||||
<div class="description flex">
|
on:change={() => client.update(object, { verdict: object.verdict })}
|
||||||
<StyledTextBox
|
/>
|
||||||
content={object.description}
|
|
||||||
on:value={(evt) => {
|
|
||||||
console.log(evt.detail)
|
|
||||||
client.update(object, { description: evt.detail })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4 mb-1">
|
|
||||||
<Label label={recruit.string.Verdict} />
|
|
||||||
</div>
|
|
||||||
<div class="description flex">
|
|
||||||
<StyledTextBox
|
|
||||||
content={object.verdict}
|
|
||||||
on:value={(evt) => {
|
|
||||||
client.update(object, { verdict: evt.detail })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -138,8 +132,6 @@
|
|||||||
|
|
||||||
.description {
|
.description {
|
||||||
height: 10rem;
|
height: 10rem;
|
||||||
padding: 1rem;
|
margin-bottom: 1rem;
|
||||||
border: 1px solid var(--theme-menu-divider);
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
<!--
|
|
||||||
// Copyright © 2020, 2021 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 { AttachmentsPresenter } from '@anticrm/attachment-resources'
|
|
||||||
import { CommentsPresenter } from '@anticrm/chunter-resources'
|
|
||||||
import { Employee, formatName, Person } from '@anticrm/contact'
|
|
||||||
import type { WithLookup } from '@anticrm/core'
|
|
||||||
import { Avatar } from '@anticrm/presentation'
|
|
||||||
import type { Review } from '@anticrm/recruit'
|
|
||||||
import { ActionIcon, IconMoreH, showPanel } from '@anticrm/ui'
|
|
||||||
import view from '@anticrm/view'
|
|
||||||
import PersonsPresenter from './PersonsPresenter.svelte'
|
|
||||||
import ReviewPresenter from './ReviewPresenter.svelte'
|
|
||||||
|
|
||||||
export let object: WithLookup<Review>
|
|
||||||
export let draggable: boolean
|
|
||||||
|
|
||||||
function showCandidate () {
|
|
||||||
showPanel(view.component.EditDoc, object.attachedTo, object.attachedToClass, 'full')
|
|
||||||
}
|
|
||||||
function getPersons (object: WithLookup<Review>): Person[] {
|
|
||||||
const r = (object.$lookup?.participants as unknown as Employee[] ?? [])
|
|
||||||
const assignee = object.$lookup?.assignee as Employee
|
|
||||||
if (assignee != null && r.findIndex(it => it._id === assignee._id) === -1) {
|
|
||||||
return [...r, assignee]
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="card-container" {draggable} class:draggable on:dragstart on:dragend>
|
|
||||||
<div class="flex-between mb-3">
|
|
||||||
<Avatar avatar={object.$lookup?.attachedTo?.avatar} size={'medium'} />
|
|
||||||
<div class="flex-grow flex-col min-w-0 ml-2">
|
|
||||||
<div class="fs-title over-underline lines-limit-2" on:click={showCandidate}>
|
|
||||||
{#if object.$lookup?.attachedTo}
|
|
||||||
{formatName(object.$lookup?.attachedTo?.name)}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="small-text lines-limit-2">{object.$lookup?.attachedTo?.title ?? ''}</div>
|
|
||||||
</div>
|
|
||||||
<div class="tool"><ActionIcon label={undefined} icon={IconMoreH} size={'small'} /></div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-between">
|
|
||||||
<div class="flex-row-center">
|
|
||||||
<div class="sm-tool-icon step-lr75">
|
|
||||||
<ReviewPresenter value={object} />
|
|
||||||
</div>
|
|
||||||
{#if (object.attachments ?? 0) > 0}
|
|
||||||
<div class="step-lr75"><AttachmentsPresenter value={object} /></div>
|
|
||||||
{/if}
|
|
||||||
{#if (object.comments ?? 0) > 0}
|
|
||||||
<div class="step-lr75"><CommentsPresenter value={object} /></div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{#if object.$lookup?.participants || object.$lookup?.assignee}
|
|
||||||
<PersonsPresenter value={getPersons(object)}></PersonsPresenter>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.card-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 1rem 1.25rem;
|
|
||||||
background-color: rgba(222, 222, 240, 0.06);
|
|
||||||
border-radius: 0.75rem;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
&.draggable {
|
|
||||||
cursor: grab;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tool {
|
|
||||||
align-self: start;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -0,0 +1,37 @@
|
|||||||
|
<!--
|
||||||
|
// 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.EditVacancy, 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}
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
function show () {
|
function show () {
|
||||||
closeTooltip()
|
closeTooltip()
|
||||||
showPanel(view.component.EditDoc, value._id, value._class, 'full')
|
showPanel(view.component.EditDoc, value._id, value._class, 'right')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -43,21 +43,19 @@
|
|||||||
config={[
|
config={[
|
||||||
'',
|
'',
|
||||||
{ key: '$lookup.space.name', label: recruit.string.ReviewCategoryTitle },
|
{ key: '$lookup.space.name', label: recruit.string.ReviewCategoryTitle },
|
||||||
'dueDate',
|
'verdict',
|
||||||
{
|
{
|
||||||
key: '',
|
key: '',
|
||||||
presenter: recruit.component.OpinionsPresenter,
|
presenter: recruit.component.OpinionsPresenter,
|
||||||
label: recruit.string.Opinions,
|
label: recruit.string.Opinions,
|
||||||
sortingKey: 'opinions'
|
sortingKey: 'opinions'
|
||||||
},
|
},
|
||||||
'$lookup.state',
|
'date',
|
||||||
'$lookup.doneState'
|
'dueDate'
|
||||||
]}
|
]}
|
||||||
options={{
|
options={{
|
||||||
lookup: {
|
lookup: {
|
||||||
state: task.class.State,
|
space: core.class.Space
|
||||||
space: core.class.Space,
|
|
||||||
doneState: task.class.DoneState
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
query={{ attachedTo: objectId }}
|
query={{ attachedTo: objectId }}
|
||||||
|
@ -35,7 +35,6 @@ import CreateOpinion from './components/review/CreateOpinion.svelte'
|
|||||||
import CreateReviewCategory from './components/review/CreateReviewCategory.svelte'
|
import CreateReviewCategory from './components/review/CreateReviewCategory.svelte'
|
||||||
import EditReview from './components/review/EditReview.svelte'
|
import EditReview from './components/review/EditReview.svelte'
|
||||||
import EditReviewCategory from './components/review/EditReviewCategory.svelte'
|
import EditReviewCategory from './components/review/EditReviewCategory.svelte'
|
||||||
import KanbanReviewCard from './components/review/KanbanReviewCard.svelte'
|
|
||||||
import OpinionPresenter from './components/review/OpinionPresenter.svelte'
|
import OpinionPresenter from './components/review/OpinionPresenter.svelte'
|
||||||
import OpinionsPresenter from './components/review/OpinionsPresenter.svelte'
|
import OpinionsPresenter from './components/review/OpinionsPresenter.svelte'
|
||||||
import Opinions from './components/review/Opinions.svelte'
|
import Opinions from './components/review/Opinions.svelte'
|
||||||
@ -48,8 +47,8 @@ import VacancyItemPresenter from './components/VacancyItemPresenter.svelte'
|
|||||||
import VacancyPresenter from './components/VacancyPresenter.svelte'
|
import VacancyPresenter from './components/VacancyPresenter.svelte'
|
||||||
import VacancyCountPresenter from './components/VacancyCountPresenter.svelte'
|
import VacancyCountPresenter from './components/VacancyCountPresenter.svelte'
|
||||||
import VacancyModifiedPresenter from './components/VacancyModifiedPresenter.svelte'
|
import VacancyModifiedPresenter from './components/VacancyModifiedPresenter.svelte'
|
||||||
|
import ReviewCategoryPresenter from './components/review/ReviewCategoryPresenter.svelte'
|
||||||
import recruit from './plugin'
|
import recruit from './plugin'
|
||||||
import PersonsPresenter from './components/review/PersonsPresenter.svelte'
|
|
||||||
|
|
||||||
async function createApplication (object: Doc): Promise<void> {
|
async function createApplication (object: Doc): Promise<void> {
|
||||||
showPopup(CreateApplication, { candidate: object._id, preserveCandidate: true })
|
showPopup(CreateApplication, { candidate: object._id, preserveCandidate: true })
|
||||||
@ -163,12 +162,11 @@ export default async (): Promise<Resources> => ({
|
|||||||
CreateReview,
|
CreateReview,
|
||||||
ReviewPresenter,
|
ReviewPresenter,
|
||||||
EditReview,
|
EditReview,
|
||||||
KanbanReviewCard,
|
|
||||||
Reviews,
|
Reviews,
|
||||||
Opinions,
|
Opinions,
|
||||||
OpinionPresenter,
|
OpinionPresenter,
|
||||||
OpinionsPresenter,
|
OpinionsPresenter,
|
||||||
PersonsPresenter
|
ReviewCategoryPresenter
|
||||||
},
|
},
|
||||||
completion: {
|
completion: {
|
||||||
ApplicationQuery: async (client: Client, query: string) => await queryApplication(client, query)
|
ApplicationQuery: async (client: Client, query: string) => await queryApplication(client, query)
|
||||||
|
@ -101,9 +101,7 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
StartDate: '' as IntlString,
|
StartDate: '' as IntlString,
|
||||||
DueDate: '' as IntlString,
|
DueDate: '' as IntlString,
|
||||||
CandidateReviews: '' as IntlString,
|
CandidateReviews: '' as IntlString,
|
||||||
Participants: '' as IntlString,
|
AddDescription: '' as IntlString
|
||||||
NoParticipants: '' as IntlString,
|
|
||||||
PersonsLabel: '' as IntlString
|
|
||||||
},
|
},
|
||||||
space: {
|
space: {
|
||||||
CandidatesPublic: '' as Ref<Space>
|
CandidatesPublic: '' as Ref<Space>
|
||||||
@ -116,7 +114,6 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
VacancyItemPresenter: '' as AnyComponent,
|
VacancyItemPresenter: '' as AnyComponent,
|
||||||
VacancyCountPresenter: '' as AnyComponent,
|
VacancyCountPresenter: '' as AnyComponent,
|
||||||
OpinionsPresenter: '' as AnyComponent,
|
OpinionsPresenter: '' as AnyComponent,
|
||||||
PersonsPresenter: '' as AnyComponent,
|
|
||||||
VacancyModifiedPresenter: '' as AnyComponent
|
VacancyModifiedPresenter: '' as AnyComponent
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
"@anticrm/contact": "~0.6.5",
|
"@anticrm/contact": "~0.6.5",
|
||||||
"@anticrm/chunter": "~0.6.1",
|
"@anticrm/chunter": "~0.6.1",
|
||||||
"@anticrm/task": "~0.6.0",
|
"@anticrm/task": "~0.6.0",
|
||||||
|
"@anticrm/calendar": "~0.6.0",
|
||||||
"@anticrm/ui": "~0.6.0"
|
"@anticrm/ui": "~0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import type { Employee, Organization, Person } from '@anticrm/contact'
|
import { Calendar, Event } from '@anticrm/calendar'
|
||||||
|
import type { Organization, Person } from '@anticrm/contact'
|
||||||
import type { AttachedDoc, Class, Doc, Mixin, Ref, Space, Timestamp } from '@anticrm/core'
|
import type { AttachedDoc, Class, Doc, Mixin, Ref, Space, Timestamp } from '@anticrm/core'
|
||||||
import type { Asset, Plugin } from '@anticrm/platform'
|
import type { Asset, Plugin } from '@anticrm/platform'
|
||||||
import { plugin } from '@anticrm/platform'
|
import { plugin } from '@anticrm/platform'
|
||||||
@ -34,10 +35,10 @@ export interface Vacancy extends SpaceWithStates {
|
|||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export interface ReviewCategory extends SpaceWithStates {
|
export interface ReviewCategory extends Calendar {
|
||||||
fullDescription?: string
|
fullDescription?: string
|
||||||
attachments?: number
|
attachments?: number
|
||||||
company?: Ref<Organization>
|
comments?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,22 +71,14 @@ export interface Applicant extends Task {
|
|||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export interface Review extends Task {
|
export interface Review extends Event {
|
||||||
attachedTo: Ref<Candidate>
|
attachedTo: Ref<Candidate>
|
||||||
attachments?: number
|
|
||||||
comments?: number
|
|
||||||
description: string
|
|
||||||
verdict: string
|
verdict: string
|
||||||
|
|
||||||
location?: string
|
company?: Ref<Organization>
|
||||||
company?: string
|
|
||||||
|
|
||||||
startDate: Timestamp | null
|
|
||||||
dueDate: Timestamp | null
|
|
||||||
|
|
||||||
opinions?: number
|
opinions?: number
|
||||||
|
|
||||||
participants?: Ref<Employee>[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { TypeDate } from '@anticrm/core'
|
||||||
import { IntlString } from '@anticrm/platform'
|
import { IntlString } from '@anticrm/platform'
|
||||||
import { DatePopup, showPopup } from '@anticrm/ui'
|
import { DatePopup, showPopup } from '@anticrm/ui'
|
||||||
import DatePresenter from './DatePresenter.svelte'
|
import DatePresenter from './DatePresenter.svelte'
|
||||||
@ -22,6 +23,9 @@
|
|||||||
export let value: number | Date | undefined
|
export let value: number | Date | undefined
|
||||||
export let label: IntlString
|
export let label: IntlString
|
||||||
export let onChange: (value: any) => void
|
export let onChange: (value: any) => void
|
||||||
|
|
||||||
|
export let attributeType: TypeDate | undefined
|
||||||
|
|
||||||
$: date = value ? new Date(value) : new Date()
|
$: date = value ? new Date(value) : new Date()
|
||||||
let container: HTMLElement
|
let container: HTMLElement
|
||||||
let opened: boolean = false
|
let opened: boolean = false
|
||||||
@ -31,7 +35,7 @@
|
|||||||
on:click|preventDefault={() => {
|
on:click|preventDefault={() => {
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
opened = true
|
opened = true
|
||||||
showPopup(DatePopup, { selected: date, title: label }, container, (result) => {
|
showPopup(DatePopup, { value: date, title: label, withTime: attributeType?.withTime ?? false }, container, (result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
value = result.getTime()
|
value = result.getTime()
|
||||||
onChange(value)
|
onChange(value)
|
||||||
@ -40,5 +44,5 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}} >
|
}} >
|
||||||
<DatePresenter {value} />
|
<DatePresenter {value} {attributeType} />
|
||||||
</div>
|
</div>
|
@ -15,16 +15,18 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { TypeDate } from '@anticrm/core'
|
||||||
import { DatePresenter } from '@anticrm/ui'
|
import { DatePresenter } from '@anticrm/ui'
|
||||||
|
|
||||||
export let value: number | Date | undefined
|
export let value: number | Date | undefined
|
||||||
|
export let attributeType: TypeDate | undefined
|
||||||
|
|
||||||
$: date = value ? new Date(value) : undefined
|
$: date = value ? new Date(value) : undefined
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="antiSelect">
|
<div class="antiSelect">
|
||||||
{#if date}
|
{#if date}
|
||||||
<DatePresenter value={date} />
|
<DatePresenter value={date} withTime={attributeType?.withTime ?? false} />
|
||||||
{:else}
|
{:else}
|
||||||
No date
|
No date
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
<!--
|
||||||
|
// 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 { IntlString } from '@anticrm/platform'
|
||||||
|
import { Label } from '@anticrm/ui'
|
||||||
|
|
||||||
|
export let value: IntlString
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span class="lines-limit-2">
|
||||||
|
<Label label={value}/>
|
||||||
|
</span>
|
@ -23,6 +23,7 @@ import DateEditor from './components/DateEditor.svelte'
|
|||||||
import DatePresenter from './components/DatePresenter.svelte'
|
import DatePresenter from './components/DatePresenter.svelte'
|
||||||
import StringEditor from './components/StringEditor.svelte'
|
import StringEditor from './components/StringEditor.svelte'
|
||||||
import StringPresenter from './components/StringPresenter.svelte'
|
import StringPresenter from './components/StringPresenter.svelte'
|
||||||
|
import IntlStringPresenter from './components/IntlStringPresenter.svelte'
|
||||||
import NumberEditor from './components/NumberEditor.svelte'
|
import NumberEditor from './components/NumberEditor.svelte'
|
||||||
import NumberPresenter from './components/NumberPresenter.svelte'
|
import NumberPresenter from './components/NumberPresenter.svelte'
|
||||||
import Table from './components/Table.svelte'
|
import Table from './components/Table.svelte'
|
||||||
@ -80,6 +81,7 @@ export default async (): Promise<Resources> => ({
|
|||||||
RolePresenter,
|
RolePresenter,
|
||||||
ObjectPresenter,
|
ObjectPresenter,
|
||||||
EditDoc,
|
EditDoc,
|
||||||
HTMLPresenter
|
HTMLPresenter,
|
||||||
|
IntlStringPresenter
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -98,12 +98,14 @@ async function getAttributePresenter (
|
|||||||
const resultKey = preserveKey.sortingKey ?? preserveKey.key
|
const resultKey = preserveKey.sortingKey ?? preserveKey.key
|
||||||
const sortingKey = attribute.type._class === core.class.ArrOf ? resultKey + '.length' : resultKey
|
const sortingKey = attribute.type._class === core.class.ArrOf ? resultKey + '.length' : resultKey
|
||||||
const presenter = await getResource(presenterMixin.presenter)
|
const presenter = await getResource(presenterMixin.presenter)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: preserveKey.key,
|
key: preserveKey.key,
|
||||||
sortingKey,
|
sortingKey,
|
||||||
_class: attrClass,
|
_class: attrClass,
|
||||||
label: preserveKey.label ?? attribute.label,
|
label: preserveKey.label ?? attribute.label,
|
||||||
presenter,
|
presenter,
|
||||||
|
props: { attributeType: attribute.type },
|
||||||
icon: presenterMixin.icon,
|
icon: presenterMixin.icon,
|
||||||
attribute
|
attribute
|
||||||
}
|
}
|
||||||
@ -215,7 +217,7 @@ export async function getActions (
|
|||||||
|
|
||||||
export async function deleteObject (client: TxOperations, object: Doc): Promise<void> {
|
export async function deleteObject (client: TxOperations, object: Doc): Promise<void> {
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
const promises: Promise<any>[] = []
|
const promises: Array<Promise<any>> = []
|
||||||
if (client.getHierarchy().isDerived(object._class, core.class.AttachedDoc)) {
|
if (client.getHierarchy().isDerived(object._class, core.class.AttachedDoc)) {
|
||||||
const adoc = object as AttachedDoc
|
const adoc = object as AttachedDoc
|
||||||
promises.push(client.removeCollection(object._class, object.space, adoc._id, adoc.attachedTo, adoc.attachedToClass, adoc.collection).catch(err => console.error(err)))
|
promises.push(client.removeCollection(object._class, object.space, adoc._id, adoc.attachedTo, adoc.attachedToClass, adoc.collection).catch(err => console.error(err)))
|
||||||
@ -261,7 +263,7 @@ function getParentClass (hierarchy: Hierarchy, _class: Ref<Class<Doc>>): Ref<Cla
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMixins (hierarchy: Hierarchy, _class: Ref<Class<Doc>>, object: Doc): Ref<Mixin<Doc>>[] {
|
function getMixins (hierarchy: Hierarchy, _class: Ref<Class<Doc>>, object: Doc): Array<Ref<Mixin<Doc>>> {
|
||||||
const parentClass = getParentClass(hierarchy, _class)
|
const parentClass = getParentClass(hierarchy, _class)
|
||||||
const descendants = hierarchy.getDescendants(parentClass)
|
const descendants = hierarchy.getDescendants(parentClass)
|
||||||
return descendants.filter(
|
return descendants.filter(
|
||||||
|
@ -65,8 +65,12 @@
|
|||||||
{#if spaceSample !== undefined && model}
|
{#if spaceSample !== undefined && model}
|
||||||
<Table
|
<Table
|
||||||
_class={spaceSample._class}
|
_class={spaceSample._class}
|
||||||
config={['', 'company', 'location', 'modifiedOn']}
|
config={['', '$lookup._class.label', 'modifiedOn']}
|
||||||
options={{}}
|
options={{
|
||||||
|
lookup: {
|
||||||
|
_class: core.class.Class
|
||||||
|
}
|
||||||
|
}}
|
||||||
showNotification
|
showNotification
|
||||||
baseMenuClass={core.class.Space}
|
baseMenuClass={core.class.Space}
|
||||||
query={{
|
query={{
|
||||||
|
20
rush.json
20
rush.json
@ -1131,5 +1131,25 @@
|
|||||||
"projectFolder": "server-plugins/setting-resources",
|
"projectFolder": "server-plugins/setting-resources",
|
||||||
"shouldPublish": true
|
"shouldPublish": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"packageName": "@anticrm/calendar",
|
||||||
|
"projectFolder": "plugins/calendar",
|
||||||
|
"shouldPublish": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"packageName": "@anticrm/calendar-assets",
|
||||||
|
"projectFolder": "plugins/calendar-assets",
|
||||||
|
"shouldPublish": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"packageName": "@anticrm/calendar-resources",
|
||||||
|
"projectFolder": "plugins/calendar-resources",
|
||||||
|
"shouldPublish": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"packageName": "@anticrm/model-calendar",
|
||||||
|
"projectFolder": "models/calendar",
|
||||||
|
"shouldPublish": true
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user