mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 11:42:30 +03:00
Kanban due date (#3034)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
cb8996fc1f
commit
cc5e7adb41
@ -27,7 +27,11 @@
|
||||
"AddDueDate": "Add due date",
|
||||
"EditDueDate": "Edit due date",
|
||||
"SaveDueDate": "Save due date",
|
||||
"IssueNeedsToBeCompletedByThisDate": "Issue needs to be completed by this date",
|
||||
"NeedsToBeCompletedByThisDate": "Needs to be completed by this date",
|
||||
"DueDatePopupTitle": "Due on {value}",
|
||||
"DueDatePopupOverdueTitle": "Was due on {value}",
|
||||
"DueDatePopupDescription": "{value, plural, =0 {Today} =1 {Tomorrow} other {# days remaining}}",
|
||||
"DueDatePopupOverdueDescription": "{value, plural, =1 {1 day overdue} other {# days overdue}}",
|
||||
"English": "English",
|
||||
"Russian": "Russian",
|
||||
"MinutesBefore": "{minutes, plural, =1 {a minute before} other {# minutes before}}",
|
||||
|
@ -27,7 +27,11 @@
|
||||
"AddDueDate": "Установить дату",
|
||||
"EditDueDate": "Изменить дату",
|
||||
"SaveDueDate": "Сохранить дату",
|
||||
"IssueNeedsToBeCompletedByThisDate": "Задача должна быть завершена к этой дате",
|
||||
"NeedsToBeCompletedByThisDate": "Должно быть завершено к этой дате",
|
||||
"DueDatePopupTitle": "Срок {value}",
|
||||
"DueDatePopupOverdueTitle": "Должно было завершится {value}",
|
||||
"DueDatePopupDescription": "{value, plural, =0 {Сегодня} =1 {Завтра} other {# дней осталось}}",
|
||||
"DueDatePopupOverdueDescription": "{value, plural, =1 {1 день опоздания} other {# дней опаздания}}",
|
||||
"English": "Английский",
|
||||
"Russian": "Русский",
|
||||
"MinutesBefore": "{minutes, plural, =1 {за минуту} other {за # минут}}",
|
||||
|
@ -13,21 +13,22 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import { afterUpdate, createEventDispatcher } from 'svelte'
|
||||
import ui from '../../plugin'
|
||||
import ActionIcon from '../ActionIcon.svelte'
|
||||
import Button from '../Button.svelte'
|
||||
import Icon from '../Icon.svelte'
|
||||
import IconClose from '../icons/Close.svelte'
|
||||
import Label from '../Label.svelte'
|
||||
import { daysInMonth } from './internal/DateUtils'
|
||||
import IconClose from '../icons/Close.svelte'
|
||||
import MonthSquare from './MonthSquare.svelte'
|
||||
import { daysInMonth } from './internal/DateUtils'
|
||||
|
||||
export let currentDate: Date | null
|
||||
export let withTime: boolean = false
|
||||
export let mondayStart: boolean = true
|
||||
export let label = currentDate != null ? ui.string.EditDueDate : ui.string.AddDueDate
|
||||
export let detail = ui.string.IssueNeedsToBeCompletedByThisDate
|
||||
export let detail: IntlString | undefined = undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@ -242,8 +243,10 @@
|
||||
<div class="content">
|
||||
<div class="label">
|
||||
<span class="bold"><Label {label} /></span>
|
||||
<span class="divider">-</span>
|
||||
<Label label={detail} />
|
||||
{#if detail}
|
||||
<span class="divider">-</span>
|
||||
<Label label={detail} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="datetime-input">
|
||||
|
@ -16,15 +16,16 @@
|
||||
import type { IntlString } from '@hcengineering/platform'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
import { DateRangeMode } from '@hcengineering/core'
|
||||
import ui from '../../plugin'
|
||||
import { showPopup } from '../../popups'
|
||||
import { ButtonKind } from '../../types'
|
||||
import Icon from '../Icon.svelte'
|
||||
import Label from '../Label.svelte'
|
||||
import DatePopup from './DatePopup.svelte'
|
||||
import DPCalendar from './icons/DPCalendar.svelte'
|
||||
import DPCalendarOver from './icons/DPCalendarOver.svelte'
|
||||
import { getMonthName } from './internal/DateUtils'
|
||||
import DatePopup from './DatePopup.svelte'
|
||||
import { DateRangeMode } from '@hcengineering/core'
|
||||
|
||||
export let value: number | null | undefined
|
||||
export let mode: DateRangeMode = DateRangeMode.DATE
|
||||
@ -36,9 +37,9 @@
|
||||
export let showIcon = true
|
||||
export let shouldShowLabel: boolean = true
|
||||
export let size: 'x-small' | 'small' = 'small'
|
||||
export let kind: 'transparent' | 'primary' | 'link' | 'list' = 'primary'
|
||||
export let kind: ButtonKind = 'link'
|
||||
export let label = ui.string.DueDate
|
||||
export let detail = ui.string.IssueNeedsToBeCompletedByThisDate
|
||||
export let detail = ui.string.NeedsToBeCompletedByThisDate
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@ -70,8 +71,10 @@
|
||||
class:h-6={size === 'small'}
|
||||
class:h-3={size === 'x-small'}
|
||||
class:text-xs={size === 'x-small'}
|
||||
on:click={() => {
|
||||
on:click={(e) => {
|
||||
if (editable && !opened) {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
opened = true
|
||||
showPopup(
|
||||
DatePopup,
|
||||
@ -251,6 +254,19 @@
|
||||
border-color: var(--button-border-color);
|
||||
}
|
||||
}
|
||||
&.link-bordered {
|
||||
padding: 0 0.375rem;
|
||||
color: var(--accent-color);
|
||||
border-color: var(--divider-color);
|
||||
&:hover {
|
||||
color: var(--accent-color);
|
||||
background-color: var(--button-bg-hover);
|
||||
border-color: var(--button-border-hover);
|
||||
.btn-icon {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.time-divider {
|
||||
flex-shrink: 0;
|
||||
|
@ -13,8 +13,11 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Icon, Label, IconDPCalendarOver, IconDPCalendar } from '@hcengineering/ui'
|
||||
import tracker from '../plugin'
|
||||
import DPCalendar from './icons/DPCalendar.svelte'
|
||||
import DPCalendarOver from './icons/DPCalendarOver.svelte'
|
||||
import ui from '../../plugin'
|
||||
import Icon from '../Icon.svelte'
|
||||
import Label from '../Label.svelte'
|
||||
|
||||
export let formattedDate: string = ''
|
||||
export let daysDifference: number = 0
|
||||
@ -29,18 +32,18 @@
|
||||
class:mIconContainerWarning={iconModifier === 'warning'}
|
||||
class:mIconContainerCritical={iconModifier === 'critical' || iconModifier === 'overdue'}
|
||||
>
|
||||
<Icon icon={isOverdue ? IconDPCalendarOver : IconDPCalendar} size={'small'} />
|
||||
<Icon icon={isOverdue ? DPCalendarOver : DPCalendar} size={'small'} />
|
||||
</div>
|
||||
<div class="messageContainer">
|
||||
<div class="title">
|
||||
<Label
|
||||
label={isOverdue ? tracker.string.DueDatePopupOverdueTitle : tracker.string.DueDatePopupTitle}
|
||||
label={isOverdue ? ui.string.DueDatePopupOverdueTitle : ui.string.DueDatePopupTitle}
|
||||
params={{ value: formattedDate }}
|
||||
/>
|
||||
</div>
|
||||
<div class="description">
|
||||
<Label
|
||||
label={isOverdue ? tracker.string.DueDatePopupOverdueDescription : tracker.string.DueDatePopupDescription}
|
||||
label={isOverdue ? ui.string.DueDatePopupOverdueDescription : ui.string.DueDatePopupDescription}
|
||||
params={{ value: daysDifference }}
|
||||
/>
|
||||
</div>
|
89
packages/ui/src/components/calendar/DueDatePresenter.svelte
Normal file
89
packages/ui/src/components/calendar/DueDatePresenter.svelte
Normal file
@ -0,0 +1,89 @@
|
||||
<!--
|
||||
// Copyright © 2022 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Timestamp } from '@hcengineering/core'
|
||||
import DueDatePopup from './DueDatePopup.svelte'
|
||||
import { tooltip } from '../../tooltips'
|
||||
import DatePresenter from './DatePresenter.svelte'
|
||||
import { getDaysDifference } from './internal/DateUtils'
|
||||
import { ButtonKind } from '../../types'
|
||||
|
||||
export let value: number | null = null
|
||||
export let shouldRender: boolean = true
|
||||
export let onChange: (newDate: number | null) => void
|
||||
export let kind: ButtonKind = 'link'
|
||||
export let editable: boolean = true
|
||||
|
||||
const today = new Date(new Date(Date.now()).setHours(0, 0, 0, 0))
|
||||
$: isOverdue = value !== null && value < today.getTime()
|
||||
$: dueDate = value === null ? null : new Date(value)
|
||||
$: daysDifference = dueDate === null ? null : getDaysDifference(today, dueDate)
|
||||
$: iconModifier = getDueDateIconModifier(isOverdue, daysDifference)
|
||||
let formattedDate = getFormattedDate(value)
|
||||
$: formattedDate = getFormattedDate(value)
|
||||
|
||||
function getFormattedDate (value: number | null): string {
|
||||
return !value ? '' : new Date(value).toLocaleString('default', { month: 'short', day: 'numeric' })
|
||||
}
|
||||
|
||||
const handleDueDateChanged = async (event: CustomEvent<Timestamp>) => {
|
||||
const newDate = event.detail
|
||||
|
||||
if (newDate === undefined || value === newDate || !editable) {
|
||||
return
|
||||
}
|
||||
|
||||
onChange(newDate)
|
||||
}
|
||||
|
||||
const WARNING_DAYS = 7
|
||||
|
||||
const getDueDateIconModifier = (
|
||||
isOverdue: boolean,
|
||||
daysDifference: number | null
|
||||
): 'overdue' | 'critical' | 'warning' | undefined => {
|
||||
if (isOverdue) {
|
||||
return 'overdue'
|
||||
}
|
||||
|
||||
if (daysDifference === 0) {
|
||||
return 'critical'
|
||||
}
|
||||
|
||||
if (daysDifference !== null && daysDifference <= WARNING_DAYS) {
|
||||
return 'warning'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if shouldRender}
|
||||
<div
|
||||
class="clear-mins"
|
||||
use:tooltip={formattedDate
|
||||
? {
|
||||
direction: 'top',
|
||||
component: DueDatePopup,
|
||||
props: {
|
||||
formattedDate,
|
||||
daysDifference,
|
||||
isOverdue,
|
||||
iconModifier
|
||||
}
|
||||
}
|
||||
: undefined}
|
||||
>
|
||||
<DatePresenter {value} {editable} icon={iconModifier} {kind} on:change={handleDueDateChanged} />
|
||||
</div>
|
||||
{/if}
|
@ -72,6 +72,7 @@ export { default as TimePopup } from './components/calendar/TimePopup.svelte'
|
||||
export { default as DateRangePresenter } from './components/calendar/DateRangePresenter.svelte'
|
||||
export { default as DateTimeRangePresenter } from './components/calendar/DateTimeRangePresenter.svelte'
|
||||
export { default as DatePresenter } from './components/calendar/DatePresenter.svelte'
|
||||
export { default as DueDatePresenter } from './components/calendar/DueDatePresenter.svelte'
|
||||
export { default as DateTimePresenter } from './components/calendar/DateTimePresenter.svelte'
|
||||
export { default as StylishEdit } from './components/StylishEdit.svelte'
|
||||
export { default as Grid } from './components/Grid.svelte'
|
||||
|
@ -52,7 +52,7 @@ export const uis = plugin(uiId, {
|
||||
AddDueDate: '' as IntlString,
|
||||
EditDueDate: '' as IntlString,
|
||||
SaveDueDate: '' as IntlString,
|
||||
IssueNeedsToBeCompletedByThisDate: '' as IntlString,
|
||||
NeedsToBeCompletedByThisDate: '' as IntlString,
|
||||
English: '' as IntlString,
|
||||
Russian: '' as IntlString,
|
||||
MinutesBefore: '' as IntlString,
|
||||
@ -70,7 +70,11 @@ export const uis = plugin(uiId, {
|
||||
DD: '' as IntlString,
|
||||
MM: '' as IntlString,
|
||||
YYYY: '' as IntlString,
|
||||
HH: '' as IntlString
|
||||
HH: '' as IntlString,
|
||||
DueDatePopupTitle: '' as IntlString,
|
||||
DueDatePopupOverdueTitle: '' as IntlString,
|
||||
DueDatePopupDescription: '' as IntlString,
|
||||
DueDatePopupOverdueDescription: '' as IntlString
|
||||
},
|
||||
metadata: {
|
||||
DefaultApplication: '' as Metadata<AnyComponent>,
|
||||
|
@ -24,7 +24,7 @@
|
||||
import recruit from '@hcengineering/recruit'
|
||||
import { AssigneePresenter, StateRefPresenter } from '@hcengineering/task-resources'
|
||||
import tracker from '@hcengineering/tracker'
|
||||
import { Component, showPanel } from '@hcengineering/ui'
|
||||
import { Component, DueDatePresenter, showPanel } from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import { ObjectPresenter } from '@hcengineering/view-resources'
|
||||
import ApplicationPresenter from './ApplicationPresenter.svelte'
|
||||
@ -90,6 +90,13 @@
|
||||
</div>
|
||||
<Component is={tracker.component.RelatedIssueSelector} props={{ object }} />
|
||||
</div>
|
||||
<DueDatePresenter
|
||||
value={object.dueDate}
|
||||
shouldRender={object.dueDate !== null}
|
||||
onChange={async (e) => {
|
||||
await client.update(object, { dueDate: e })
|
||||
}}
|
||||
/>
|
||||
{#if (object.attachments ?? 0) > 0}
|
||||
<div class="step-lr75">
|
||||
<AttachmentsPresenter value={object.attachments} {object} />
|
||||
|
@ -113,10 +113,6 @@
|
||||
"NewIssueDialogCloseNote": "All changes will be lost",
|
||||
"RemoveComponentDialogClose": "Delete the component?",
|
||||
"RemoveComponentDialogCloseNote": "Are you sure you want to delete this component? This operation cannot be undone",
|
||||
"DueDatePopupTitle": "Due on {value}",
|
||||
"DueDatePopupOverdueTitle": "Was due on {value}",
|
||||
"DueDatePopupDescription": "{value, plural, =0 {Today} =1 {Tomorrow} other {# days remaining}}",
|
||||
"DueDatePopupOverdueDescription": "{value, plural, =1 {1 day overdue} other {# days overdue}}",
|
||||
"Grouping": "Grouping",
|
||||
"Ordering": "Ordering",
|
||||
"CompletedIssues": "Completed issues",
|
||||
|
@ -113,10 +113,6 @@
|
||||
"NewIssueDialogCloseNote": "Все внесенные изменения будут потеряны",
|
||||
"RemoveComponentDialogClose": "Удалить компонент?",
|
||||
"RemoveComponentDialogCloseNote": "Уверены, что хотите удалить этот компонент? Эта операция не может быть отменена",
|
||||
"DueDatePopupTitle": "Срок {value}",
|
||||
"DueDatePopupOverdueTitle": "Должна была завершится {value}",
|
||||
"DueDatePopupDescription": "{value, plural, =0 {Сегодня} =1 {Завтра} other {# дней осталось}}",
|
||||
"DueDatePopupOverdueDescription": "{value, plural, =1 {1 день опозщдания} other {# дней опазданий}}",
|
||||
"Grouping": "Группировка",
|
||||
"Ordering": "Сортировка",
|
||||
"CompletedIssues": "Завершённые задачи",
|
||||
|
@ -1,79 +0,0 @@
|
||||
<!--
|
||||
// Copyright © 2022 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Timestamp } from '@hcengineering/core'
|
||||
import { DatePresenter, tooltip, getDaysDifference } from '@hcengineering/ui'
|
||||
import DueDatePopup from './DueDatePopup.svelte'
|
||||
import { getDueDateIconModifier } from '../utils'
|
||||
|
||||
export let dateMs: number | null = null
|
||||
export let shouldRender: boolean = true
|
||||
export let onDateChange: (newDate: number | null) => void
|
||||
export let kind: 'transparent' | 'primary' | 'link' | 'list' = 'primary'
|
||||
export let editable: boolean = true
|
||||
|
||||
$: today = new Date(new Date(Date.now()).setHours(0, 0, 0, 0))
|
||||
$: isOverdue = dateMs !== null && dateMs < today.getTime()
|
||||
$: dueDate = dateMs === null ? null : new Date(dateMs)
|
||||
$: daysDifference = dueDate === null ? null : getDaysDifference(today, dueDate)
|
||||
$: iconModifier = getDueDateIconModifier(isOverdue, daysDifference)
|
||||
$: formattedDate = !dateMs ? '' : new Date(dateMs).toLocaleString('default', { month: 'short', day: 'numeric' })
|
||||
|
||||
const handleDueDateChanged = async (event: CustomEvent<Timestamp>) => {
|
||||
const newDate = event.detail
|
||||
|
||||
if (newDate === undefined || dateMs === newDate || !editable) {
|
||||
return
|
||||
}
|
||||
|
||||
onDateChange(newDate)
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if shouldRender}
|
||||
{#if formattedDate}
|
||||
<div
|
||||
class="clear-mins"
|
||||
use:tooltip={{
|
||||
direction: 'top',
|
||||
component: DueDatePopup,
|
||||
props: {
|
||||
formattedDate,
|
||||
daysDifference,
|
||||
isOverdue,
|
||||
iconModifier
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DatePresenter
|
||||
value={dateMs}
|
||||
{editable}
|
||||
shouldShowLabel={false}
|
||||
icon={iconModifier}
|
||||
{kind}
|
||||
on:change={handleDueDateChanged}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<DatePresenter
|
||||
value={dateMs}
|
||||
{editable}
|
||||
shouldShowLabel={false}
|
||||
icon={iconModifier}
|
||||
{kind}
|
||||
on:change={handleDueDateChanged}
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import { Component } from '@hcengineering/tracker'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import CommonTrackerDatePresenter from '../CommonTrackerDatePresenter.svelte'
|
||||
import { DueDatePresenter } from '@hcengineering/ui'
|
||||
|
||||
export let value: Component
|
||||
|
||||
@ -28,4 +28,4 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<CommonTrackerDatePresenter dateMs={dueDateMs} shouldRender={true} onDateChange={handleDueDateChanged} />
|
||||
<DueDatePresenter value={dueDateMs} shouldRender={true} onChange={handleDueDateChanged} />
|
||||
|
@ -15,14 +15,13 @@
|
||||
<script lang="ts">
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Issue } from '@hcengineering/tracker'
|
||||
import { DatePresenter, getDaysDifference } from '@hcengineering/ui'
|
||||
import { getDueDateIconModifier } from '../../utils'
|
||||
import { DueDatePresenter } from '@hcengineering/ui'
|
||||
|
||||
export let value: Issue
|
||||
|
||||
const client = getClient()
|
||||
|
||||
const handleDueDateChanged = async (newDueDate: number | undefined) => {
|
||||
const handleDueDateChanged = async (newDueDate: number | undefined | null) => {
|
||||
if (newDueDate === undefined || value.dueDate === newDueDate) {
|
||||
return
|
||||
}
|
||||
@ -37,21 +36,8 @@
|
||||
{ dueDate: newDueDate }
|
||||
)
|
||||
}
|
||||
|
||||
$: today = new Date(new Date(Date.now()).setHours(0, 0, 0, 0))
|
||||
$: isOverdue = value.dueDate !== null && value.dueDate < today.getTime()
|
||||
$: dueDate = value.dueDate === null ? null : new Date(value.dueDate)
|
||||
$: daysDifference = dueDate === null ? null : getDaysDifference(today, dueDate)
|
||||
$: iconModifier = getDueDateIconModifier(isOverdue, daysDifference)
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
<!-- TODO: fix button style and alignment -->
|
||||
<DatePresenter
|
||||
kind={'link'}
|
||||
value={value.dueDate}
|
||||
icon={iconModifier}
|
||||
editable
|
||||
on:change={({ detail }) => handleDueDateChanged(detail)}
|
||||
/>
|
||||
<DueDatePresenter kind={'link'} value={value.dueDate} editable onChange={(e) => handleDueDateChanged(e)} />
|
||||
{/if}
|
||||
|
@ -16,11 +16,11 @@
|
||||
import { WithLookup } from '@hcengineering/core'
|
||||
import { Issue } from '@hcengineering/tracker'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import CommonTrackerDatePresenter from '../CommonTrackerDatePresenter.svelte'
|
||||
import tracker from '../../plugin'
|
||||
import { ButtonKind, DueDatePresenter } from '@hcengineering/ui'
|
||||
|
||||
export let value: WithLookup<Issue>
|
||||
export let kind: 'transparent' | 'primary' | 'link' | 'list' = 'primary'
|
||||
export let kind: ButtonKind = 'link'
|
||||
export let isEditable = true
|
||||
|
||||
const client = getClient()
|
||||
@ -45,10 +45,10 @@
|
||||
value.$lookup?.status?.category !== tracker.issueStatusCategory.Canceled
|
||||
</script>
|
||||
|
||||
<CommonTrackerDatePresenter
|
||||
dateMs={dueDateMs}
|
||||
<DueDatePresenter
|
||||
value={dueDateMs}
|
||||
shouldRender={shouldRenderPresenter}
|
||||
onDateChange={handleDueDateChanged}
|
||||
onChange={handleDueDateChanged}
|
||||
editable={isEditable}
|
||||
{kind}
|
||||
/>
|
||||
|
@ -78,6 +78,7 @@
|
||||
import PriorityEditor from './PriorityEditor.svelte'
|
||||
import StatusEditor from './StatusEditor.svelte'
|
||||
import EstimationEditor from './timereport/EstimationEditor.svelte'
|
||||
import DueDatePresenter from './DueDatePresenter.svelte'
|
||||
|
||||
export let space: Ref<Project> | undefined = undefined
|
||||
export let baseMenuClass: Ref<Class<Doc>> | undefined = undefined
|
||||
@ -341,7 +342,7 @@
|
||||
<Component is={notification.component.NotificationPresenter} props={{ value: object }} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="buttons-group xsmall-gap states-bar">
|
||||
<div class="xsmall-gap states-bar">
|
||||
{#if issue && issue.subIssues > 0}
|
||||
<SubIssuesSelector value={issue} {currentProject} />
|
||||
{/if}
|
||||
@ -355,6 +356,7 @@
|
||||
width={''}
|
||||
bind:onlyIcon={fullFilled[issueId]}
|
||||
/>
|
||||
<DueDatePresenter value={issue} kind={'link-bordered'} />
|
||||
<EstimationEditor kind={'list'} size={'small'} value={issue} />
|
||||
<div
|
||||
class="clear-mins"
|
||||
@ -403,8 +405,9 @@
|
||||
min-height: 6.5rem;
|
||||
}
|
||||
.states-bar {
|
||||
flex-shrink: 10;
|
||||
width: fit-content;
|
||||
margin: 0.625rem 1rem 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.375rem;
|
||||
margin: 0.625rem 1rem;
|
||||
}
|
||||
</style>
|
||||
|
@ -141,10 +141,6 @@ export default mergeIds(trackerId, tracker, {
|
||||
DocumentIcon: '' as IntlString,
|
||||
DocumentColor: '' as IntlString,
|
||||
Rank: '' as IntlString,
|
||||
DueDatePopupTitle: '' as IntlString,
|
||||
DueDatePopupOverdueTitle: '' as IntlString,
|
||||
DueDatePopupDescription: '' as IntlString,
|
||||
DueDatePopupOverdueDescription: '' as IntlString,
|
||||
Grouping: '' as IntlString,
|
||||
Ordering: '' as IntlString,
|
||||
CompletedIssues: '' as IntlString,
|
||||
|
@ -227,25 +227,6 @@ export const getArraysUnion = (a: any[], b: any[]): any[] => {
|
||||
return Array.from(union)
|
||||
}
|
||||
|
||||
const WARNING_DAYS = 7
|
||||
|
||||
export const getDueDateIconModifier = (
|
||||
isOverdue: boolean,
|
||||
daysDifference: number | null
|
||||
): 'overdue' | 'critical' | 'warning' | undefined => {
|
||||
if (isOverdue) {
|
||||
return 'overdue'
|
||||
}
|
||||
|
||||
if (daysDifference === 0) {
|
||||
return 'critical'
|
||||
}
|
||||
|
||||
if (daysDifference !== null && daysDifference <= WARNING_DAYS) {
|
||||
return 'warning'
|
||||
}
|
||||
}
|
||||
|
||||
export type ComponentsViewMode = 'all' | 'backlog' | 'active' | 'closed'
|
||||
|
||||
export type SprintViewMode = 'all' | 'planned' | 'active' | 'closed'
|
||||
|
Loading…
Reference in New Issue
Block a user