mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-23 18:15:03 +02:00
TSK-651: Fix Team editing (#2611)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
@@ -13,7 +13,6 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { AttachmentStyledBox } from '@hcengineering/attachment-resources'
|
||||
import chunter from '@hcengineering/chunter'
|
||||
import { Employee } from '@hcengineering/contact'
|
||||
@@ -49,9 +48,7 @@
|
||||
IssueTemplateChild,
|
||||
Project,
|
||||
Sprint,
|
||||
Team,
|
||||
TimeReportDayType,
|
||||
WorkDayLength
|
||||
Team
|
||||
} from '@hcengineering/tracker'
|
||||
import {
|
||||
ActionIcon,
|
||||
@@ -69,10 +66,12 @@
|
||||
} from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import { ObjectBox } from '@hcengineering/view-resources'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { activeProject, activeSprint, generateIssueShortLink, getIssueId, updateIssueRelation } from '../issues'
|
||||
import tracker from '../plugin'
|
||||
import AssigneeEditor from './issues/AssigneeEditor.svelte'
|
||||
import IssueNotification from './issues/IssueNotification.svelte'
|
||||
import ParentIssue from './issues/ParentIssue.svelte'
|
||||
import PriorityEditor from './issues/PriorityEditor.svelte'
|
||||
import StatusEditor from './issues/StatusEditor.svelte'
|
||||
@@ -82,7 +81,6 @@
|
||||
import SetParentIssueActionPopup from './SetParentIssueActionPopup.svelte'
|
||||
import SprintSelector from './sprints/SprintSelector.svelte'
|
||||
import IssueTemplateChilds from './templates/IssueTemplateChilds.svelte'
|
||||
import IssueNotification from './issues/IssueNotification.svelte'
|
||||
|
||||
export let space: Ref<Team>
|
||||
export let status: Ref<IssueStatus> | undefined = undefined
|
||||
@@ -130,9 +128,7 @@
|
||||
reportedTime: 0,
|
||||
estimation: 0,
|
||||
reports: 0,
|
||||
childInfo: [],
|
||||
workDayLength: currentTeam?.workDayLength ?? WorkDayLength.EIGHT_HOURS,
|
||||
defaultTimeReportDay: currentTeam?.defaultTimeReportDay ?? TimeReportDayType.PreviousWorkDay
|
||||
childInfo: []
|
||||
}
|
||||
|
||||
let object = originalIssue
|
||||
@@ -147,13 +143,6 @@
|
||||
}
|
||||
: 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 {
|
||||
templateId = undefined
|
||||
template = undefined
|
||||
@@ -453,9 +442,7 @@
|
||||
estimation: object.estimation,
|
||||
reports: 0,
|
||||
relations: relatedTo !== undefined ? [{ _id: relatedTo._id, _class: relatedTo._class }] : [],
|
||||
childInfo: [],
|
||||
workDayLength: object.workDayLength,
|
||||
defaultTimeReportDay: object.defaultTimeReportDay
|
||||
childInfo: []
|
||||
}
|
||||
|
||||
await client.addCollection(
|
||||
@@ -527,9 +514,7 @@
|
||||
estimation: subIssue.estimation,
|
||||
reports: 0,
|
||||
relations: [],
|
||||
childInfo: [],
|
||||
workDayLength: object.workDayLength,
|
||||
defaultTimeReportDay: object.defaultTimeReportDay
|
||||
childInfo: []
|
||||
}
|
||||
|
||||
await client.addCollection(
|
||||
@@ -803,7 +788,7 @@
|
||||
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} />
|
||||
<SprintSelector
|
||||
value={object.sprint}
|
||||
|
||||
@@ -369,7 +369,7 @@
|
||||
width={''}
|
||||
bind:onlyIcon={fullFilled[issueId]}
|
||||
/>
|
||||
<EstimationEditor kind={'list'} size={'small'} value={issue} />
|
||||
<EstimationEditor kind={'list'} size={'small'} value={issue} {currentTeam} />
|
||||
<div
|
||||
class="clear-mins"
|
||||
use:tooltip={{
|
||||
|
||||
@@ -65,9 +65,7 @@
|
||||
estimation: 0,
|
||||
reportedTime: 0,
|
||||
reports: 0,
|
||||
childInfo: [],
|
||||
workDayLength: currentTeam.workDayLength,
|
||||
defaultTimeReportDay: currentTeam.defaultTimeReportDay
|
||||
childInfo: []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +245,7 @@
|
||||
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 class="buttons-group small-gap">
|
||||
<Button label={presentation.string.Cancel} size="small" kind="transparent" on:click={close} />
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { AttachedData } from '@hcengineering/core'
|
||||
|
||||
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 EditBoxPopup from '@hcengineering/view-resources/src/components/EditBoxPopup.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
@@ -31,6 +31,7 @@
|
||||
export let size: ButtonSize = 'large'
|
||||
export let justify: 'left' | 'center' = 'left'
|
||||
export let width: string | undefined = undefined
|
||||
export let currentTeam: Team | undefined
|
||||
|
||||
const client = getClient()
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -73,7 +74,7 @@
|
||||
|
||||
{#if value}
|
||||
{#if kind === 'list'}
|
||||
<EstimationStatsPresenter {value} on:click={handleestimationEditorOpened} />
|
||||
<EstimationStatsPresenter {value} on:click={handleestimationEditorOpened} {currentTeam} />
|
||||
{:else}
|
||||
<Button
|
||||
showTooltip={isEditable ? { label: tracker.string.Estimation } : undefined}
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
let currentTeam: Team | undefined
|
||||
let issueStatuses: WithLookup<IssueStatus>[] | undefined
|
||||
|
||||
$: defaultTimeReportDay = object.defaultTimeReportDay
|
||||
$: query.query(
|
||||
object._class,
|
||||
{ _id: object._id },
|
||||
@@ -60,6 +59,7 @@
|
||||
}
|
||||
}
|
||||
)
|
||||
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||
|
||||
const statusesQuery = createQuery()
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
)
|
||||
}}
|
||||
>
|
||||
<EstimationStatsPresenter value={object} estimation={_value} />
|
||||
<EstimationStatsPresenter value={object} estimation={_value} {currentTeam} />
|
||||
</div>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
@@ -147,6 +147,7 @@
|
||||
showPopup(
|
||||
TimeSpendReportPopup,
|
||||
{
|
||||
issue: object,
|
||||
issueId: object._id,
|
||||
issueClass: object._class,
|
||||
space: object.space,
|
||||
|
||||
+3
-2
@@ -15,17 +15,18 @@
|
||||
<script lang="ts">
|
||||
import { AttachedData } from '@hcengineering/core'
|
||||
|
||||
import { Issue } from '@hcengineering/tracker'
|
||||
import { Issue, Team } from '@hcengineering/tracker'
|
||||
import { floorFractionDigits } from '@hcengineering/ui'
|
||||
import EstimationProgressCircle from './EstimationProgressCircle.svelte'
|
||||
import TimePresenter from './TimePresenter.svelte'
|
||||
|
||||
export let value: Issue | AttachedData<Issue>
|
||||
export let estimation: number | undefined = undefined
|
||||
export let currentTeam: Team | undefined
|
||||
|
||||
$: _estimation = estimation ?? value.estimation
|
||||
|
||||
$: workDayLength = value.workDayLength
|
||||
$: workDayLength = currentTeam?.workDayLength
|
||||
$: childReportTime = floorFractionDigits(
|
||||
value.reportedTime + (value.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0),
|
||||
3
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@
|
||||
/>
|
||||
</FixedColumn>
|
||||
<FixedColumn key={'estimation'} justify={'left'}>
|
||||
<EstimationEditor value={issue} kind={'list'} />
|
||||
<EstimationEditor value={issue} kind={'list'} {currentTeam} />
|
||||
</FixedColumn>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
+18
-5
@@ -15,30 +15,43 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
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 ReportsPopup from './ReportsPopup.svelte'
|
||||
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
||||
import TimePresenter from './TimePresenter.svelte'
|
||||
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
||||
|
||||
// export let label: IntlString
|
||||
export let placeholder: IntlString
|
||||
export let object: Issue
|
||||
export let value: number
|
||||
export let kind: 'no-border' | 'link' = 'no-border'
|
||||
export let currentTeam: Team | undefined
|
||||
|
||||
$: defaultTimeReportDay = object.defaultTimeReportDay
|
||||
$: workDayLength = object.workDayLength
|
||||
const spaceQuery = createQuery()
|
||||
$: 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 {
|
||||
showPopup(
|
||||
TimeSpendReportPopup,
|
||||
{
|
||||
issue: object,
|
||||
issueId: object._id,
|
||||
defaultTimeReportDay,
|
||||
issueClass: object._class,
|
||||
space: object.space,
|
||||
assignee: object.assignee
|
||||
assignee: object.assignee,
|
||||
currentTeam
|
||||
},
|
||||
eventToHTMLElement(event)
|
||||
)
|
||||
|
||||
@@ -16,16 +16,17 @@
|
||||
import contact from '@hcengineering/contact'
|
||||
import { FindOptions } from '@hcengineering/core'
|
||||
import presentation, { Card } from '@hcengineering/presentation'
|
||||
import { Issue, TimeSpendReport } from '@hcengineering/tracker'
|
||||
import { Button, eventToHTMLElement, IconAdd, Scroller, tableSP, showPopup } from '@hcengineering/ui'
|
||||
import { Issue, Team, TimeSpendReport } from '@hcengineering/tracker'
|
||||
import { Button, eventToHTMLElement, IconAdd, Scroller, showPopup, tableSP } from '@hcengineering/ui'
|
||||
import { TableBrowser } from '@hcengineering/view-resources'
|
||||
import tracker from '../../../plugin'
|
||||
import IssuePresenter from '../IssuePresenter.svelte'
|
||||
import ParentNamesPresenter from '../ParentNamesPresenter.svelte'
|
||||
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
||||
export let issue: Issue
|
||||
export let currentTeam: Team | undefined
|
||||
|
||||
$: defaultTimeReportDay = issue.defaultTimeReportDay
|
||||
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||
|
||||
export function canClose (): boolean {
|
||||
return true
|
||||
@@ -40,6 +41,7 @@
|
||||
showPopup(
|
||||
TimeSpendReportPopup,
|
||||
{
|
||||
issue,
|
||||
issueId: issue._id,
|
||||
issueClass: issue._class,
|
||||
space: issue.space,
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
<script lang="ts">
|
||||
import { WithLookup } from '@hcengineering/core'
|
||||
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 TimePresenter from './TimePresenter.svelte'
|
||||
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
||||
|
||||
export let value: WithLookup<TimeSpendReport>
|
||||
export let currentTeam: Team | undefined
|
||||
const client = getClient()
|
||||
|
||||
$: issue = value.$lookup?.attachedTo
|
||||
@@ -29,15 +30,16 @@
|
||||
issue = r as Issue
|
||||
})
|
||||
}
|
||||
$: workDayLength = issue?.workDayLength
|
||||
$: defaultTimeReportDay = issue?.defaultTimeReportDay
|
||||
$: workDayLength = currentTeam?.workDayLength
|
||||
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||
|
||||
function editSpendReport (event: MouseEvent): void {
|
||||
showPopup(
|
||||
TimeSpendReportPopup,
|
||||
{
|
||||
issue: value.attachedTo,
|
||||
issue,
|
||||
issueClass: value.attachedToClass,
|
||||
space: value.space,
|
||||
value,
|
||||
assignee: value.employee,
|
||||
defaultTimeReportDay
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
let reports: TimeSpendReport[] | undefined
|
||||
|
||||
$: workDayLength = issue.workDayLength
|
||||
$: workDayLength = teams.get(issue.space)?.workDayLength
|
||||
$: subIssuesQuery.query(tracker.class.TimeSpendReport, query, async (result) => (reports = result), {
|
||||
sort: { modifiedOn: SortingOrder.Descending },
|
||||
lookup: {
|
||||
|
||||
+2
-1
@@ -51,8 +51,9 @@
|
||||
showPopup(
|
||||
TimeSpendReportPopup,
|
||||
{
|
||||
issue: value.attachedTo,
|
||||
issueId: value.attachedTo,
|
||||
issueClass: value.attachedToClass,
|
||||
space: value.space,
|
||||
value,
|
||||
assignee: value.employee,
|
||||
defaultTimeReportDay
|
||||
|
||||
@@ -21,8 +21,12 @@
|
||||
export let value: WithLookup<Project>
|
||||
export let withIcon = false
|
||||
export let onClick: () => void | undefined
|
||||
export let isInteractive = true
|
||||
|
||||
function navigateToProject () {
|
||||
if (!isInteractive) {
|
||||
return
|
||||
}
|
||||
if (onClick) {
|
||||
onClick()
|
||||
}
|
||||
|
||||
@@ -21,8 +21,12 @@
|
||||
export let value: WithLookup<Sprint>
|
||||
export let withIcon = false
|
||||
export let onClick: () => void | undefined
|
||||
export let isInteractive = true
|
||||
|
||||
function navigateToSprint () {
|
||||
if (!isInteractive) {
|
||||
return
|
||||
}
|
||||
if (onClick) {
|
||||
onClick()
|
||||
}
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<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 {
|
||||
Button,
|
||||
DropdownIntlItem,
|
||||
@@ -24,14 +28,10 @@
|
||||
showPopup,
|
||||
ToggleWithLabel
|
||||
} from '@hcengineering/ui'
|
||||
import presentation, { Card, getClient } from '@hcengineering/presentation'
|
||||
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 { createEventDispatcher } from 'svelte'
|
||||
import tracker from '../../plugin'
|
||||
import TeamIconChooser from './TeamIconChooser.svelte'
|
||||
import TimeReportDayDropdown from '../issues/timereport/TimeReportDayDropdown.svelte'
|
||||
import TeamIconChooser from './TeamIconChooser.svelte'
|
||||
|
||||
export let team: Team | undefined = undefined
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
isNew ? createTeam() : updateTeam()
|
||||
}
|
||||
|
||||
let identifier: string = 'TSK'
|
||||
|
||||
const defaultStatusId: Ref<IssueStatus> = generateId()
|
||||
|
||||
function getTeamData () {
|
||||
@@ -71,7 +73,7 @@
|
||||
private: isPrivate,
|
||||
members: [getCurrentAccount()._id],
|
||||
archived: false,
|
||||
identifier: name.toUpperCase().replaceAll(' ', '_'),
|
||||
identifier,
|
||||
sequence: 0,
|
||||
issueStatuses: 0,
|
||||
defaultIssueStatus: defaultStatusId,
|
||||
@@ -82,20 +84,9 @@
|
||||
}
|
||||
|
||||
async function updateTeam () {
|
||||
const teamData = getTeamData()
|
||||
const { sequence, issueStatuses, defaultIssueStatus, members, identifier, ...teamData } = getTeamData()
|
||||
// update team doc
|
||||
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 () {
|
||||
@@ -149,7 +140,23 @@
|
||||
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
|
||||
alwaysEdit
|
||||
showButtons={false}
|
||||
|
||||
Reference in New Issue
Block a user