mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-28 04:25:03 +02:00
@@ -0,0 +1,16 @@
|
||||
<span class="root" />
|
||||
|
||||
<style lang="scss">
|
||||
.root {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
flex-shrink: 10;
|
||||
|
||||
&.with-margin {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -16,7 +16,7 @@
|
||||
import contact, { Employee } from '@anticrm/contact'
|
||||
import { Class, Doc, FindOptions, getObjectValue, Ref, WithLookup } from '@anticrm/core'
|
||||
import notification from '@anticrm/notification'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import { createQuery, getClient } from '@anticrm/presentation'
|
||||
import { Issue, IssueStatus, Team } from '@anticrm/tracker'
|
||||
import {
|
||||
Button,
|
||||
@@ -36,6 +36,7 @@
|
||||
import tracker from '../../plugin'
|
||||
import { IssuesGroupByKeys, issuesGroupEditorMap, IssuesOrderByKeys, issuesSortOrderMap } from '../../utils'
|
||||
import CreateIssue from '../CreateIssue.svelte'
|
||||
import GrowPresenter from './GrowPresenter.svelte'
|
||||
|
||||
export let _class: Ref<Class<Doc>>
|
||||
export let currentSpace: Ref<Team> | undefined = undefined
|
||||
@@ -59,10 +60,19 @@
|
||||
lookup: {
|
||||
assignee: contact.class.Employee,
|
||||
status: tracker.class.IssueStatus,
|
||||
space: tracker.class.Team
|
||||
space: tracker.class.Team,
|
||||
_id: {
|
||||
subIssues: tracker.class.Issue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const spaceQuery = createQuery()
|
||||
let currentTeam: Team | undefined
|
||||
$: spaceQuery.query(tracker.class.Team, { _id: currentSpace }, (res) => {
|
||||
currentTeam = res.shift()
|
||||
})
|
||||
|
||||
let personPresenter: AttributeModel
|
||||
|
||||
$: isCollapsedMap = Object.fromEntries(categories.map((category) => [category, false]))
|
||||
@@ -175,6 +185,7 @@
|
||||
shouldShowPlaceholder={true}
|
||||
isInteractive={false}
|
||||
avatarSize={'x-small'}
|
||||
{currentSpace}
|
||||
/>
|
||||
{:else if headerComponent}
|
||||
<Component
|
||||
@@ -186,7 +197,8 @@
|
||||
statuses: groupByKey === 'status' ? statuses : undefined,
|
||||
issues: groupedIssues[category],
|
||||
size: 'inline',
|
||||
kind: 'list'
|
||||
kind: 'list',
|
||||
currentSpace
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
@@ -244,6 +256,8 @@
|
||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
||||
groupBy={groupByKey}
|
||||
{...attributeModel.props}
|
||||
{statuses}
|
||||
{currentTeam}
|
||||
/>
|
||||
</div>
|
||||
{:else if attributeModelIndex === 1}
|
||||
@@ -259,10 +273,12 @@
|
||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
||||
groupBy={groupByKey}
|
||||
{...attributeModel.props}
|
||||
{statuses}
|
||||
{currentTeam}
|
||||
/>
|
||||
</FixedColumn>
|
||||
</div>
|
||||
{:else if attributeModelIndex === 3}
|
||||
{:else if attributeModelIndex === 3 || attributeModel.presenter === GrowPresenter}
|
||||
<svelte:component
|
||||
this={attributeModel.presenter}
|
||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
||||
@@ -281,6 +297,8 @@
|
||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
||||
groupBy={groupByKey}
|
||||
{...attributeModel.props}
|
||||
{statuses}
|
||||
{currentTeam}
|
||||
/>
|
||||
</FixedColumn>
|
||||
{:else}
|
||||
@@ -291,6 +309,8 @@
|
||||
issueId={docObject._id}
|
||||
groupBy={groupByKey}
|
||||
{...attributeModel.props}
|
||||
{statuses}
|
||||
{currentTeam}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -367,12 +387,7 @@
|
||||
|
||||
.priorityPresenter,
|
||||
.issuePresenter {
|
||||
min-width: 0;
|
||||
// min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
// .grow-cell {
|
||||
// flex-grow: 1;
|
||||
// flex-shrink: 0;
|
||||
// min-width: 0;
|
||||
// }
|
||||
</style>
|
||||
|
||||
@@ -252,7 +252,7 @@
|
||||
</div>
|
||||
<div class="buttons-group xsmall-gap states-bar">
|
||||
{#if issue && issueStatuses && issue.subIssues > 0}
|
||||
<SubIssuesSelector {issue} {currentTeam} {issueStatuses} />
|
||||
<SubIssuesSelector value={issue} {currentTeam} statuses={issueStatuses} />
|
||||
{/if}
|
||||
<PriorityEditor value={issue} isEditable={true} kind={'link-bordered'} size={'inline'} justify={'center'} />
|
||||
<ProjectEditor
|
||||
|
||||
@@ -58,7 +58,10 @@
|
||||
assignee: contact.class.Employee,
|
||||
status: tracker.class.IssueStatus,
|
||||
space: tracker.class.Team,
|
||||
sprint: tracker.class.Sprint
|
||||
sprint: tracker.class.Sprint,
|
||||
_id: {
|
||||
subIssues: tracker.class.Issue
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
<style lang="scss">
|
||||
.root {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
flex-grow: 0;
|
||||
min-width: 7rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
flex-shrink: 10;
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
import tracker from '../../../plugin'
|
||||
import { getIssueId } from '../../../issues'
|
||||
|
||||
export let issue: WithLookup<Issue>
|
||||
export let value: WithLookup<Issue>
|
||||
export let currentTeam: Team | undefined
|
||||
export let issueStatuses: WithLookup<IssueStatus>[] | undefined
|
||||
export let statuses: WithLookup<IssueStatus>[] | undefined
|
||||
|
||||
export let kind: ButtonKind = 'link-bordered'
|
||||
export let size: ButtonSize = 'inline'
|
||||
@@ -36,18 +36,18 @@
|
||||
let doneStatus: Ref<Doc> | undefined
|
||||
let countComplate: number = 0
|
||||
|
||||
$: if (issue.$lookup?.subIssues !== undefined) {
|
||||
subIssues = issue.$lookup.subIssues as Issue[]
|
||||
subIssues.sort((a, b) => a.rank.localeCompare(b.rank))
|
||||
$: if (value.$lookup?.subIssues !== undefined) {
|
||||
subIssues = value.$lookup.subIssues as Issue[]
|
||||
subIssues.sort((a, b) => (a.rank ?? '').localeCompare(b.rank ?? ''))
|
||||
}
|
||||
$: if (issueStatuses && subIssues) {
|
||||
doneStatus = issueStatuses.find((s) => s.category === tracker.issueStatusCategory.Completed)?._id ?? undefined
|
||||
$: if (statuses && subIssues) {
|
||||
doneStatus = statuses.find((s) => s.category === tracker.issueStatusCategory.Completed)?._id ?? undefined
|
||||
if (doneStatus) countComplate = subIssues.filter((si) => si.status === doneStatus).length
|
||||
}
|
||||
$: hasSubIssues = (subIssues?.length ?? 0) > 0
|
||||
|
||||
function getIssueStatusIcon (issue: Issue) {
|
||||
const status = issueStatuses?.find((s) => issue.status === s._id)
|
||||
const status = statuses?.find((s) => issue.status === s._id)
|
||||
const category = status?.$lookup?.category
|
||||
const color = status?.color ?? category?.color
|
||||
|
||||
@@ -58,8 +58,8 @@
|
||||
}
|
||||
|
||||
function openIssue (target: Ref<Issue>) {
|
||||
if (target !== issue._id) {
|
||||
showPanel(tracker.component.EditIssue, target, issue._class, 'content')
|
||||
if (target !== value._id) {
|
||||
showPanel(tracker.component.EditIssue, target, value._class, 'content')
|
||||
}
|
||||
}
|
||||
function showSubIssues () {
|
||||
@@ -71,7 +71,7 @@
|
||||
value: subIssues.map((iss) => {
|
||||
const text = currentTeam ? `${getIssueId(currentTeam, iss)} ${iss.title}` : iss.title
|
||||
|
||||
return { id: iss._id, text, isSelected: iss._id === issue._id, ...getIssueStatusIcon(iss) }
|
||||
return { id: iss._id, text, isSelected: iss._id === value._id, ...getIssueStatusIcon(iss) }
|
||||
}),
|
||||
width: 'large'
|
||||
},
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
function hourFloor (value: number): number {
|
||||
const days = Math.ceil(value)
|
||||
const hours = value - days
|
||||
return days + Math.floor(hours * 10) / 10
|
||||
return days + Math.floor(hours * 100) / 100
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
+13
-11
@@ -44,17 +44,19 @@
|
||||
style:stroke-dasharray={lenghtC}
|
||||
style:stroke-dashoffset={dashOffset === 0 ? 0 : dashOffset + 3}
|
||||
/>
|
||||
<circle
|
||||
cx={8}
|
||||
cy={8}
|
||||
r={7}
|
||||
class="progress-circle"
|
||||
style:stroke={primary ? 'var(--primary-bg-color)' : color}
|
||||
style:opacity={dashOffset === 0 ? 0 : 1}
|
||||
style:transform={'rotate(-82deg)'}
|
||||
style:stroke-dasharray={lenghtC}
|
||||
style:stroke-dashoffset={dashOffset === 0 ? lenghtC : lenghtC - dashOffset + 1}
|
||||
/>
|
||||
{#if min !== max && min !== value}
|
||||
<circle
|
||||
cx={8}
|
||||
cy={8}
|
||||
r={7}
|
||||
class="progress-circle"
|
||||
style:stroke={primary ? 'var(--primary-bg-color)' : color}
|
||||
style:opacity={dashOffset === 0 ? 0 : 1}
|
||||
style:transform={'rotate(-82deg)'}
|
||||
style:stroke-dasharray={lenghtC}
|
||||
style:stroke-dashoffset={dashOffset === 0 ? lenghtC : lenghtC - dashOffset + 1}
|
||||
/>
|
||||
{/if}
|
||||
</svg>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@
|
||||
okLabel={value === undefined ? presentation.string.Create : presentation.string.Save}
|
||||
>
|
||||
<div class="flex-row-center gap-2">
|
||||
<EditBox bind:value={data.value} {placeholder} format={'number'} kind={'editbox'} {maxWidth} focus />
|
||||
<EditBox focus bind:value={data.value} {placeholder} format={'number'} kind={'editbox'} {maxWidth} />
|
||||
<UserBox
|
||||
_class={contact.class.Employee}
|
||||
label={contact.string.Employee}
|
||||
|
||||
Reference in New Issue
Block a user