mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-07 16:30:49 +00:00
TSK-651: Fix Team editing (#2611)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
0e12e73172
commit
0f503edccb
File diff suppressed because it is too large
Load Diff
@ -58,7 +58,7 @@ services:
|
|||||||
- MINIO_ENDPOINT=minio
|
- MINIO_ENDPOINT=minio
|
||||||
- MINIO_ACCESS_KEY=minioadmin
|
- MINIO_ACCESS_KEY=minioadmin
|
||||||
- MINIO_SECRET_KEY=minioadmin
|
- MINIO_SECRET_KEY=minioadmin
|
||||||
- FRONT_URL=http://localhost:8087
|
- FRONT_URL=http://front:8080
|
||||||
- SES_URL=http://localhost:8091
|
- SES_URL=http://localhost:8091
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
collaborator:
|
collaborator:
|
||||||
@ -87,8 +87,9 @@ services:
|
|||||||
- SERVER_PORT=8080
|
- SERVER_PORT=8080
|
||||||
- SERVER_SECRET=secret
|
- SERVER_SECRET=secret
|
||||||
- ACCOUNTS_URL=http://localhost:3000
|
- ACCOUNTS_URL=http://localhost:3000
|
||||||
|
- REKONI_URL=http://localhost:4004
|
||||||
- COLLABORATOR_URL=ws://localhost:3078
|
- COLLABORATOR_URL=ws://localhost:3078
|
||||||
- FRONT_URL=http://localhost:8087
|
- FRONT_URL=http://front:8080
|
||||||
- UPLOAD_URL=/files
|
- UPLOAD_URL=/files
|
||||||
- TRANSACTOR_URL=ws://localhost:3333
|
- TRANSACTOR_URL=ws://localhost:3333
|
||||||
- ELASTIC_URL=http://elastic:9200
|
- ELASTIC_URL=http://elastic:9200
|
||||||
|
@ -2,23 +2,16 @@ import faker from 'faker'
|
|||||||
|
|
||||||
import contact from '@hcengineering/contact'
|
import contact from '@hcengineering/contact'
|
||||||
import core, {
|
import core, {
|
||||||
TxOperations,
|
|
||||||
MeasureMetricsContext,
|
|
||||||
metricsToString,
|
|
||||||
AttachedData,
|
AttachedData,
|
||||||
generateId,
|
generateId,
|
||||||
|
MeasureMetricsContext,
|
||||||
|
metricsToString,
|
||||||
Ref,
|
Ref,
|
||||||
SortingOrder,
|
SortingOrder,
|
||||||
|
TxOperations,
|
||||||
WorkspaceId
|
WorkspaceId
|
||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
import tracker, {
|
import tracker, { calcRank, Issue, IssuePriority, IssueStatus } from '../../../plugins/tracker/lib'
|
||||||
calcRank,
|
|
||||||
Issue,
|
|
||||||
IssuePriority,
|
|
||||||
IssueStatus,
|
|
||||||
TimeReportDayType,
|
|
||||||
WorkDayLength
|
|
||||||
} from '../../../plugins/tracker/lib'
|
|
||||||
|
|
||||||
import { connect } from './connect'
|
import { connect } from './connect'
|
||||||
|
|
||||||
@ -42,9 +35,7 @@ const object: AttachedData<Issue> = {
|
|||||||
reportedTime: 0,
|
reportedTime: 0,
|
||||||
estimation: 0,
|
estimation: 0,
|
||||||
reports: 0,
|
reports: 0,
|
||||||
childInfo: [],
|
childInfo: []
|
||||||
workDayLength: WorkDayLength.EIGHT_HOURS,
|
|
||||||
defaultTimeReportDay: TimeReportDayType.PreviousWorkDay
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IssueOptions {
|
export interface IssueOptions {
|
||||||
@ -106,9 +97,7 @@ async function genIssue (client: TxOperations): Promise<void> {
|
|||||||
estimation: object.estimation,
|
estimation: object.estimation,
|
||||||
reports: 0,
|
reports: 0,
|
||||||
relations: [],
|
relations: [],
|
||||||
childInfo: [],
|
childInfo: []
|
||||||
workDayLength: object.workDayLength,
|
|
||||||
defaultTimeReportDay: object.defaultTimeReportDay
|
|
||||||
}
|
}
|
||||||
await client.addCollection(
|
await client.addCollection(
|
||||||
tracker.class.Issue,
|
tracker.class.Issue,
|
||||||
|
@ -3,7 +3,7 @@ LOGIN_ENDPOINT=ws://localhost:3333
|
|||||||
|
|
||||||
TELEGRAM_URL=http://localhost:8086
|
TELEGRAM_URL=http://localhost:8086
|
||||||
GMAIL_URL=http://localhost:8088
|
GMAIL_URL=http://localhost:8088
|
||||||
FRONT_URL=http://localhost:8080
|
FRONT_URL=http://front:8080
|
||||||
|
|
||||||
REKONI_URL=http://localhost:4004
|
REKONI_URL=http://localhost:4004
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
"postcss-loader": "^7.0.2",
|
"postcss-loader": "^7.0.2",
|
||||||
"postcss-load-config": "^4.0.1",
|
"postcss-load-config": "^4.0.1",
|
||||||
"compression-webpack-plugin": "^10.0.0",
|
"compression-webpack-plugin": "^10.0.0",
|
||||||
"html-webpack-plugin": "^5.5.0"
|
"html-webpack-plugin": "^5.5.0",
|
||||||
|
"fork-ts-checker-webpack-plugin": "~7.3.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hcengineering/platform": "^0.6.8",
|
"@hcengineering/platform": "^0.6.8",
|
||||||
|
@ -21,12 +21,17 @@ const CompressionPlugin = require('compression-webpack-plugin')
|
|||||||
const DefinePlugin = require('webpack').DefinePlugin
|
const DefinePlugin = require('webpack').DefinePlugin
|
||||||
const { resolve } = require('path')
|
const { resolve } = require('path')
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const { Configuration } = require('webpack')
|
||||||
|
|
||||||
const mode = process.env.NODE_ENV || 'development'
|
const mode = process.env.NODE_ENV || 'development'
|
||||||
const prod = mode === 'production'
|
const prod = mode === 'production'
|
||||||
const devServer = (process.env.CLIENT_TYPE ?? '') === 'dev-server'
|
const devServer = (process.env.CLIENT_TYPE ?? '') === 'dev-server'
|
||||||
const dev = (process.env.CLIENT_TYPE ?? '') === 'dev' || devServer
|
const dev = (process.env.CLIENT_TYPE ?? '') === 'dev' || devServer
|
||||||
|
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Configuration}
|
||||||
|
*/
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
bundle: [
|
bundle: [
|
||||||
@ -57,14 +62,21 @@ module.exports = {
|
|||||||
path: __dirname + '/dist',
|
path: __dirname + '/dist',
|
||||||
filename: '[name].[contenthash].js',
|
filename: '[name].[contenthash].js',
|
||||||
chunkFilename: '[name].[contenthash].js',
|
chunkFilename: '[name].[contenthash].js',
|
||||||
publicPath: '/'
|
publicPath: '/',
|
||||||
|
pathinfo: false
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
minimize: prod
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.ts?$/,
|
test: /\.ts?$/,
|
||||||
use: 'ts-loader',
|
loader:'ts-loader',
|
||||||
exclude: /node_modules/
|
options: {
|
||||||
|
transpileOnly: true
|
||||||
|
},
|
||||||
|
exclude: /node_modules/,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.svelte$/,
|
test: /\.svelte$/,
|
||||||
@ -190,8 +202,15 @@ module.exports = {
|
|||||||
new Dotenv({path: prod ? '.env-prod' : '.env'}),
|
new Dotenv({path: prod ? '.env-prod' : '.env'}),
|
||||||
new DefinePlugin({
|
new DefinePlugin({
|
||||||
'process.env.CLIENT_TYPE': JSON.stringify(process.env.CLIENT_TYPE)
|
'process.env.CLIENT_TYPE': JSON.stringify(process.env.CLIENT_TYPE)
|
||||||
})
|
}),
|
||||||
|
new ForkTsCheckerWebpackPlugin()
|
||||||
],
|
],
|
||||||
|
watchOptions: {
|
||||||
|
// for some systems, watching many files can result in a lot of CPU or memory usage
|
||||||
|
// https://webpack.js.org/configuration/watch/#watchoptionsignored
|
||||||
|
// don't use this pattern, if you have a monorepo with linked packages
|
||||||
|
ignored: /node_modules/,
|
||||||
|
},
|
||||||
devtool: prod ? false : 'inline-source-map',
|
devtool: prod ? false : 'inline-source-map',
|
||||||
devServer: {
|
devServer: {
|
||||||
static: {
|
static: {
|
||||||
|
@ -1033,6 +1033,24 @@ export function createModel (builder: Builder): void {
|
|||||||
},
|
},
|
||||||
recruit.action.MoveApplicant
|
recruit.action.MoveApplicant
|
||||||
)
|
)
|
||||||
|
|
||||||
|
createAction(
|
||||||
|
builder,
|
||||||
|
{
|
||||||
|
label: recruit.string.RecognizeAttachment,
|
||||||
|
action: recruit.actionImpl.MoveApplicant,
|
||||||
|
icon: view.icon.Move,
|
||||||
|
input: 'any',
|
||||||
|
category: view.category.General,
|
||||||
|
target: recruit.class.Applicant,
|
||||||
|
context: {
|
||||||
|
mode: ['context', 'browser'],
|
||||||
|
group: 'tools'
|
||||||
|
},
|
||||||
|
override: [task.action.Move]
|
||||||
|
},
|
||||||
|
recruit.action.MoveApplicant
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export { recruitOperation } from './migration'
|
export { recruitOperation } from './migration'
|
||||||
|
@ -63,7 +63,8 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
GotoAssigned: '' as IntlString,
|
GotoAssigned: '' as IntlString,
|
||||||
GotoApplicants: '' as IntlString,
|
GotoApplicants: '' as IntlString,
|
||||||
GotoRecruitApplication: '' as IntlString,
|
GotoRecruitApplication: '' as IntlString,
|
||||||
VacancyList: '' as IntlString
|
VacancyList: '' as IntlString,
|
||||||
|
RecognizeAttachment: '' as IntlString
|
||||||
},
|
},
|
||||||
validator: {
|
validator: {
|
||||||
ApplicantValidator: '' as Resource<<T extends Doc>(doc: T, client: Client) => Promise<Status>>
|
ApplicantValidator: '' as Resource<<T extends Doc>(doc: T, client: Client) => Promise<Status>>
|
||||||
|
@ -266,9 +266,6 @@ export class TIssue extends TAttachedDoc implements Issue {
|
|||||||
reports!: number
|
reports!: number
|
||||||
|
|
||||||
declare childInfo: IssueChildInfo[]
|
declare childInfo: IssueChildInfo[]
|
||||||
|
|
||||||
declare workDayLength: WorkDayLength
|
|
||||||
declare defaultTimeReportDay: TimeReportDayType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,27 +13,18 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import core, {
|
import core, { Doc, DocumentUpdate, generateId, Ref, SortingOrder, TxOperations, TxResult } from '@hcengineering/core'
|
||||||
Doc,
|
|
||||||
DocumentUpdate,
|
|
||||||
generateId,
|
|
||||||
Ref,
|
|
||||||
SortingOrder,
|
|
||||||
toIdMap,
|
|
||||||
TxOperations,
|
|
||||||
TxResult
|
|
||||||
} from '@hcengineering/core'
|
|
||||||
import { createOrUpdate, MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model'
|
import { createOrUpdate, MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model'
|
||||||
|
import tags from '@hcengineering/tags'
|
||||||
import {
|
import {
|
||||||
|
genRanks,
|
||||||
|
Issue,
|
||||||
IssueStatus,
|
IssueStatus,
|
||||||
IssueStatusCategory,
|
IssueStatusCategory,
|
||||||
Team,
|
Team,
|
||||||
genRanks,
|
|
||||||
Issue,
|
|
||||||
TimeReportDayType,
|
TimeReportDayType,
|
||||||
WorkDayLength
|
WorkDayLength
|
||||||
} from '@hcengineering/tracker'
|
} from '@hcengineering/tracker'
|
||||||
import tags from '@hcengineering/tags'
|
|
||||||
import { DOMAIN_TRACKER } from '.'
|
import { DOMAIN_TRACKER } from '.'
|
||||||
import tracker from './plugin'
|
import tracker from './plugin'
|
||||||
|
|
||||||
@ -212,25 +203,6 @@ async function upgradeIssueStatuses (tx: TxOperations): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function upgradeIssueTimeReportSettings (tx: TxOperations): Promise<void> {
|
|
||||||
const issues = await tx.findAll(tracker.class.Issue, {
|
|
||||||
defaultTimeReportDay: { $exists: false },
|
|
||||||
workDayLength: { $exists: false }
|
|
||||||
})
|
|
||||||
|
|
||||||
const teams = await tx.findAll(tracker.class.Team, {
|
|
||||||
_id: { $in: Array.from(new Set(issues.map((issue) => issue.space))) }
|
|
||||||
})
|
|
||||||
const teamsById = toIdMap(teams)
|
|
||||||
|
|
||||||
await Promise.all(
|
|
||||||
issues.map((issue) => {
|
|
||||||
const team = teamsById.get(issue.space)
|
|
||||||
return tx.update(issue, { defaultTimeReportDay: team?.defaultTimeReportDay, workDayLength: team?.workDayLength })
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function migrateParentIssues (client: MigrationClient): Promise<void> {
|
async function migrateParentIssues (client: MigrationClient): Promise<void> {
|
||||||
let { updated } = await client.update(
|
let { updated } = await client.update(
|
||||||
DOMAIN_TRACKER,
|
DOMAIN_TRACKER,
|
||||||
@ -363,7 +335,6 @@ async function upgradeTeams (tx: TxOperations): Promise<void> {
|
|||||||
|
|
||||||
async function upgradeIssues (tx: TxOperations): Promise<void> {
|
async function upgradeIssues (tx: TxOperations): Promise<void> {
|
||||||
await upgradeIssueStatuses(tx)
|
await upgradeIssueStatuses(tx)
|
||||||
await upgradeIssueTimeReportSettings(tx)
|
|
||||||
|
|
||||||
const issues = await tx.findAll(tracker.class.Issue, {
|
const issues = await tx.findAll(tracker.class.Issue, {
|
||||||
$or: [{ blockedBy: { $exists: true } }, { relatedIssue: { $exists: true } }]
|
$or: [{ blockedBy: { $exists: true } }, { relatedIssue: { $exists: true } }]
|
||||||
|
@ -127,7 +127,6 @@
|
|||||||
on:keydown={handleKeydown}
|
on:keydown={handleKeydown}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{JSON.stringify(options)}
|
|
||||||
<div
|
<div
|
||||||
class="popup {showing === undefined ? 'endShow' : showing === false ? 'preShow' : 'startShow'}"
|
class="popup {showing === undefined ? 'endShow' : showing === false ? 'preShow' : 'startShow'}"
|
||||||
class:anim={element === 'float'}
|
class:anim={element === 'float'}
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
<!--
|
|
||||||
// Copyright © 2020 Anticrm Platform Contributors.
|
|
||||||
//
|
|
||||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License. You may
|
|
||||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
//
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import type { IntlString } from '@hcengineering/platform'
|
|
||||||
import type { AnySvelteComponent } from '../types'
|
|
||||||
import Label from './Label.svelte'
|
|
||||||
import Check from './icons/Check.svelte'
|
|
||||||
|
|
||||||
export let title: IntlString | undefined = undefined
|
|
||||||
export let component: AnySvelteComponent | undefined = undefined
|
|
||||||
export let props: Object = {}
|
|
||||||
export let selectable: boolean = false
|
|
||||||
export let selected: boolean = false
|
|
||||||
export let action: () => Promise<void> = async () => {}
|
|
||||||
|
|
||||||
if (title) {
|
|
||||||
component = Label
|
|
||||||
props = { label: title }
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<button class="popup-item" on:click={() => {
|
|
||||||
if (selectable) selected = !selected
|
|
||||||
action()
|
|
||||||
}}>
|
|
||||||
<div class="title">
|
|
||||||
<svelte:component this={component} {...props}/>
|
|
||||||
</div>
|
|
||||||
{#if selectable}
|
|
||||||
<div class="check" class:selected={selected}><Check/></div>
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.popup-item {
|
|
||||||
position: relative;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: .5rem .75rem;
|
|
||||||
height: 2.5rem;
|
|
||||||
border-radius: .5rem;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
flex-grow: 1;
|
|
||||||
text-align: left;
|
|
||||||
color: var(--theme-content-accent-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.check {
|
|
||||||
margin-left: .75rem;
|
|
||||||
border-radius: 50%;
|
|
||||||
opacity: 0;
|
|
||||||
&.selected { opacity: .8; }
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--theme-button-bg-pressed);
|
|
||||||
border: 1px solid var(--theme-bg-accent-color);
|
|
||||||
.title { color: var(--theme-caption-color); }
|
|
||||||
.check {
|
|
||||||
opacity: .2;
|
|
||||||
&.selected { opacity: 1; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:focus {
|
|
||||||
border: 1px solid var(--primary-button-focused-border);
|
|
||||||
box-shadow: 0 0 0 3px var(--primary-button-outline);
|
|
||||||
z-index: 1;
|
|
||||||
.title { color: var(--theme-caption-color); }
|
|
||||||
.check {
|
|
||||||
opacity: .2;
|
|
||||||
&.selected { opacity: .8; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -246,7 +246,8 @@
|
|||||||
async function createCandidate () {
|
async function createCandidate () {
|
||||||
const candidate: Data<Person> = {
|
const candidate: Data<Person> = {
|
||||||
name: combineName(firstName, lastName),
|
name: combineName(firstName, lastName),
|
||||||
city: object.city
|
city: object.city,
|
||||||
|
createOn: Date.now()
|
||||||
}
|
}
|
||||||
if (avatar !== undefined) {
|
if (avatar !== undefined) {
|
||||||
candidate.avatar = await avatarEditor.createAvatar()
|
candidate.avatar = await avatarEditor.createAvatar()
|
||||||
@ -349,7 +350,8 @@
|
|||||||
|
|
||||||
async function recognize (contentType: string): Promise<void> {
|
async function recognize (contentType: string): Promise<void> {
|
||||||
const token = getMetadata(login.metadata.LoginToken) ?? ''
|
const token = getMetadata(login.metadata.LoginToken) ?? ''
|
||||||
const fileUrl = window.location.origin + getFileUrl(resume.uuid)
|
const frontUrl = getMetadata(login.metadata.FrontUrl) ?? ''
|
||||||
|
const fileUrl = frontUrl + getFileUrl(resume.uuid)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const doc = await recognizeDocument(token, fileUrl, contentType)
|
const doc = await recognizeDocument(token, fileUrl, contentType)
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
import { Card, createQuery, getClient, UserBox } from '@hcengineering/presentation'
|
import { Card, createQuery, getClient, UserBox } from '@hcengineering/presentation'
|
||||||
import { Vacancy as VacancyClass } from '@hcengineering/recruit'
|
import { Vacancy as VacancyClass } from '@hcengineering/recruit'
|
||||||
import task, { createKanban, KanbanTemplate } from '@hcengineering/task'
|
import task, { createKanban, KanbanTemplate } from '@hcengineering/task'
|
||||||
import tracker, { IssueStatus, IssueTemplate, TimeReportDayType, WorkDayLength } from '@hcengineering/tracker'
|
import tracker, { IssueStatus, IssueTemplate } from '@hcengineering/tracker'
|
||||||
import { Button, Component, createFocusManager, EditBox, FocusHandler, IconAttachment } from '@hcengineering/ui'
|
import { Button, Component, createFocusManager, EditBox, FocusHandler, IconAttachment } from '@hcengineering/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import recruit from '../plugin'
|
import recruit from '../plugin'
|
||||||
@ -118,9 +118,7 @@
|
|||||||
estimation: issueTemplate.estimation,
|
estimation: issueTemplate.estimation,
|
||||||
reports: 0,
|
reports: 0,
|
||||||
relations: [{ _id: id, _class: recruit.class.Vacancy }],
|
relations: [{ _id: id, _class: recruit.class.Vacancy }],
|
||||||
childInfo: [],
|
childInfo: []
|
||||||
workDayLength: WorkDayLength.EIGHT_HOURS,
|
|
||||||
defaultTimeReportDay: TimeReportDayType.PreviousWorkDay
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
"CreateTeam": "Create team",
|
"CreateTeam": "Create team",
|
||||||
"NewTeam": "New team",
|
"NewTeam": "New team",
|
||||||
"TeamTitlePlaceholder": "Team title",
|
"TeamTitlePlaceholder": "Team title",
|
||||||
|
"TeamIdentifierPlaceholder": "Team ID",
|
||||||
"MakePrivate": "Make private",
|
"MakePrivate": "Make private",
|
||||||
"MakePrivateDescription": "Only members can see it",
|
"MakePrivateDescription": "Only members can see it",
|
||||||
"ChooseIcon": "Choose icon",
|
"ChooseIcon": "Choose icon",
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
"CreateTeam": "Создать команду",
|
"CreateTeam": "Создать команду",
|
||||||
"NewTeam": "Новая команда",
|
"NewTeam": "Новая команда",
|
||||||
"TeamTitlePlaceholder": "Название команды",
|
"TeamTitlePlaceholder": "Название команды",
|
||||||
|
"TeamIdentifierPlaceholder": "Идентификатор Команды",
|
||||||
"MakePrivate": "Сделать личным",
|
"MakePrivate": "Сделать личным",
|
||||||
"MakePrivateDescription": "Только пользователи могут видеть это",
|
"MakePrivateDescription": "Только пользователи могут видеть это",
|
||||||
"ChooseIcon": "Выбрать иконку",
|
"ChooseIcon": "Выбрать иконку",
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { deepEqual } from 'fast-equals'
|
|
||||||
import { AttachmentStyledBox } from '@hcengineering/attachment-resources'
|
import { AttachmentStyledBox } from '@hcengineering/attachment-resources'
|
||||||
import chunter from '@hcengineering/chunter'
|
import chunter from '@hcengineering/chunter'
|
||||||
import { Employee } from '@hcengineering/contact'
|
import { Employee } from '@hcengineering/contact'
|
||||||
@ -49,9 +48,7 @@
|
|||||||
IssueTemplateChild,
|
IssueTemplateChild,
|
||||||
Project,
|
Project,
|
||||||
Sprint,
|
Sprint,
|
||||||
Team,
|
Team
|
||||||
TimeReportDayType,
|
|
||||||
WorkDayLength
|
|
||||||
} from '@hcengineering/tracker'
|
} from '@hcengineering/tracker'
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
@ -69,10 +66,12 @@
|
|||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
import { ObjectBox } from '@hcengineering/view-resources'
|
import { ObjectBox } from '@hcengineering/view-resources'
|
||||||
|
import { deepEqual } from 'fast-equals'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import { activeProject, activeSprint, generateIssueShortLink, getIssueId, updateIssueRelation } from '../issues'
|
import { activeProject, activeSprint, generateIssueShortLink, getIssueId, updateIssueRelation } from '../issues'
|
||||||
import tracker from '../plugin'
|
import tracker from '../plugin'
|
||||||
import AssigneeEditor from './issues/AssigneeEditor.svelte'
|
import AssigneeEditor from './issues/AssigneeEditor.svelte'
|
||||||
|
import IssueNotification from './issues/IssueNotification.svelte'
|
||||||
import ParentIssue from './issues/ParentIssue.svelte'
|
import ParentIssue from './issues/ParentIssue.svelte'
|
||||||
import PriorityEditor from './issues/PriorityEditor.svelte'
|
import PriorityEditor from './issues/PriorityEditor.svelte'
|
||||||
import StatusEditor from './issues/StatusEditor.svelte'
|
import StatusEditor from './issues/StatusEditor.svelte'
|
||||||
@ -82,7 +81,6 @@
|
|||||||
import SetParentIssueActionPopup from './SetParentIssueActionPopup.svelte'
|
import SetParentIssueActionPopup from './SetParentIssueActionPopup.svelte'
|
||||||
import SprintSelector from './sprints/SprintSelector.svelte'
|
import SprintSelector from './sprints/SprintSelector.svelte'
|
||||||
import IssueTemplateChilds from './templates/IssueTemplateChilds.svelte'
|
import IssueTemplateChilds from './templates/IssueTemplateChilds.svelte'
|
||||||
import IssueNotification from './issues/IssueNotification.svelte'
|
|
||||||
|
|
||||||
export let space: Ref<Team>
|
export let space: Ref<Team>
|
||||||
export let status: Ref<IssueStatus> | undefined = undefined
|
export let status: Ref<IssueStatus> | undefined = undefined
|
||||||
@ -130,9 +128,7 @@
|
|||||||
reportedTime: 0,
|
reportedTime: 0,
|
||||||
estimation: 0,
|
estimation: 0,
|
||||||
reports: 0,
|
reports: 0,
|
||||||
childInfo: [],
|
childInfo: []
|
||||||
workDayLength: currentTeam?.workDayLength ?? WorkDayLength.EIGHT_HOURS,
|
|
||||||
defaultTimeReportDay: currentTeam?.defaultTimeReportDay ?? TimeReportDayType.PreviousWorkDay
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let object = originalIssue
|
let object = originalIssue
|
||||||
@ -147,13 +143,6 @@
|
|||||||
}
|
}
|
||||||
: toIssue(defaultIssue, draft)
|
: toIssue(defaultIssue, draft)
|
||||||
|
|
||||||
$: {
|
|
||||||
defaultIssue.workDayLength = currentTeam?.workDayLength ?? WorkDayLength.EIGHT_HOURS
|
|
||||||
defaultIssue.defaultTimeReportDay = currentTeam?.defaultTimeReportDay ?? TimeReportDayType.PreviousWorkDay
|
|
||||||
object.workDayLength = defaultIssue.workDayLength
|
|
||||||
object.defaultTimeReportDay = defaultIssue.defaultTimeReportDay
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetObject (): void {
|
function resetObject (): void {
|
||||||
templateId = undefined
|
templateId = undefined
|
||||||
template = undefined
|
template = undefined
|
||||||
@ -453,9 +442,7 @@
|
|||||||
estimation: object.estimation,
|
estimation: object.estimation,
|
||||||
reports: 0,
|
reports: 0,
|
||||||
relations: relatedTo !== undefined ? [{ _id: relatedTo._id, _class: relatedTo._class }] : [],
|
relations: relatedTo !== undefined ? [{ _id: relatedTo._id, _class: relatedTo._class }] : [],
|
||||||
childInfo: [],
|
childInfo: []
|
||||||
workDayLength: object.workDayLength,
|
|
||||||
defaultTimeReportDay: object.defaultTimeReportDay
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await client.addCollection(
|
await client.addCollection(
|
||||||
@ -527,9 +514,7 @@
|
|||||||
estimation: subIssue.estimation,
|
estimation: subIssue.estimation,
|
||||||
reports: 0,
|
reports: 0,
|
||||||
relations: [],
|
relations: [],
|
||||||
childInfo: [],
|
childInfo: []
|
||||||
workDayLength: object.workDayLength,
|
|
||||||
defaultTimeReportDay: object.defaultTimeReportDay
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await client.addCollection(
|
await client.addCollection(
|
||||||
@ -803,7 +788,7 @@
|
|||||||
labels = labels.filter((it) => it._id !== evt.detail)
|
labels = labels.filter((it) => it._id !== evt.detail)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<EstimationEditor kind={'no-border'} size={'small'} value={object} />
|
<EstimationEditor kind={'no-border'} size={'small'} value={object} {currentTeam} />
|
||||||
<ProjectSelector value={object.project} onChange={handleProjectIdChanged} />
|
<ProjectSelector value={object.project} onChange={handleProjectIdChanged} />
|
||||||
<SprintSelector
|
<SprintSelector
|
||||||
value={object.sprint}
|
value={object.sprint}
|
||||||
|
@ -369,7 +369,7 @@
|
|||||||
width={''}
|
width={''}
|
||||||
bind:onlyIcon={fullFilled[issueId]}
|
bind:onlyIcon={fullFilled[issueId]}
|
||||||
/>
|
/>
|
||||||
<EstimationEditor kind={'list'} size={'small'} value={issue} />
|
<EstimationEditor kind={'list'} size={'small'} value={issue} {currentTeam} />
|
||||||
<div
|
<div
|
||||||
class="clear-mins"
|
class="clear-mins"
|
||||||
use:tooltip={{
|
use:tooltip={{
|
||||||
|
@ -65,9 +65,7 @@
|
|||||||
estimation: 0,
|
estimation: 0,
|
||||||
reportedTime: 0,
|
reportedTime: 0,
|
||||||
reports: 0,
|
reports: 0,
|
||||||
childInfo: [],
|
childInfo: []
|
||||||
workDayLength: currentTeam.workDayLength,
|
|
||||||
defaultTimeReportDay: currentTeam.defaultTimeReportDay
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +245,7 @@
|
|||||||
labels = labels.filter((it) => it._id !== evt.detail)
|
labels = labels.filter((it) => it._id !== evt.detail)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<EstimationEditor kind={'no-border'} size={'small'} value={newIssue} />
|
<EstimationEditor kind={'no-border'} size={'small'} value={newIssue} {currentTeam} />
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons-group small-gap">
|
<div class="buttons-group small-gap">
|
||||||
<Button label={presentation.string.Cancel} size="small" kind="transparent" on:click={close} />
|
<Button label={presentation.string.Cancel} size="small" kind="transparent" on:click={close} />
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
import { AttachedData } from '@hcengineering/core'
|
import { AttachedData } from '@hcengineering/core'
|
||||||
|
|
||||||
import { getClient } from '@hcengineering/presentation'
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { Issue } from '@hcengineering/tracker'
|
import { Issue, Team } from '@hcengineering/tracker'
|
||||||
import { Button, ButtonKind, ButtonSize, eventToHTMLElement, showPopup } from '@hcengineering/ui'
|
import { Button, ButtonKind, ButtonSize, eventToHTMLElement, showPopup } from '@hcengineering/ui'
|
||||||
import EditBoxPopup from '@hcengineering/view-resources/src/components/EditBoxPopup.svelte'
|
import EditBoxPopup from '@hcengineering/view-resources/src/components/EditBoxPopup.svelte'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
@ -31,6 +31,7 @@
|
|||||||
export let size: ButtonSize = 'large'
|
export let size: ButtonSize = 'large'
|
||||||
export let justify: 'left' | 'center' = 'left'
|
export let justify: 'left' | 'center' = 'left'
|
||||||
export let width: string | undefined = undefined
|
export let width: string | undefined = undefined
|
||||||
|
export let currentTeam: Team | undefined
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
@ -73,7 +74,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if kind === 'list'}
|
{#if kind === 'list'}
|
||||||
<EstimationStatsPresenter {value} on:click={handleestimationEditorOpened} />
|
<EstimationStatsPresenter {value} on:click={handleestimationEditorOpened} {currentTeam} />
|
||||||
{:else}
|
{:else}
|
||||||
<Button
|
<Button
|
||||||
showTooltip={isEditable ? { label: tracker.string.Estimation } : undefined}
|
showTooltip={isEditable ? { label: tracker.string.Estimation } : undefined}
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
let currentTeam: Team | undefined
|
let currentTeam: Team | undefined
|
||||||
let issueStatuses: WithLookup<IssueStatus>[] | undefined
|
let issueStatuses: WithLookup<IssueStatus>[] | undefined
|
||||||
|
|
||||||
$: defaultTimeReportDay = object.defaultTimeReportDay
|
|
||||||
$: query.query(
|
$: query.query(
|
||||||
object._class,
|
object._class,
|
||||||
{ _id: object._id },
|
{ _id: object._id },
|
||||||
@ -60,6 +59,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||||
|
|
||||||
const statusesQuery = createQuery()
|
const statusesQuery = createQuery()
|
||||||
|
|
||||||
@ -115,7 +115,7 @@
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EstimationStatsPresenter value={object} estimation={_value} />
|
<EstimationStatsPresenter value={object} estimation={_value} {currentTeam} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
@ -147,6 +147,7 @@
|
|||||||
showPopup(
|
showPopup(
|
||||||
TimeSpendReportPopup,
|
TimeSpendReportPopup,
|
||||||
{
|
{
|
||||||
|
issue: object,
|
||||||
issueId: object._id,
|
issueId: object._id,
|
||||||
issueClass: object._class,
|
issueClass: object._class,
|
||||||
space: object.space,
|
space: object.space,
|
||||||
|
@ -15,17 +15,18 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AttachedData } from '@hcengineering/core'
|
import { AttachedData } from '@hcengineering/core'
|
||||||
|
|
||||||
import { Issue } from '@hcengineering/tracker'
|
import { Issue, Team } from '@hcengineering/tracker'
|
||||||
import { floorFractionDigits } from '@hcengineering/ui'
|
import { floorFractionDigits } from '@hcengineering/ui'
|
||||||
import EstimationProgressCircle from './EstimationProgressCircle.svelte'
|
import EstimationProgressCircle from './EstimationProgressCircle.svelte'
|
||||||
import TimePresenter from './TimePresenter.svelte'
|
import TimePresenter from './TimePresenter.svelte'
|
||||||
|
|
||||||
export let value: Issue | AttachedData<Issue>
|
export let value: Issue | AttachedData<Issue>
|
||||||
export let estimation: number | undefined = undefined
|
export let estimation: number | undefined = undefined
|
||||||
|
export let currentTeam: Team | undefined
|
||||||
|
|
||||||
$: _estimation = estimation ?? value.estimation
|
$: _estimation = estimation ?? value.estimation
|
||||||
|
|
||||||
$: workDayLength = value.workDayLength
|
$: workDayLength = currentTeam?.workDayLength
|
||||||
$: childReportTime = floorFractionDigits(
|
$: childReportTime = floorFractionDigits(
|
||||||
value.reportedTime + (value.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0),
|
value.reportedTime + (value.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0),
|
||||||
3
|
3
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
/>
|
/>
|
||||||
</FixedColumn>
|
</FixedColumn>
|
||||||
<FixedColumn key={'estimation'} justify={'left'}>
|
<FixedColumn key={'estimation'} justify={'left'}>
|
||||||
<EstimationEditor value={issue} kind={'list'} />
|
<EstimationEditor value={issue} kind={'list'} {currentTeam} />
|
||||||
</FixedColumn>
|
</FixedColumn>
|
||||||
</div>
|
</div>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
@ -15,30 +15,43 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { IntlString } from '@hcengineering/platform'
|
import type { IntlString } from '@hcengineering/platform'
|
||||||
import { Issue } from '@hcengineering/tracker'
|
import { createQuery } from '@hcengineering/presentation'
|
||||||
|
import tracker, { Issue, Team } from '@hcengineering/tracker'
|
||||||
import { ActionIcon, eventToHTMLElement, floorFractionDigits, IconAdd, Label, showPopup } from '@hcengineering/ui'
|
import { ActionIcon, eventToHTMLElement, floorFractionDigits, IconAdd, Label, showPopup } from '@hcengineering/ui'
|
||||||
import ReportsPopup from './ReportsPopup.svelte'
|
import ReportsPopup from './ReportsPopup.svelte'
|
||||||
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
|
||||||
import TimePresenter from './TimePresenter.svelte'
|
import TimePresenter from './TimePresenter.svelte'
|
||||||
|
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
||||||
|
|
||||||
// export let label: IntlString
|
// export let label: IntlString
|
||||||
export let placeholder: IntlString
|
export let placeholder: IntlString
|
||||||
export let object: Issue
|
export let object: Issue
|
||||||
export let value: number
|
export let value: number
|
||||||
export let kind: 'no-border' | 'link' = 'no-border'
|
export let kind: 'no-border' | 'link' = 'no-border'
|
||||||
|
export let currentTeam: Team | undefined
|
||||||
|
|
||||||
$: defaultTimeReportDay = object.defaultTimeReportDay
|
const spaceQuery = createQuery()
|
||||||
$: workDayLength = object.workDayLength
|
$: if (currentTeam === undefined) {
|
||||||
|
spaceQuery.query(tracker.class.Team, { _id: object.space }, (res) => {
|
||||||
|
currentTeam = res.shift()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
spaceQuery.unsubscribe()
|
||||||
|
}
|
||||||
|
|
||||||
|
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||||
|
$: workDayLength = currentTeam?.workDayLength
|
||||||
|
|
||||||
function addTimeReport (event: MouseEvent): void {
|
function addTimeReport (event: MouseEvent): void {
|
||||||
showPopup(
|
showPopup(
|
||||||
TimeSpendReportPopup,
|
TimeSpendReportPopup,
|
||||||
{
|
{
|
||||||
|
issue: object,
|
||||||
issueId: object._id,
|
issueId: object._id,
|
||||||
defaultTimeReportDay,
|
defaultTimeReportDay,
|
||||||
issueClass: object._class,
|
issueClass: object._class,
|
||||||
space: object.space,
|
space: object.space,
|
||||||
assignee: object.assignee
|
assignee: object.assignee,
|
||||||
|
currentTeam
|
||||||
},
|
},
|
||||||
eventToHTMLElement(event)
|
eventToHTMLElement(event)
|
||||||
)
|
)
|
||||||
|
@ -16,16 +16,17 @@
|
|||||||
import contact from '@hcengineering/contact'
|
import contact from '@hcengineering/contact'
|
||||||
import { FindOptions } from '@hcengineering/core'
|
import { FindOptions } from '@hcengineering/core'
|
||||||
import presentation, { Card } from '@hcengineering/presentation'
|
import presentation, { Card } from '@hcengineering/presentation'
|
||||||
import { Issue, TimeSpendReport } from '@hcengineering/tracker'
|
import { Issue, Team, TimeSpendReport } from '@hcengineering/tracker'
|
||||||
import { Button, eventToHTMLElement, IconAdd, Scroller, tableSP, showPopup } from '@hcengineering/ui'
|
import { Button, eventToHTMLElement, IconAdd, Scroller, showPopup, tableSP } from '@hcengineering/ui'
|
||||||
import { TableBrowser } from '@hcengineering/view-resources'
|
import { TableBrowser } from '@hcengineering/view-resources'
|
||||||
import tracker from '../../../plugin'
|
import tracker from '../../../plugin'
|
||||||
import IssuePresenter from '../IssuePresenter.svelte'
|
import IssuePresenter from '../IssuePresenter.svelte'
|
||||||
import ParentNamesPresenter from '../ParentNamesPresenter.svelte'
|
import ParentNamesPresenter from '../ParentNamesPresenter.svelte'
|
||||||
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
||||||
export let issue: Issue
|
export let issue: Issue
|
||||||
|
export let currentTeam: Team | undefined
|
||||||
|
|
||||||
$: defaultTimeReportDay = issue.defaultTimeReportDay
|
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||||
|
|
||||||
export function canClose (): boolean {
|
export function canClose (): boolean {
|
||||||
return true
|
return true
|
||||||
@ -40,6 +41,7 @@
|
|||||||
showPopup(
|
showPopup(
|
||||||
TimeSpendReportPopup,
|
TimeSpendReportPopup,
|
||||||
{
|
{
|
||||||
|
issue,
|
||||||
issueId: issue._id,
|
issueId: issue._id,
|
||||||
issueClass: issue._class,
|
issueClass: issue._class,
|
||||||
space: issue.space,
|
space: issue.space,
|
||||||
|
@ -15,12 +15,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { WithLookup } from '@hcengineering/core'
|
import { WithLookup } from '@hcengineering/core'
|
||||||
import { getClient } from '@hcengineering/presentation'
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { Issue, TimeSpendReport } from '@hcengineering/tracker'
|
import { Issue, Team, TimeSpendReport } from '@hcengineering/tracker'
|
||||||
import { eventToHTMLElement, showPopup } from '@hcengineering/ui'
|
import { eventToHTMLElement, showPopup } from '@hcengineering/ui'
|
||||||
import TimePresenter from './TimePresenter.svelte'
|
import TimePresenter from './TimePresenter.svelte'
|
||||||
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
||||||
|
|
||||||
export let value: WithLookup<TimeSpendReport>
|
export let value: WithLookup<TimeSpendReport>
|
||||||
|
export let currentTeam: Team | undefined
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
$: issue = value.$lookup?.attachedTo
|
$: issue = value.$lookup?.attachedTo
|
||||||
@ -29,15 +30,16 @@
|
|||||||
issue = r as Issue
|
issue = r as Issue
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
$: workDayLength = issue?.workDayLength
|
$: workDayLength = currentTeam?.workDayLength
|
||||||
$: defaultTimeReportDay = issue?.defaultTimeReportDay
|
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||||
|
|
||||||
function editSpendReport (event: MouseEvent): void {
|
function editSpendReport (event: MouseEvent): void {
|
||||||
showPopup(
|
showPopup(
|
||||||
TimeSpendReportPopup,
|
TimeSpendReportPopup,
|
||||||
{
|
{
|
||||||
issue: value.attachedTo,
|
issue,
|
||||||
issueClass: value.attachedToClass,
|
issueClass: value.attachedToClass,
|
||||||
|
space: value.space,
|
||||||
value,
|
value,
|
||||||
assignee: value.employee,
|
assignee: value.employee,
|
||||||
defaultTimeReportDay
|
defaultTimeReportDay
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
let reports: TimeSpendReport[] | undefined
|
let reports: TimeSpendReport[] | undefined
|
||||||
|
|
||||||
$: workDayLength = issue.workDayLength
|
$: workDayLength = teams.get(issue.space)?.workDayLength
|
||||||
$: subIssuesQuery.query(tracker.class.TimeSpendReport, query, async (result) => (reports = result), {
|
$: subIssuesQuery.query(tracker.class.TimeSpendReport, query, async (result) => (reports = result), {
|
||||||
sort: { modifiedOn: SortingOrder.Descending },
|
sort: { modifiedOn: SortingOrder.Descending },
|
||||||
lookup: {
|
lookup: {
|
||||||
|
@ -51,8 +51,9 @@
|
|||||||
showPopup(
|
showPopup(
|
||||||
TimeSpendReportPopup,
|
TimeSpendReportPopup,
|
||||||
{
|
{
|
||||||
issue: value.attachedTo,
|
issueId: value.attachedTo,
|
||||||
issueClass: value.attachedToClass,
|
issueClass: value.attachedToClass,
|
||||||
|
space: value.space,
|
||||||
value,
|
value,
|
||||||
assignee: value.employee,
|
assignee: value.employee,
|
||||||
defaultTimeReportDay
|
defaultTimeReportDay
|
||||||
|
@ -21,8 +21,12 @@
|
|||||||
export let value: WithLookup<Project>
|
export let value: WithLookup<Project>
|
||||||
export let withIcon = false
|
export let withIcon = false
|
||||||
export let onClick: () => void | undefined
|
export let onClick: () => void | undefined
|
||||||
|
export let isInteractive = true
|
||||||
|
|
||||||
function navigateToProject () {
|
function navigateToProject () {
|
||||||
|
if (!isInteractive) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (onClick) {
|
if (onClick) {
|
||||||
onClick()
|
onClick()
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,12 @@
|
|||||||
export let value: WithLookup<Sprint>
|
export let value: WithLookup<Sprint>
|
||||||
export let withIcon = false
|
export let withIcon = false
|
||||||
export let onClick: () => void | undefined
|
export let onClick: () => void | undefined
|
||||||
|
export let isInteractive = true
|
||||||
|
|
||||||
function navigateToSprint () {
|
function navigateToSprint () {
|
||||||
|
if (!isInteractive) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (onClick) {
|
if (onClick) {
|
||||||
onClick()
|
onClick()
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,11 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte'
|
import core, { generateId, getCurrentAccount, Ref, SortingOrder } from '@hcengineering/core'
|
||||||
|
import { Asset } from '@hcengineering/platform'
|
||||||
|
import presentation, { Card, getClient } from '@hcengineering/presentation'
|
||||||
|
import { StyledTextBox } from '@hcengineering/text-editor'
|
||||||
|
import { genRanks, IssueStatus, Team, TimeReportDayType, WorkDayLength } from '@hcengineering/tracker'
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
DropdownIntlItem,
|
DropdownIntlItem,
|
||||||
@ -24,14 +28,10 @@
|
|||||||
showPopup,
|
showPopup,
|
||||||
ToggleWithLabel
|
ToggleWithLabel
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import presentation, { Card, getClient } from '@hcengineering/presentation'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import core, { generateId, getCurrentAccount, Ref, SortingOrder } from '@hcengineering/core'
|
|
||||||
import { genRanks, IssueStatus, Team, TimeReportDayType, WorkDayLength } from '@hcengineering/tracker'
|
|
||||||
import { StyledTextBox } from '@hcengineering/text-editor'
|
|
||||||
import { Asset } from '@hcengineering/platform'
|
|
||||||
import tracker from '../../plugin'
|
import tracker from '../../plugin'
|
||||||
import TeamIconChooser from './TeamIconChooser.svelte'
|
|
||||||
import TimeReportDayDropdown from '../issues/timereport/TimeReportDayDropdown.svelte'
|
import TimeReportDayDropdown from '../issues/timereport/TimeReportDayDropdown.svelte'
|
||||||
|
import TeamIconChooser from './TeamIconChooser.svelte'
|
||||||
|
|
||||||
export let team: Team | undefined = undefined
|
export let team: Team | undefined = undefined
|
||||||
|
|
||||||
@ -62,6 +62,8 @@
|
|||||||
isNew ? createTeam() : updateTeam()
|
isNew ? createTeam() : updateTeam()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let identifier: string = 'TSK'
|
||||||
|
|
||||||
const defaultStatusId: Ref<IssueStatus> = generateId()
|
const defaultStatusId: Ref<IssueStatus> = generateId()
|
||||||
|
|
||||||
function getTeamData () {
|
function getTeamData () {
|
||||||
@ -71,7 +73,7 @@
|
|||||||
private: isPrivate,
|
private: isPrivate,
|
||||||
members: [getCurrentAccount()._id],
|
members: [getCurrentAccount()._id],
|
||||||
archived: false,
|
archived: false,
|
||||||
identifier: name.toUpperCase().replaceAll(' ', '_'),
|
identifier,
|
||||||
sequence: 0,
|
sequence: 0,
|
||||||
issueStatuses: 0,
|
issueStatuses: 0,
|
||||||
defaultIssueStatus: defaultStatusId,
|
defaultIssueStatus: defaultStatusId,
|
||||||
@ -82,20 +84,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function updateTeam () {
|
async function updateTeam () {
|
||||||
const teamData = getTeamData()
|
const { sequence, issueStatuses, defaultIssueStatus, members, identifier, ...teamData } = getTeamData()
|
||||||
// update team doc
|
// update team doc
|
||||||
await client.update(team!, teamData)
|
await client.update(team!, teamData)
|
||||||
|
|
||||||
// update issues related to team
|
|
||||||
const issuesByTeam = await client.findAll(tracker.class.Issue, { space: team!._id })
|
|
||||||
await Promise.all(
|
|
||||||
issuesByTeam.map((issue) =>
|
|
||||||
client.update(issue, {
|
|
||||||
defaultTimeReportDay: teamData.defaultTimeReportDay,
|
|
||||||
workDayLength: teamData.workDayLength
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createTeam () {
|
async function createTeam () {
|
||||||
@ -149,7 +140,23 @@
|
|||||||
dispatch('close')
|
dispatch('close')
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EditBox bind:value={name} placeholder={tracker.string.TeamTitlePlaceholder} kind={'large-style'} focus />
|
<div class="flex-row-center flex-between">
|
||||||
|
<EditBox
|
||||||
|
bind:value={name}
|
||||||
|
placeholder={tracker.string.TeamTitlePlaceholder}
|
||||||
|
kind={'large-style'}
|
||||||
|
focus
|
||||||
|
on:input={() => {
|
||||||
|
identifier = name.toLocaleUpperCase().replaceAll(' ', '_').substring(0, 5)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<EditBox
|
||||||
|
bind:value={identifier}
|
||||||
|
disabled={!isNew}
|
||||||
|
placeholder={tracker.string.TeamIdentifierPlaceholder}
|
||||||
|
kind={'large-style'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<StyledTextBox
|
<StyledTextBox
|
||||||
alwaysEdit
|
alwaysEdit
|
||||||
showButtons={false}
|
showButtons={false}
|
||||||
|
@ -66,6 +66,7 @@ export default mergeIds(trackerId, tracker, {
|
|||||||
CreateTeam: '' as IntlString,
|
CreateTeam: '' as IntlString,
|
||||||
NewTeam: '' as IntlString,
|
NewTeam: '' as IntlString,
|
||||||
TeamTitlePlaceholder: '' as IntlString,
|
TeamTitlePlaceholder: '' as IntlString,
|
||||||
|
TeamIdentifierPlaceholder: '' as IntlString,
|
||||||
MakePrivate: '' as IntlString,
|
MakePrivate: '' as IntlString,
|
||||||
MakePrivateDescription: '' as IntlString,
|
MakePrivateDescription: '' as IntlString,
|
||||||
ChooseIcon: '' as IntlString,
|
ChooseIcon: '' as IntlString,
|
||||||
|
@ -193,9 +193,6 @@ export interface Issue extends AttachedDoc {
|
|||||||
|
|
||||||
childInfo: IssueChildInfo[]
|
childInfo: IssueChildInfo[]
|
||||||
|
|
||||||
workDayLength: WorkDayLength
|
|
||||||
defaultTimeReportDay: TimeReportDayType
|
|
||||||
|
|
||||||
template?: {
|
template?: {
|
||||||
// A template issue is based on
|
// A template issue is based on
|
||||||
template: Ref<IssueTemplate>
|
template: Ref<IssueTemplate>
|
||||||
|
Loading…
Reference in New Issue
Block a user