mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-29 04:55:03 +02:00
Tracker Issue tracking system (#1243)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Generated
+112
-5
@@ -80,6 +80,7 @@ specifiers:
|
||||
'@rush-temp/model-server-task': file:./projects/model-server-task.tgz
|
||||
'@rush-temp/model-server-telegram': file:./projects/model-server-telegram.tgz
|
||||
'@rush-temp/model-setting': file:./projects/model-setting.tgz
|
||||
'@rush-temp/model-tracker': file:./projects/model-tracker.tgz
|
||||
'@rush-temp/model-tags': file:./projects/model-tags.tgz
|
||||
'@rush-temp/model-task': file:./projects/model-task.tgz
|
||||
'@rush-temp/model-telegram': file:./projects/model-telegram.tgz
|
||||
@@ -136,6 +137,9 @@ specifiers:
|
||||
'@rush-temp/setting': file:./projects/setting.tgz
|
||||
'@rush-temp/setting-assets': file:./projects/setting-assets.tgz
|
||||
'@rush-temp/setting-resources': file:./projects/setting-resources.tgz
|
||||
'@rush-temp/tracker': file:./projects/tracker.tgz
|
||||
'@rush-temp/tracker-assets': file:./projects/tracker-assets.tgz
|
||||
'@rush-temp/tracker-resources': file:./projects/tracker-resources.tgz
|
||||
'@rush-temp/tags': file:./projects/tags.tgz
|
||||
'@rush-temp/tags-assets': file:./projects/tags-assets.tgz
|
||||
'@rush-temp/tags-resources': file:./projects/tags-resources.tgz
|
||||
@@ -339,6 +343,7 @@ dependencies:
|
||||
'@rush-temp/model-server-task': file:projects/model-server-task.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-server-telegram': file:projects/model-server-telegram.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-setting': file:projects/model-setting.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-tracker': file:projects/model-tracker.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-tags': file:projects/model-tags.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-task': file:projects/model-task.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-telegram': file:projects/model-telegram.tgz_typescript@4.5.4
|
||||
@@ -395,6 +400,9 @@ dependencies:
|
||||
'@rush-temp/setting': file:projects/setting.tgz
|
||||
'@rush-temp/setting-assets': file:projects/setting-assets.tgz_typescript@4.5.4
|
||||
'@rush-temp/setting-resources': file:projects/setting-resources.tgz_096c09b0b673a57c275d9767a12070b1
|
||||
'@rush-temp/tracker': file:projects/tracker.tgz
|
||||
'@rush-temp/tracker-assets': file:projects/tracker-assets.tgz_typescript@4.5.4
|
||||
'@rush-temp/tracker-resources': file:projects/tracker-resources.tgz_096c09b0b673a57c275d9767a12070b1
|
||||
'@rush-temp/tags': file:projects/tags.tgz
|
||||
'@rush-temp/tags-assets': file:projects/tags-assets.tgz
|
||||
'@rush-temp/tags-resources': file:projects/tags-resources.tgz_096c09b0b673a57c275d9767a12070b1
|
||||
@@ -12440,7 +12448,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/model-all.tgz_typescript@4.5.4:
|
||||
resolution: {integrity: sha512-CTYZ52iBQ2S06DVd6jUK+PHCpgLDvO7lrujkMWxCO3RUn+77uyDZBGK43n+7UF1HZNSHvYAhyA8fBTvp1kOylw==, tarball: file:projects/model-all.tgz}
|
||||
resolution: {integrity: sha512-LFMD9UgTqaXrqIVbVyZudBvzL8xL6KphHnShut9no15Y5ZozOYv9hksYqBU959YFHClTkUI22XzwaFUPTSideA==, tarball: file:projects/model-all.tgz}
|
||||
id: file:projects/model-all.tgz
|
||||
name: '@rush-temp/model-all'
|
||||
version: 0.0.0
|
||||
@@ -13051,6 +13059,27 @@ packages:
|
||||
- typescript
|
||||
dev: false
|
||||
|
||||
file:projects/model-tracker.tgz_typescript@4.5.4:
|
||||
resolution: {integrity: sha512-PWxsEQ61Fe/moBL+dROHGw2bQRaaJBL/N7HozRZPxXoRfXkH/DwNMvH/UofBL4mIFVs8FfQU03FaFnNdahgNZw==, tarball: file:projects/model-tracker.tgz}
|
||||
id: file:projects/model-tracker.tgz
|
||||
name: '@rush-temp/model-tracker'
|
||||
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-tags.tgz_typescript@4.5.4:
|
||||
resolution: {integrity: sha512-tRhFRRosgUsAll6FSrGLSKycNeDNbH8M2JTvhOrMOQjsVafRvCz+oM+/sHg+tln4CSFTxU/+9cjPfHfQNx5fVA==, tarball: file:projects/model-tags.tgz}
|
||||
id: file:projects/model-tags.tgz
|
||||
@@ -13439,7 +13468,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/presentation.tgz_096c09b0b673a57c275d9767a12070b1:
|
||||
resolution: {integrity: sha512-MP45QOJeNLCukhDFHH8hPeV0lX/HivC+PW3nIIALWyHstmCshVJiu8KjkfrwDl6gj6kRENV9pUOlQcWdp+9ezA==, tarball: file:projects/presentation.tgz}
|
||||
resolution: {integrity: sha512-DSAHNO42i3or1GCHYIM6/V6Yx0aLQlGy1QG6hVTipV/KeBdxZF/hetQNcEufUbwWKAZAwyEIEMIZDFl8tlpKIw==, tarball: file:projects/presentation.tgz}
|
||||
id: file:projects/presentation.tgz
|
||||
name: '@rush-temp/presentation'
|
||||
version: 0.0.0
|
||||
@@ -13475,7 +13504,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/prod.tgz_a07ec81d4d975778878ca12202ea119e:
|
||||
resolution: {integrity: sha512-HHCNzvjIf/tNB1Wr5Fk4HGuoP66fHONafJd6DPh4kpTC7T8Vc5Y/UlneWS3cUjhCsB9jgYejEbu1Osp0DPXCZA==, tarball: file:projects/prod.tgz}
|
||||
resolution: {integrity: sha512-lAhrU2LvSbV+Hg0ug0LHYTe3RMC8MgyyuFOFXQNMwXftXqQfXkgciBMjWh+g9PB/aXcJwSLm3scgACCtGG0wWw==, tarball: file:projects/prod.tgz}
|
||||
id: file:projects/prod.tgz
|
||||
name: '@rush-temp/prod'
|
||||
version: 0.0.0
|
||||
@@ -14289,7 +14318,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/server.tgz:
|
||||
resolution: {integrity: sha512-Gx/PoIoObAiRX21Fo+Z/y7tqqgHW8URVudDz8azH/0hW25pRfR03xPw7oR0GsuF2IBZ4S8nyH1U2HSPpE76W7g==, tarball: file:projects/server.tgz}
|
||||
resolution: {integrity: sha512-TEYNvDfpWbWWHcltHwEyC1B81v5c9UUyGmNx9C9sdItiWxLb8P/lQ+a+xca+5eJ+FQmRxm3VJywrvscmttTfPg==, tarball: file:projects/server.tgz}
|
||||
name: '@rush-temp/server'
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
@@ -14395,6 +14424,84 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
file:projects/tracker-assets.tgz_typescript@4.5.4:
|
||||
resolution: {integrity: sha512-sTaCJb1JkS7lN4xuyIFPuQwlafQHtMB7yZ3lrWTX/MgMwxr4UWHnZODK631lGxhio4MlMgXX0KYqiDwfxnQJqg==, tarball: file:projects/tracker-assets.tgz}
|
||||
id: file:projects/tracker-assets.tgz
|
||||
name: '@rush-temp/tracker-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/tracker-resources.tgz_096c09b0b673a57c275d9767a12070b1:
|
||||
resolution: {integrity: sha512-IwrLGQsCGO7NtMvEY2i7mA81An6fhYDq8Y4aKYZKSX/ptG85/xCJ+YayjxbX70iUoogHJfgYGPTklPJjBAXIKg==, tarball: file:projects/tracker-resources.tgz}
|
||||
id: file:projects/tracker-resources.tgz
|
||||
name: '@rush-temp/tracker-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
|
||||
lexorank: 1.0.4
|
||||
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/tracker.tgz:
|
||||
resolution: {integrity: sha512-4BE4OCd7TawHUfz5pI8hYADlDGMLsNrczRPbsuEy1hrA+4BSTkjn5rDDSZ3iu9TLtB3TV3anvbjiZhZOrbiDyw==, tarball: file:projects/tracker.tgz}
|
||||
name: '@rush-temp/tracker'
|
||||
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/tags-assets.tgz:
|
||||
resolution: {integrity: sha512-c3kDt2CRIqT3lDJNJPawZ+M3j979cOkF1mYeRKUOsNQ1Zs9wnqXjxDxe1ZECpOAUbWXNhKj/Mru0XfEyaCxHQA==, tarball: file:projects/tags-assets.tgz}
|
||||
name: '@rush-temp/tags-assets'
|
||||
@@ -14808,7 +14915,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/tool.tgz:
|
||||
resolution: {integrity: sha512-F3Px6/29RVwqI/G3FsImf5dKvi53Tz7R/LSRyeG81NIN0WMGEsuOB6iWE9GD8PS/W7qSnKsFC8+VWVvJN+gVeQ==, tarball: file:projects/tool.tgz}
|
||||
resolution: {integrity: sha512-JwGKWGU/S/EONMAYohP8k5D9kO8xvd8VG2f7Mw375r83TpoSKBPpLVqrmNZUb70EZTTCihEO9oiM6NVqbjWq9w==, tarball: file:projects/tool.tgz}
|
||||
name: '@rush-temp/tool'
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
|
||||
@@ -130,6 +130,10 @@
|
||||
"@anticrm/server-gmail": "~0.6.0",
|
||||
"@anticrm/server-gmail-resources": "~0.6.0",
|
||||
"@anticrm/server-telegram": "~0.6.0",
|
||||
"@anticrm/server-telegram-resources": "~0.6.0"
|
||||
"@anticrm/server-telegram-resources": "~0.6.0",
|
||||
"@anticrm/presentation": "~0.6.2",
|
||||
"@anticrm/tracker": "~0.6.0",
|
||||
"@anticrm/tracker-assets": "~0.6.0",
|
||||
"@anticrm/tracker-resources": "~0.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import { templatesId } from '@anticrm/templates'
|
||||
import { notificationId } from '@anticrm/notification'
|
||||
import { tagsId } from '@anticrm/tags'
|
||||
import { calendarId } from '@anticrm/calendar'
|
||||
import { trackerId } from '@anticrm/tracker'
|
||||
import rekoni from '@anticrm/rekoni'
|
||||
|
||||
import '@anticrm/login-assets'
|
||||
@@ -56,6 +57,8 @@ import '@anticrm/templates-assets'
|
||||
import '@anticrm/notification-assets'
|
||||
import '@anticrm/tags-assets'
|
||||
import '@anticrm/calendar-assets'
|
||||
import '@anticrm/tracker-assets'
|
||||
import presentation from '@anticrm/presentation'
|
||||
|
||||
import { setMetadata } from '@anticrm/platform'
|
||||
export async function configurePlatform() {
|
||||
@@ -67,7 +70,7 @@ export async function configurePlatform() {
|
||||
|
||||
if( config.MODEL_VERSION != null) {
|
||||
console.log('Minimal Model version requirement', config.MODEL_VERSION)
|
||||
setMetadata(workbench.metadata.RequiredVersion, config.MODEL_VERSION)
|
||||
setMetadata(presentation.metadata.RequiredVersion, config.MODEL_VERSION)
|
||||
}
|
||||
setMetadata(login.metadata.TelegramUrl, process.env.TELEGRAM_URL ?? 'http://localhost:8086')
|
||||
setMetadata(login.metadata.GmailUrl, process.env.GMAIL_URL ?? 'http://localhost:8087')
|
||||
@@ -98,4 +101,6 @@ export async function configurePlatform() {
|
||||
addLocation(notificationId, () => import(/* webpackChunkName: "notification" */ '@anticrm/notification-resources'))
|
||||
addLocation(tagsId, () => import(/* webpackChunkName: "tags" */ '@anticrm/tags-resources'))
|
||||
addLocation(calendarId, () => import(/* webpackChunkName: "calendar" */ '@anticrm/calendar-resources'))
|
||||
|
||||
addLocation(trackerId, () => import(/* webpackChunkName: "tracker" */ '@anticrm/tracker-resources'))
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"@anticrm/model-calendar": "~0.6.0",
|
||||
"@anticrm/model-server-calendar": "~0.6.0",
|
||||
"@anticrm/model-server-gmail": "~0.6.0",
|
||||
"@anticrm/model-server-telegram": "~0.6.0"
|
||||
"@anticrm/model-server-telegram": "~0.6.0",
|
||||
"@anticrm/model-tracker": "~0.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import { createModel as calendarModel } from '@anticrm/model-calendar'
|
||||
import { createModel as serverCalendarModel } from '@anticrm/model-server-calendar'
|
||||
import { createModel as serverGmailModel } from '@anticrm/model-server-gmail'
|
||||
import { createModel as serverTelegramModel } from '@anticrm/model-server-telegram'
|
||||
import { createModel as trackerModel } from '@anticrm/model-tracker'
|
||||
|
||||
export const version: Data<Version> = jsonVersion as Data<Version>
|
||||
|
||||
@@ -92,6 +93,7 @@ const builders = [
|
||||
serverCalendarModel,
|
||||
serverGmailModel,
|
||||
serverTelegramModel,
|
||||
trackerModel,
|
||||
createDemo
|
||||
]
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import { taskOperation } from '@anticrm/model-task'
|
||||
import { telegramOperation } from '@anticrm/model-telegram'
|
||||
import { templatesOperation } from '@anticrm/model-templates'
|
||||
import { viewOperation } from '@anticrm/model-view'
|
||||
import { trackerOperation } from '@anticrm/model-tracker'
|
||||
|
||||
export const migrateOperations: MigrateOperation[] = [
|
||||
coreOperation,
|
||||
@@ -44,5 +45,6 @@ export const migrateOperations: MigrateOperation[] = [
|
||||
contactOperation,
|
||||
tagsOperation,
|
||||
notificationOperation,
|
||||
settingOperation
|
||||
settingOperation,
|
||||
trackerOperation
|
||||
]
|
||||
|
||||
+29
-29
@@ -265,35 +265,35 @@ export function createModel (builder: Builder): void {
|
||||
task.viewlet.StatusTable
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
workbench.class.Application,
|
||||
core.space.Model,
|
||||
{
|
||||
label: task.string.ApplicationLabelTask,
|
||||
icon: task.icon.Task,
|
||||
hidden: false,
|
||||
navigatorModel: {
|
||||
spaces: [
|
||||
{
|
||||
label: task.string.Projects,
|
||||
spaceClass: task.class.Project,
|
||||
addSpaceLabel: task.string.CreateProject,
|
||||
createComponent: task.component.CreateProject
|
||||
}
|
||||
],
|
||||
specials: [
|
||||
{
|
||||
id: 'assigned',
|
||||
label: task.string.Assigned,
|
||||
icon: task.icon.Task,
|
||||
component: task.component.AssignedTasks,
|
||||
position: 'top'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
task.app.Tasks
|
||||
)
|
||||
// builder.createDoc(
|
||||
// workbench.class.Application,
|
||||
// core.space.Model,
|
||||
// {
|
||||
// label: task.string.ApplicationLabelTask,
|
||||
// icon: task.icon.Task,
|
||||
// hidden: false,
|
||||
// navigatorModel: {
|
||||
// spaces: [
|
||||
// {
|
||||
// label: task.string.Projects,
|
||||
// spaceClass: task.class.Project,
|
||||
// addSpaceLabel: task.string.CreateProject,
|
||||
// createComponent: task.component.CreateProject
|
||||
// }
|
||||
// ],
|
||||
// specials: [
|
||||
// {
|
||||
// id: 'assigned',
|
||||
// label: task.string.Assigned,
|
||||
// icon: task.icon.Task,
|
||||
// component: task.component.AssignedTasks,
|
||||
// position: 'top'
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// task.app.Tasks
|
||||
// )
|
||||
|
||||
builder.createDoc(view.class.Viewlet, core.space.Model, {
|
||||
attachTo: task.class.Issue,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@anticrm/model-rig/profiles/default/config/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
*
|
||||
!/lib/**
|
||||
!CHANGELOG.md
|
||||
/lib/**/__tests__/
|
||||
@@ -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"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@anticrm/model-tracker",
|
||||
"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.16",
|
||||
"@anticrm/model": "~0.6.0",
|
||||
"@anticrm/ui": "~0.6.0",
|
||||
"@anticrm/contact": "~0.6.5",
|
||||
"@anticrm/platform": "~0.6.5",
|
||||
"@anticrm/model-core": "~0.6.0",
|
||||
"@anticrm/model-view": "~0.6.0",
|
||||
"@anticrm/model-workbench": "~0.6.1",
|
||||
"@anticrm/model-contact": "~0.6.1",
|
||||
"@anticrm/model-attachment": "~0.6.0",
|
||||
"@anticrm/tracker": "~0.6.0",
|
||||
"@anticrm/tracker-resources": "~0.6.0",
|
||||
"@anticrm/model-chunter": "~0.6.0",
|
||||
"@anticrm/workbench": "~0.6.1",
|
||||
"@anticrm/view": "~0.6.0",
|
||||
"@anticrm/model-presentation": "~0.6.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// 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 core, { Client, TxOperations } from '@anticrm/core'
|
||||
import { Team } from '@anticrm/tracker'
|
||||
import tracker from './plugin'
|
||||
|
||||
export async function createDeps (client: Client): Promise<void> {
|
||||
const tx = new TxOperations(client, core.account.System)
|
||||
|
||||
const current = await tx.findOne(tracker.class.Team, {
|
||||
_id: tracker.team.DefaultTeam
|
||||
})
|
||||
|
||||
if (current === undefined) {
|
||||
await tx.createDoc<Team>(
|
||||
tracker.class.Team,
|
||||
core.space.Space,
|
||||
{
|
||||
name: 'Default',
|
||||
description: 'Default team',
|
||||
private: false,
|
||||
members: [],
|
||||
archived: false,
|
||||
identifier: 'TSK',
|
||||
sequence: 0
|
||||
},
|
||||
tracker.team.DefaultTeam
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
//
|
||||
// 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 type { Employee } from '@anticrm/contact'
|
||||
import contact from '@anticrm/contact'
|
||||
import { Domain, IndexKind, Markup, Ref, Timestamp } from '@anticrm/core'
|
||||
import {
|
||||
Builder,
|
||||
Collection, Hidden, Index, Model,
|
||||
Prop, TypeDate,
|
||||
TypeMarkup,
|
||||
TypeNumber,
|
||||
TypeRef,
|
||||
TypeString,
|
||||
UX
|
||||
} from '@anticrm/model'
|
||||
import attachment from '@anticrm/model-attachment'
|
||||
import chunter from '@anticrm/model-chunter'
|
||||
import core, { DOMAIN_SPACE, TDoc, TSpace } from '@anticrm/model-core'
|
||||
import { IntlString } from '@anticrm/platform'
|
||||
import { Document, Issue, IssuePriority, IssueStatus, Team } from '@anticrm/tracker'
|
||||
import tracker from './plugin'
|
||||
|
||||
import workbench from '@anticrm/model-workbench'
|
||||
|
||||
export { createDeps } from './creation'
|
||||
export { trackerOperation } from './migration'
|
||||
export { default } from './plugin'
|
||||
|
||||
export const DOMAIN_TRACKER = 'tracker' as Domain
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@Model(tracker.class.Team, core.class.Space, DOMAIN_SPACE)
|
||||
@UX(tracker.string.Team, tracker.icon.Team, tracker.string.Team)
|
||||
export class TTeam extends TSpace implements Team {
|
||||
@Prop(TypeString(), tracker.string.Title)
|
||||
@Index(IndexKind.FullText)
|
||||
reamLogo!: IntlString
|
||||
|
||||
@Prop(TypeString(), tracker.string.Identifier)
|
||||
@Index(IndexKind.FullText)
|
||||
identifier!: IntlString
|
||||
|
||||
@Prop(TypeNumber(), tracker.string.Number)
|
||||
@Hidden()
|
||||
sequence!: number
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@Model(tracker.class.Issue, core.class.Doc, DOMAIN_TRACKER)
|
||||
@UX(tracker.string.Issue, tracker.icon.Issue, tracker.string.Issue)
|
||||
export class TIssue extends TDoc implements Issue {
|
||||
@Prop(TypeString(), tracker.string.Title)
|
||||
@Index(IndexKind.FullText)
|
||||
title!: string
|
||||
|
||||
@Prop(TypeMarkup(), tracker.string.Description)
|
||||
@Index(IndexKind.FullText)
|
||||
description!: Markup
|
||||
|
||||
@Prop(TypeNumber(), tracker.string.Status)
|
||||
status!: IssueStatus
|
||||
|
||||
@Prop(TypeNumber(), tracker.string.Priority)
|
||||
priority!: IssuePriority
|
||||
|
||||
@Prop(TypeNumber(), tracker.string.Number)
|
||||
number!: number
|
||||
|
||||
@Prop(TypeRef(contact.class.Employee), tracker.string.Assignee)
|
||||
assignee!: Ref<Employee> | null
|
||||
|
||||
@Prop(TypeRef(tracker.class.Issue), tracker.string.Parent)
|
||||
parentIssue!: Ref<Issue>
|
||||
|
||||
@Prop(Collection(tracker.class.Issue), tracker.string.BlockedBy)
|
||||
blockedBy!: Ref<Issue>[]
|
||||
|
||||
@Prop(Collection(tracker.class.Issue), tracker.string.RelatedTo)
|
||||
relatedIssue!: Ref<Issue>[]
|
||||
|
||||
@Prop(Collection(chunter.class.Comment), tracker.string.Comments)
|
||||
comments!: number
|
||||
|
||||
@Prop(Collection(attachment.class.Attachment), tracker.string.Attachments)
|
||||
attachments!: number
|
||||
|
||||
// @Prop(Collection(core.class.TypeString), tracker.string.Labels)
|
||||
labels?: string[]
|
||||
|
||||
declare space: Ref<Team>
|
||||
|
||||
@Prop(TypeDate(true), tracker.string.Number)
|
||||
dueDate!: Timestamp | null
|
||||
|
||||
@Prop(TypeString(), tracker.string.Rank)
|
||||
@Hidden()
|
||||
rank!: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@Model(tracker.class.Document, core.class.Doc, DOMAIN_TRACKER)
|
||||
@UX(tracker.string.Document, tracker.icon.Document, tracker.string.Document)
|
||||
export class TDocument extends TDoc implements Document {
|
||||
@Prop(TypeString(), tracker.string.Title)
|
||||
@Index(IndexKind.FullText)
|
||||
title!: string
|
||||
|
||||
@Prop(TypeString(), tracker.string.DocumentIcon)
|
||||
icon!: string | null
|
||||
|
||||
@Prop(TypeString(), tracker.string.DocumentColor)
|
||||
color!: number
|
||||
|
||||
@Prop(TypeMarkup(), tracker.string.Description)
|
||||
@Index(IndexKind.FullText)
|
||||
content!: Markup
|
||||
|
||||
declare space: Ref<Team>
|
||||
}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createModel(
|
||||
TTeam,
|
||||
TIssue
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
workbench.class.Application,
|
||||
core.space.Model,
|
||||
{
|
||||
label: tracker.string.TrackerApplication,
|
||||
icon: tracker.icon.Issue,
|
||||
hidden: false,
|
||||
navigatorModel: {
|
||||
specials: [
|
||||
{
|
||||
id: 'inbox',
|
||||
position: 'top',
|
||||
label: tracker.string.Inbox,
|
||||
icon: tracker.icon.TrackerApplication,
|
||||
component: tracker.component.Inbox
|
||||
},
|
||||
{
|
||||
id: 'my-issues',
|
||||
position: 'top',
|
||||
label: tracker.string.MyIssues,
|
||||
icon: tracker.icon.TrackerApplication,
|
||||
component: tracker.component.MyIssues
|
||||
},
|
||||
{
|
||||
id: 'views',
|
||||
position: 'top',
|
||||
label: tracker.string.Views,
|
||||
icon: tracker.icon.TrackerApplication,
|
||||
component: tracker.component.Views
|
||||
}
|
||||
],
|
||||
spaces: [
|
||||
{
|
||||
label: tracker.string.Teams,
|
||||
spaceClass: tracker.class.Team,
|
||||
// icon: tracker.icon.TrackerApplication,
|
||||
addSpaceLabel: tracker.string.CreateTeam,
|
||||
createComponent: tracker.component.CreateTeam,
|
||||
specials: [
|
||||
{
|
||||
id: 'issues',
|
||||
label: tracker.string.Issues,
|
||||
icon: tracker.icon.TrackerApplication,
|
||||
component: tracker.component.Issues
|
||||
},
|
||||
{
|
||||
id: 'active',
|
||||
label: tracker.string.Active,
|
||||
// icon: tracker.icon.TrackerApplication,
|
||||
component: tracker.component.Active
|
||||
},
|
||||
{
|
||||
id: 'backlog',
|
||||
label: tracker.string.Backlog,
|
||||
// icon: tracker.icon.TrackerApplication,
|
||||
component: tracker.component.Backlog
|
||||
},
|
||||
{
|
||||
id: 'board',
|
||||
label: tracker.string.Board,
|
||||
// icon: tracker.icon.TrackerApplication,
|
||||
component: tracker.component.Board
|
||||
},
|
||||
{
|
||||
id: 'projects',
|
||||
label: tracker.string.Projects,
|
||||
icon: tracker.icon.TrackerApplication,
|
||||
component: tracker.component.Projects
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
navHeaderComponent: tracker.component.NewIssueHeader
|
||||
},
|
||||
tracker.app.Tracker
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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 {
|
||||
MigrateOperation, MigrationClient, MigrationUpgradeClient
|
||||
} from '@anticrm/model'
|
||||
import { createDeps } from './creation'
|
||||
|
||||
export const trackerOperation: MigrateOperation = {
|
||||
async migrate (client: MigrationClient): Promise<void> {
|
||||
},
|
||||
async upgrade (client: MigrationUpgradeClient): Promise<void> {
|
||||
await createDeps(client)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
import { Ref } from '@anticrm/core'
|
||||
import { IntlString, mergeIds } from '@anticrm/platform'
|
||||
import { Team, trackerId } from '@anticrm/tracker'
|
||||
import tracker from '@anticrm/tracker-resources/src/plugin'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
import { Application } from '@anticrm/workbench'
|
||||
|
||||
export default mergeIds(trackerId, tracker, {
|
||||
string: {
|
||||
TrackerApplication: '' as IntlString,
|
||||
Teams: '' as IntlString
|
||||
},
|
||||
team: {
|
||||
DefaultTeam: '' as Ref<Team>
|
||||
},
|
||||
component: {
|
||||
// Required to pass build without errorsF
|
||||
Nope: '' as AnyComponent
|
||||
},
|
||||
app: {
|
||||
Tracker: '' as Ref<Application>
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./node_modules/@anticrm/model-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@
|
||||
"svelte": "^3.37.0",
|
||||
"@anticrm/contact": "~0.6.5",
|
||||
"@anticrm/login": "~0.6.1",
|
||||
"@anticrm/image-cropper": "~0.6.0"
|
||||
"@anticrm/image-cropper": "~0.6.0",
|
||||
"@anticrm/client": "~0.6.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import client from '@anticrm/client'
|
||||
import contact from '@anticrm/contact'
|
||||
import core, { Client, setCurrentAccount, Version } from '@anticrm/core'
|
||||
import login from '@anticrm/login'
|
||||
import { getMetadata, getResource } from '@anticrm/platform'
|
||||
import { fetchMetadataLocalStorage, getCurrentLocation, navigate, setMetadataLocalStorage } from '@anticrm/ui'
|
||||
import presentation from './plugin'
|
||||
|
||||
export let versionError: string | undefined = ''
|
||||
|
||||
export async function connect (title: string): Promise<Client | undefined> {
|
||||
const token = fetchMetadataLocalStorage(login.metadata.LoginToken)
|
||||
const endpoint = fetchMetadataLocalStorage(login.metadata.LoginEndpoint)
|
||||
const email = fetchMetadataLocalStorage(login.metadata.LoginEmail)
|
||||
|
||||
if (token === null || endpoint === null || email === null) {
|
||||
navigate({ path: [login.component.LoginApp], query: { navigateUrl: encodeURIComponent(JSON.stringify(getCurrentLocation())) } })
|
||||
return
|
||||
}
|
||||
|
||||
const getClient = await getResource(client.function.GetClient)
|
||||
const instance = await getClient(token, endpoint)
|
||||
console.log('logging in as', email)
|
||||
|
||||
const me = await instance.findOne(contact.class.EmployeeAccount, { email })
|
||||
if (me !== undefined) {
|
||||
console.log('login: employee account', me)
|
||||
setCurrentAccount(me)
|
||||
} else {
|
||||
console.error('WARNING: no employee account found.')
|
||||
setMetadataLocalStorage(login.metadata.LoginToken, null)
|
||||
setMetadataLocalStorage(login.metadata.LoginEndpoint, null)
|
||||
setMetadataLocalStorage(login.metadata.LoginEmail, null)
|
||||
setMetadataLocalStorage(login.metadata.CurrentWorkspace, null)
|
||||
navigate({ path: [login.component.LoginApp], query: { navigateUrl: encodeURIComponent(JSON.stringify(getCurrentLocation())) } })
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('checking model version')
|
||||
const version = await instance.findOne<Version>(core.class.Version, {})
|
||||
console.log('Model version', version)
|
||||
|
||||
const requirdVersion = getMetadata(presentation.metadata.RequiredVersion)
|
||||
if (requirdVersion !== undefined) {
|
||||
console.log('checking min model version', requirdVersion)
|
||||
const versionStr = `${version?.major as number}.${version?.minor as number}.${version?.patch as number}`
|
||||
|
||||
if (version === undefined || requirdVersion !== versionStr) {
|
||||
versionError = `${versionStr} => ${requirdVersion}`
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.log(err)
|
||||
const requirdVersion = getMetadata(presentation.metadata.RequiredVersion)
|
||||
console.log('checking min model version', requirdVersion)
|
||||
if (requirdVersion !== undefined) {
|
||||
versionError = `'unknown' => ${requirdVersion}`
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
// Update window title
|
||||
document.title = [(fetchMetadataLocalStorage(login.metadata.CurrentWorkspace)), title].filter(it => it).join(' - ')
|
||||
|
||||
return instance
|
||||
}
|
||||
@@ -41,3 +41,4 @@ addStringsLoader(presentationId, async (lang: string) => {
|
||||
})
|
||||
|
||||
export { default } from './plugin'
|
||||
export { connect, versionError } from './connect'
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//
|
||||
|
||||
import { Class, Ref } from '@anticrm/core'
|
||||
import type { IntlString, Plugin } from '@anticrm/platform'
|
||||
import type { IntlString, Metadata, Plugin } from '@anticrm/platform'
|
||||
import { plugin } from '@anticrm/platform'
|
||||
import { ObjectSearchCategory } from '.'
|
||||
|
||||
@@ -40,5 +40,8 @@ export default plugin(presentationId, {
|
||||
AddSocialLinks: '' as IntlString,
|
||||
Change: '' as IntlString,
|
||||
Remove: '' as IntlString
|
||||
},
|
||||
metadata: {
|
||||
RequiredVersion: '' as Metadata<string>
|
||||
}
|
||||
})
|
||||
|
||||
@@ -272,6 +272,7 @@ p:last-child { margin-block-end: 0; }
|
||||
.ml-3 { margin-left: .75rem; }
|
||||
.ml-4 { margin-left: 1rem; }
|
||||
.ml-6 { margin-left: 1.5rem; }
|
||||
.ml-8 { margin-left: 2rem; }
|
||||
.ml-10 { margin-left: 2.5rem; }
|
||||
.mr-1 { margin-right: .25rem; }
|
||||
.mr-2 { margin-right: .5rem; }
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 1rem;
|
||||
padding: 0.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: .5rem;
|
||||
user-select: none;
|
||||
@@ -65,8 +65,7 @@
|
||||
.an-element__icon {
|
||||
min-width: 1rem;
|
||||
color: var(--theme-content-trans-color);
|
||||
margin: 0 1.125rem 0 .625rem;
|
||||
&.sub { margin: 0 .5rem 0 2.75rem }
|
||||
margin: 0 1.125rem 0 0;
|
||||
}
|
||||
.an-element__label {
|
||||
flex-grow: 1;
|
||||
|
||||
@@ -34,7 +34,9 @@
|
||||
{:then Ctor}
|
||||
<ErrorBoundary>
|
||||
<Ctor {...props} on:change on:close on:open on:click on:delete>
|
||||
<slot />
|
||||
{#if $$slots.default}
|
||||
<slot />
|
||||
{/if}
|
||||
</Ctor>
|
||||
</ErrorBoundary>
|
||||
{:catch err}
|
||||
|
||||
@@ -29,7 +29,6 @@ export default mergeIds(calendarId, calendar, {
|
||||
CreateReminder: '' as IntlString,
|
||||
EditReminder: '' as IntlString,
|
||||
ReminderTime: '' as IntlString,
|
||||
Reminders: '' as IntlString,
|
||||
ModeDay: '' as IntlString,
|
||||
ModeWeek: '' as IntlString,
|
||||
ModeMonth: '' as IntlString,
|
||||
|
||||
@@ -99,7 +99,8 @@ const calendarPlugin = plugin(calendarId, {
|
||||
Participants: '' as IntlString,
|
||||
NoParticipants: '' as IntlString,
|
||||
PersonsLabel: '' as IntlString,
|
||||
EventNumber: '' as IntlString
|
||||
EventNumber: '' as IntlString,
|
||||
Reminders: '' as IntlString
|
||||
},
|
||||
ids: {
|
||||
ReminderNotification: '' as Ref<NotificationType>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@anticrm/platform-rig/profiles/default/config/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||
<symbol id="tracker" viewBox="0 0 24 24">
|
||||
<g>
|
||||
<path d="M21.4,3.1c-0.2-0.2-0.6-0.2-0.8,0L11.1,13l-2.3-2.4c-0.2-0.2-0.6-0.2-0.8,0s-0.2,0.6,0,0.8l2.7,2.8 c0.1,0.1,0.3,0.2,0.4,0.2s0.3-0.1,0.4-0.2l9.9-10.4C21.7,3.7,21.7,3.3,21.4,3.1z"/>
|
||||
<path d="M19.2,11.4c-0.3,0-0.6,0.3-0.6,0.6v6.6c0,0.7-0.5,1.3-1.2,1.3H4.8c-0.7,0-1.2-0.6-1.2-1.3V5.4 c0-0.7,0.5-1.3,1.2-1.3h9.9c0.3,0,0.6-0.3,0.6-0.6S15,2.9,14.7,2.9H4.8C3.5,2.9,2.4,4,2.4,5.4v13.2c0,1.4,1.1,2.5,2.4,2.5h12.6 c1.3,0,2.4-1.1,2.4-2.5V12C19.8,11.7,19.5,11.4,19.2,11.4z"/>
|
||||
</g>
|
||||
</symbol>
|
||||
<symbol id="project" viewBox="0 0 16 16">
|
||||
<path d="M11.7,3.6h-1.1C10.4,2.7,9.7,2,8.8,2H7.2C6.3,2,5.6,2.7,5.4,3.6H4.3C3,3.6,2,4.6,2,5.9V8c0,0.2,0.1,0.3,0.2,0.4 C3.8,9.3,5.9,9.9,8,9.9c2.1,0,4.2-0.5,5.8-1.5C13.9,8.3,14,8.2,14,8V5.9C14,4.6,13,3.6,11.7,3.6z M7.2,3h1.5c0.4,0,0.6,0.2,0.8,0.6 H6.5C6.6,3.2,6.9,3,7.2,3z M13,7.7c-1.4,0.8-3.2,1.2-5,1.2c-1.8,0-3.6-0.4-5-1.2V5.9c0-0.7,0.6-1.3,1.3-1.3h7.4 c0.7,0,1.3,0.6,1.3,1.3V7.7z"/>
|
||||
<path d="M13.5,9.7c-0.3,0-0.5,0.2-0.5,0.5l-0.1,1.5c-0.1,0.8-0.7,1.3-1.4,1.3H4.5c-0.7,0-1.4-0.6-1.4-1.3L3,10.1 c0-0.3-0.3-0.5-0.5-0.5C2.2,9.7,2,9.9,2,10.2l0.1,1.5C2.2,13,3.3,14,4.5,14h6.9c1.3,0,2.3-1,2.4-2.3l0.1-1.5 C14,9.9,13.8,9.7,13.5,9.7z"/>
|
||||
</symbol>
|
||||
<symbol id="issue" viewBox="0 0 16 16">
|
||||
<path d="M13.3,8.3c-0.1,2.8-2.5,5.1-5.4,5.1C5,13.4,2.6,11,2.6,8c0-2.9,2.3-5.2,5.1-5.4c0.1-0.4,0.2-0.7,0.4-1c0,0-0.1,0-0.1,0 C4.4,1.7,1.6,4.5,1.6,8c0,3.5,2.9,6.4,6.4,6.4s6.4-2.9,6.4-6.4c0,0,0-0.1,0-0.1C14,8.1,13.7,8.2,13.3,8.3z"/>
|
||||
<ellipse cx="12.1" cy="3.9" rx="2.5" ry="2.5"/>
|
||||
</symbol>
|
||||
<symbol id="team" viewBox="0 0 24 24">
|
||||
<path d="M13,1h-2.2H9.4H6.6H5.2H3C1.9,1,1,1.9,1,3v10c0,1.1,0.9,2,2,2h2.2h1.4h2.8h1.4H13c1.1,0,2-0.9,2-2V3C15,1.9,14.1,1,13,1z M3,13.8c-0.4,0-0.8-0.4-0.8-0.8V3c0-0.4,0.4-0.8,0.8-0.8h2.2v11.6H3z M6.6,13.8V2.2h2.8v11.6H6.6z M13.8,13c0,0.4-0.4,0.8-0.8,0.8 h-2.2V2.2H13c0.4,0,0.8,0.4,0.8,0.8V13z"/>
|
||||
</symbol>
|
||||
<symbol id="document" viewBox="0 0 16 16">
|
||||
<path d="M8,14.5c-3.6,0-6.5-2.9-6.5-6.5S4.4,1.5,8,1.5s6.5,2.9,6.5,6.5S11.6,14.5,8,14.5z M8,2.5C5,2.5,2.5,5,2.5,8 c0,3,2.5,5.5,5.5,5.5c3,0,5.5-2.5,5.5-5.5C13.5,5,11,2.5,8,2.5z"/>
|
||||
<polygon points="7.4,10.7 5,8.4 5.7,7.6 7.3,9.3 10.3,5.7 11,6.3 "/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -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"
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"string": {
|
||||
"TrackerApplication": "Tracker",
|
||||
"Teams": "Your teams",
|
||||
"More": "More",
|
||||
"Delete": "Delete",
|
||||
"Open": "Open",
|
||||
"Members": "Members",
|
||||
"Inbox": "Inbox",
|
||||
"MyIssues": "My issues",
|
||||
"Issues": "Issues",
|
||||
"Views": "Views",
|
||||
"Active": "Active",
|
||||
"Backlog": "Backlog",
|
||||
"Board": "Board",
|
||||
"Projects": "Projects",
|
||||
"CreateTeam": "Create team",
|
||||
"NewIssue": "New issue",
|
||||
|
||||
"Title": "Title",
|
||||
"Description": "",
|
||||
"Status": "",
|
||||
"Priority": "",
|
||||
"Number": "",
|
||||
"Assignee": "",
|
||||
"Parent": "",
|
||||
"BlockedBy": "",
|
||||
"RelatedTo": "",
|
||||
"Comments": "",
|
||||
"Attachments": "",
|
||||
"Labels": "",
|
||||
"Space": "",
|
||||
"DueDate": "",
|
||||
"Team": "",
|
||||
"Issue": "",
|
||||
"Document": "",
|
||||
"DocumentIcon": "",
|
||||
"DocumentColor": "",
|
||||
"Rank": "",
|
||||
"IssueTitlePlaceholder": "Issue title",
|
||||
"IssueDescriptionPlaceholder": "Add description"
|
||||
},
|
||||
"status": {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"string": {
|
||||
"TrackerApplication": "Tracker",
|
||||
"Teams": "Your teams",
|
||||
"More": "More",
|
||||
"Delete": "Delete",
|
||||
"Open": "Open",
|
||||
"Members": "Members",
|
||||
"Inbox": "Inbox",
|
||||
"MyIssues": "My issues",
|
||||
"Issues": "Issues",
|
||||
"Views": "Views",
|
||||
"Active": "Active",
|
||||
"Backlog": "Backlog",
|
||||
"Board": "Board",
|
||||
"Projects": "Projects",
|
||||
"CreateTeam": "Create team"
|
||||
},
|
||||
"status": {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "@anticrm/tracker-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.11.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anticrm/platform": "~0.6.5",
|
||||
"@anticrm/tracker": "~0.6.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// 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 { loadMetadata, addStringsLoader } from '@anticrm/platform'
|
||||
import tracker, { trackerId } from '@anticrm/tracker'
|
||||
|
||||
const icons = require('../assets/icons.svg') as string // eslint-disable-line
|
||||
loadMetadata(tracker.icon, {
|
||||
TrackerApplication: `${icons}#tracker`,
|
||||
Project: `${icons}#project`,
|
||||
Issue: `${icons}#issue`,
|
||||
Team: `${icons}#team`,
|
||||
Document: `${icons}#document`
|
||||
})
|
||||
|
||||
addStringsLoader(trackerId, async (lang: string) => await import(`../lang/${lang}.json`))
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"declaration": true,
|
||||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 957 B |
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "@anticrm/tracker-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": "eslint",
|
||||
"lint:fix": "eslint --fix src",
|
||||
"format": "prettier --write --plugin-search-dir=. src && eslint --fix src"
|
||||
},
|
||||
"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": {
|
||||
"svelte": "^3.37.0",
|
||||
"@anticrm/platform": "~0.6.5",
|
||||
"@anticrm/core": "~0.6.16",
|
||||
"@anticrm/client": "~0.6.1",
|
||||
"@anticrm/tracker": "~0.6.0",
|
||||
"@anticrm/ui": "~0.6.0",
|
||||
"@anticrm/view": "~0.6.0",
|
||||
"@anticrm/presentation": "~0.6.2",
|
||||
"@anticrm/login": "~0.6.1",
|
||||
"@anticrm/setting": "~0.6.0",
|
||||
"@anticrm/calendar": "~0.6.0",
|
||||
"@anticrm/task": "~0.6.0",
|
||||
"@anticrm/chunter": "~0.6.0",
|
||||
"@anticrm/notification": "~0.6.0",
|
||||
"@anticrm/notification-resources": "~0.6.0",
|
||||
"@anticrm/contact": "~0.6.5",
|
||||
"@anticrm/view-resources": "~0.6.0",
|
||||
"lexorank": "~1.0.4",
|
||||
"@anticrm/text-editor": "~0.6.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('autoprefixer')
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<!--
|
||||
// Copyright © 2020 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import contact, { Employee, EmployeeAccount, formatName } from '@anticrm/contact'
|
||||
import { getCurrentAccount } from '@anticrm/core'
|
||||
import login from '@anticrm/login'
|
||||
import { Avatar, createQuery } from '@anticrm/presentation'
|
||||
import setting, { SettingsCategory } from '@anticrm/setting'
|
||||
import { closePopup, getCurrentLocation, Icon, Label, navigate, setMetadataLocalStorage } from '@anticrm/ui'
|
||||
|
||||
// const client = getClient()
|
||||
async function getItems (): Promise<SettingsCategory[]> {
|
||||
return []
|
||||
}
|
||||
|
||||
const account = getCurrentAccount() as EmployeeAccount
|
||||
let employee: Employee | undefined
|
||||
const employeeQ = createQuery()
|
||||
|
||||
employeeQ.query(contact.class.Employee, {
|
||||
_id: account.employee
|
||||
}, (res) => {
|
||||
employee = res[0]
|
||||
}, { limit: 1 })
|
||||
|
||||
|
||||
function selectCategory (sp: SettingsCategory): void {
|
||||
closePopup()
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = setting.ids.SettingApp
|
||||
loc.path[2] = sp.name
|
||||
loc.path.length = 3
|
||||
navigate(loc)
|
||||
}
|
||||
|
||||
function signOut (): void {
|
||||
setMetadataLocalStorage(login.metadata.LoginToken, null)
|
||||
setMetadataLocalStorage(login.metadata.LoginEndpoint, null)
|
||||
setMetadataLocalStorage(login.metadata.LoginEmail, null)
|
||||
setMetadataLocalStorage(login.metadata.CurrentWorkspace, null)
|
||||
navigate({ path: [login.component.LoginApp] })
|
||||
}
|
||||
|
||||
function selectWorkspace (): void {
|
||||
navigate({ path: [login.component.LoginApp, 'selectWorkspace'] })
|
||||
}
|
||||
|
||||
function filterItems (items: SettingsCategory[]): SettingsCategory[] {
|
||||
return items?.filter((p) => p.name !== 'profile' && p.name !== 'password')
|
||||
}
|
||||
|
||||
function editProfile (items: SettingsCategory[] | undefined): void {
|
||||
const profile = items?.find((p) => p.name === 'profile')
|
||||
if (profile === undefined) return
|
||||
selectCategory(profile)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="antiPopup">
|
||||
<div class="ap-space" />
|
||||
<div class="ap-scroll"><div class="ap-box">
|
||||
{#await getItems() then items}
|
||||
<div class="ap-menuItem flex-row-center" on:click={() => { editProfile(items) }}>
|
||||
{#if employee}
|
||||
<Avatar avatar={employee.avatar} size={'medium'} />
|
||||
{/if}
|
||||
<div class="ml-2 flex-col">
|
||||
{#if account}
|
||||
<div class="overflow-label fs-bold caption-color">{formatName(account.name)}</div>
|
||||
<div class="overflow-label text-sm content-dark-color">{account.email}</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if items}
|
||||
{#each filterItems(items) as item }
|
||||
<button class="ap-menuItem" on:click={() => selectCategory(item)}>
|
||||
<div class='mr-2'>
|
||||
<Icon icon={item.icon} size={'small'}/>
|
||||
</div>
|
||||
<Label label={item.label} />
|
||||
</button>
|
||||
{/each}
|
||||
{/if}
|
||||
<button class="ap-menuItem" on:click={selectWorkspace}>
|
||||
<div class='mr-2'>
|
||||
<Icon icon={setting.icon.SelectWorkspace} size={'small'}/>
|
||||
</div>
|
||||
<Label label={setting.string.SelectWorkspace} />
|
||||
</button>
|
||||
<button class="ap-menuItem" on:click={signOut}>
|
||||
<div class='mr-2'>
|
||||
<Icon icon={setting.icon.Signout} size={'small'}/>
|
||||
</div>
|
||||
<Label label={setting.string.Signout} />
|
||||
</button>
|
||||
{/await}
|
||||
</div></div>
|
||||
<div class="ap-space" />
|
||||
</div>
|
||||
@@ -0,0 +1,80 @@
|
||||
<!--
|
||||
// Copyright © 2020 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type { IntlString, Asset } from '@anticrm/platform'
|
||||
import type { AnySvelteComponent } from '@anticrm/ui'
|
||||
import { Icon, Tooltip } from '@anticrm/ui'
|
||||
|
||||
export let label: IntlString
|
||||
export let icon: Asset | AnySvelteComponent
|
||||
export let action: () => Promise<void>
|
||||
export let selected: boolean
|
||||
export let notify: boolean
|
||||
</script>
|
||||
|
||||
<Tooltip {label}>
|
||||
<button class="app" id={'app-' + label} class:selected={selected} on:click|stopPropagation={action}>
|
||||
<div class="flex-center icon-container" class:noty={notify}>
|
||||
<Icon icon={icon} size={'large'}/>
|
||||
</div>
|
||||
{#if notify}<div class="marker"/>{/if}
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<style lang="scss">
|
||||
.app {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
width: 3.25rem;
|
||||
height: 3.25rem;
|
||||
background-color: transparent;
|
||||
border: 1px solid transparent;
|
||||
border-radius: .5rem;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
|
||||
.icon-container {
|
||||
width: 3.25rem;
|
||||
height: 3.25rem;
|
||||
color: var(--theme-content-trans-color);
|
||||
|
||||
.normal-font &.noty { clip-path: url(#notify-normal); }
|
||||
.small-font &.noty { clip-path: url(#notify-small); }
|
||||
}
|
||||
|
||||
&:hover .icon-container { color: var(--theme-caption-color); }
|
||||
&:focus {
|
||||
border: 1px solid var(--primary-button-focused-border);
|
||||
box-shadow: 0 0 0 3px var(--primary-button-outline);
|
||||
.icon-container { color: var(--theme-caption-color); }
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: var(--theme-menu-selection);
|
||||
.icon-container { color: var(--theme-caption-color); }
|
||||
}
|
||||
}
|
||||
|
||||
.marker {
|
||||
position: absolute;
|
||||
top: .75rem;
|
||||
right: .75rem;
|
||||
width: .5rem;
|
||||
height: .5rem;
|
||||
border-radius: 50%;
|
||||
background-color: var(--highlight-red);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,63 @@
|
||||
<!--
|
||||
// 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 type { IntlString } from '@anticrm/platform'
|
||||
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import type { Ref, Class, Space, DocumentQuery } from '@anticrm/core'
|
||||
|
||||
import { Button, Label } from '@anticrm/ui'
|
||||
import SpaceSelect from './SpaceSelect.svelte'
|
||||
import presentation from '@anticrm/presentation'
|
||||
|
||||
export let spaceClass: Ref<Class<Space>> | undefined = undefined
|
||||
export let space: Ref<Space> | undefined = undefined
|
||||
export let spaceQuery: DocumentQuery<Space> | undefined = { archived: false }
|
||||
export let spaceLabel: IntlString | undefined = undefined
|
||||
export let spacePlaceholder: IntlString | undefined = undefined
|
||||
export let label: IntlString
|
||||
export let labelProps: any | undefined = undefined
|
||||
export let okAction: () => void
|
||||
export let canSave: boolean = false
|
||||
|
||||
export let okLabel: IntlString = presentation.string.Create
|
||||
export let cancelLabel: IntlString = presentation.string.Cancel
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
<form class="antiCard w-165" on:submit|preventDefault={ () => {} }>
|
||||
<div class="antiCard-header">
|
||||
<div class="antiCard-header__title"><Label {label} params={labelProps ?? {}} /></div>
|
||||
{#if $$slots.error}
|
||||
<div class="antiCard-header__error">
|
||||
<slot name="error" />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="antiCard-content"><slot /></div>
|
||||
{#if spaceClass && spaceLabel && spacePlaceholder}
|
||||
<div class="antiCard-pool">
|
||||
<div class="antiCard-pool__separator" />
|
||||
<SpaceSelect _class={spaceClass} spaceQuery={spaceQuery} label={spaceLabel} placeholder={spacePlaceholder} bind:value={space} />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="antiCard-footer">
|
||||
<Button disabled={!canSave} label={okLabel} size={'small'} transparent primary on:click={() => { okAction(); dispatch('close') }} />
|
||||
<Button label={cancelLabel} size={'small'} transparent on:click={() => { dispatch('close') }} />
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,121 @@
|
||||
<!--
|
||||
// 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.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { Employee } from '@anticrm/contact'
|
||||
import core, { Data, generateId, Ref, SortingOrder } from '@anticrm/core'
|
||||
import { OK, Status } from '@anticrm/platform'
|
||||
import { getClient, UserBox } from '@anticrm/presentation'
|
||||
import { Issue, IssuePriority, IssueStatus, Team } from '@anticrm/tracker'
|
||||
import { StyledTextBox } from '@anticrm/text-editor'
|
||||
import { EditBox, Grid, Status as StatusControl } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import tracker from '../plugin'
|
||||
import { calcRank } from '../utils'
|
||||
import Card from './Card.svelte';
|
||||
|
||||
export let space: Ref<Team>
|
||||
export let parent: Ref<Issue> | undefined
|
||||
|
||||
$: _space = space
|
||||
$: _parent = parent
|
||||
const status: Status = OK
|
||||
|
||||
let assignee: Ref<Employee> | null = null
|
||||
|
||||
const object: Data<Issue> = {
|
||||
title: '',
|
||||
description: '',
|
||||
assignee: null,
|
||||
number: 0,
|
||||
rank: '',
|
||||
status: IssueStatus.Backlog,
|
||||
priority: IssuePriority.NoPriority,
|
||||
dueDate: null,
|
||||
comments: 0
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
const taskId: Ref<Issue> = generateId()
|
||||
|
||||
export function canClose (): boolean {
|
||||
return object.title !== ''
|
||||
}
|
||||
|
||||
async function createIssue () {
|
||||
const lastOne = await client.findOne<Issue>(
|
||||
tracker.class.Issue,
|
||||
{ status: object.status },
|
||||
{ sort: { rank: SortingOrder.Descending } }
|
||||
)
|
||||
const incResult = await client.updateDoc(
|
||||
tracker.class.Team,
|
||||
core.space.Space,
|
||||
_space,
|
||||
{
|
||||
$inc: { sequence: 1 }
|
||||
},
|
||||
true
|
||||
)
|
||||
|
||||
const value: Data<Issue> = {
|
||||
title: object.title,
|
||||
description: object.description,
|
||||
assignee,
|
||||
number: (incResult as any).object.sequence,
|
||||
status: object.status,
|
||||
priority: object.priority,
|
||||
rank: calcRank(lastOne, undefined),
|
||||
parentIssue: _parent,
|
||||
comments: 0,
|
||||
dueDate: object.dueDate
|
||||
}
|
||||
|
||||
await client.createDoc(tracker.class.Issue, _space, value, taskId)
|
||||
}
|
||||
</script>
|
||||
|
||||
<Card
|
||||
label={tracker.string.NewIssue}
|
||||
okAction={createIssue}
|
||||
canSave={object.title.length > 0 && _space != null}
|
||||
spaceClass={tracker.class.Team}
|
||||
spaceLabel={tracker.string.Team}
|
||||
spacePlaceholder={tracker.string.SelectTeam}
|
||||
bind:space={_space}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<StatusControl slot="error" {status} />
|
||||
<Grid column={1} rowGap={1.5}>
|
||||
<EditBox
|
||||
label={tracker.string.Title}
|
||||
bind:value={object.title}
|
||||
placeholder={tracker.string.IssueTitlePlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<StyledTextBox alwaysEdit bind:content={object.description} placeholder={tracker.string.IssueDescriptionPlaceholder}/>
|
||||
<UserBox
|
||||
_class={contact.class.Employee}
|
||||
title={tracker.string.Assignee}
|
||||
caption={tracker.string.Assignee}
|
||||
bind:value={assignee}
|
||||
allowDeselect
|
||||
titleDeselect={tracker.string.TaskUnAssign}
|
||||
/>
|
||||
</Grid>
|
||||
</Card>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { Ref, Space } from '@anticrm/core'
|
||||
import ui, { ActionIcon, Button, IconEdit, IconSearch, showPopup } from '@anticrm/ui'
|
||||
import tracker from '../plugin'
|
||||
import CreateIssue from './CreateIssue.svelte'
|
||||
export let currentSpace: Ref<Space>
|
||||
|
||||
async function newIssue(target: EventTarget | null): Promise<void> {
|
||||
showPopup(CreateIssue, { space: currentSpace }, target as HTMLElement)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex-between mt-4 mb-4">
|
||||
<div class="flex-grow">
|
||||
<Button
|
||||
icon={IconEdit}
|
||||
label={tracker.string.NewIssue}
|
||||
width={'100%'}
|
||||
size={'small'}
|
||||
on:click={(evt) => newIssue(evt.currentTarget)}
|
||||
/>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
<ActionIcon icon={IconSearch} label={ui.string.Search} action={async () => {}} size={'large'} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,43 @@
|
||||
<!--
|
||||
// Copyright © 2020 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { IconFolder } from '@anticrm/ui'
|
||||
|
||||
import type { Space } from '@anticrm/core'
|
||||
|
||||
export let value: Space
|
||||
export let subtitle: string | undefined = undefined
|
||||
export let size: 'medium' | 'large'
|
||||
</script>
|
||||
|
||||
<div class="flex-row-center">
|
||||
<div class="flex-center {size} caption-color flex-no-shrink"><IconFolder size={'small'} /></div>
|
||||
<div class="flex-col ml-2 min-w-0">
|
||||
{#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if}
|
||||
<div class="content-accent-color overflow-label">{value.name}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.medium {
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
}
|
||||
.large {
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,79 @@
|
||||
<!--
|
||||
// Copyright © 2020 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { Class, DocumentQuery, Ref, Space } from '@anticrm/core'
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import { IconFolder, Label, showPopup } from '@anticrm/ui'
|
||||
import { onMount } from 'svelte'
|
||||
import SpacesPopup from './SpacesPopup.svelte'
|
||||
|
||||
export let _class: Ref<Class<Space>>
|
||||
export let spaceQuery: DocumentQuery<Space> | undefined = { archived: false }
|
||||
export let label: IntlString
|
||||
export let placeholder: IntlString
|
||||
export let value: Ref<Space> | undefined
|
||||
export let show: boolean = false
|
||||
|
||||
let selected: Space | undefined
|
||||
let btn: HTMLElement
|
||||
|
||||
const client = getClient()
|
||||
|
||||
async function updateSelected (value: Ref<Space> | undefined) {
|
||||
selected = value !== undefined ? await client.findOne(_class, { ...(spaceQuery ?? {}), _id: value }) : undefined
|
||||
}
|
||||
|
||||
$: updateSelected(value)
|
||||
|
||||
onMount(() => {
|
||||
if (btn && show) {
|
||||
btn.click()
|
||||
show = false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex-col cursor-pointer"
|
||||
bind:this={btn}
|
||||
on:click|preventDefault={() => {
|
||||
showPopup(SpacesPopup, { _class, spaceQuery }, btn, (result) => {
|
||||
if (result) {
|
||||
value = result._id
|
||||
}
|
||||
})
|
||||
}}
|
||||
>
|
||||
<div class="overflow-label label"><Label {label} /></div>
|
||||
<div class="flex-row-center space">
|
||||
<span class="mr-1"><IconFolder size={'small'} /></span>
|
||||
<span class="overflow-label" class:caption-color={selected} class:content-dark-color={!selected}>
|
||||
{#if selected}
|
||||
{selected.name}
|
||||
{:else}
|
||||
<Label label={placeholder} />
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.label {
|
||||
margin-bottom: .125rem;
|
||||
font-weight: 500;
|
||||
font-size: .75rem;
|
||||
color: var(--theme-content-accent-color);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,53 @@
|
||||
<!--
|
||||
// Copyright © 2020 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { afterUpdate, createEventDispatcher } from 'svelte'
|
||||
|
||||
import ui, { Label, EditWithIcon, IconSearch } from '@anticrm/ui'
|
||||
import SpaceInfo from './SpaceInfo.svelte'
|
||||
|
||||
import type { Ref, Class, Space, DocumentQuery } from '@anticrm/core'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
|
||||
export let _class: Ref<Class<Space>>
|
||||
export let spaceQuery: DocumentQuery<Space> | undefined
|
||||
|
||||
let search: string = ''
|
||||
let objects: Space[] = []
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const query = createQuery()
|
||||
$: query.query(_class, { ...(spaceQuery ?? {}), name: { $like: '%' + search + '%' } }, result => { objects = result })
|
||||
afterUpdate(() => { dispatch('update', Date.now()) })
|
||||
</script>
|
||||
|
||||
<div class="antiPopup antiPopup-withHeader">
|
||||
<div class="ap-space" />
|
||||
<div class="ap-header">
|
||||
<EditWithIcon icon={IconSearch} bind:value={search} placeholder={ui.string.SearchDots} focus />
|
||||
<div class="ap-caption"><Label label={ui.string.Suggested} /></div>
|
||||
</div>
|
||||
<div class="ap-space" />
|
||||
<div class="ap-scroll">
|
||||
<div class="ap-box">
|
||||
{#each objects as space}
|
||||
<button class="ap-menuItem" on:click={() => { dispatch('close', space) }}>
|
||||
<SpaceInfo size={'large'} value={space} />
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ap-space" />
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
export let size: 'small' | 'medium' | 'large'
|
||||
const fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="6.4,14.4 5.6,13.6 11.3,8 5.6,2.4 6.4,1.6 12.7,8 "/>
|
||||
</svg>
|
||||
@@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
export let size: 'small' | 'medium' | 'large'
|
||||
const fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="8,11.7 1.6,5.4 2.4,4.6 8,10.3 13.6,4.6 14.4,5.4 "/>
|
||||
</svg>
|
||||
@@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
export let size: 'small' | 'medium' | 'large'
|
||||
const fill: string = 'var(--theme-caption-color)'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.5,8c0-1.4-0.4-2.7-1.2-3.8c-0.8-1.1-1.9-1.9-3.2-2.4c-1.3-0.4-2.7-0.5-4-0.1C4.8,2.2,3.7,3,2.8,4C2,5.1,1.5,6.4,1.5,7.8 c0,1.4,0.3,2.7,1.1,3.8c0.8,1.1,1.8,2,3.1,2.5c0.7,0.3,1.5,0.4,2.3,0.4c0.6,0,1.1-0.1,1.7-0.2c0.3-0.1,0.4-0.3,0.4-0.6 c-0.1-0.3-0.3-0.4-0.6-0.4c-1.1,0.3-2.3,0.2-3.4-0.2c-1.1-0.4-2-1.1-2.6-2.1c-0.6-1-1-2.1-0.9-3.2c0-1.2,0.4-2.3,1.1-3.2 c0.7-0.9,1.7-1.6,2.8-1.9c1.1-0.3,2.3-0.3,3.4,0.1c1.1,0.4,2,1.1,2.7,2c0.7,0.9,1,2,1,3.2c0,0,0,0,0,0v1c0,0.6-0.5,1.2-1.2,1.2 c-0.6,0-1.2-0.5-1.2-1.2V8c0,0,0,0,0,0s0,0,0,0V6c0-0.3-0.2-0.5-0.5-0.5c-0.2,0-0.3,0.1-0.4,0.3C9.7,5.2,8.9,4.8,8,4.8 C6.3,4.8,4.8,6.3,4.8,8s1.4,3.2,3.2,3.2c1,0,1.8-0.5,2.4-1.2c0.4,0.7,1.1,1.2,1.9,1.2c1.2,0,2.2-1,2.2-2.2L14.5,8 C14.5,8,14.5,8,14.5,8z M8,10.2c-1.2,0-2.2-1-2.2-2.2c0-1.2,1-2.2,2.2-2.2c1.2,0,2.2,1,2.2,2.2v0C10.2,9.2,9.2,10.2,8,10.2z"/>
|
||||
</svg>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
export let size: 'small' | 'medium' | 'large'
|
||||
const fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3,9.6h18c0.3,0,0.6-0.3,0.6-0.6S21.3,8.4,21,8.4H3C2.7,8.4,2.4,8.7,2.4,9S2.7,9.6,3,9.6z"/>
|
||||
<path d="M21,14.4H3c-0.3,0-0.6,0.3-0.6,0.6s0.3,0.6,0.6,0.6h18c0.3,0,0.6-0.3,0.6-0.6S21.3,14.4,21,14.4z"/>
|
||||
</svg>
|
||||
@@ -0,0 +1 @@
|
||||
Some inbox stuff here.
|
||||
@@ -0,0 +1,12 @@
|
||||
<script lang='ts'>
|
||||
import { Ref } from '@anticrm/core'
|
||||
import { IssueStatus, Team } from '@anticrm/tracker'
|
||||
import Issues from './Issues.svelte'
|
||||
export let currentSpace: Ref<Team>
|
||||
|
||||
let todalIssues = 0
|
||||
</script>
|
||||
<div class='fs-title'>
|
||||
Active issues {todalIssues}
|
||||
</div>
|
||||
<Issues currentSpace={currentSpace} categories={[IssueStatus.InProgress, IssueStatus.Todo]} on:content={(evt) => { todalIssues = evt.detail.length } }></Issues>
|
||||
@@ -0,0 +1,7 @@
|
||||
<script lang='ts'>
|
||||
import { Ref } from '@anticrm/core'
|
||||
import { IssueStatus, Team } from '@anticrm/tracker'
|
||||
import Issues from './Issues.svelte'
|
||||
export let currentSpace: Ref<Team>
|
||||
</script>
|
||||
<Issues {currentSpace} categories={[IssueStatus.Backlog]}></Issues>
|
||||
@@ -0,0 +1,52 @@
|
||||
<script lang="ts">
|
||||
import { DocumentQuery, FindOptions } from '@anticrm/core'
|
||||
import { Issue, IssueStatus, Team } from '@anticrm/tracker'
|
||||
import { Scroller } from '@anticrm/ui'
|
||||
import { Table } from '@anticrm/view-resources'
|
||||
import tracker from '../../plugin'
|
||||
import contact from '@anticrm/contact'
|
||||
|
||||
export let query: DocumentQuery<Issue>
|
||||
export let category: IssueStatus
|
||||
export let currentTeam: Team
|
||||
|
||||
const options: FindOptions<Issue> = {
|
||||
lookup: {
|
||||
assignee: contact.class.Employee
|
||||
}
|
||||
}
|
||||
|
||||
let visible = false
|
||||
</script>
|
||||
|
||||
<div class='category' class:visible={visible}>
|
||||
<div class='fs-title'>
|
||||
{IssueStatus[category]}
|
||||
</div>
|
||||
<Scroller>
|
||||
<Table
|
||||
_class={tracker.class.Issue}
|
||||
config={[
|
||||
{ key: '', presenter: tracker.component.IssuePresenter, props: { currentTeam }, label: tracker.string.Issue },
|
||||
'title',
|
||||
// 'status',
|
||||
'$lookup.assignee',
|
||||
'modifiedOn'
|
||||
]}
|
||||
options={options}
|
||||
query={{ ...query, status: category }}
|
||||
showNotification
|
||||
highlightRows
|
||||
on:content={(evt) => { visible = evt.detail.length > 0 }}
|
||||
/>
|
||||
</Scroller>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.category {
|
||||
display: none;
|
||||
&.visible {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,81 @@
|
||||
<!--
|
||||
// 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 contact from '@anticrm/contact'
|
||||
import { getClient, UserBox } from '@anticrm/presentation'
|
||||
import type { Issue } from '@anticrm/tracker'
|
||||
import { StyledTextBox } from '@anticrm/text-editor'
|
||||
import { EditBox, Grid } from '@anticrm/ui'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import tracker from '../../plugin'
|
||||
import Card from '../Card.svelte'
|
||||
|
||||
export let object: Issue
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
|
||||
function change (field: string, value: any) {
|
||||
client.update(object, { [field]: value })
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
dispatch('open', { ignoreKeys: ['comments', 'name', 'description', 'number'] })
|
||||
})
|
||||
</script>
|
||||
|
||||
<Card
|
||||
label={tracker.string.NewIssue}
|
||||
okAction={() => {}}
|
||||
canSave={true}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
{#if object !== undefined}
|
||||
<Grid column={1} rowGap={1.5}>
|
||||
<EditBox
|
||||
label={tracker.string.Title}
|
||||
bind:value={object.title}
|
||||
placeholder={tracker.string.IssueTitlePlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
on:change={() => change('title', object.title) }
|
||||
/>
|
||||
<StyledTextBox alwaysEdit bind:content={object.description} placeholder={tracker.string.IssueDescriptionPlaceholder}
|
||||
on:change={() => change('description', object.description) }/>
|
||||
<UserBox
|
||||
_class={contact.class.Employee}
|
||||
title={tracker.string.Assignee}
|
||||
caption={tracker.string.Assignee}
|
||||
bind:value={object.assignee}
|
||||
allowDeselect
|
||||
titleDeselect={tracker.string.TaskUnAssign}
|
||||
on:change={() => change('assignee', object.assignee) }
|
||||
/>
|
||||
</Grid>
|
||||
{/if}
|
||||
</Card>
|
||||
<style lang="scss">
|
||||
.description {
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
height: 12rem;
|
||||
border-radius: .25rem;
|
||||
background-color: var(--theme-bg-accent-color);
|
||||
border: 1px solid var(--theme-bg-accent-color);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,45 @@
|
||||
<!--
|
||||
// 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 { getClient } from '@anticrm/presentation'
|
||||
import type { Issue, Team } from '@anticrm/tracker'
|
||||
import { Icon, showPopup } from '@anticrm/ui'
|
||||
import tracker from '../../plugin'
|
||||
|
||||
export let value: Issue
|
||||
export let currentTeam: Team
|
||||
export let inline: boolean = false
|
||||
|
||||
const client = getClient()
|
||||
const shortLabel = client.getHierarchy().getClass(value._class).shortLabel
|
||||
|
||||
function show (evt: Event) {
|
||||
showPopup(tracker.component.EditIssue, { object: value }, evt.currentTarget)
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if value && shortLabel}
|
||||
<div
|
||||
class="flex-presenter"
|
||||
class:inline-presenter={inline}
|
||||
on:click={show}
|
||||
>
|
||||
<div class="icon">
|
||||
<Icon icon={tracker.icon.Issue} size={'small'} />
|
||||
</div>
|
||||
<span class="label nowrap">{currentTeam.identifier}-{value.number}</span>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -0,0 +1,55 @@
|
||||
<!--
|
||||
// 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.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { DocumentQuery, Ref } from '@anticrm/core'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
import { Issue, IssueStatus, Team } from '@anticrm/tracker'
|
||||
import { ScrollBox } from '@anticrm/ui'
|
||||
import CategoryPresenter from './CategoryPresenter.svelte'
|
||||
import tracker from '../../plugin'
|
||||
|
||||
export let currentSpace: Ref<Team>
|
||||
export let categories = [
|
||||
IssueStatus.InProgress,
|
||||
IssueStatus.Todo,
|
||||
IssueStatus.Backlog,
|
||||
IssueStatus.Done,
|
||||
IssueStatus.Canceled
|
||||
]
|
||||
|
||||
export let query: DocumentQuery<Issue> = {}
|
||||
export let search: string = ''
|
||||
|
||||
$: resultQuery =
|
||||
search === '' ? { space: currentSpace, ...query } : { $search: search, space: currentSpace, ...query }
|
||||
|
||||
const spaceQuery = createQuery()
|
||||
|
||||
let currentTeam: Team | undefined
|
||||
|
||||
$: spaceQuery.query(tracker.class.Team, { _id: currentSpace }, (res) => {
|
||||
currentTeam = res.shift()
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if currentTeam}
|
||||
<ScrollBox vertical stretch>
|
||||
<div class="ml-4 mt-4">
|
||||
{#each categories as category}
|
||||
<CategoryPresenter {category} query={resultQuery} {currentTeam} />
|
||||
{/each}
|
||||
</div>
|
||||
</ScrollBox>
|
||||
{/if}
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// 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 { Resources } from '@anticrm/platform'
|
||||
|
||||
import NopeComponent from './components/NopeComponent.svelte'
|
||||
|
||||
import Active from './components/issues/Active.svelte'
|
||||
import Backlog from './components/issues/Backlog.svelte'
|
||||
import Board from './components/issues/Board.svelte'
|
||||
import Inbox from './components/inbox/Inbox.svelte'
|
||||
import Issues from './components/issues/Issues.svelte'
|
||||
import MyIssues from './components/myissues/MyIssues.svelte'
|
||||
import Projects from './components/projects/Projects.svelte'
|
||||
import Views from './components/views/Views.svelte'
|
||||
import IssuePresenter from './components/issues/IssuePresenter.svelte'
|
||||
import EditIssue from './components/issues/EditIssue.svelte'
|
||||
import NewIssueHeader from './components/NewIssueHeader.svelte'
|
||||
|
||||
export default async (): Promise<Resources> => ({
|
||||
component: {
|
||||
NopeComponent,
|
||||
Active,
|
||||
Backlog,
|
||||
Board,
|
||||
Inbox,
|
||||
Issues,
|
||||
MyIssues,
|
||||
Projects,
|
||||
Views,
|
||||
IssuePresenter,
|
||||
EditIssue,
|
||||
NewIssueHeader
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// 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 type { IntlString } from '@anticrm/platform'
|
||||
import { mergeIds } from '@anticrm/platform'
|
||||
import tracker, { trackerId } from '../../tracker/lib'
|
||||
import { AnyComponent } from '@anticrm/ui'
|
||||
|
||||
export default mergeIds(trackerId, tracker, {
|
||||
string: {
|
||||
More: '' as IntlString,
|
||||
Delete: '' as IntlString,
|
||||
Open: '' as IntlString,
|
||||
Members: '' as IntlString,
|
||||
Inbox: '' as IntlString,
|
||||
MyIssues: '' as IntlString,
|
||||
Issues: '' as IntlString,
|
||||
Views: '' as IntlString,
|
||||
Active: '' as IntlString,
|
||||
Backlog: '' as IntlString,
|
||||
Board: '' as IntlString,
|
||||
Projects: '' as IntlString,
|
||||
CreateTeam: '' as IntlString,
|
||||
NewIssue: '' as IntlString,
|
||||
Team: '' as IntlString,
|
||||
SelectTeam: '' as IntlString,
|
||||
|
||||
Title: '' as IntlString,
|
||||
Identifier: '' as IntlString,
|
||||
Description: '' as IntlString,
|
||||
Status: '' as IntlString,
|
||||
Priority: '' as IntlString,
|
||||
Number: '' as IntlString,
|
||||
Assignee: '' as IntlString,
|
||||
Parent: '' as IntlString,
|
||||
BlockedBy: '' as IntlString,
|
||||
RelatedTo: '' as IntlString,
|
||||
Comments: '' as IntlString,
|
||||
Attachments: '' as IntlString,
|
||||
Labels: '' as IntlString,
|
||||
Space: '' as IntlString,
|
||||
DueDate: '' as IntlString,
|
||||
Issue: '' as IntlString,
|
||||
Document: '' as IntlString,
|
||||
DocumentIcon: '' as IntlString,
|
||||
DocumentColor: '' as IntlString,
|
||||
Rank: '' as IntlString,
|
||||
|
||||
IssueTitlePlaceholder: '' as IntlString,
|
||||
IssueDescriptionPlaceholder: '' as IntlString,
|
||||
TaskUnAssign: '' as IntlString
|
||||
},
|
||||
component: {
|
||||
NopeComponent: '' as AnyComponent,
|
||||
Inbox: '' as AnyComponent,
|
||||
MyIssues: '' as AnyComponent,
|
||||
Issues: '' as AnyComponent,
|
||||
Views: '' as AnyComponent,
|
||||
Active: '' as AnyComponent,
|
||||
Backlog: '' as AnyComponent,
|
||||
Board: '' as AnyComponent,
|
||||
Projects: '' as AnyComponent,
|
||||
IssuePresenter: '' as AnyComponent,
|
||||
EditIssue: '' as AnyComponent,
|
||||
CreateTeam: '' as AnyComponent,
|
||||
NewIssueHeader: '' as AnyComponent
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
import { Ref } from '@anticrm/core'
|
||||
import type { Asset, IntlString } from '@anticrm/platform'
|
||||
import { Team } from '@anticrm/tracker'
|
||||
import { AnyComponent } from '@anticrm/ui'
|
||||
import { LexoDecimal, LexoNumeralSystem36, LexoRank } from 'lexorank'
|
||||
import LexoRankBucket from 'lexorank/lib/lexoRank/lexoRankBucket'
|
||||
|
||||
export interface NavigationItem {
|
||||
id: string
|
||||
label: IntlString
|
||||
icon: Asset
|
||||
component: AnyComponent
|
||||
componentProps?: Record<string, string>
|
||||
top: boolean
|
||||
}
|
||||
|
||||
export interface Selection {
|
||||
currentTeam?: Ref<Team>
|
||||
currentSpecial?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const genRanks = (count: number): Generator<string, void, unknown> =>
|
||||
(function * () {
|
||||
const sys = new LexoNumeralSystem36()
|
||||
const base = 36
|
||||
const max = base ** 6
|
||||
const gap = LexoDecimal.parse(Math.trunc(max / (count + 2)).toString(base), sys)
|
||||
let cur = LexoDecimal.parse('0', sys)
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
cur = cur.add(gap)
|
||||
yield new LexoRank(LexoRankBucket.BUCKET_0, cur).toString()
|
||||
}
|
||||
})()
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const calcRank = (prev?: { rank: string }, next?: { rank: string }): string => {
|
||||
const a = prev?.rank !== undefined ? LexoRank.parse(prev.rank) : LexoRank.min()
|
||||
const b = next?.rank !== undefined ? LexoRank.parse(next.rank) : LexoRank.max()
|
||||
|
||||
return a.between(b).toString()
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
const sveltePreprocess = require('svelte-preprocess')
|
||||
|
||||
module.exports = {
|
||||
preprocess: sveltePreprocess()
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"declaration": true,
|
||||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@anticrm/platform-rig/profiles/default/config/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
*
|
||||
!/lib/**
|
||||
!CHANGELOG.md
|
||||
/lib/**/__tests__/
|
||||
@@ -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"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "@anticrm/tracker",
|
||||
"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/core": "~0.6.16",
|
||||
"@anticrm/platform": "~0.6.5",
|
||||
"@anticrm/ui": "~0.6.0",
|
||||
"@anticrm/contact": "~0.6.5",
|
||||
"@anticrm/chunter": "~0.6.1",
|
||||
"@anticrm/attachment": "~0.6.1",
|
||||
"@anticrm/task": "~0.6.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
//
|
||||
// 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 { 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 Team extends Space {
|
||||
teamLogo?: string | null
|
||||
identifier: string // Team identifier
|
||||
sequence: number
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export enum IssueStatus {
|
||||
Backlog,
|
||||
Todo,
|
||||
InProgress,
|
||||
Done,
|
||||
Canceled
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export enum IssuePriority {
|
||||
NoPriority,
|
||||
Urgent,
|
||||
High,
|
||||
Medium,
|
||||
Low
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Issue extends Doc {
|
||||
title: string
|
||||
description: Markup
|
||||
status: IssueStatus
|
||||
priority: IssuePriority
|
||||
|
||||
number: number
|
||||
assignee: Ref<Employee> | null
|
||||
|
||||
// For subtasks
|
||||
parentIssue?: Ref<Issue>
|
||||
blockedBy?: Ref<Issue>[]
|
||||
relatedIssue?: Ref<Issue>[]
|
||||
|
||||
comments: number
|
||||
attachments?: number
|
||||
labels?: string[]
|
||||
|
||||
space: Ref<Team>
|
||||
|
||||
dueDate: Timestamp | null
|
||||
|
||||
rank: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Document extends Doc {
|
||||
title: string
|
||||
icon: string | null
|
||||
color: number
|
||||
content?: Markup
|
||||
|
||||
space: Ref<Team>
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export enum ProjectStatus {
|
||||
Planned,
|
||||
InProgress,
|
||||
Paused,
|
||||
Completed,
|
||||
Canceled
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Project extends Doc {
|
||||
label: IntlString
|
||||
description?: Markup
|
||||
|
||||
space: Ref<Team>
|
||||
|
||||
comments: number
|
||||
attachments?: number
|
||||
|
||||
startDate: Timestamp | null
|
||||
targetDate: Timestamp | null
|
||||
|
||||
// Ref<Document>[]
|
||||
documents: number
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const trackerId = 'tracker' as Plugin
|
||||
|
||||
export default plugin(trackerId, {
|
||||
class: {
|
||||
Team: '' as Ref<Class<Team>>,
|
||||
Issue: '' as Ref<Class<Issue>>,
|
||||
Document: '' as Ref<Class<Document>>,
|
||||
Project: '' as Ref<Class<Project>>
|
||||
},
|
||||
component: {
|
||||
Tracker: '' as AnyComponent,
|
||||
TrackerApp: '' as AnyComponent
|
||||
},
|
||||
icon: {
|
||||
TrackerApplication: '' as Asset,
|
||||
Project: '' as Asset,
|
||||
Issue: '' as Asset,
|
||||
Team: '' as Asset,
|
||||
Document: '' as Asset
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./node_modules/@anticrm/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"lib": ["esnext", "dom"]
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
import MoreV from './icons/MoreV.svelte'
|
||||
import Menu from './Menu.svelte'
|
||||
import notification from '@anticrm/notification'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export let _class: Ref<Class<Doc>>
|
||||
export let query: DocumentQuery<Doc>
|
||||
@@ -45,6 +46,8 @@
|
||||
|
||||
const q = createQuery()
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
$: sortingFunction = (config.find(it => (typeof it !== 'string') && it.sortingKey === sortKey) as BuildModelKey)?.sortingFunction
|
||||
|
||||
let qindex = 0
|
||||
@@ -69,6 +72,7 @@
|
||||
const sf = sortingFunction
|
||||
objects.sort((a, b) => -1 * sortOrder * sf(a, b))
|
||||
}
|
||||
dispatch('content', objects)
|
||||
loading = false
|
||||
},
|
||||
{ sort: { [sortKey]: sortOrder }, ...options, limit: 200 }
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import contact, { Employee, EmployeeAccount, formatName } from '@anticrm/contact'
|
||||
import { getCurrentAccount, Ref } from '@anticrm/core'
|
||||
import { getCurrentAccount } from '@anticrm/core'
|
||||
import login from '@anticrm/login'
|
||||
import { Avatar, createQuery, getClient } from '@anticrm/presentation'
|
||||
import setting, { SettingsCategory } from '@anticrm/setting'
|
||||
|
||||
@@ -15,13 +15,20 @@
|
||||
|
||||
<script lang="ts">
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { Label } from '@anticrm/ui'
|
||||
import { fetchMetadataLocalStorage, Label } from '@anticrm/ui'
|
||||
import login from '@anticrm/login'
|
||||
|
||||
export let label: IntlString
|
||||
// export let action: () => Promise<void> | void
|
||||
</script>
|
||||
|
||||
<div class="antiNav-header">
|
||||
<span class="fs-title overflow-label"><Label {label}></Label></span>
|
||||
<div class='flex-row'>
|
||||
|
||||
<span class="fs-title overflow-label"><Label {label}></Label></span>
|
||||
<div>
|
||||
{fetchMetadataLocalStorage(login.metadata.CurrentWorkspace)}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <ActionIcon label={workbench.string.More} icon={IconMoreH} size={'small'} {action}/> -->
|
||||
</div>
|
||||
|
||||
@@ -95,18 +95,18 @@
|
||||
<Scroller>
|
||||
{#if model.specials}
|
||||
{#each topSpecials as special}
|
||||
<SpecialElement label={special.label} icon={special.icon} on:click={() => dispatch('special', special.id)} selected={special.id === currentSpecial} />
|
||||
<SpecialElement label={special.label} icon={special.icon} on:click={() => dispatch('special', special.id)} selected={special.id === currentSpecial} indent={'ml-2'} />
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
{#if showDivider}<TreeSeparator />{/if}
|
||||
|
||||
{#each model.spaces as m (m.label)}
|
||||
<SpacesNav spaces={shownSpaces.filter(it => hierarchy.isDerived(it._class, m.spaceClass))} {currentSpace} model={m} on:space/>
|
||||
<SpacesNav spaces={shownSpaces.filter(it => hierarchy.isDerived(it._class, m.spaceClass))} {currentSpace} model={m} on:space {currentSpecial}/>
|
||||
{/each}
|
||||
{#if model.specials}
|
||||
{#each bottomSpecials as special}
|
||||
<SpecialElement label={special.label} icon={special.icon} on:click={() => dispatch('special', special.id)} selected={special.id === currentSpecial} />
|
||||
<SpecialElement label={special.label} icon={special.icon} on:click={() => dispatch('special', special.id)} selected={special.id === currentSpecial} indent={'ml-2'} />
|
||||
{/each}
|
||||
{/if}
|
||||
<div class="antiNav-space" />
|
||||
|
||||
@@ -13,17 +13,17 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import calendar from '@anticrm/calendar'
|
||||
import contact, { Employee, EmployeeAccount } from '@anticrm/contact'
|
||||
import core, { Client, getCurrentAccount, Ref, Space } from '@anticrm/core'
|
||||
import notification, { NotificationStatus } from '@anticrm/notification'
|
||||
import { NotificationClientImpl } from '@anticrm/notification-resources'
|
||||
import { IntlString } from '@anticrm/platform'
|
||||
import { Avatar, createQuery, getClient, setClient } from '@anticrm/presentation'
|
||||
import { Avatar, createQuery, setClient } from '@anticrm/presentation'
|
||||
import {
|
||||
AnyComponent, closePopup,
|
||||
closeTooltip,
|
||||
Component,
|
||||
getCurrentLocation,
|
||||
Component, getCurrentLocation,
|
||||
location,
|
||||
navigate,
|
||||
PanelInstance,
|
||||
@@ -33,7 +33,6 @@
|
||||
} from '@anticrm/ui'
|
||||
import type { Application, NavigatorModel, SpecialNavModel, ViewConfiguration } from '@anticrm/workbench'
|
||||
import { onDestroy } from 'svelte'
|
||||
import calendar from '@anticrm/calendar'
|
||||
import workbench from '../plugin'
|
||||
import AccountPopup from './AccountPopup.svelte'
|
||||
import ActivityStatus from './ActivityStatus.svelte'
|
||||
@@ -43,6 +42,7 @@
|
||||
import NavHeader from './NavHeader.svelte'
|
||||
import Navigator from './Navigator.svelte'
|
||||
import SpaceView from './SpaceView.svelte'
|
||||
|
||||
|
||||
export let client: Client
|
||||
|
||||
@@ -72,20 +72,42 @@
|
||||
const currentFolder = loc.path[2] as Ref<Space>
|
||||
|
||||
if (currentSpecial !== currentFolder) {
|
||||
specialComponent = getSpecialComponent(currentFolder)
|
||||
if (specialComponent !== undefined) {
|
||||
const newSpecial = getSpecialComponent(currentFolder)
|
||||
if (newSpecial !== undefined) {
|
||||
specialComponent = newSpecial
|
||||
currentSpecial = currentFolder
|
||||
currentSpace = undefined
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
updateSpace(currentFolder)
|
||||
updateSpace(currentFolder, loc.path[3])
|
||||
})
|
||||
)
|
||||
|
||||
async function updateSpace (spaceId?: Ref<Space>): Promise<void> {
|
||||
async function updateSpace (spaceId?: Ref<Space>, spaceSpecial?: string): Promise<void> {
|
||||
if (spaceId === currentSpace) {
|
||||
// Check if we need update location.
|
||||
const loc = getCurrentLocation()
|
||||
if (loc.path[3] !== spaceSpecial) {
|
||||
if (spaceSpecial !== undefined) {
|
||||
loc.path[3] = spaceSpecial
|
||||
loc.path.length = 4
|
||||
} else {
|
||||
loc.path.length = 3
|
||||
}
|
||||
if (spaceSpecial !== undefined) {
|
||||
loc.path[3] = spaceSpecial
|
||||
loc.path.length = 4
|
||||
specialComponent = getSpecialComponent(spaceSpecial)
|
||||
currentSpecial = spaceSpecial
|
||||
} else {
|
||||
loc.path.length = 3
|
||||
spaceSpecial = undefined
|
||||
currentSpecial = undefined
|
||||
}
|
||||
navigate(loc)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (spaceId === undefined) {
|
||||
@@ -95,16 +117,23 @@
|
||||
if (space) {
|
||||
currentSpace = spaceId
|
||||
currentSpecial = undefined
|
||||
specialComponent = undefined
|
||||
|
||||
const spaceClass = client.getHierarchy().getClass(space._class) // (await client.findAll(core.class.Class, { _id: space._class }))[0]
|
||||
const view = client.getHierarchy().as(spaceClass, workbench.mixin.SpaceView)
|
||||
currentView = view.view
|
||||
createItemDialog = currentView.createItemDialog ?? undefined
|
||||
createItemLabel = currentView.createItemLabel ?? undefined
|
||||
createItemDialog = currentView?.createItemDialog ?? undefined
|
||||
createItemLabel = currentView?.createItemLabel ?? undefined
|
||||
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[2] = spaceId
|
||||
loc.path.length = 3
|
||||
if (spaceSpecial !== undefined) {
|
||||
loc.path[3] = spaceSpecial
|
||||
currentSpecial = spaceSpecial
|
||||
loc.path.length = 4
|
||||
specialComponent = getSpecialComponent(spaceSpecial)
|
||||
}
|
||||
navigate(loc)
|
||||
} else {
|
||||
currentView = undefined
|
||||
@@ -112,7 +141,6 @@
|
||||
createItemLabel = undefined
|
||||
}
|
||||
}
|
||||
$: updateSpace(currentSpace)
|
||||
|
||||
function selectSpecial (id: string): void {
|
||||
specialComponent = getSpecialComponent(id)
|
||||
@@ -136,7 +164,16 @@
|
||||
}
|
||||
|
||||
function getSpecialComponent (id: string): SpecialNavModel | undefined {
|
||||
return navigatorModel?.specials?.find((x) => x.id === id)
|
||||
const sp = navigatorModel?.specials?.find((x) => x.id === id)
|
||||
if (sp !== undefined) {
|
||||
return sp
|
||||
}
|
||||
for (const s of navigatorModel?.spaces ?? []) {
|
||||
const sp = s.specials?.find((x) => x.id === id)
|
||||
if (sp !== undefined) {
|
||||
return sp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let apps: Application[] = []
|
||||
@@ -227,8 +264,8 @@
|
||||
</svg>
|
||||
<div class="workbench-container">
|
||||
<div class="antiPanel-application" on:click={toggleNav}>
|
||||
<div class="flex-col">
|
||||
<ActivityStatus status="active" />
|
||||
<div class="flex-col">
|
||||
<ActivityStatus status="active" />
|
||||
<AppItem
|
||||
icon={TopMenu}
|
||||
label={visibileNav ? workbench.string.HideMenu : workbench.string.ShowMenu}
|
||||
@@ -279,24 +316,30 @@
|
||||
</div>
|
||||
{#if currentApplication && navigatorModel && navigator && visibileNav}
|
||||
<div class="antiPanel-navigator filled indent">
|
||||
{#if currentApplication}
|
||||
{#if currentApplication}
|
||||
<NavHeader label={currentApplication.label} />
|
||||
{#if currentApplication.navHeaderComponent}
|
||||
<Component is={currentApplication.navHeaderComponent} props={{ currentSpace }}/>
|
||||
{/if}
|
||||
{/if}
|
||||
<Navigator
|
||||
{currentSpace}
|
||||
{currentSpecial}
|
||||
model={navigatorModel}
|
||||
on:special={(evt) => selectSpecial(evt.detail)}
|
||||
on:space={(evt) => updateSpace(evt.detail)}
|
||||
on:space={(evt) => updateSpace(evt.detail.space, evt.detail.spaceSpecial)}
|
||||
on:archive={(evt) => selectArchive()}
|
||||
/>
|
||||
{#if currentApplication.navFooterComponent}
|
||||
<Component is={currentApplication.navFooterComponent} props={{ currentSpace }}/>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="antiPanel-component indent antiComponent" class:filled={isNavigate}>
|
||||
{#if currentApplication && currentApplication.component}
|
||||
<Component is={currentApplication.component} />
|
||||
<Component is={currentApplication.component} props={{ currentSpace }}/>
|
||||
{:else if specialComponent}
|
||||
<Component is={specialComponent.component} props={{ model: navigatorModel, ...specialComponent.componentProps }} />
|
||||
<Component is={specialComponent.component} props={{ model: navigatorModel, ...specialComponent.componentProps, currentSpace }} />
|
||||
{:else}
|
||||
<SpaceView {currentSpace} {currentView} {createItemDialog} {createItemLabel} />
|
||||
{/if}
|
||||
|
||||
@@ -14,84 +14,13 @@
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import { getMetadata, getResource } from '@anticrm/platform'
|
||||
import type { Client } from '@anticrm/core'
|
||||
import core from '@anticrm/core'
|
||||
import { setCurrentAccount } from '@anticrm/core'
|
||||
import { navigate, Loading, fetchMetadataLocalStorage, setMetadataLocalStorage, getCurrentLocation, locationToUrl } from '@anticrm/ui'
|
||||
|
||||
import client from '@anticrm/client'
|
||||
import login from '@anticrm/login'
|
||||
import contact from '@anticrm/contact'
|
||||
|
||||
import { connect, versionError } from '@anticrm/presentation'
|
||||
import { Loading } from '@anticrm/ui'
|
||||
import Workbench from './Workbench.svelte'
|
||||
import workbench from '../plugin'
|
||||
|
||||
let versionError: string | undefined = ''
|
||||
|
||||
async function connect (): Promise<Client | undefined> {
|
||||
const token = fetchMetadataLocalStorage(login.metadata.LoginToken)
|
||||
const endpoint = fetchMetadataLocalStorage(login.metadata.LoginEndpoint)
|
||||
const email = fetchMetadataLocalStorage(login.metadata.LoginEmail)
|
||||
|
||||
if (token === null || endpoint === null || email === null) {
|
||||
navigate({ path: [login.component.LoginApp], query: { navigateUrl: encodeURIComponent(JSON.stringify(getCurrentLocation())) } })
|
||||
return
|
||||
}
|
||||
|
||||
const getClient = await getResource(client.function.GetClient)
|
||||
const instance = await getClient(token, endpoint)
|
||||
console.log('logging in as', email)
|
||||
|
||||
const me = await instance.findOne(contact.class.EmployeeAccount, { email })
|
||||
if (me !== undefined) {
|
||||
console.log('login: employee account', me)
|
||||
setCurrentAccount(me)
|
||||
} else {
|
||||
console.error('WARNING: no employee account found.')
|
||||
setMetadataLocalStorage(login.metadata.LoginToken, null)
|
||||
setMetadataLocalStorage(login.metadata.LoginEndpoint, null)
|
||||
setMetadataLocalStorage(login.metadata.LoginEmail, null)
|
||||
setMetadataLocalStorage(login.metadata.CurrentWorkspace, null)
|
||||
navigate({ path: [login.component.LoginApp], query: { navigateUrl: encodeURIComponent(JSON.stringify(getCurrentLocation())) } })
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('checking model version')
|
||||
const version = await instance.findOne(core.class.Version, {})
|
||||
console.log('Model version', version)
|
||||
|
||||
const requirdVersion = getMetadata(workbench.metadata.RequiredVersion)
|
||||
if (requirdVersion !== undefined) {
|
||||
console.log('checking min model version', requirdVersion)
|
||||
const versionStr = `${version?.major}.${version?.minor}.${version?.patch}`
|
||||
|
||||
if (version === undefined || requirdVersion !== versionStr) {
|
||||
versionError = `${versionStr} => ${requirdVersion}`
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.log(err)
|
||||
const requirdVersion = getMetadata(workbench.metadata.RequiredVersion)
|
||||
console.log('checking min model version', requirdVersion)
|
||||
if (requirdVersion !== undefined) {
|
||||
versionError = `'unknown' => ${requirdVersion}`
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
// Update window title
|
||||
document.title = [(fetchMetadataLocalStorage(login.metadata.CurrentWorkspace)), 'Platform'].filter(it => it).join(' - ')
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
{#await connect()}
|
||||
{#await connect('Platform')}
|
||||
<Loading/>
|
||||
{:then client}
|
||||
{#if !client && versionError}
|
||||
@@ -99,7 +28,7 @@ async function connect (): Promise<Client | undefined> {
|
||||
<h1>Server is under maintenance.</h1>
|
||||
{versionError}
|
||||
</div>
|
||||
{:else}
|
||||
{:else if client}
|
||||
<Workbench {client}/>
|
||||
{/if}
|
||||
{:catch error}
|
||||
|
||||
@@ -13,23 +13,25 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { Class,Doc,Ref,Space } from '@anticrm/core'
|
||||
import type { Class, Doc, Ref, Space } from '@anticrm/core'
|
||||
import core from '@anticrm/core'
|
||||
import { getResource } from '@anticrm/platform'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import { Action,AnyComponent,IconAdd,IconEdit,showPanel,showPopup } from '@anticrm/ui'
|
||||
import { Action, AnyComponent, IconAdd, IconEdit, showPanel, showPopup } from '@anticrm/ui'
|
||||
import view from '@anticrm/view'
|
||||
import { getActions as getContributedActions } from '@anticrm/view-resources'
|
||||
import { SpacesNavModel } from '@anticrm/workbench'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import plugin from '../../plugin'
|
||||
import { classIcon } from '../../utils'
|
||||
import SpecialElement from './SpecialElement.svelte'
|
||||
import TreeItem from './TreeItem.svelte'
|
||||
import TreeNode from './TreeNode.svelte'
|
||||
|
||||
export let model: SpacesNavModel
|
||||
export let currentSpace: Ref<Space> | undefined
|
||||
export let spaces: Space[]
|
||||
export let currentSpecial: string | undefined
|
||||
const client = getClient()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -50,7 +52,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function getEditor (_class: Ref<Class<Doc>>): Promise<AnyComponent | undefined> {
|
||||
async function getEditor(_class: Ref<Class<Doc>>): Promise<AnyComponent | undefined> {
|
||||
const hierarchy = client.getHierarchy()
|
||||
const clazz = hierarchy.getClass(_class)
|
||||
const editorMixin = hierarchy.as(clazz, view.mixin.ObjectEditor)
|
||||
@@ -58,11 +60,11 @@
|
||||
return editorMixin.editor
|
||||
}
|
||||
|
||||
function selectSpace (id: Ref<Space>) {
|
||||
dispatch('space', id)
|
||||
function selectSpace(id: Ref<Space>, spaceSpecial?: string) {
|
||||
dispatch('space', { space: id, spaceSpecial })
|
||||
}
|
||||
|
||||
async function getActions (space: Space): Promise<Action[]> {
|
||||
async function getActions(space: Space): Promise<Action[]> {
|
||||
const result = [editSpace]
|
||||
|
||||
const extraActions = await getContributedActions(client, space, core.class.Space)
|
||||
@@ -80,10 +82,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<TreeNode label={model.label} actions={async () => [addSpace]}>
|
||||
{#each spaces as space (space._id)}
|
||||
<TreeNode label={model.label} actions={async () => [addSpace]} indent={'ml-2'}>
|
||||
{#each spaces as space (space._id)}
|
||||
{#if model.specials}
|
||||
<TreeNode title={space.name} indent={'ml-2'}>
|
||||
{#each model.specials as special}
|
||||
<SpecialElement
|
||||
indent={'ml-4'}
|
||||
label={special.label}
|
||||
icon={special.icon}
|
||||
on:click={() => dispatch('special', special.id)}
|
||||
selected={currentSpace === space._id && special.id === currentSpecial}
|
||||
on:click={() => {
|
||||
selectSpace(space._id, special.id)
|
||||
}}
|
||||
/>
|
||||
{/each}
|
||||
</TreeNode>
|
||||
{:else}
|
||||
<TreeItem
|
||||
indent={'ml-4'}
|
||||
_id={space._id}
|
||||
title={space.name}
|
||||
icon={classIcon(client, space._class)}
|
||||
@@ -93,6 +111,6 @@
|
||||
selectSpace(space._id)
|
||||
}}
|
||||
/>
|
||||
{/each}
|
||||
</TreeNode>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
</TreeNode>
|
||||
|
||||
@@ -23,13 +23,14 @@
|
||||
export let notifications = 0
|
||||
export let actions: Action[] = []
|
||||
export let selected: boolean = false
|
||||
export let indent: 'default' | 'ml-2' | 'ml-4' | 'ml-8' = 'default'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
||||
<div
|
||||
class="antiNav-element" class:selected
|
||||
class="antiNav-element" class:selected class:ml-2={indent === 'ml-2'} class:ml-4={indent === 'ml-4'} class:ml-8={indent === 'ml-8'}
|
||||
on:click|stopPropagation={() => {
|
||||
dispatch('click')
|
||||
}}
|
||||
|
||||
@@ -31,11 +31,12 @@
|
||||
export let collapsed = false
|
||||
export let selected = false
|
||||
export let actions: () => Promise<Action[]> = async () => []
|
||||
export let indent: 'default' | 'ml-2' | 'ml-4' | 'ml-8' = 'default'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let hovered = false
|
||||
async function onMenuClick (ev: MouseEvent) {
|
||||
async function onMenuClick(ev: MouseEvent) {
|
||||
showPopup(Menu, { actions: await actions(), ctx: _id }, ev.target as HTMLElement, () => {
|
||||
hovered = false
|
||||
})
|
||||
@@ -43,19 +44,37 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="antiNav-element" class:selected class:hovered
|
||||
<div
|
||||
class="antiNav-element"
|
||||
class:selected
|
||||
class:hovered
|
||||
class:ml-2={indent === 'ml-2'}
|
||||
class:ml-4={indent === 'ml-4'}
|
||||
class:ml-8={indent === 'ml-8'}
|
||||
on:click|stopPropagation={() => {
|
||||
if (node && !icon) collapsed = !collapsed
|
||||
dispatch('click')
|
||||
}}
|
||||
>
|
||||
<div class="an-element__icon" class:sub={!node}>
|
||||
{#if icon}
|
||||
<Icon {icon} size={'small'} />
|
||||
{:else if collapsed}<Collapsed size={'small'} />{:else}<Expanded size={'small'} />{/if}
|
||||
</div>
|
||||
<span class="an-element__label" class:title={node}>
|
||||
{#if label}<Label {label} />{:else}{title}{/if}
|
||||
<div class="flex-row-center">
|
||||
{#if icon}
|
||||
<div class="an-element__icon" class:sub={!node}>
|
||||
<Icon {icon} size={'small'} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if label}<Label {label} />{:else}{title}{/if}
|
||||
|
||||
{#if !icon}
|
||||
<div class="ml-2" class:sub={!node}>
|
||||
{#if collapsed}
|
||||
<Collapsed size={'small'} />
|
||||
{:else}
|
||||
<Expanded size={'small'} />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</span>
|
||||
{#if node === false}
|
||||
<div class="an-element__tool" on:click|stopPropagation={onMenuClick}>
|
||||
|
||||
@@ -26,9 +26,10 @@
|
||||
export let notifications = 0
|
||||
export let actions: () => Promise<Action[]> = async () => []
|
||||
export let selected: boolean = false
|
||||
export let indent: 'default' | 'ml-2' | 'ml-4' | 'ml-8' = 'default'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
</script>
|
||||
|
||||
<TreeElement {_id} {icon} {title} {notifications} {selected} {actions} collapsed on:click={() => { dispatch('click') }}/>
|
||||
<TreeElement {_id} {icon} {title} {notifications} {selected} {actions} collapsed {indent} on:click={() => { dispatch('click') }}/>
|
||||
|
||||
@@ -18,13 +18,15 @@
|
||||
import type { Action } from '@anticrm/ui'
|
||||
import TreeElement from './TreeElement.svelte'
|
||||
|
||||
export let label: IntlString
|
||||
export let title: string | undefined = undefined
|
||||
export let label: IntlString | undefined = undefined
|
||||
export let actions: () => Promise<Action[]> = async () => []
|
||||
export let notifications = 0
|
||||
export let collapsed = false
|
||||
export let indent: 'default' | 'ml-2' | 'ml-4' | 'ml-8' = 'default'
|
||||
|
||||
</script>
|
||||
|
||||
<TreeElement {label} {notifications} {collapsed} {actions} node>
|
||||
<TreeElement {title} {label} {notifications} {collapsed} {actions} node {indent}>
|
||||
<slot/>
|
||||
</TreeElement>
|
||||
@@ -14,7 +14,7 @@
|
||||
//
|
||||
|
||||
import type { Class, Doc, Mixin, Obj, Ref, Space } from '@anticrm/core'
|
||||
import type { Asset, IntlString, Metadata, Plugin, Resource } from '@anticrm/platform'
|
||||
import type { Asset, IntlString, Plugin, Resource } from '@anticrm/platform'
|
||||
import { plugin } from '@anticrm/platform'
|
||||
import { AnyComponent } from '@anticrm/ui'
|
||||
|
||||
@@ -29,6 +29,9 @@ export interface Application extends Doc {
|
||||
|
||||
// Component will be displayed in case navigator model is not defined, or nothing is selected in navigator model
|
||||
component?: AnyComponent
|
||||
|
||||
navHeaderComponent?: AnyComponent
|
||||
navFooterComponent?: AnyComponent
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,6 +42,9 @@ export interface SpacesNavModel {
|
||||
spaceClass: Ref<Class<Space>>
|
||||
addSpaceLabel: IntlString
|
||||
createComponent: AnyComponent
|
||||
|
||||
// Child special items.
|
||||
specials?: SpecialNavModel[]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +61,7 @@ export interface NavigatorModel {
|
||||
export interface SpecialNavModel {
|
||||
id: string // Uniq id
|
||||
label: IntlString
|
||||
icon: Asset
|
||||
icon?: Asset
|
||||
component: AnyComponent
|
||||
componentProps?: Record<string, string>
|
||||
position?: 'top'|'bottom' // undefined == 'top
|
||||
@@ -94,8 +100,5 @@ export default plugin(workbenchId, {
|
||||
},
|
||||
component: {
|
||||
WorkbenchApp: '' as AnyComponent
|
||||
},
|
||||
metadata: {
|
||||
RequiredVersion: '' as Metadata<string>
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1211,5 +1211,26 @@
|
||||
"projectFolder": "server-plugins/telegram-resources",
|
||||
"shouldPublish": true
|
||||
},
|
||||
|
||||
{
|
||||
"packageName": "@anticrm/tracker",
|
||||
"projectFolder": "plugins/tracker",
|
||||
"shouldPublish": true
|
||||
},
|
||||
{
|
||||
"packageName": "@anticrm/tracker-assets",
|
||||
"projectFolder": "plugins/tracker-assets",
|
||||
"shouldPublish": true
|
||||
},
|
||||
{
|
||||
"packageName": "@anticrm/tracker-resources",
|
||||
"projectFolder": "plugins/tracker-resources",
|
||||
"shouldPublish": true
|
||||
},
|
||||
{
|
||||
"packageName": "@anticrm/model-tracker",
|
||||
"projectFolder": "models/tracker",
|
||||
"shouldPublish": true
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
res=''
|
||||
echo "Warting Elastic to up and running with attachment processor..."
|
||||
echo "Warning Elastic to up and running with attachment processor..."
|
||||
while true
|
||||
do
|
||||
res=$(curl -s -XPUT "localhost:9201/_ingest/pipeline/attachment?pretty" -H 'Content-Type: application/json' -d'
|
||||
|
||||
Reference in New Issue
Block a user