mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-22 17:45:02 +02:00
TSK-810 Rename Team -> Project, Project -> Component (#2756)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
@@ -15,11 +15,11 @@
|
||||
<script lang="ts">
|
||||
import { DocumentQuery, Ref } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Issue, Team } from '@hcengineering/tracker'
|
||||
import { Issue, Project } from '@hcengineering/tracker'
|
||||
import tracker from '../../plugin'
|
||||
import IssuesView from './IssuesView.svelte'
|
||||
|
||||
export let currentSpace: Ref<Team>
|
||||
export let currentSpace: Ref<Project>
|
||||
|
||||
const statusQuery = createQuery()
|
||||
let query: DocumentQuery<Issue>
|
||||
|
||||
@@ -44,20 +44,20 @@
|
||||
return (issue as Issue).space !== undefined
|
||||
}
|
||||
|
||||
async function updateProjectMembers (issue: Issue | AttachedData<Issue> | IssueTemplateData) {
|
||||
if (issue.project) {
|
||||
const project = await client.findOne(tracker.class.Project, { _id: issue.project })
|
||||
projectLead = project?.lead || undefined
|
||||
projectMembers = project?.members || []
|
||||
async function updateComponentMembers (issue: Issue | AttachedData<Issue> | IssueTemplateData) {
|
||||
if (issue.component) {
|
||||
const component = await client.findOne(tracker.class.Component, { _id: issue.component })
|
||||
projectLead = component?.lead || undefined
|
||||
projectMembers = component?.members || []
|
||||
} else {
|
||||
projectLead = undefined
|
||||
projectMembers = []
|
||||
}
|
||||
if (hasSpace(issue)) {
|
||||
const team = await client.findOne(tracker.class.Team, { _id: issue.space })
|
||||
if (team !== undefined) {
|
||||
const project = await client.findOne(tracker.class.Project, { _id: issue.space })
|
||||
if (project !== undefined) {
|
||||
const accounts = await client.findAll(contact.class.EmployeeAccount, {
|
||||
_id: { $in: team.members as Ref<EmployeeAccount>[] }
|
||||
_id: { $in: project.members as Ref<EmployeeAccount>[] }
|
||||
})
|
||||
members = accounts.map((p) => p.employee)
|
||||
} else {
|
||||
@@ -66,7 +66,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: updateProjectMembers(value)
|
||||
$: updateComponentMembers(value)
|
||||
|
||||
const handleAssigneeChanged = async (newAssignee: Ref<Employee> | undefined) => {
|
||||
if (newAssignee === undefined || value.assignee === newAssignee) {
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
<script lang="ts">
|
||||
import { DocumentQuery, Ref } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Issue, Team } from '@hcengineering/tracker'
|
||||
import { Issue, Project } from '@hcengineering/tracker'
|
||||
import tracker from '../../plugin'
|
||||
import IssuesView from './IssuesView.svelte'
|
||||
|
||||
export let currentSpace: Ref<Team>
|
||||
export let currentSpace: Ref<Project>
|
||||
|
||||
const statusQuery = createQuery()
|
||||
let query: DocumentQuery<Issue> = {}
|
||||
|
||||
+9
-9
@@ -30,22 +30,22 @@
|
||||
const elements: FilterSectionElement[] = []
|
||||
|
||||
const client = getClient()
|
||||
const projects = await client.findAll(tracker.class.Project, {})
|
||||
const components = await client.findAll(tracker.class.Component, {})
|
||||
for (const [key, value] of Object.entries(groups)) {
|
||||
const project = key === 'null' ? null : key
|
||||
const label = project
|
||||
? projects.find(({ _id }) => _id === project)?.label
|
||||
: await translate(tracker.string.NoProject, {})
|
||||
const component = key === 'null' ? null : key
|
||||
const label = component
|
||||
? components.find(({ _id }) => _id === component)?.label
|
||||
: await translate(tracker.string.NoComponent, {})
|
||||
|
||||
if (!label) {
|
||||
continue
|
||||
}
|
||||
elements.splice(project ? 1 : 0, 0, {
|
||||
icon: tracker.icon.Project,
|
||||
elements.splice(component ? 1 : 0, 0, {
|
||||
icon: tracker.icon.Component,
|
||||
title: label,
|
||||
count: value,
|
||||
isSelected: selected.includes(project),
|
||||
onSelect: () => onUpdate({ project }, index)
|
||||
isSelected: selected.includes(component),
|
||||
onSelect: () => onUpdate({ component }, index)
|
||||
})
|
||||
}
|
||||
return onBack
|
||||
@@ -15,13 +15,13 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { WithLookup } from '@hcengineering/core'
|
||||
import type { Issue, Team } from '@hcengineering/tracker'
|
||||
import type { Issue, Project } from '@hcengineering/tracker'
|
||||
import { Icon } from '@hcengineering/ui'
|
||||
import tracker from '../../plugin'
|
||||
import { getIssueId } from '../../issues'
|
||||
|
||||
export let value: WithLookup<Issue>
|
||||
$: title = getIssueId(value.$lookup?.space as Team, value)
|
||||
$: title = getIssueId(value.$lookup?.space as Project, value)
|
||||
</script>
|
||||
|
||||
<div class="flex item">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import { Ref, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import type { Issue, Team } from '@hcengineering/tracker'
|
||||
import type { Issue, Project } from '@hcengineering/tracker'
|
||||
import { Icon, tooltip } from '@hcengineering/ui'
|
||||
import { DocNavLink } from '@hcengineering/view-resources'
|
||||
import tracker from '../../plugin'
|
||||
@@ -28,22 +28,22 @@
|
||||
export let inline = false
|
||||
|
||||
// Extra properties
|
||||
export let teams: Map<Ref<Team>, Team> | undefined = undefined
|
||||
export let projects: Map<Ref<Project>, Project> | undefined = undefined
|
||||
|
||||
const spaceQuery = createQuery()
|
||||
let currentTeam: Team | undefined = value?.$lookup?.space
|
||||
let currentProject: Project | undefined = value?.$lookup?.space
|
||||
|
||||
$: if (teams === undefined) {
|
||||
$: if (projects === undefined) {
|
||||
if (value && value?.$lookup?.space === undefined) {
|
||||
spaceQuery.query(tracker.class.Team, { _id: value.space }, (res) => ([currentTeam] = res))
|
||||
spaceQuery.query(tracker.class.Project, { _id: value.space }, (res) => ([currentProject] = res))
|
||||
} else {
|
||||
spaceQuery.unsubscribe()
|
||||
}
|
||||
} else {
|
||||
currentTeam = teams.get(value.space)
|
||||
currentProject = projects.get(value.space)
|
||||
}
|
||||
|
||||
$: title = currentTeam ? `${currentTeam.identifier}-${value?.number}` : `${value?.number}`
|
||||
$: title = currentProject ? `${currentProject.identifier}-${value?.number}` : `${value?.number}`
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import { CommentPopup } from '@hcengineering/chunter-resources'
|
||||
import { Ref, SortingOrder } from '@hcengineering/core'
|
||||
import { createQuery, getClient, MessageViewer } from '@hcengineering/presentation'
|
||||
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||
import { Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import { Label, resizeObserver, Scroller } from '@hcengineering/ui'
|
||||
import tracker from '../../plugin'
|
||||
import AssigneeEditor from './AssigneeEditor.svelte'
|
||||
@@ -57,10 +57,10 @@
|
||||
sort: { rank: SortingOrder.Ascending }
|
||||
}
|
||||
)
|
||||
let currentTeam: Team | undefined
|
||||
let currentProject: Project | undefined
|
||||
|
||||
$: spaceQuery.query(tracker.class.Team, { _id: space }, (res) => ([currentTeam] = res))
|
||||
$: issueName = currentTeam && issue && `${currentTeam.identifier}-${issue.number}`
|
||||
$: spaceQuery.query(tracker.class.Project, { _id: space }, (res) => ([currentProject] = res))
|
||||
$: issueName = currentProject && issue && `${currentProject.identifier}-${issue.number}`
|
||||
|
||||
const limit: number = 350
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Ref } from '@hcengineering/core'
|
||||
import { Team } from '@hcengineering/tracker'
|
||||
import { Project } from '@hcengineering/tracker'
|
||||
import tracker from '../../plugin'
|
||||
import IssuesView from './IssuesView.svelte'
|
||||
|
||||
export let currentSpace: Ref<Team>
|
||||
export let currentSpace: Ref<Project>
|
||||
|
||||
$: query = { space: currentSpace }
|
||||
</script>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
} from '../../utils'
|
||||
import FilterMenu from '../FilterMenu.svelte'
|
||||
import PriorityFilterMenuSection from './PriorityFilterMenuSection.svelte'
|
||||
import ProjectFilterMenuSection from './ProjectFilterMenuSection.svelte'
|
||||
import ComponentFilterMenuSection from './ComponentFilterMenuSection.svelte'
|
||||
import SprintFilterMenuSection from './SprintFilterMenuSection.svelte'
|
||||
import StatusFilterMenuSection from './StatusFilterMenuSection.svelte'
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
$: defaultStatusIds = defaultStatuses.map((x) => x._id)
|
||||
$: groupedByStatus = getGroupedIssues('status', issues, defaultStatusIds)
|
||||
$: groupedByPriority = getGroupedIssues('priority', issues, defaultPriorities)
|
||||
$: groupedByProject = getGroupedIssues('project', issues)
|
||||
$: groupedByComponent = getGroupedIssues('component', issues)
|
||||
$: groupedBySprint = getGroupedIssues('sprint', issues)
|
||||
|
||||
const handleStatusFilterMenuSectionOpened = () => {
|
||||
@@ -86,17 +86,17 @@
|
||||
)
|
||||
}
|
||||
|
||||
const handleProjectFilterMenuSectionOpened = () => {
|
||||
const projectGroups: { [key: string]: number } = {}
|
||||
const handleComponentFilterMenuSectionOpened = () => {
|
||||
const componentGroups: { [key: string]: number } = {}
|
||||
|
||||
for (const [project, value] of Object.entries(groupedByProject)) {
|
||||
projectGroups[project] = value?.length ?? 0
|
||||
for (const [component, value] of Object.entries(groupedByComponent)) {
|
||||
componentGroups[component] = value?.length ?? 0
|
||||
}
|
||||
showPopup(
|
||||
ProjectFilterMenuSection,
|
||||
ComponentFilterMenuSection,
|
||||
{
|
||||
groups: projectGroups,
|
||||
selectedElements: currentFilterQuery?.project?.[currentFilterMode] ?? [],
|
||||
groups: componentGroups,
|
||||
selectedElements: currentFilterQuery?.component?.[currentFilterMode] ?? [],
|
||||
index,
|
||||
onUpdate,
|
||||
onBack
|
||||
@@ -108,8 +108,8 @@
|
||||
const handleSprintFilterMenuSectionOpened = () => {
|
||||
const sprintGroups: { [key: string]: number } = {}
|
||||
|
||||
for (const [project, value] of Object.entries(groupedBySprint)) {
|
||||
sprintGroups[project] = value?.length ?? 0
|
||||
for (const [sprint, value] of Object.entries(groupedBySprint)) {
|
||||
sprintGroups[sprint] = value?.length ?? 0
|
||||
}
|
||||
showPopup(
|
||||
SprintFilterMenuSection,
|
||||
@@ -134,8 +134,8 @@
|
||||
onSelect: handlePriorityFilterMenuSectionOpened
|
||||
},
|
||||
{
|
||||
...getIssueFilterAssetsByType('project'),
|
||||
onSelect: handleProjectFilterMenuSectionOpened
|
||||
...getIssueFilterAssetsByType('component'),
|
||||
onSelect: handleComponentFilterMenuSectionOpened
|
||||
},
|
||||
{
|
||||
...getIssueFilterAssetsByType('sprint'),
|
||||
|
||||
@@ -20,7 +20,15 @@
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import tags from '@hcengineering/tags'
|
||||
import { Issue, IssuesGrouping, IssuesOrdering, IssueStatus, Project, Sprint, Team } from '@hcengineering/tracker'
|
||||
import {
|
||||
Issue,
|
||||
IssuesGrouping,
|
||||
IssuesOrdering,
|
||||
IssueStatus,
|
||||
Component as ComponentType,
|
||||
Sprint,
|
||||
Project
|
||||
} from '@hcengineering/tracker'
|
||||
import {
|
||||
Button,
|
||||
Component,
|
||||
@@ -47,7 +55,7 @@
|
||||
import tracker from '../../plugin'
|
||||
import { issuesGroupBySorting, mapKanbanCategories } from '../../utils'
|
||||
import CreateIssue from '../CreateIssue.svelte'
|
||||
import ProjectEditor from '../projects/ProjectEditor.svelte'
|
||||
import ComponentEditor from '../components/ComponentEditor.svelte'
|
||||
import AssigneePresenter from './AssigneePresenter.svelte'
|
||||
import SubIssuesSelector from './edit/SubIssuesSelector.svelte'
|
||||
import IssuePresenter from './IssuePresenter.svelte'
|
||||
@@ -57,13 +65,13 @@
|
||||
import StatusEditor from './StatusEditor.svelte'
|
||||
import EstimationEditor from './timereport/EstimationEditor.svelte'
|
||||
|
||||
export let space: Ref<Team> | undefined = undefined
|
||||
export let space: Ref<Project> | undefined = undefined
|
||||
export let baseMenuClass: Ref<Class<Doc>> | undefined = undefined
|
||||
export let query: DocumentQuery<Issue> = {}
|
||||
export let viewOptionsConfig: ViewOptionModel[] | undefined
|
||||
export let viewOptions: ViewOptions
|
||||
|
||||
$: currentSpace = space || tracker.team.DefaultTeam
|
||||
$: currentSpace = space || tracker.project.DefaultProject
|
||||
$: groupBy = (viewOptions.groupBy[0] ?? noCategory) as IssuesGrouping
|
||||
$: orderBy = viewOptions.orderBy
|
||||
$: sort = { [orderBy[0]]: orderBy[1] }
|
||||
@@ -71,9 +79,9 @@
|
||||
|
||||
const spaceQuery = createQuery()
|
||||
|
||||
let currentTeam: Team | undefined
|
||||
$: spaceQuery.query(tracker.class.Team, { _id: currentSpace }, (res) => {
|
||||
currentTeam = res.shift()
|
||||
let currentProject: Project | undefined
|
||||
$: spaceQuery.query(tracker.class.Project, { _id: currentSpace }, (res) => {
|
||||
currentProject = res.shift()
|
||||
})
|
||||
|
||||
let resultQuery: DocumentQuery<any> = query
|
||||
@@ -104,7 +112,7 @@
|
||||
|
||||
const lookup: Lookup<Issue> = {
|
||||
assignee: contact.class.Employee,
|
||||
space: tracker.class.Team,
|
||||
space: tracker.class.Project,
|
||||
_id: {
|
||||
subIssues: tracker.class.Issue
|
||||
}
|
||||
@@ -128,7 +136,7 @@
|
||||
let issues: Issue[] = []
|
||||
const lookupIssue: Lookup<Issue> = {
|
||||
status: tracker.class.IssueStatus,
|
||||
project: tracker.class.Project,
|
||||
component: tracker.class.Component,
|
||||
sprint: tracker.class.Sprint,
|
||||
assignee: contact.class.Employee
|
||||
}
|
||||
@@ -167,15 +175,15 @@
|
||||
}
|
||||
)
|
||||
|
||||
const projectsQuery = createQuery()
|
||||
let projects: Project[] = []
|
||||
$: projectsQuery.query(
|
||||
tracker.class.Project,
|
||||
const componentsQuery = createQuery()
|
||||
let components: ComponentType[] = []
|
||||
$: componentsQuery.query(
|
||||
tracker.class.Component,
|
||||
{
|
||||
space: currentSpace
|
||||
},
|
||||
(result) => {
|
||||
projects = result
|
||||
components = result
|
||||
}
|
||||
)
|
||||
|
||||
@@ -202,7 +210,7 @@
|
||||
viewOptions,
|
||||
viewOptionsConfig,
|
||||
statuses,
|
||||
projects,
|
||||
components,
|
||||
sprints,
|
||||
assignee
|
||||
)
|
||||
@@ -215,7 +223,7 @@
|
||||
viewOptions,
|
||||
viewOptionsConfig,
|
||||
statuses,
|
||||
projects,
|
||||
components,
|
||||
sprints,
|
||||
assignee
|
||||
)
|
||||
@@ -228,7 +236,7 @@
|
||||
viewOptions: ViewOptions,
|
||||
viewOptionsModel: ViewOptionModel[] | undefined,
|
||||
statuses: WithLookup<IssueStatus>[],
|
||||
projects: Project[],
|
||||
components: ComponentType[],
|
||||
sprints: Sprint[],
|
||||
assignee: Employee[]
|
||||
) {
|
||||
@@ -251,7 +259,7 @@
|
||||
}
|
||||
}
|
||||
const indexes = new Map(categories.map((p, i) => [p, i]))
|
||||
const res = await mapKanbanCategories(groupByKey, categories, statuses, projects, sprints, assignee)
|
||||
const res = await mapKanbanCategories(groupByKey, categories, statuses, components, sprints, assignee)
|
||||
res.sort((a, b) => {
|
||||
const aIndex = indexes.get(a._id ?? undefined) ?? -1
|
||||
const bIndex = indexes.get(b._id ?? undefined) ?? -1
|
||||
@@ -357,10 +365,10 @@
|
||||
</div>
|
||||
<div class="buttons-group xsmall-gap states-bar">
|
||||
{#if issue && issue.subIssues > 0}
|
||||
<SubIssuesSelector value={issue} {currentTeam} />
|
||||
<SubIssuesSelector value={issue} {currentProject} />
|
||||
{/if}
|
||||
<PriorityEditor value={issue} isEditable={true} kind={'link-bordered'} size={'inline'} justify={'center'} />
|
||||
<ProjectEditor
|
||||
<ComponentEditor
|
||||
value={issue}
|
||||
isEditable={true}
|
||||
kind={'link-bordered'}
|
||||
@@ -369,7 +377,7 @@
|
||||
width={''}
|
||||
bind:onlyIcon={fullFilled[issueId]}
|
||||
/>
|
||||
<EstimationEditor kind={'list'} size={'small'} value={issue} {currentTeam} />
|
||||
<EstimationEditor kind={'list'} size={'small'} value={issue} {currentProject} />
|
||||
<div
|
||||
class="clear-mins"
|
||||
use:tooltip={{
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Team, Issue } from '@hcengineering/tracker'
|
||||
import { Project, Issue } from '@hcengineering/tracker'
|
||||
import { Spinner, IconClose, tooltip } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import tracker from '../../plugin'
|
||||
@@ -25,10 +25,10 @@
|
||||
const dispatch = createEventDispatcher()
|
||||
const spaceQuery = createQuery()
|
||||
|
||||
let team: Team | undefined
|
||||
let project: Project | undefined
|
||||
|
||||
$: spaceQuery.query(tracker.class.Team, { _id: issue.space }, (res) => ([team] = res))
|
||||
$: issueId = team && getIssueId(team, issue)
|
||||
$: spaceQuery.query(tracker.class.Project, { _id: issue.space }, (res) => ([project] = res))
|
||||
$: issueId = project && getIssueId(project, issue)
|
||||
</script>
|
||||
|
||||
<div class="flex-center root">
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
(result) => {
|
||||
documents = result
|
||||
},
|
||||
{ lookup: isIssue ? { space: tracker.class.Team } : {} }
|
||||
{ lookup: isIssue ? { space: tracker.class.Project } : {} }
|
||||
)
|
||||
|
||||
async function handleClick (issue: RelatedDocument) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import { AttachedData, Ref, SortingOrder, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { DraftIssueChild, Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||
import { DraftIssueChild, Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import type { ButtonKind, ButtonSize } from '@hcengineering/ui'
|
||||
import { Button, eventToHTMLElement, SelectPopup, showPopup, TooltipAlignment } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
@@ -35,7 +35,7 @@
|
||||
export let width: string | undefined = undefined
|
||||
|
||||
// Extra properties
|
||||
export let issueStatuses: Map<Ref<Team>, WithLookup<IssueStatus>[]> | undefined = undefined
|
||||
export let issueStatuses: Map<Ref<Project>, WithLookup<IssueStatus>[]> | undefined = undefined
|
||||
|
||||
const client = getClient()
|
||||
const statusesQuery = createQuery()
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
import { ObjectBox } from '@hcengineering/view-resources'
|
||||
import { getFiltredKeys, isCollectionAttr } from '@hcengineering/view-resources/src/utils'
|
||||
import tracker from '../../../plugin'
|
||||
import ProjectEditor from '../../projects/ProjectEditor.svelte'
|
||||
import ComponentEditor from '../../components/ComponentEditor.svelte'
|
||||
import SprintEditor from '../../sprints/SprintEditor.svelte'
|
||||
import AssigneeEditor from '../AssigneeEditor.svelte'
|
||||
import DueDateEditor from '../DueDateEditor.svelte'
|
||||
@@ -75,7 +75,7 @@
|
||||
return res
|
||||
}
|
||||
|
||||
$: updateKeys(['title', 'description', 'priority', 'status', 'number', 'assignee', 'project', 'dueDate', 'sprint'])
|
||||
$: updateKeys(['title', 'description', 'priority', 'status', 'number', 'assignee', 'component', 'dueDate', 'sprint'])
|
||||
|
||||
const employeeAccountQuery = createQuery()
|
||||
const employeeQuery = createQuery()
|
||||
@@ -174,9 +174,9 @@
|
||||
<div class="divider" />
|
||||
|
||||
<span class="label">
|
||||
<Label label={tracker.string.Project} />
|
||||
<Label label={tracker.string.Component} />
|
||||
</span>
|
||||
<ProjectEditor value={issue} />
|
||||
<ComponentEditor value={issue} />
|
||||
|
||||
{#if issue.sprint}
|
||||
<span class="label">
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import core, { Account, AttachedData, Doc, generateId, Ref, SortingOrder, WithLookup } from '@hcengineering/core'
|
||||
import presentation, { getClient, KeyedAttribute } from '@hcengineering/presentation'
|
||||
import { IssueStatus, IssuePriority, Issue, Team, calcRank } from '@hcengineering/tracker'
|
||||
import { IssueStatus, IssuePriority, Issue, Project, calcRank } from '@hcengineering/tracker'
|
||||
import { addNotification, Button, Component, EditBox } from '@hcengineering/ui'
|
||||
import tags, { TagElement, TagReference } from '@hcengineering/tags'
|
||||
import tracker from '../../../plugin'
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
export let parentIssue: Issue
|
||||
export let issueStatuses: WithLookup<IssueStatus>[]
|
||||
export let currentTeam: Team
|
||||
export let currentProject: Project
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
@@ -52,7 +52,7 @@
|
||||
title: '',
|
||||
description: '',
|
||||
assignee: null,
|
||||
project: null,
|
||||
component: null,
|
||||
number: 0,
|
||||
rank: '',
|
||||
status: '' as Ref<IssueStatus>,
|
||||
@@ -90,10 +90,10 @@
|
||||
}
|
||||
loading = true
|
||||
try {
|
||||
const space = currentTeam._id
|
||||
const space = currentProject._id
|
||||
const lastOne = await client.findOne<Issue>(tracker.class.Issue, {}, { sort: { rank: SortingOrder.Descending } })
|
||||
const incResult = await client.updateDoc(
|
||||
tracker.class.Team,
|
||||
tracker.class.Project,
|
||||
core.space.Space,
|
||||
space,
|
||||
{ $inc: { sequence: 1 } },
|
||||
@@ -105,7 +105,7 @@
|
||||
title: getTitle(newIssue.title),
|
||||
number: (incResult as any).object.sequence,
|
||||
rank: calcRank(lastOne, undefined),
|
||||
project: parentIssue.project,
|
||||
component: parentIssue.component,
|
||||
parents: [{ parentId: parentIssue._id, parentTitle: parentIssue.title }, ...parentIssue.parents]
|
||||
}
|
||||
|
||||
@@ -162,8 +162,8 @@
|
||||
|
||||
$: thisRef && thisRef.scrollIntoView({ behavior: 'smooth' })
|
||||
$: canSave = getTitle(newIssue.title ?? '').length > 0
|
||||
$: if (!newIssue.status && currentTeam?.defaultIssueStatus) {
|
||||
newIssue.status = currentTeam.defaultIssueStatus
|
||||
$: if (!newIssue.status && currentProject?.defaultIssueStatus) {
|
||||
newIssue.status = currentProject.defaultIssueStatus
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
{objectId}
|
||||
refContainer={thisRef}
|
||||
_class={tracker.class.Issue}
|
||||
space={currentTeam._id}
|
||||
space={currentProject._id}
|
||||
alwaysEdit
|
||||
showButtons
|
||||
maxHeight={'20vh'}
|
||||
@@ -208,7 +208,7 @@
|
||||
</div>
|
||||
<div class="mt-4 flex-between">
|
||||
<div class="buttons-group xsmall-gap">
|
||||
<!-- <SpaceSelector _class={tracker.class.Team} label={tracker.string.Team} bind:space /> -->
|
||||
<!-- <SpaceSelector _class={tracker.class.Project} label={tracker.string.Project} bind:space /> -->
|
||||
<PriorityEditor
|
||||
value={newIssue}
|
||||
shouldShowLabel
|
||||
@@ -241,7 +241,7 @@
|
||||
labels = labels.filter((it) => it._id !== evt.detail)
|
||||
}}
|
||||
/>
|
||||
<EstimationEditor kind={'no-border'} size={'small'} value={newIssue} {currentTeam} />
|
||||
<EstimationEditor kind={'no-border'} size={'small'} value={newIssue} {currentProject} />
|
||||
</div>
|
||||
<div class="buttons-group small-gap">
|
||||
<Button label={presentation.string.Cancel} size="small" kind="transparent" on:click={close} />
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import presentation, { createQuery, getClient, MessageViewer } from '@hcengineering/presentation'
|
||||
import setting, { settingId } from '@hcengineering/setting'
|
||||
import type { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||
import type { Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import {
|
||||
Button,
|
||||
EditBox,
|
||||
@@ -55,7 +55,7 @@
|
||||
const client = getClient()
|
||||
|
||||
let issue: WithLookup<Issue> | undefined
|
||||
let currentTeam: Team | undefined
|
||||
let currentProject: Project | undefined
|
||||
let issueStatuses: WithLookup<IssueStatus>[] | undefined
|
||||
let title = ''
|
||||
let description = ''
|
||||
@@ -90,15 +90,15 @@
|
||||
;[issue] = result
|
||||
title = issue.title
|
||||
description = issue.description
|
||||
currentTeam = issue.$lookup?.space
|
||||
currentProject = issue.$lookup?.space
|
||||
},
|
||||
{ lookup: { attachedTo: tracker.class.Issue, space: tracker.class.Team } }
|
||||
{ lookup: { attachedTo: tracker.class.Issue, space: tracker.class.Project } }
|
||||
)
|
||||
|
||||
$: currentTeam &&
|
||||
$: currentProject &&
|
||||
statusesQuery.query(
|
||||
tracker.class.IssueStatus,
|
||||
{ attachedTo: currentTeam._id },
|
||||
{ attachedTo: currentProject._id },
|
||||
(statuses) => (issueStatuses = statuses),
|
||||
{
|
||||
lookup: { category: tracker.class.IssueStatusCategory },
|
||||
@@ -106,7 +106,7 @@
|
||||
}
|
||||
)
|
||||
|
||||
$: issueId = currentTeam && issue && getIssueId(currentTeam, issue)
|
||||
$: issueId = currentProject && issue && getIssueId(currentProject, issue)
|
||||
$: canSave = title.trim().length > 0
|
||||
$: isDescriptionEmpty = !new DOMParser().parseFromString(description, 'text/html').documentElement.innerText?.trim()
|
||||
$: parentIssue = issue?.$lookup?.attachedTo
|
||||
@@ -206,7 +206,7 @@
|
||||
<div class="popupPanel-body__main-content py-10 clear-mins content">
|
||||
{#if parentIssue}
|
||||
<div class="mb-6">
|
||||
{#if currentTeam && issueStatuses}
|
||||
{#if currentProject && issueStatuses}
|
||||
<SubIssueSelector {issue} />
|
||||
{:else}
|
||||
<Spinner />
|
||||
@@ -233,7 +233,7 @@
|
||||
{:else}
|
||||
{#if parentIssue}
|
||||
<div class="mb-6">
|
||||
{#if currentTeam && issueStatuses}
|
||||
{#if currentProject && issueStatuses}
|
||||
<SubIssueSelector {issue} />
|
||||
{:else}
|
||||
<Spinner />
|
||||
@@ -252,12 +252,12 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
{#key issue._id && currentTeam !== undefined}
|
||||
{#if currentTeam !== undefined && issueStatuses !== undefined}
|
||||
{#key issue._id && currentProject !== undefined}
|
||||
{#if currentProject !== undefined && issueStatuses !== undefined}
|
||||
<SubIssues
|
||||
{issue}
|
||||
issueStatuses={new Map([[currentTeam._id, issueStatuses]])}
|
||||
teams={new Map([[currentTeam?._id, currentTeam]])}
|
||||
issueStatuses={new Map([[currentProject._id, issueStatuses]])}
|
||||
projects={new Map([[currentProject?._id, currentProject]])}
|
||||
/>
|
||||
{/if}
|
||||
{/key}
|
||||
@@ -306,7 +306,7 @@
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="custom-attributes">
|
||||
{#if issue && currentTeam && issueStatuses}
|
||||
{#if issue && currentProject && issueStatuses}
|
||||
<ControlPanel {issue} {issueStatuses} {showAllMixins} />
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Doc, DocumentQuery, Ref, WithLookup } from '@hcengineering/core'
|
||||
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||
import { Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import { Viewlet, ViewOptions } from '@hcengineering/view'
|
||||
import {
|
||||
ActionContext,
|
||||
@@ -33,8 +33,8 @@
|
||||
export let disableHeader = false
|
||||
|
||||
// Extra properties
|
||||
export let teams: Map<Ref<Team>, Team> | undefined
|
||||
export let issueStatuses: Map<Ref<Team>, WithLookup<IssueStatus>[]>
|
||||
export let projects: Map<Ref<Project>, Project> | undefined
|
||||
export let issueStatuses: Map<Ref<Project>, WithLookup<IssueStatus>[]>
|
||||
|
||||
let list: List
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
documents={issues}
|
||||
{query}
|
||||
flatHeaders={true}
|
||||
props={{ teams, issueStatuses }}
|
||||
props={{ projects, issueStatuses }}
|
||||
{disableHeader}
|
||||
selectedObjectIds={$selectionStore ?? []}
|
||||
on:row-focus={(event) => {
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
SelectPopup,
|
||||
{
|
||||
value: subIssues.map((iss) => {
|
||||
const team = iss.$lookup?.space
|
||||
const project = iss.$lookup?.space
|
||||
const status = iss.$lookup?.status as WithLookup<IssueStatus>
|
||||
const icon = status.$lookup?.category?.icon
|
||||
const color = status.color ?? status.$lookup?.category?.color
|
||||
@@ -70,7 +70,7 @@
|
||||
id: iss._id,
|
||||
icon,
|
||||
isSelected: iss._id === issue._id,
|
||||
...(team !== undefined ? { text: `${getIssueId(team, iss)} ${iss.title}` } : undefined),
|
||||
...(project !== undefined ? { text: `${getIssueId(project, iss)} ${iss.title}` } : undefined),
|
||||
...(color !== undefined ? { iconColor: getPlatformColor(color) } : undefined)
|
||||
}
|
||||
}),
|
||||
@@ -100,7 +100,7 @@
|
||||
{
|
||||
sort: { modifiedOn: SortingOrder.Descending },
|
||||
lookup: {
|
||||
space: tracker.class.Team,
|
||||
space: tracker.class.Project,
|
||||
status: [tracker.class.IssueStatus, { category: tracker.class.IssueStatusCategory }]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import { Ref, SortingOrder, toIdMap, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Issue, IssueStatus, Team, trackerId } from '@hcengineering/tracker'
|
||||
import { Issue, IssueStatus, Project, trackerId } from '@hcengineering/tracker'
|
||||
import {
|
||||
Button,
|
||||
Chevron,
|
||||
@@ -41,8 +41,8 @@
|
||||
import SubIssueList from './SubIssueList.svelte'
|
||||
|
||||
export let issue: Issue
|
||||
export let teams: Map<Ref<Team>, Team>
|
||||
export let issueStatuses: Map<Ref<Team>, WithLookup<IssueStatus>[]>
|
||||
export let projects: Map<Ref<Project>, Project>
|
||||
export let issueStatuses: Map<Ref<Project>, WithLookup<IssueStatus>[]>
|
||||
|
||||
let subIssueEditorRef: HTMLDivElement
|
||||
let isCollapsed = false
|
||||
@@ -57,17 +57,17 @@
|
||||
;[viewlet] = res
|
||||
})
|
||||
|
||||
let _teams = teams
|
||||
let _projects = projects
|
||||
let _issueStatuses = issueStatuses
|
||||
|
||||
const teamsQuery = createQuery()
|
||||
const projectsQuery = createQuery()
|
||||
|
||||
$: if (teams === undefined) {
|
||||
teamsQuery.query(tracker.class.Team, {}, async (result) => {
|
||||
_teams = toIdMap(result)
|
||||
$: if (projects === undefined) {
|
||||
projectsQuery.query(tracker.class.Project, {}, async (result) => {
|
||||
_projects = toIdMap(result)
|
||||
})
|
||||
} else {
|
||||
teamsQuery.unsubscribe()
|
||||
projectsQuery.unsubscribe()
|
||||
}
|
||||
|
||||
const statusesQuery = createQuery()
|
||||
@@ -76,9 +76,9 @@
|
||||
tracker.class.IssueStatus,
|
||||
{},
|
||||
(statuses) => {
|
||||
const st = new Map<Ref<Team>, WithLookup<IssueStatus>[]>()
|
||||
const st = new Map<Ref<Project>, WithLookup<IssueStatus>[]>()
|
||||
for (const s of statuses) {
|
||||
const id = s.attachedTo as Ref<Team>
|
||||
const id = s.attachedTo as Ref<Project>
|
||||
st.set(id, [...(st.get(id) ?? []), s])
|
||||
}
|
||||
_issueStatuses = st
|
||||
@@ -160,30 +160,30 @@
|
||||
<div class="mt-1">
|
||||
{#if issueStatuses}
|
||||
{#if hasSubIssues && viewOptions && viewlet}
|
||||
<ExpandCollapse isExpanded={!isCollapsed}>
|
||||
{#if !isCollapsed}
|
||||
{#if !isCollapsed}
|
||||
<ExpandCollapse isExpanded={!isCollapsed}>
|
||||
<div class="list" class:collapsed={isCollapsed}>
|
||||
<SubIssueList
|
||||
teams={_teams}
|
||||
projects={_projects}
|
||||
{viewlet}
|
||||
{viewOptions}
|
||||
issueStatuses={_issueStatuses}
|
||||
query={{ attachedTo: issue._id }}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</ExpandCollapse>
|
||||
</ExpandCollapse>
|
||||
{/if}
|
||||
{/if}
|
||||
<ExpandCollapse isExpanded={!isCollapsed}>
|
||||
{#if isCreating}
|
||||
{@const team = teams.get(issue.space)}
|
||||
{@const project = projects.get(issue.space)}
|
||||
{@const statuses = issueStatuses.get(issue.space)}
|
||||
{#if team !== undefined && statuses !== undefined}
|
||||
{#if project !== undefined && statuses !== undefined}
|
||||
<div class="pt-4" bind:this={subIssueEditorRef}>
|
||||
<CreateSubIssue
|
||||
parentIssue={issue}
|
||||
issueStatuses={statuses}
|
||||
currentTeam={team}
|
||||
currentProject={project}
|
||||
on:close={() => (isCreating = false)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import { Ref, SortingOrder, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||
import { Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import {
|
||||
Button,
|
||||
ButtonKind,
|
||||
@@ -32,7 +32,7 @@
|
||||
import { subIssueListProvider } from '../../../utils'
|
||||
|
||||
export let value: WithLookup<Issue>
|
||||
export let currentTeam: Team | undefined = undefined
|
||||
export let currentProject: Project | undefined = undefined
|
||||
|
||||
export let kind: ButtonKind = 'link-bordered'
|
||||
export let size: ButtonSize = 'inline'
|
||||
@@ -41,22 +41,22 @@
|
||||
|
||||
let btn: HTMLElement
|
||||
|
||||
$: team = currentTeam
|
||||
$: project = currentProject
|
||||
|
||||
let subIssues: Issue[] = []
|
||||
let countComplate: number = 0
|
||||
|
||||
const teamQuery = createQuery()
|
||||
$: if (currentTeam === undefined) {
|
||||
teamQuery.query(
|
||||
tracker.class.Team,
|
||||
const projectQuery = createQuery()
|
||||
$: if (currentProject === undefined) {
|
||||
projectQuery.query(
|
||||
tracker.class.Project,
|
||||
{
|
||||
_id: value.space
|
||||
},
|
||||
(res) => ([team] = res)
|
||||
(res) => ([project] = res)
|
||||
)
|
||||
} else {
|
||||
teamQuery.unsubscribe()
|
||||
projectQuery.unsubscribe()
|
||||
}
|
||||
const query = createQuery()
|
||||
const statusesQuery = createQuery()
|
||||
@@ -117,7 +117,7 @@
|
||||
SelectPopup,
|
||||
{
|
||||
value: subIssues.map((iss) => {
|
||||
const text = team ? `${getIssueId(team, iss)} ${iss.title}` : iss.title
|
||||
const text = project ? `${getIssueId(project, iss)} ${iss.title}` : iss.title
|
||||
|
||||
return { id: iss._id, text, isSelected: iss._id === value._id, ...getIssueStatusIcon(iss, statuses) }
|
||||
}),
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import { Doc, Ref, SortingOrder, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||
import { Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import {
|
||||
Button,
|
||||
ButtonKind,
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
export let object: WithLookup<Doc & { related: number }> | undefined
|
||||
export let value: WithLookup<Doc & { related: number }> | undefined
|
||||
export let currentTeam: Team | undefined
|
||||
export let currentProject: Project | undefined
|
||||
|
||||
export let kind: ButtonKind = 'link-bordered'
|
||||
export let size: ButtonSize = 'inline'
|
||||
@@ -103,7 +103,7 @@
|
||||
SelectPopup,
|
||||
{
|
||||
value: subIssues.map((iss) => {
|
||||
const text = currentTeam ? `${getIssueId(currentTeam, iss)} ${iss.title}` : iss.title
|
||||
const text = currentProject ? `${getIssueId(currentProject, iss)} ${iss.title}` : iss.title
|
||||
|
||||
return { id: iss._id, text, isSelected: false, ...getIssueStatusIcon(iss, statuses) }
|
||||
}),
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { Doc, DocumentQuery, Ref, SortingOrder, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||
import { Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import { Label, Spinner } from '@hcengineering/ui'
|
||||
import { Viewlet, ViewOptions } from '@hcengineering/view'
|
||||
import tracker from '../../../plugin'
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
let subIssues: Issue[] = []
|
||||
|
||||
let teams: Map<Ref<Team>, Team> | undefined
|
||||
let projects: Map<Ref<Project>, Project> | undefined
|
||||
|
||||
$: subIssuesQuery.query(tracker.class.Issue, query, async (result) => (subIssues = result), {
|
||||
sort: { rank: SortingOrder.Ascending },
|
||||
@@ -47,22 +47,22 @@
|
||||
}
|
||||
})
|
||||
|
||||
const teamsQuery = createQuery()
|
||||
const projectsQuery = createQuery()
|
||||
|
||||
$: teamsQuery.query(tracker.class.Team, {}, async (result) => {
|
||||
teams = new Map(result.map((it) => [it._id, it]))
|
||||
$: projectsQuery.query(tracker.class.Project, {}, async (result) => {
|
||||
projects = new Map(result.map((it) => [it._id, it]))
|
||||
})
|
||||
|
||||
let issueStatuses = new Map<Ref<Team>, WithLookup<IssueStatus>[]>()
|
||||
let issueStatuses = new Map<Ref<Project>, WithLookup<IssueStatus>[]>()
|
||||
|
||||
const statusesQuery = createQuery()
|
||||
$: statusesQuery.query(
|
||||
tracker.class.IssueStatus,
|
||||
{},
|
||||
(statuses) => {
|
||||
const st = new Map<Ref<Team>, WithLookup<IssueStatus>[]>()
|
||||
const st = new Map<Ref<Project>, WithLookup<IssueStatus>[]>()
|
||||
for (const s of statuses) {
|
||||
const id = s.attachedTo as Ref<Team>
|
||||
const id = s.attachedTo as Ref<Project>
|
||||
st.set(id, [...(st.get(id) ?? []), s])
|
||||
}
|
||||
issueStatuses = st
|
||||
@@ -75,8 +75,8 @@
|
||||
</script>
|
||||
|
||||
{#if subIssues !== undefined && viewlet !== undefined}
|
||||
{#if issueStatuses.size > 0 && teams && subIssues.length > 0}
|
||||
<SubIssueList bind:viewOptions {viewlet} issues={subIssues} {teams} {issueStatuses} {disableHeader} />
|
||||
{#if issueStatuses.size > 0 && projects && subIssues.length > 0}
|
||||
<SubIssueList bind:viewOptions {viewlet} issues={subIssues} {projects} {issueStatuses} {disableHeader} />
|
||||
{:else}
|
||||
<div class="antiSection-empty solid flex-col mt-3">
|
||||
<div class="flex-center content-accent-color">
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { AttachedData } from '@hcengineering/core'
|
||||
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Issue, Team } from '@hcengineering/tracker'
|
||||
import { Issue, Project } 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,7 +31,7 @@
|
||||
export let size: ButtonSize = 'large'
|
||||
export let justify: 'left' | 'center' = 'left'
|
||||
export let width: string | undefined = undefined
|
||||
export let currentTeam: Team | undefined = undefined
|
||||
export let currentProject: Project | undefined = undefined
|
||||
|
||||
const client = getClient()
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
{#if value}
|
||||
{#if kind === 'list'}
|
||||
<EstimationStatsPresenter {value} on:click={handleestimationEditorOpened} {currentTeam} />
|
||||
<EstimationStatsPresenter {value} on:click={handleestimationEditorOpened} {currentProject} />
|
||||
{:else}
|
||||
<Button
|
||||
showTooltip={isEditable ? { label: tracker.string.Estimation } : undefined}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<script lang="ts">
|
||||
import { SortingOrder, WithLookup } from '@hcengineering/core'
|
||||
import presentation, { Card, createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||
import { Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import { Button, EditStyle, eventToHTMLElement, IconAdd, Label, showPopup } from '@hcengineering/ui'
|
||||
import EditBoxPopup from '@hcengineering/view-resources/src/components/EditBoxPopup.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
const query = createQuery()
|
||||
|
||||
let currentTeam: Team | undefined
|
||||
let currentProject: Project | undefined
|
||||
let issueStatuses: WithLookup<IssueStatus>[] | undefined
|
||||
|
||||
$: query.query(
|
||||
@@ -50,23 +50,23 @@
|
||||
const r = res.shift()
|
||||
if (r !== undefined) {
|
||||
object = r
|
||||
currentTeam = r.$lookup?.space
|
||||
currentProject = r.$lookup?.space
|
||||
}
|
||||
},
|
||||
{
|
||||
lookup: {
|
||||
space: tracker.class.Team
|
||||
space: tracker.class.Project
|
||||
}
|
||||
}
|
||||
)
|
||||
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||
$: defaultTimeReportDay = currentProject?.defaultTimeReportDay
|
||||
|
||||
const statusesQuery = createQuery()
|
||||
|
||||
$: currentTeam &&
|
||||
$: currentProject &&
|
||||
statusesQuery.query(
|
||||
tracker.class.IssueStatus,
|
||||
{ attachedTo: currentTeam._id },
|
||||
{ attachedTo: currentProject._id },
|
||||
(statuses) => (issueStatuses = statuses),
|
||||
{
|
||||
lookup: { category: tracker.class.IssueStatusCategory },
|
||||
@@ -115,7 +115,7 @@
|
||||
)
|
||||
}}
|
||||
>
|
||||
<EstimationStatsPresenter value={object} estimation={_value} {currentTeam} />
|
||||
<EstimationStatsPresenter value={object} estimation={_value} {currentProject} />
|
||||
</div>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
@@ -124,18 +124,18 @@
|
||||
<IssuePresenter value={object} disableClick />
|
||||
</svelte:fragment>
|
||||
|
||||
{#if currentTeam && issueStatuses}
|
||||
{#if currentProject && issueStatuses}
|
||||
<SubIssuesEstimations
|
||||
issue={object}
|
||||
issueStatuses={new Map([[currentTeam._id, issueStatuses]])}
|
||||
teams={new Map([[currentTeam?._id, currentTeam]])}
|
||||
issueStatuses={new Map([[currentProject._id, issueStatuses]])}
|
||||
projects={new Map([[currentProject?._id, currentProject]])}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if currentTeam}
|
||||
{#if currentProject}
|
||||
<TimeSpendReports
|
||||
issue={object}
|
||||
teams={new Map([[currentTeam?._id, currentTeam]])}
|
||||
projects={new Map([[currentProject?._id, currentProject]])}
|
||||
query={{ attachedTo: { $in: [object._id, ...childIds] } }}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
+3
-3
@@ -15,18 +15,18 @@
|
||||
<script lang="ts">
|
||||
import { AttachedData } from '@hcengineering/core'
|
||||
|
||||
import { Issue, Team } from '@hcengineering/tracker'
|
||||
import { Issue, Project } 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
|
||||
export let currentProject: Project | undefined
|
||||
|
||||
$: _estimation = estimation ?? value.estimation
|
||||
|
||||
$: workDayLength = currentTeam?.workDayLength
|
||||
$: workDayLength = currentProject?.workDayLength
|
||||
$: childReportTime = floorFractionDigits(
|
||||
value.reportedTime + (value.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0),
|
||||
3
|
||||
|
||||
+6
-6
@@ -16,7 +16,7 @@
|
||||
import contact from '@hcengineering/contact'
|
||||
import { Ref } from '@hcengineering/core'
|
||||
import { AssigneeBox } from '@hcengineering/presentation'
|
||||
import { Issue, Team } from '@hcengineering/tracker'
|
||||
import { Issue, Project } from '@hcengineering/tracker'
|
||||
import { deviceOptionsStore as deviceInfo, getEventPositionElement, ListView, showPopup } from '@hcengineering/ui'
|
||||
import { ContextMenu, FixedColumn, ListSelectionProvider } from '@hcengineering/view-resources'
|
||||
import { getIssueId } from '../../../issues'
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
export let issues: Issue[]
|
||||
|
||||
export let teams: Map<Ref<Team>, Team>
|
||||
export let projects: Map<Ref<Project>, Project>
|
||||
|
||||
function showContextMenu (ev: MouseEvent, object: Issue) {
|
||||
showPopup(ContextMenu, { object }, $deviceInfo.isMobile ? 'top' : getEventPositionElement(ev))
|
||||
@@ -38,7 +38,7 @@
|
||||
<ListView count={issues.length} addClass={'step-tb-2-accent'}>
|
||||
<svelte:fragment slot="item" let:item>
|
||||
{@const issue = issues[item]}
|
||||
{@const currentTeam = teams.get(issue.space)}
|
||||
{@const currentProject = projects.get(issue.space)}
|
||||
<div
|
||||
class="{twoRows ? 'flex-col' : 'flex-between'} p-text-2"
|
||||
on:contextmenu|preventDefault={(ev) => showContextMenu(ev, issue)}
|
||||
@@ -51,8 +51,8 @@
|
||||
>
|
||||
<div class="flex-row-center clear-mins gap-2 flex-grow mr-4" class:p-text={twoRows}>
|
||||
<FixedColumn key={'estimation_issue'} justify={'left'} addClass={'fs-bold'}>
|
||||
{#if currentTeam}
|
||||
{getIssueId(currentTeam, issue)}
|
||||
{#if currentProject}
|
||||
{getIssueId(currentProject, issue)}
|
||||
{/if}
|
||||
</FixedColumn>
|
||||
<span class="overflow-label fs-bold caption-color" title={issue.title}>
|
||||
@@ -71,7 +71,7 @@
|
||||
/>
|
||||
</FixedColumn>
|
||||
<FixedColumn key={'estimation'} justify={'left'}>
|
||||
<EstimationEditor value={issue} kind={'list'} {currentTeam} />
|
||||
<EstimationEditor value={issue} kind={'list'} {currentProject} />
|
||||
</FixedColumn>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
+8
-8
@@ -16,7 +16,7 @@
|
||||
<script lang="ts">
|
||||
import type { IntlString } from '@hcengineering/platform'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import tracker, { Issue, Team } from '@hcengineering/tracker'
|
||||
import tracker, { Issue, Project } from '@hcengineering/tracker'
|
||||
import { ActionIcon, eventToHTMLElement, floorFractionDigits, IconAdd, Label, showPopup } from '@hcengineering/ui'
|
||||
import ReportsPopup from './ReportsPopup.svelte'
|
||||
import TimePresenter from './TimePresenter.svelte'
|
||||
@@ -27,19 +27,19 @@
|
||||
export let object: Issue
|
||||
export let value: number
|
||||
export let kind: 'no-border' | 'link' = 'no-border'
|
||||
export let currentTeam: Team | undefined
|
||||
export let currentProject: Project | undefined
|
||||
|
||||
const spaceQuery = createQuery()
|
||||
$: if (currentTeam === undefined) {
|
||||
spaceQuery.query(tracker.class.Team, { _id: object.space }, (res) => {
|
||||
currentTeam = res.shift()
|
||||
$: if (currentProject === undefined) {
|
||||
spaceQuery.query(tracker.class.Project, { _id: object.space }, (res) => {
|
||||
currentProject = res.shift()
|
||||
})
|
||||
} else {
|
||||
spaceQuery.unsubscribe()
|
||||
}
|
||||
|
||||
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||
$: workDayLength = currentTeam?.workDayLength
|
||||
$: defaultTimeReportDay = currentProject?.defaultTimeReportDay
|
||||
$: workDayLength = currentProject?.workDayLength
|
||||
|
||||
function addTimeReport (event: MouseEvent): void {
|
||||
showPopup(
|
||||
@@ -51,7 +51,7 @@
|
||||
issueClass: object._class,
|
||||
space: object.space,
|
||||
assignee: object.assignee,
|
||||
currentTeam
|
||||
currentProject
|
||||
},
|
||||
eventToHTMLElement(event)
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import contact from '@hcengineering/contact'
|
||||
import { FindOptions } from '@hcengineering/core'
|
||||
import presentation, { Card } from '@hcengineering/presentation'
|
||||
import { Issue, Team, TimeSpendReport } from '@hcengineering/tracker'
|
||||
import { Issue, Project, TimeSpendReport } from '@hcengineering/tracker'
|
||||
import { Button, eventToHTMLElement, IconAdd, Scroller, showPopup, tableSP } from '@hcengineering/ui'
|
||||
import { TableBrowser } from '@hcengineering/view-resources'
|
||||
import tracker from '../../../plugin'
|
||||
@@ -24,9 +24,9 @@
|
||||
import ParentNamesPresenter from '../ParentNamesPresenter.svelte'
|
||||
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
|
||||
export let issue: Issue
|
||||
export let currentTeam: Team | undefined
|
||||
export let currentProject: Project | undefined
|
||||
|
||||
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||
$: defaultTimeReportDay = currentProject?.defaultTimeReportDay
|
||||
|
||||
export function canClose (): boolean {
|
||||
return true
|
||||
|
||||
+4
-4
@@ -15,15 +15,15 @@
|
||||
<script lang="ts">
|
||||
import { Ref, SortingOrder, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||
import { Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import { Spinner } from '@hcengineering/ui'
|
||||
import Expandable from '@hcengineering/ui/src/components/Expandable.svelte'
|
||||
import tracker from '../../../plugin'
|
||||
import EstimationSubIssueList from './EstimationSubIssueList.svelte'
|
||||
|
||||
export let issue: Issue
|
||||
export let teams: Map<Ref<Team>, Team>
|
||||
export let issueStatuses: Map<Ref<Team>, WithLookup<IssueStatus>[]>
|
||||
export let projects: Map<Ref<Project>, Project>
|
||||
export let issueStatuses: Map<Ref<Project>, WithLookup<IssueStatus>[]>
|
||||
|
||||
const subIssuesQuery = createQuery()
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
{#if hasSubIssues}
|
||||
<Expandable label={tracker.string.ChildEstimation} contentColor bordered>
|
||||
<svelte:fragment slot="title">: <span class="caption-color">{total}</span></svelte:fragment>
|
||||
<EstimationSubIssueList issues={subIssues} {teams} />
|
||||
<EstimationSubIssueList issues={subIssues} {projects} />
|
||||
</Expandable>
|
||||
{/if}
|
||||
{:else}
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
<script lang="ts">
|
||||
import { WithLookup } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Issue, Team, TimeSpendReport } from '@hcengineering/tracker'
|
||||
import { Issue, Project, 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
|
||||
export let currentProject: Project | undefined
|
||||
const client = getClient()
|
||||
|
||||
$: issue = value.$lookup?.attachedTo
|
||||
@@ -30,8 +30,8 @@
|
||||
issue = r as Issue
|
||||
})
|
||||
}
|
||||
$: workDayLength = currentTeam?.workDayLength
|
||||
$: defaultTimeReportDay = currentTeam?.defaultTimeReportDay
|
||||
$: workDayLength = currentProject?.workDayLength
|
||||
$: defaultTimeReportDay = currentProject?.defaultTimeReportDay
|
||||
|
||||
function editSpendReport (event: MouseEvent): void {
|
||||
showPopup(
|
||||
|
||||
@@ -15,21 +15,21 @@
|
||||
<script lang="ts">
|
||||
import { DocumentQuery, Ref, SortingOrder } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Issue, Team, TimeSpendReport } from '@hcengineering/tracker'
|
||||
import { Issue, Project, TimeSpendReport } from '@hcengineering/tracker'
|
||||
import { Expandable, floorFractionDigits, Label, Spinner } from '@hcengineering/ui'
|
||||
import tracker from '../../../plugin'
|
||||
import TimePresenter from './TimePresenter.svelte'
|
||||
import TimeSpendReportsList from './TimeSpendReportsList.svelte'
|
||||
|
||||
export let issue: Issue
|
||||
export let teams: Map<Ref<Team>, Team>
|
||||
export let projects: Map<Ref<Project>, Project>
|
||||
export let query: DocumentQuery<TimeSpendReport>
|
||||
|
||||
const subIssuesQuery = createQuery()
|
||||
|
||||
let reports: TimeSpendReport[] | undefined
|
||||
|
||||
$: workDayLength = teams.get(issue.space)?.workDayLength
|
||||
$: workDayLength = projects.get(issue.space)?.workDayLength
|
||||
$: subIssuesQuery.query(tracker.class.TimeSpendReport, query, async (result) => (reports = result), {
|
||||
sort: { modifiedOn: SortingOrder.Descending },
|
||||
lookup: {
|
||||
@@ -51,7 +51,7 @@
|
||||
<span class="caption-color"><TimePresenter value={total} {workDayLength} /></span>
|
||||
</span>
|
||||
</svelte:fragment>
|
||||
<TimeSpendReportsList {reports} {teams} />
|
||||
<TimeSpendReportsList {reports} {projects} />
|
||||
</Expandable>
|
||||
{:else}
|
||||
<div class="flex-center">
|
||||
|
||||
+8
-8
@@ -16,7 +16,7 @@
|
||||
import contact from '@hcengineering/contact'
|
||||
import { Ref, Space, WithLookup } from '@hcengineering/core'
|
||||
import UserBox from '@hcengineering/presentation/src/components/UserBox.svelte'
|
||||
import { Team, TimeReportDayType, TimeSpendReport } from '@hcengineering/tracker'
|
||||
import { Project, TimeReportDayType, TimeSpendReport } from '@hcengineering/tracker'
|
||||
import {
|
||||
deviceOptionsStore as deviceInfo,
|
||||
eventToHTMLElement,
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
export let reports: WithLookup<TimeSpendReport>[]
|
||||
|
||||
export let teams: Map<Ref<Team>, Team>
|
||||
export let projects: Map<Ref<Project>, Project>
|
||||
|
||||
function showContextMenu (ev: MouseEvent, object: TimeSpendReport) {
|
||||
showPopup(ContextMenu, { object }, getEventPositionElement(ev))
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
const listProvider = new ListSelectionProvider(() => {})
|
||||
|
||||
const toTeamId = (ref: Ref<Space>) => ref as Ref<Team>
|
||||
const toProjectId = (ref: Ref<Space>) => ref as Ref<Project>
|
||||
|
||||
function editSpendReport (
|
||||
event: MouseEvent,
|
||||
@@ -68,7 +68,7 @@
|
||||
<ListView count={reports.length} addClass={'step-tb-2-accent'}>
|
||||
<svelte:fragment slot="item" let:item>
|
||||
{@const report = reports[item]}
|
||||
{@const currentTeam = teams.get(toTeamId(report.space))}
|
||||
{@const currentProject = projects.get(toProjectId(report.space))}
|
||||
<div
|
||||
class="{twoRows ? 'flex-col' : 'flex-between'} p-text-2"
|
||||
on:contextmenu|preventDefault={(ev) => showContextMenu(ev, report)}
|
||||
@@ -78,12 +78,12 @@
|
||||
on:focus={() => {
|
||||
listProvider.updateFocus(report)
|
||||
}}
|
||||
on:click={(evt) => editSpendReport(evt, report, currentTeam?.defaultTimeReportDay)}
|
||||
on:click={(evt) => editSpendReport(evt, report, currentProject?.defaultTimeReportDay)}
|
||||
>
|
||||
<div class="flex-row-center clear-mins gap-2 flex-grow mr-4" class:p-text={twoRows}>
|
||||
<FixedColumn key={'tmiespend_issue'} justify={'left'} addClass={'fs-bold'}>
|
||||
{#if currentTeam && report.$lookup?.attachedTo}
|
||||
{getIssueId(currentTeam, report.$lookup?.attachedTo)}
|
||||
{#if currentProject && report.$lookup?.attachedTo}
|
||||
{getIssueId(currentProject, report.$lookup?.attachedTo)}
|
||||
{/if}
|
||||
</FixedColumn>
|
||||
{#if report.$lookup?.attachedTo?.title}
|
||||
@@ -104,7 +104,7 @@
|
||||
/>
|
||||
</FixedColumn>
|
||||
<FixedColumn key={'timespend_reported'} justify={'center'}>
|
||||
<TimePresenter value={report.value} workDayLength={currentTeam?.workDayLength} />
|
||||
<TimePresenter value={report.value} workDayLength={currentProject?.workDayLength} />
|
||||
</FixedColumn>
|
||||
<FixedColumn key={'timespend_date'} justify={'left'}>
|
||||
<DatePresenter value={report.date} />
|
||||
|
||||
Reference in New Issue
Block a user