Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2023-10-16 18:20:23 +07:00 committed by GitHub
parent d5d98f64e7
commit e1af333fc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 93 additions and 165 deletions

View File

@ -52,7 +52,7 @@
export let isFullSize = false export let isFullSize = false
export let embedded = false export let embedded = false
export let contentClasses: string | undefined = undefined export let contentClasses: string | undefined = undefined
export let content: HTMLElement | undefined = undefined export let content: HTMLElement | undefined | null = undefined
let lastHref: string let lastHref: string
let timer: any let timer: any

View File

@ -13,13 +13,13 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { SvelteComponent } from 'svelte'
import { getResource } from '@hcengineering/platform' import { getResource } from '@hcengineering/platform'
import { deepEqual } from 'fast-equals'
import { SvelteComponent } from 'svelte'
import type { AnyComponent } from '../types' import type { AnyComponent } from '../types'
// import Icon from './Icon.svelte'
import ErrorPresenter from './ErrorPresenter.svelte' import ErrorPresenter from './ErrorPresenter.svelte'
import ErrorBoundary from './internal/ErrorBoundary'
import Loading from './Loading.svelte' import Loading from './Loading.svelte'
import ErrorBoundary from './internal/ErrorBoundary'
// Reference to rendered component instance // Reference to rendered component instance
export let innerRef: SvelteComponent | undefined = undefined export let innerRef: SvelteComponent | undefined = undefined
@ -30,10 +30,20 @@
export let inline: boolean = false export let inline: boolean = false
export let disabled: boolean = false export let disabled: boolean = false
$: component = is != null ? getResource(is) : Promise.reject(new Error('is not defined')) let _is: any = is
let _props: any = props
$: if (!deepEqual(_is, is)) {
_is = is
}
$: if (!deepEqual(_props, props)) {
_props = props
}
$: component = _is != null ? getResource<any>(_is) : Promise.reject(new Error('is not defined'))
</script> </script>
{#if is} {#if _is}
{#await component} {#await component}
{#if showLoading} {#if showLoading}
<Loading {shrink} /> <Loading {shrink} />
@ -43,7 +53,7 @@
{#if $$slots.default !== undefined} {#if $$slots.default !== undefined}
<Ctor <Ctor
bind:this={innerRef} bind:this={innerRef}
{...props} {..._props}
{inline} {inline}
{disabled} {disabled}
on:change on:change
@ -59,7 +69,7 @@
{:else} {:else}
<Ctor <Ctor
bind:this={innerRef} bind:this={innerRef}
{...props} {..._props}
{inline} {inline}
{disabled} {disabled}
on:change on:change

View File

@ -36,7 +36,7 @@
export let noStretch: boolean = autoscroll export let noStretch: boolean = autoscroll
export let buttons: 'normal' | 'union' | false = false export let buttons: 'normal' | 'union' | false = false
export let shrink: boolean = false export let shrink: boolean = false
export let divScroll: HTMLElement | undefined = undefined export let divScroll: HTMLElement | undefined | null = undefined
export let checkForHeaders: boolean = false export let checkForHeaders: boolean = false
export let stickedScrollBars: boolean = false export let stickedScrollBars: boolean = false
export let thinScrollBars: boolean = false export let thinScrollBars: boolean = false

View File

@ -13,13 +13,13 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { Ref, WithLookup } from '@hcengineering/core' import { WithLookup } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation' import { Asset } from '@hcengineering/platform'
import type { Issue, Project } from '@hcengineering/tracker' import type { Issue, Project } from '@hcengineering/tracker'
import { AnySvelteComponent, Icon, tooltip } from '@hcengineering/ui' import { AnySvelteComponent, Icon, tooltip } from '@hcengineering/ui'
import { DocNavLink } from '@hcengineering/view-resources' import { DocNavLink } from '@hcengineering/view-resources'
import tracker from '../../plugin' import tracker from '../../plugin'
import { Asset } from '@hcengineering/platform' import { activeProjects } from '../../utils'
export let value: WithLookup<Issue> export let value: WithLookup<Issue>
export let disabled = false export let disabled = false
@ -30,19 +30,10 @@
export let kind: 'list' | undefined = undefined export let kind: 'list' | undefined = undefined
export let icon: Asset | AnySvelteComponent | undefined = undefined export let icon: Asset | AnySvelteComponent | undefined = undefined
// Extra properties
export let projects: Map<Ref<Project>, Project> | undefined = undefined
const spaceQuery = createQuery()
let currentProject: Project | undefined = value?.$lookup?.space let currentProject: Project | undefined = value?.$lookup?.space
$: if (value !== undefined) { $: if (value !== undefined) {
if (value.$lookup?.space === undefined && !projects?.has(value.space)) { currentProject = $activeProjects.get(value?.space)
spaceQuery.query(tracker.class.Project, { _id: value.space }, (res) => ([currentProject] = res))
} else {
currentProject = value?.$lookup?.space ?? projects?.get(value?.space)
spaceQuery.unsubscribe()
}
} }
$: title = currentProject ? `${currentProject.identifier}-${value?.number}` : `${value?.number}` $: title = currentProject ? `${currentProject.identifier}-${value?.number}` : `${value?.number}`

View File

@ -18,10 +18,11 @@
import chunter from '@hcengineering/chunter' import chunter from '@hcengineering/chunter'
import { CommentPopup } from '@hcengineering/chunter-resources' import { CommentPopup } from '@hcengineering/chunter-resources'
import { Ref } from '@hcengineering/core' import { Ref } from '@hcengineering/core'
import { createQuery, getClient, MessageViewer, IconForward } from '@hcengineering/presentation' import { IconForward, MessageViewer, createQuery, getClient } from '@hcengineering/presentation'
import { Issue, Project } from '@hcengineering/tracker' import { Issue, Project } from '@hcengineering/tracker'
import { Label, Scroller, resizeObserver } from '@hcengineering/ui' import { Label, Scroller, resizeObserver } from '@hcengineering/ui'
import tracker from '../../plugin' import tracker from '../../plugin'
import { activeProjects } from '../../utils'
import AssigneeEditor from './AssigneeEditor.svelte' import AssigneeEditor from './AssigneeEditor.svelte'
import IssueStatusActivity from './IssueStatusActivity.svelte' import IssueStatusActivity from './IssueStatusActivity.svelte'
import PriorityEditor from './PriorityEditor.svelte' import PriorityEditor from './PriorityEditor.svelte'
@ -33,7 +34,6 @@
const client = getClient() const client = getClient()
$: space = object.space $: space = object.space
const issueQuery = createQuery() const issueQuery = createQuery()
const spaceQuery = createQuery()
$: issueQuery.query( $: issueQuery.query(
object._class, object._class,
@ -46,7 +46,7 @@
let currentProject: Project | undefined let currentProject: Project | undefined
$: spaceQuery.query(tracker.class.Project, { _id: space }, (res) => ([currentProject] = res)) $: currentProject = $activeProjects.get(space)
$: issueName = currentProject && issue && `${currentProject.identifier}-${issue.number}` $: issueName = currentProject && issue && `${currentProject.identifier}-${issue.number}`
const limit: number = 350 const limit: number = 350

View File

@ -72,6 +72,7 @@
import view from '@hcengineering/view-resources/src/plugin' import view from '@hcengineering/view-resources/src/plugin'
import { onMount } from 'svelte' import { onMount } from 'svelte'
import tracker from '../../plugin' import tracker from '../../plugin'
import { activeProjects } from '../../utils'
import ComponentEditor from '../components/ComponentEditor.svelte' import ComponentEditor from '../components/ComponentEditor.svelte'
import CreateIssue from '../CreateIssue.svelte' import CreateIssue from '../CreateIssue.svelte'
import AssigneeEditor from './AssigneeEditor.svelte' import AssigneeEditor from './AssigneeEditor.svelte'
@ -104,12 +105,8 @@
$: dontUpdateRank = orderBy[0] !== IssuesOrdering.Manual $: dontUpdateRank = orderBy[0] !== IssuesOrdering.Manual
const spaceQuery = createQuery()
let currentProject: Project | undefined let currentProject: Project | undefined
$: spaceQuery.query(tracker.class.Project, { _id: currentSpace }, (res) => { $: currentProject = $activeProjects.get(currentSpace)
currentProject = res.shift()
})
let resultQuery: DocumentQuery<any> = query let resultQuery: DocumentQuery<any> = query
$: getResultQuery(query, viewOptionsConfig, viewOptions).then((p) => (resultQuery = p)) $: getResultQuery(query, viewOptionsConfig, viewOptions).then((p) => (resultQuery = p))

View File

@ -13,16 +13,14 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { createQuery } from '@hcengineering/presentation'
import type { Issue, Project } from '@hcengineering/tracker' import type { Issue, Project } from '@hcengineering/tracker'
import tracker from '../../plugin' import { activeProjects } from '../../utils'
export let value: Issue export let value: Issue
const spaceQuery = createQuery()
let currentProject: Project | undefined = undefined let currentProject: Project | undefined = undefined
$: spaceQuery.query(tracker.class.Project, { _id: value.space }, (res) => ([currentProject] = res)) $: currentProject = $activeProjects.get(value.space)
$: title = currentProject ? `${currentProject.identifier}-${value?.number}` : `${value?.number}` $: title = currentProject ? `${currentProject.identifier}-${value?.number}` : `${value?.number}`
</script> </script>

View File

@ -13,22 +13,21 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { createQuery } from '@hcengineering/presentation' import { Issue, Project } from '@hcengineering/tracker'
import { Project, Issue } from '@hcengineering/tracker' import { Button, IconClose, Spinner } from '@hcengineering/ui'
import { Spinner, IconClose, Button } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import tracker from '../../plugin'
import { getIssueId } from '../../issues' import { getIssueId } from '../../issues'
import tracker from '../../plugin'
import { activeProjects } from '../../utils'
import PriorityRefPresenter from './PriorityRefPresenter.svelte' import PriorityRefPresenter from './PriorityRefPresenter.svelte'
export let issue: Issue export let issue: Issue
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const spaceQuery = createQuery()
let project: Project | undefined let project: Project | undefined
$: spaceQuery.query(tracker.class.Project, { _id: issue.space }, (res) => ([project] = res)) $: project = $activeProjects.get(issue.space)
$: issueId = project && getIssueId(project, issue) $: issueId = project && getIssueId(project, issue)
</script> </script>

View File

@ -14,13 +14,13 @@
--> -->
<script lang="ts"> <script lang="ts">
import { AttachedData, IdMap, Ref, Status, WithLookup } from '@hcengineering/core' import { AttachedData, IdMap, Ref, Status, WithLookup } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation' import { getClient } from '@hcengineering/presentation'
import { Issue, IssueDraft, IssueStatus, Project } from '@hcengineering/tracker' import { Issue, IssueDraft, IssueStatus, Project } from '@hcengineering/tracker'
import { import {
Button,
ButtonKind, ButtonKind,
ButtonSize, ButtonSize,
IconSize, IconSize,
Button,
SelectPopup, SelectPopup,
TooltipAlignment, TooltipAlignment,
eventToHTMLElement, eventToHTMLElement,
@ -29,6 +29,7 @@
import { statusStore } from '@hcengineering/view-resources' import { statusStore } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import tracker from '../../plugin' import tracker from '../../plugin'
import { activeProjects } from '../../utils'
import IssueStatusIcon from './IssueStatusIcon.svelte' import IssueStatusIcon from './IssueStatusIcon.svelte'
import StatusPresenter from './StatusPresenter.svelte' import StatusPresenter from './StatusPresenter.svelte'
type ValueType = Issue | (AttachedData<Issue> & { space: Ref<Project> }) | IssueDraft type ValueType = Issue | (AttachedData<Issue> & { space: Ref<Project> }) | IssueDraft
@ -83,10 +84,7 @@
let space: Project | undefined = undefined let space: Project | undefined = undefined
const query = createQuery() $: space = $activeProjects.get(value.space)
$: query.query(tracker.class.Project, { _id: value.space }, (res) => {
space = res[0]
})
function getStatuses (statuses: IdMap<Status>, space: Project | undefined): IssueStatus[] { function getStatuses (statuses: IdMap<Status>, space: Project | undefined): IssueStatus[] {
if (space === undefined) return [] if (space === undefined) return []

View File

@ -246,12 +246,7 @@
<div class="mt-6"> <div class="mt-6">
{#key issue._id && currentProject !== undefined} {#key issue._id && currentProject !== undefined}
{#if currentProject !== undefined} {#if currentProject !== undefined}
<SubIssues <SubIssues focusIndex={50} {issue} shouldSaveDraft />
focusIndex={50}
{issue}
shouldSaveDraft
projects={new Map([[currentProject?._id, currentProject]])}
/>
{/if} {/if}
{/key} {/key}
</div> </div>

View File

@ -13,9 +13,9 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { Class, Doc, DocumentQuery, Ref, toIdMap } from '@hcengineering/core' import { Class, Doc, DocumentQuery, Ref } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation' import { createQuery, getClient } from '@hcengineering/presentation'
import { Issue, Project } from '@hcengineering/tracker' import { Issue } from '@hcengineering/tracker'
import { Button, Chevron, ExpandCollapse, IconAdd, closeTooltip, showPopup } from '@hcengineering/ui' import { Button, Chevron, ExpandCollapse, IconAdd, closeTooltip, showPopup } from '@hcengineering/ui'
import view, { ViewOptions, Viewlet, ViewletPreference } from '@hcengineering/view' import view, { ViewOptions, Viewlet, ViewletPreference } from '@hcengineering/view'
import { ViewletsSettingButton } from '@hcengineering/view-resources' import { ViewletsSettingButton } from '@hcengineering/view-resources'
@ -24,7 +24,6 @@
import CreateIssue from '../../CreateIssue.svelte' import CreateIssue from '../../CreateIssue.svelte'
import SubIssueList from './SubIssueList.svelte' import SubIssueList from './SubIssueList.svelte'
export let projects: Map<Ref<Project>, Project> | undefined = undefined
export let shouldSaveDraft: boolean = false export let shouldSaveDraft: boolean = false
export let object: Doc export let object: Doc
export let query: DocumentQuery<Issue> = {} export let query: DocumentQuery<Issue> = {}
@ -39,23 +38,12 @@
let viewlet: Viewlet | undefined let viewlet: Viewlet | undefined
let viewOptions: ViewOptions | undefined let viewOptions: ViewOptions | undefined
let _projects = projects
export let focusIndex = -1 export let focusIndex = -1
const projectsQuery = createQuery()
function openNewIssueDialog (): void { function openNewIssueDialog (): void {
showPopup(tracker.component.CreateIssue, { space: object.space, ...createParams, shouldSaveDraft }, 'top') showPopup(tracker.component.CreateIssue, { space: object.space, ...createParams, shouldSaveDraft }, 'top')
} }
$: if (projects === undefined) {
projectsQuery.query(tracker.class.Project, { archived: false }, async (result) => {
_projects = toIdMap(result)
})
} else {
projectsQuery.unsubscribe()
}
let lastIssueId: Ref<Doc> let lastIssueId: Ref<Doc>
afterUpdate(() => { afterUpdate(() => {
if (lastIssueId !== object._id) { if (lastIssueId !== object._id) {
@ -178,7 +166,6 @@
createItemLabel={tracker.string.AddIssueTooltip} createItemLabel={tracker.string.AddIssueTooltip}
createItemDialogProps={{ space: object.space, ...createParams, shouldSaveDraft }} createItemDialogProps={{ space: object.space, ...createParams, shouldSaveDraft }}
focusIndex={focusIndex === -1 ? -1 : focusIndex + 1} focusIndex={focusIndex === -1 ? -1 : focusIndex + 1}
projects={_projects}
{configurations} {configurations}
{preference} {preference}
{viewlet} {viewlet}

View File

@ -16,12 +16,12 @@
import { Class, Doc, DocumentQuery, Ref } from '@hcengineering/core' import { Class, Doc, DocumentQuery, Ref } from '@hcengineering/core'
import { IntlString } from '@hcengineering/platform' import { IntlString } from '@hcengineering/platform'
import { ActionContext } from '@hcengineering/presentation' import { ActionContext } from '@hcengineering/presentation'
import { Issue, Project } from '@hcengineering/tracker' import { Issue } from '@hcengineering/tracker'
import { AnyComponent, AnySvelteComponent, registerFocus } from '@hcengineering/ui' import { AnyComponent, AnySvelteComponent, registerFocus } from '@hcengineering/ui'
import { ViewOptions, Viewlet, ViewletPreference } from '@hcengineering/view' import { ViewOptions, Viewlet, ViewletPreference } from '@hcengineering/view'
import { List, ListSelectionProvider, SelectDirection, selectionStore } from '@hcengineering/view-resources' import { List, ListSelectionProvider, SelectDirection, selectionStore } from '@hcengineering/view-resources'
import tracker from '../../../plugin'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import tracker from '../../../plugin'
export let query: DocumentQuery<Issue> | undefined = undefined export let query: DocumentQuery<Issue> | undefined = undefined
export let viewlet: Viewlet export let viewlet: Viewlet
@ -31,9 +31,6 @@
export let configurations: Record<Ref<Class<Doc>>, Viewlet['config']> = {} export let configurations: Record<Ref<Class<Doc>>, Viewlet['config']> = {}
export let preference: ViewletPreference[] = [] export let preference: ViewletPreference[] = []
// Extra properties
export let projects: Map<Ref<Project>, Project> | undefined
let list: List let list: List
const listProvider = new ListSelectionProvider( const listProvider = new ListSelectionProvider(
@ -87,7 +84,6 @@
{configurations} {configurations}
{query} {query}
flatHeaders={true} flatHeaders={true}
props={{ projects }}
{disableHeader} {disableHeader}
{createItemDialog} {createItemDialog}
{createItemDialogProps} {createItemDialogProps}

View File

@ -13,15 +13,13 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { Ref } from '@hcengineering/core' import { Issue, trackerId } from '@hcengineering/tracker'
import { Issue, Project, trackerId } from '@hcengineering/tracker'
import { Button, IconScaleFull, Label, closeTooltip, getCurrentResolvedLocation, navigate } from '@hcengineering/ui' import { Button, IconScaleFull, Label, closeTooltip, getCurrentResolvedLocation, navigate } from '@hcengineering/ui'
import { createFilter, setFilters } from '@hcengineering/view-resources' import { createFilter, setFilters } from '@hcengineering/view-resources'
import tracker from '../../../plugin' import tracker from '../../../plugin'
import QueryIssuesList from './QueryIssuesList.svelte' import QueryIssuesList from './QueryIssuesList.svelte'
export let issue: Issue export let issue: Issue
export let projects: Map<Ref<Project>, Project> | undefined
export let shouldSaveDraft: boolean = false export let shouldSaveDraft: boolean = false
// showPopup(tracker.component.CreateIssue, { space: issue.space, parentIssue: issue, shouldSaveDraft }, 'top') // showPopup(tracker.component.CreateIssue, { space: issue.space, parentIssue: issue, shouldSaveDraft }, 'top')
@ -37,7 +35,6 @@
createLabel={tracker.string.AddSubIssues} createLabel={tracker.string.AddSubIssues}
hasSubIssues={issue.subIssues > 0} hasSubIssues={issue.subIssues > 0}
{focusIndex} {focusIndex}
{projects}
{shouldSaveDraft} {shouldSaveDraft}
on:docs={(evt) => { on:docs={(evt) => {
size = evt.detail.length size = evt.detail.length

View File

@ -13,15 +13,11 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { Doc, DocumentQuery, Ref } from '@hcengineering/core' import { Doc, DocumentQuery } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation' import { Issue } from '@hcengineering/tracker'
import { Issue, Project } from '@hcengineering/tracker'
import { Label, Spinner } from '@hcengineering/ui'
import { ViewOptions, Viewlet } from '@hcengineering/view' import { ViewOptions, Viewlet } from '@hcengineering/view'
import { createEventDispatcher } from 'svelte'
import tracker from '../../../plugin' import tracker from '../../../plugin'
import CreateIssue from '../../CreateIssue.svelte' import CreateIssue from '../../CreateIssue.svelte'
import AddIssueDuo from '../../icons/AddIssueDuo.svelte'
import SubIssueList from '../edit/SubIssueList.svelte' import SubIssueList from '../edit/SubIssueList.svelte'
export let object: Doc export let object: Doc
@ -30,49 +26,20 @@
export let disableHeader: boolean = false export let disableHeader: boolean = false
export let compactMode: boolean = false export let compactMode: boolean = false
const dispatch = createEventDispatcher()
let query: DocumentQuery<Issue> let query: DocumentQuery<Issue>
$: query = { 'relations._id': object._id, 'relations._class': object._class } $: query = { 'relations._id': object._id, 'relations._class': object._class }
let projects: Map<Ref<Project>, Project> | undefined
const projectsQuery = createQuery()
$: projectsQuery.query(tracker.class.Project, { archived: false }, async (result) => {
projects = new Map(result.map((it) => [it._id, it]))
})
</script> </script>
{#if viewlet !== undefined} {#if viewlet !== undefined}
{#if projects} <!-- svelte-ignore a11y-no-static-element-interactions -->
<SubIssueList <SubIssueList
bind:viewOptions bind:viewOptions
{viewlet} {viewlet}
{query} {query}
{projects} {disableHeader}
{disableHeader} {compactMode}
{compactMode} createItemDialog={CreateIssue}
createItemDialog={CreateIssue} createItemLabel={tracker.string.AddIssueTooltip}
createItemLabel={tracker.string.AddIssueTooltip} createItemDialogProps={{ relatedTo: object }}
createItemDialogProps={{ relatedTo: object }} />
/>
{:else}
<div class="antiSection-empty solid flex-col">
<div class="flex-center content-color">
<AddIssueDuo size={'large'} />
</div>
<div class="text-sm content-dark-color" style:pointer-events="none">
<Label label={tracker.string.RelatedIssuesNotFound} />
</div>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="over-underline text-sm content-color" on:click={() => dispatch('add-issue')}>
<Label label={tracker.string.NewRelatedIssue} />
</div>
</div>
{/if}
{:else}
<div class="flex-center">
<Spinner />
</div>
{/if} {/if}

View File

@ -112,15 +112,11 @@
</svelte:fragment> </svelte:fragment>
{#if currentProject} {#if currentProject}
<SubIssuesEstimations issue={object} projects={new Map([[currentProject?._id, currentProject]])} /> <SubIssuesEstimations issue={object} />
{/if} {/if}
{#if currentProject} {#if currentProject}
<TimeSpendReports <TimeSpendReports issue={object} query={{ attachedTo: { $in: [object._id, ...childIds] } }} />
issue={object}
projects={new Map([[currentProject?._id, currentProject]])}
query={{ attachedTo: { $in: [object._id, ...childIds] } }}
/>
{/if} {/if}
<svelte:fragment slot="buttons"> <svelte:fragment slot="buttons">
<Button <Button

View File

@ -14,19 +14,17 @@
--> -->
<script lang="ts"> <script lang="ts">
import contact from '@hcengineering/contact' import contact from '@hcengineering/contact'
import { Ref } from '@hcengineering/core'
import { AssigneeBox } from '@hcengineering/contact-resources' import { AssigneeBox } from '@hcengineering/contact-resources'
import { Issue, Project } from '@hcengineering/tracker' import { Issue } from '@hcengineering/tracker'
import { deviceOptionsStore as deviceInfo, getEventPositionElement, ListView, showPopup } from '@hcengineering/ui' import { ListView, deviceOptionsStore as deviceInfo, getEventPositionElement, showPopup } from '@hcengineering/ui'
import { ContextMenu, FixedColumn, ListSelectionProvider } from '@hcengineering/view-resources' import { ContextMenu, FixedColumn, ListSelectionProvider } from '@hcengineering/view-resources'
import { getIssueId } from '../../../issues' import { getIssueId } from '../../../issues'
import tracker from '../../../plugin' import tracker from '../../../plugin'
import { activeProjects } from '../../../utils'
import EstimationEditor from './EstimationEditor.svelte' import EstimationEditor from './EstimationEditor.svelte'
export let issues: Issue[] export let issues: Issue[]
export let projects: Map<Ref<Project>, Project>
function showContextMenu (ev: MouseEvent, object: Issue) { function showContextMenu (ev: MouseEvent, object: Issue) {
showPopup(ContextMenu, { object }, $deviceInfo.isMobile ? 'top' : getEventPositionElement(ev)) showPopup(ContextMenu, { object }, $deviceInfo.isMobile ? 'top' : getEventPositionElement(ev))
} }
@ -35,10 +33,11 @@
$: twoRows = $deviceInfo.twoRows $: twoRows = $deviceInfo.twoRows
</script> </script>
<!-- svelte-ignore a11y-no-static-element-interactions -->
<ListView count={issues.length} addClass={'step-tb-2-accent'}> <ListView count={issues.length} addClass={'step-tb-2-accent'}>
<svelte:fragment slot="item" let:item> <svelte:fragment slot="item" let:item>
{@const issue = issues[item]} {@const issue = issues[item]}
{@const currentProject = projects.get(issue.space)} {@const currentProject = $activeProjects.get(issue.space)}
<div <div
class="{twoRows ? 'flex-col' : 'flex-between'} p-text-2 clear-mins" class="{twoRows ? 'flex-col' : 'flex-between'} p-text-2 clear-mins"
on:contextmenu|preventDefault={(ev) => showContextMenu(ev, issue)} on:contextmenu|preventDefault={(ev) => showContextMenu(ev, issue)}

View File

@ -15,9 +15,9 @@
--> -->
<script lang="ts"> <script lang="ts">
import type { IntlString } from '@hcengineering/platform' import type { IntlString } from '@hcengineering/platform'
import { createQuery } from '@hcengineering/presentation' import { Issue, Project } from '@hcengineering/tracker'
import tracker, { Issue, Project } from '@hcengineering/tracker' import { ActionIcon, IconAdd, Label, eventToHTMLElement, floorFractionDigits, showPopup } from '@hcengineering/ui'
import { ActionIcon, eventToHTMLElement, floorFractionDigits, IconAdd, Label, showPopup } from '@hcengineering/ui' import { activeProjects } from '../../../utils'
import ReportsPopup from './ReportsPopup.svelte' import ReportsPopup from './ReportsPopup.svelte'
import TimePresenter from './TimePresenter.svelte' import TimePresenter from './TimePresenter.svelte'
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte' import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
@ -30,13 +30,8 @@
export let size: 'small' | 'medium' | 'large' = 'large' export let size: 'small' | 'medium' | 'large' = 'large'
export let currentProject: Project | undefined export let currentProject: Project | undefined
const spaceQuery = createQuery()
$: if (currentProject === undefined) { $: if (currentProject === undefined) {
spaceQuery.query(tracker.class.Project, { _id: object.space }, (res) => { currentProject = $activeProjects.get(object.space)
currentProject = res.shift()
})
} else {
spaceQuery.unsubscribe()
} }
$: defaultTimeReportDay = currentProject?.defaultTimeReportDay $: defaultTimeReportDay = currentProject?.defaultTimeReportDay

View File

@ -13,15 +13,14 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { Ref, SortingOrder } from '@hcengineering/core' import { SortingOrder } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation' import { createQuery } from '@hcengineering/presentation'
import { Issue, Project } from '@hcengineering/tracker' import { Issue } from '@hcengineering/tracker'
import { Expandable, Spinner } from '@hcengineering/ui' import { Expandable, Spinner } from '@hcengineering/ui'
import tracker from '../../../plugin' import tracker from '../../../plugin'
import EstimationSubIssueList from './EstimationSubIssueList.svelte' import EstimationSubIssueList from './EstimationSubIssueList.svelte'
export let issue: Issue export let issue: Issue
export let projects: Map<Ref<Project>, Project>
const subIssuesQuery = createQuery() const subIssuesQuery = createQuery()
@ -38,7 +37,7 @@
{#if hasSubIssues} {#if hasSubIssues}
<Expandable label={tracker.string.ChildEstimation} contentColor bordered> <Expandable label={tracker.string.ChildEstimation} contentColor bordered>
<svelte:fragment slot="title">: <span class="caption-color">{total}</span></svelte:fragment> <svelte:fragment slot="title">: <span class="caption-color">{total}</span></svelte:fragment>
<EstimationSubIssueList issues={subIssues} {projects} /> <EstimationSubIssueList issues={subIssues} />
</Expandable> </Expandable>
{/if} {/if}
{:else} {:else}

View File

@ -13,16 +13,15 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { DocumentQuery, Ref, SortingOrder } from '@hcengineering/core' import { DocumentQuery, SortingOrder } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation' import { createQuery } from '@hcengineering/presentation'
import { Issue, Project, TimeSpendReport } from '@hcengineering/tracker' import { Issue, TimeSpendReport } from '@hcengineering/tracker'
import { Expandable, floorFractionDigits, Label, Spinner } from '@hcengineering/ui' import { Expandable, Label, Spinner, floorFractionDigits } from '@hcengineering/ui'
import tracker from '../../../plugin' import tracker from '../../../plugin'
import TimePresenter from './TimePresenter.svelte' import TimePresenter from './TimePresenter.svelte'
import TimeSpendReportsList from './TimeSpendReportsList.svelte' import TimeSpendReportsList from './TimeSpendReportsList.svelte'
export let issue: Issue export let issue: Issue
export let projects: Map<Ref<Project>, Project>
export let query: DocumentQuery<TimeSpendReport> export let query: DocumentQuery<TimeSpendReport>
const subIssuesQuery = createQuery() const subIssuesQuery = createQuery()
@ -50,7 +49,7 @@
<span class="caption-color"><TimePresenter value={floorFractionDigits(total / 8, 3)} /></span> <span class="caption-color"><TimePresenter value={floorFractionDigits(total / 8, 3)} /></span>
</span> </span>
</svelte:fragment> </svelte:fragment>
<TimeSpendReportsList {reports} {projects} /> <TimeSpendReportsList {reports} />
</Expandable> </Expandable>
{:else} {:else}
<div class="flex-center"> <div class="flex-center">

View File

@ -30,11 +30,10 @@
import tracker from '../../../plugin' import tracker from '../../../plugin'
import TimePresenter from './TimePresenter.svelte' import TimePresenter from './TimePresenter.svelte'
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte' import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
import { activeProjects } from '../../../utils'
export let reports: WithLookup<TimeSpendReport>[] export let reports: WithLookup<TimeSpendReport>[]
export let projects: Map<Ref<Project>, Project>
function showContextMenu (ev: MouseEvent, object: TimeSpendReport) { function showContextMenu (ev: MouseEvent, object: TimeSpendReport) {
showPopup(ContextMenu, { object }, getEventPositionElement(ev)) showPopup(ContextMenu, { object }, getEventPositionElement(ev))
} }
@ -65,10 +64,11 @@
</script> </script>
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<ListView count={reports.length} addClass={'step-tb-2-accent'}> <ListView count={reports.length} addClass={'step-tb-2-accent'}>
<svelte:fragment slot="item" let:item> <svelte:fragment slot="item" let:item>
{@const report = reports[item]} {@const report = reports[item]}
{@const currentProject = projects.get(toProjectId(report.space))} {@const currentProject = $activeProjects.get(toProjectId(report.space))}
<div <div
class="{twoRows ? 'flex-col' : 'flex-between'} p-text-2 clear-mins" class="{twoRows ? 'flex-col' : 'flex-between'} p-text-2 clear-mins"
on:contextmenu|preventDefault={(ev) => showContextMenu(ev, report)} on:contextmenu|preventDefault={(ev) => showContextMenu(ev, report)}

View File

@ -1,12 +1,13 @@
<script lang="ts"> <script lang="ts">
import { Ref } from '@hcengineering/core' import { Ref } from '@hcengineering/core'
import presentation, { createQuery, getClient } from '@hcengineering/presentation' import presentation, { getClient } from '@hcengineering/presentation'
import { getStates } from '@hcengineering/task' import { getStates } from '@hcengineering/task'
import { Issue, IssueStatus, Project } from '@hcengineering/tracker' import { Issue, IssueStatus, Project } from '@hcengineering/tracker'
import { Button, Label, SelectPopup, eventToHTMLElement, showPopup } from '@hcengineering/ui' import { Button, Label, SelectPopup, eventToHTMLElement, showPopup } from '@hcengineering/ui'
import { StatusPresenter, statusStore } from '@hcengineering/view-resources' import { StatusPresenter, statusStore } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import tracker from '../../plugin' import tracker from '../../plugin'
import { activeProjects } from '../../utils'
import IssueStatusIcon from '../issues/IssueStatusIcon.svelte' import IssueStatusIcon from '../issues/IssueStatusIcon.svelte'
export let projectId: Ref<Project> export let projectId: Ref<Project>
@ -17,10 +18,7 @@
let _space: Project | undefined = undefined let _space: Project | undefined = undefined
const query = createQuery() $: _space = $activeProjects.get(projectId)
$: query.query(tracker.class.Project, { space: projectId }, (result) => {
_space = result[0]
})
const client = getClient() const client = getClient()

View File

@ -69,7 +69,7 @@ import {
groupBy, groupBy,
statusStore statusStore
} from '@hcengineering/view-resources' } from '@hcengineering/view-resources'
import { get } from 'svelte/store' import { get, writable } from 'svelte/store'
import tracker from './plugin' import tracker from './plugin'
import { defaultMilestoneStatuses, defaultPriorities } from './types' import { defaultMilestoneStatuses, defaultPriorities } from './types'
@ -371,6 +371,13 @@ export async function milestoneSort (
}) })
} }
export const activeProjects = writable<IdMap<Project>>(new Map())
const activeProjectsQuery = createQuery(true)
activeProjectsQuery.query(tracker.class.Project, { archived: false }, (projects) => {
activeProjects.set(toIdMap(projects))
})
export async function moveIssuesToAnotherMilestone ( export async function moveIssuesToAnotherMilestone (
client: TxOperations, client: TxOperations,
oldMilestone: Milestone, oldMilestone: Milestone,

View File

@ -82,7 +82,7 @@
showPopup( showPopup(
ViewOptionsEditor, ViewOptionsEditor,
{ viewlet, config: mergedModel, viewOptions }, { viewlet, config: mergedModel, viewOptions: getClient().getHierarchy().clone(viewOptions) },
eventToHTMLElement(event), eventToHTMLElement(event),
undefined, undefined,
(result) => { (result) => {
@ -93,8 +93,8 @@
// Clear selection on view settings change. // Clear selection on view settings change.
focusStore.set({}) focusStore.set({})
dispatch('viewOptions', viewOptions)
setViewOptions(viewlet, viewOptions) setViewOptions(viewlet, viewOptions)
dispatch('viewOptions', viewOptions)
} }
} }
) )

View File

@ -76,7 +76,7 @@
revert?: () => void revert?: () => void
} }
export let listDiv: HTMLDivElement export let listDiv: HTMLDivElement
export let selection: number | undefined = undefined export let selection: number | undefined
export let groupPersistKey: string export let groupPersistKey: string
export let compactMode: boolean = false export let compactMode: boolean = false