mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 11:01:54 +03:00
UBER-832: fixed DatePresenter (#3653)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
25514b58ab
commit
bf9dd1b494
@ -1081,12 +1081,21 @@
|
||||
|
||||
&:not(.only-icon) .btn-icon,
|
||||
&:not(.only-icon) .icon { margin-right: .375rem !important; }
|
||||
.icon, .btn-icon { color: var(--theme-halfcontent-color) !important; }
|
||||
.label {
|
||||
font-size: 0.8125rem !important;
|
||||
color: var(--theme-halfcontent-color) !important;
|
||||
}
|
||||
}
|
||||
.list-container .listitems-container,
|
||||
.list-container .listitems-container:hover,
|
||||
.list-container .antiButton.list,
|
||||
.list-container .antiButton.list:hover {
|
||||
.icon, .btn-icon { color: var(--theme-halfcontent-color) !important; }
|
||||
}
|
||||
.list-container .datetime-button .btn-icon.normal,
|
||||
.list-container .datetime-button:hover .btn-icon.normal {
|
||||
color: var(--theme-halfcontent-color) !important;
|
||||
}
|
||||
|
||||
/* Kanban - global style */
|
||||
.kanban-container .card-container .antiButton.link-bordered { padding: 0 .5rem; }
|
||||
|
@ -24,6 +24,7 @@
|
||||
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 { ComponentType } from 'svelte'
|
||||
|
||||
@ -33,6 +34,7 @@
|
||||
export let editable: boolean = false
|
||||
export let icon: Asset | AnySvelteComponent | ComponentType | undefined = undefined
|
||||
export let iconModifier: 'normal' | 'warning' | 'critical' | 'overdue' = 'normal'
|
||||
export let shouldIgnoreOverdue: boolean = false
|
||||
export let labelNull: IntlString = ui.string.NoDate
|
||||
export let showIcon = true
|
||||
export let shouldShowLabel: boolean = true
|
||||
@ -94,7 +96,10 @@
|
||||
>
|
||||
{#if showIcon}
|
||||
<div class="btn-icon {iconModifier}" class:buttonIconNoLabel={!shouldShowLabel}>
|
||||
<Icon icon={icon ?? DPCalendar} size="full" />
|
||||
<Icon
|
||||
icon={icon ?? (iconModifier === 'overdue' && !shouldIgnoreOverdue) ? DPCalendarOver : DPCalendar}
|
||||
size={'full'}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if value !== null && value !== undefined}
|
||||
|
@ -23,12 +23,14 @@
|
||||
import IconClose from '../icons/Close.svelte'
|
||||
import DatePopup from './DatePopup.svelte'
|
||||
import DPCalendar from './icons/DPCalendar.svelte'
|
||||
import DPCalendarOver from './icons/DPCalendarOver.svelte'
|
||||
import { daysInMonth, getMonthName } from './internal/DateUtils'
|
||||
|
||||
export let value: number | null | undefined = null
|
||||
export let mode: DateRangeMode = DateRangeMode.DATE
|
||||
export let editable: boolean = false
|
||||
export let iconModifier: 'normal' | 'warning' | 'overdue' = 'normal'
|
||||
export let iconModifier: 'overdue' | 'critical' | 'warning' | 'normal' = 'normal'
|
||||
export let shouldIgnoreOverdue: boolean = false
|
||||
export let labelNull: IntlString = ui.string.NoDate
|
||||
export let kind: 'default' | 'no-border' | 'link' | 'regular' = 'default'
|
||||
export let size: 'small' | 'medium' | 'large' = 'small'
|
||||
@ -397,7 +399,7 @@
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="btn-icon {iconModifier}">
|
||||
<Icon icon={DPCalendar} size={'full'} />
|
||||
<Icon icon={iconModifier === 'overdue' && !shouldIgnoreOverdue ? DPCalendarOver : DPCalendar} size={'full'} />
|
||||
</div>
|
||||
{#if value !== undefined && value !== null && value.toString() !== ''}
|
||||
{#if withDate}
|
||||
@ -469,6 +471,9 @@
|
||||
&.overdue {
|
||||
color: var(--theme-error-color);
|
||||
}
|
||||
&.critical {
|
||||
color: var(--theme-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.default {
|
||||
@ -525,6 +530,9 @@
|
||||
&.overdue {
|
||||
color: var(--theme-error-color);
|
||||
}
|
||||
&.critical {
|
||||
color: var(--theme-error-color);
|
||||
}
|
||||
}
|
||||
.time-divider {
|
||||
background-color: var(--theme-divider-color);
|
||||
|
@ -22,7 +22,7 @@
|
||||
export let formattedDate: string = ''
|
||||
export let daysDifference: number = 0
|
||||
export let isOverdue: boolean = false
|
||||
export let iconModifier: 'warning' | 'critical' | 'overdue' | undefined = undefined
|
||||
export let iconModifier: 'warning' | 'critical' | 'overdue' | 'normal' = 'normal'
|
||||
export let shouldIgnoreOverdue: boolean = false
|
||||
</script>
|
||||
|
||||
@ -42,14 +42,14 @@
|
||||
params={{ value: formattedDate }}
|
||||
/>
|
||||
</div>
|
||||
<div class="description">
|
||||
{#if !shouldIgnoreOverdue}
|
||||
{#if !shouldIgnoreOverdue}
|
||||
<div class="description">
|
||||
<Label
|
||||
label={isOverdue ? ui.string.DueDatePopupOverdueDescription : ui.string.DueDatePopupDescription}
|
||||
params={{ value: daysDifference }}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@ -58,11 +58,13 @@
|
||||
.root {
|
||||
display: flex;
|
||||
width: 10rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.iconContainer {
|
||||
color: var(--content-color);
|
||||
margin-right: 1rem;
|
||||
margin-top: 0.125rem;
|
||||
margin-right: 0.5rem;
|
||||
color: var(--theme-caption-color);
|
||||
|
||||
&.mIconContainerWarning {
|
||||
color: var(--theme-warning-color);
|
||||
@ -80,12 +82,12 @@
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--caption-color);
|
||||
color: var(--theme-caption-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 0.25rem;
|
||||
color: var(--dark-color);
|
||||
color: var(--theme-dark-color);
|
||||
}
|
||||
</style>
|
||||
|
@ -17,7 +17,7 @@
|
||||
import DueDatePopup from './DueDatePopup.svelte'
|
||||
import { tooltip } from '../../tooltips'
|
||||
import DatePresenter from './DatePresenter.svelte'
|
||||
import { getDaysDifference } from './internal/DateUtils'
|
||||
import { getDaysDifference, getDueDateIconModifier, getFormattedDate } from './internal/DateUtils'
|
||||
import { ButtonKind, ButtonSize } from '../../types'
|
||||
|
||||
export let value: number | null = null
|
||||
@ -33,14 +33,10 @@
|
||||
$: isOverdue = value !== null && value < today.getTime()
|
||||
$: dueDate = value === null ? null : new Date(value)
|
||||
$: daysDifference = dueDate === null ? null : getDaysDifference(today, dueDate)
|
||||
$: iconModifier = getDueDateIconModifier(isOverdue, daysDifference)
|
||||
$: iconModifier = getDueDateIconModifier(isOverdue, daysDifference, shouldIgnoreOverdue)
|
||||
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
|
||||
|
||||
@ -50,29 +46,6 @@
|
||||
|
||||
onChange(newDate)
|
||||
}
|
||||
|
||||
const WARNING_DAYS = 7
|
||||
|
||||
const getDueDateIconModifier = (
|
||||
isOverdue: boolean,
|
||||
daysDifference: number | null
|
||||
): 'overdue' | 'critical' | 'warning' | undefined => {
|
||||
if (shouldIgnoreOverdue) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isOverdue) {
|
||||
return 'overdue'
|
||||
}
|
||||
|
||||
if (daysDifference === 0) {
|
||||
return 'critical'
|
||||
}
|
||||
|
||||
if (daysDifference !== null && daysDifference <= WARNING_DAYS) {
|
||||
return 'warning'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if shouldRender}
|
||||
@ -93,6 +66,15 @@
|
||||
}
|
||||
: undefined}
|
||||
>
|
||||
<DatePresenter {value} {editable} {iconModifier} {kind} {size} {width} on:change={handleDueDateChanged} />
|
||||
<DatePresenter
|
||||
{value}
|
||||
{editable}
|
||||
{iconModifier}
|
||||
{kind}
|
||||
{size}
|
||||
{width}
|
||||
{shouldIgnoreOverdue}
|
||||
on:change={handleDueDateChanged}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -3,8 +3,13 @@
|
||||
export let fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M11 1C13.2091 1 15 2.79086 15 5V6.25C15 6.66421 14.6642 7 14.25 7C13.8358 7 13.5 6.66421 13.5 6.25V6H2.5V11C2.5 12.3807 3.61929 13.5 5 13.5H6.25C6.66421 13.5 7 13.8358 7 14.25C7 14.6642 6.66421 15 6.25 15H5C2.79086 15 1 13.2091 1 11V5C1 2.79086 2.79086 1 5 1H11ZM9.53033 8.46967L11.5 10.4393L13.4697 8.46967C13.7626 8.17678 14.2374 8.17678 14.5303 8.46967C14.8232 8.76256 14.8232 9.23744 14.5303 9.53033L12.5607 11.5L14.5303 13.4697C14.8232 13.7626 14.8232 14.2374 14.5303 14.5303C14.2374 14.8232 13.7626 14.8232 13.4697 14.5303L11.5 12.5607L9.53033 14.5303C9.23744 14.8232 8.76256 14.8232 8.46967 14.5303C8.17678 14.2374 8.17678 13.7626 8.46967 13.4697L10.4393 11.5L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967Z"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M4 7.99988V23.9999C4 26.209 5.79086 27.9999 8 27.9999H17C17.5523 27.9999 18 27.5522 18 26.9999C18 26.4476 17.5523 25.9999 17 25.9999H8C6.89543 25.9999 6 25.1044 6 23.9999V13.9999H26V17C26 17.5523 26.4477 18 27 18C27.5523 18 28 17.5523 28 17V7.99988C28 5.79074 26.2091 3.99988 24 3.99988H21.9995V2.99988C21.9995 2.44759 21.5518 1.99988 20.9995 1.99988C20.4472 1.99988 19.9995 2.44759 19.9995 2.99988V3.99988H12V2.99988C12 2.44759 11.5523 1.99988 11 1.99988C10.4477 1.99988 10 2.44759 10 2.99988V3.99988H8C5.79086 3.99988 4 5.79074 4 7.99988ZM19.9995 5.99988V6.99988C19.9995 7.55216 20.4472 7.99988 20.9995 7.99988C21.5518 7.99988 21.9995 7.55216 21.9995 6.99988V5.99988H24C25.1046 5.99988 26 6.89531 26 7.99988V11.9999H6V7.99988C6 6.89531 6.89543 5.99988 8 5.99988H10V6.99988C10 7.55216 10.4477 7.99988 11 7.99988C11.5523 7.99988 12 7.55216 12 6.99988V5.99988H19.9995Z"
|
||||
/>
|
||||
<path
|
||||
d="M20.2929 21.7071C19.9024 21.3166 19.9024 20.6834 20.2929 20.2929C20.6834 19.9024 21.3166 19.9024 21.7071 20.2929L25 23.5858L28.2929 20.2929C28.6834 19.9024 29.3166 19.9024 29.7071 20.2929C30.0976 20.6834 30.0976 21.3166 29.7071 21.7071L26.4142 25L29.7071 28.2929C30.0976 28.6834 30.0976 29.3166 29.7071 29.7071C29.3166 30.0976 28.6834 30.0976 28.2929 29.7071L25 26.4136L21.6849 29.7287C21.2929 30.0975 20.6761 30.0903 20.2929 29.7071C19.9024 29.3166 19.9024 28.6834 20.2929 28.2929L23.5858 25L20.2929 21.7071Z"
|
||||
/>
|
||||
</svg>
|
||||
|
@ -108,3 +108,21 @@ export const getDaysDifference = (from: Date, to: Date): number => {
|
||||
export const getMillisecondsInMonth = (date: Date): number => {
|
||||
return daysInMonth(date) * MILLISECONDS_IN_DAY
|
||||
}
|
||||
|
||||
const WARNING_DAYS = 7
|
||||
|
||||
export const getDueDateIconModifier = (
|
||||
isOverdue: boolean,
|
||||
daysDifference: number | null,
|
||||
shouldIgnoreOverdue: boolean
|
||||
): 'overdue' | 'critical' | 'warning' | 'normal' => {
|
||||
if (shouldIgnoreOverdue) return 'normal'
|
||||
if (isOverdue) return 'overdue'
|
||||
if (daysDifference === 0) return 'critical'
|
||||
if (daysDifference !== null && daysDifference <= WARNING_DAYS) return 'warning'
|
||||
return 'normal'
|
||||
}
|
||||
|
||||
export function getFormattedDate (value: number | null): string {
|
||||
return value === null ? '' : new Date(value).toLocaleString('default', { month: 'short', day: 'numeric' })
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
export let editable: boolean = true
|
||||
|
||||
const client = getClient()
|
||||
$: shouldIgnoreOverdue = object.doneState != null
|
||||
$: shouldIgnoreOverdue = object.doneState !== null
|
||||
|
||||
const handleDueDateChanged = async (newDueDate: number | undefined | null) => {
|
||||
if (newDueDate === undefined || object.dueDate === newDueDate) {
|
||||
|
Loading…
Reference in New Issue
Block a user