mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
feat(planner): new priority layout, update item layout (#4896)
Signed-off-by: Eduard Aksamitov <e@euaaaio.ru>
This commit is contained in:
parent
94acee60d1
commit
4b6c36d296
@ -62,9 +62,17 @@
|
||||
--global-accent-SkyText: #B9D1F5;
|
||||
--global-accent-BackgroundColor: #204DC8;
|
||||
|
||||
--global-low-PriorityColor: #6493FF;
|
||||
--global-medium-PriorityColor: #FFBD2E;
|
||||
--global-high-PriorityColor: #F6684B;
|
||||
--global-urgent-PriorityColor: #F6684B;
|
||||
--global-disabled-PriorityColor: #5A667E;
|
||||
|
||||
--tag-on-subtle-PorpoiseText: #F2F4F6;
|
||||
--tag-subtle-PorpoiseBackground: #343F49;
|
||||
|
||||
--icon-disabled-IconColor: #394358;
|
||||
|
||||
/** Buttons **/
|
||||
--button-subtle-LabelColor: #fff;
|
||||
--button-subtle-IconColor: #fff;
|
||||
@ -128,9 +136,17 @@
|
||||
--global-accent-SkyText:#B9D1F5;
|
||||
--global-accent-BackgroundColor: #3566E2;
|
||||
|
||||
--global-low-PriorityColor: #3566E2;
|
||||
--global-medium-PriorityColor: #FF9838;
|
||||
--global-high-PriorityColor: #E9403D;
|
||||
--global-urgent-PriorityColor: #E9403D;
|
||||
--global-disabled-PriorityColor: #A1ABBF;
|
||||
|
||||
--tag-on-subtle-PorpoiseText: #293139;
|
||||
--tag-subtle-PorpoiseBackground: #C8D1D9;
|
||||
|
||||
--icon-disabled-IconColor: #B3BCCC;
|
||||
|
||||
/** Buttons **/
|
||||
--button-subtle-LabelColor: #000;
|
||||
--button-subtle-IconColor: #000;
|
||||
|
@ -518,19 +518,25 @@
|
||||
align-items: flex-start;
|
||||
gap: var(--spacing-1);
|
||||
margin: 0;
|
||||
padding: var(--spacing-1) var(--spacing-1_5) var(--spacing-1) var(--spacing-0_75);
|
||||
padding: var(--spacing-0_75) var(--spacing-1) var(--spacing-0_75) var(--spacing-0_75);
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
min-height: var(--global-medium-Size);
|
||||
color: var(--global-secondary-TextColor);
|
||||
border: none;
|
||||
border-radius: var(--medium-BorderRadius);
|
||||
outline: none;
|
||||
|
||||
&.small {
|
||||
max-height: var(--global-max-Size);
|
||||
|
||||
&.isDone {
|
||||
.hulyToDoLine-title {
|
||||
color: var(--global-tertiary-TextColor);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
.hulyToDoLine-statusPriority {
|
||||
display: flex;
|
||||
gap: var(--spacing-0_25);
|
||||
}
|
||||
.hulyToDoLine-dragbox,
|
||||
.hulyToDoLine-checkbox {
|
||||
display: flex;
|
||||
@ -570,7 +576,7 @@
|
||||
}
|
||||
}
|
||||
.hulyToDoLine-top-align {
|
||||
color: var(--global-secondary-TextColor);
|
||||
color: var(--global-primary-TextColor);
|
||||
|
||||
&.top-12 {
|
||||
padding-top: 0.25rem;
|
||||
|
@ -14,7 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { Asset, IntlString } from '@hcengineering/platform'
|
||||
import { AnySvelteComponent, IconSize, LabelAndProps } from '../types'
|
||||
import { AnySvelteComponent, ButtonBaseKind, ButtonBaseSize, ButtonBaseType, IconSize, LabelAndProps } from '../types'
|
||||
import { tooltip as tp } from '../tooltips'
|
||||
import { registerFocus } from '../focus'
|
||||
import { ComponentType } from 'svelte'
|
||||
@ -28,13 +28,13 @@
|
||||
export let icon: Asset | AnySvelteComponent | ComponentType | undefined = undefined
|
||||
export let iconSize: IconSize | undefined = undefined
|
||||
export let iconProps: any | undefined = undefined
|
||||
export let kind: 'primary' | 'secondary' | 'tertiary' | 'negative'
|
||||
export let size: 'large' | 'medium' | 'small' | 'extra-small' | 'min'
|
||||
export let kind: ButtonBaseKind
|
||||
export let size: ButtonBaseSize
|
||||
export let disabled: boolean = false
|
||||
export let loading: boolean = false
|
||||
export let pressed: boolean = false
|
||||
export let hasMenu: boolean = false
|
||||
export let type: 'type-button' | 'type-button-icon'
|
||||
export let type: ButtonBaseType
|
||||
export let inheritColor: boolean = false
|
||||
export let inheritFont: boolean = false
|
||||
export let tooltip: LabelAndProps | undefined = undefined
|
||||
|
@ -20,6 +20,7 @@
|
||||
export let size: 'small' | 'medium' | 'large' = 'small'
|
||||
export let circle: boolean = false
|
||||
export let kind: 'default' | 'primary' | 'positive' | 'negative' | 'todo' = 'default'
|
||||
export let color: string | undefined = undefined
|
||||
export let readonly = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
@ -44,7 +45,7 @@
|
||||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||
<label class="checkbox {size} {kind}" class:circle class:readonly class:checked on:click|stopPropagation>
|
||||
<input class="chBox" disabled={readonly} type="checkbox" bind:checked on:change|capture={handleValueChanged} />
|
||||
<svg class="checkSVG" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none">
|
||||
<svg class="checkSVG" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" style:color>
|
||||
{#if kind === 'todo'}
|
||||
{#if readonly}
|
||||
<path
|
||||
|
@ -138,6 +138,12 @@ export interface RadioItem {
|
||||
action?: () => void
|
||||
}
|
||||
|
||||
export type ButtonBaseType = 'type-button' | 'type-button-icon'
|
||||
|
||||
export type ButtonBaseKind = 'primary' | 'secondary' | 'tertiary' | 'negative'
|
||||
|
||||
export type ButtonBaseSize = 'large' | 'medium' | 'small' | 'extra-small' | 'min'
|
||||
|
||||
export type ButtonKind =
|
||||
| 'primary'
|
||||
| 'secondary'
|
||||
|
@ -31,10 +31,16 @@
|
||||
"Unplanned": "Unplanned",
|
||||
"Planned": "Planned",
|
||||
"AddSlot": "Add Slot",
|
||||
"SetPriority": "Set Priority",
|
||||
"NoPriority": "No Priority",
|
||||
"LowPriority": "Low Priority",
|
||||
"MediumPriority": "Medium Priority",
|
||||
"HighPriority": "High Priority",
|
||||
"UrgentPriority": "Urgent Priority",
|
||||
"Low": "Low",
|
||||
"Medium": "Medium",
|
||||
"High": "High",
|
||||
"Urgent": "Urgent",
|
||||
"AddTo": "Add to",
|
||||
"AddTitle": "Add Title",
|
||||
"MyWork": "My work",
|
||||
|
@ -31,10 +31,16 @@
|
||||
"Unplanned": "No planificado",
|
||||
"Planned": "Planificado",
|
||||
"AddSlot": "Agregar intervalo",
|
||||
"SetPriority": "Establecer prioridad",
|
||||
"NoPriority": "Sin prioridad",
|
||||
"LowPriority": "Prioridad baja",
|
||||
"MediumPriority": "Prioridad media",
|
||||
"HighPriority": "Alta prioridad",
|
||||
"UrgentPriority": "Urgente prioridad",
|
||||
"Low": "Baja",
|
||||
"Medium": "Media",
|
||||
"High": "Alta",
|
||||
"Urgent": "Urgente",
|
||||
"AddTo": "Agregar a",
|
||||
"AddTitle": "Agregar título",
|
||||
"MyWork": "Mi trabajo",
|
||||
|
@ -31,10 +31,16 @@
|
||||
"Unplanned": "Não planeado",
|
||||
"Planned": "Planeado",
|
||||
"AddSlot": "Adicionar intervalo",
|
||||
"SetPriority": "Definir prioridade",
|
||||
"NoPriority": "Sem prioridade",
|
||||
"LowPriority": "Prioridade baixa",
|
||||
"MediumPriority": "Prioridade média",
|
||||
"HighPriority": "Alta prioridade",
|
||||
"UrgentPriority": "Urgente prioridade",
|
||||
"Low": "Baixa",
|
||||
"Medium": "Média",
|
||||
"High": "Alta",
|
||||
"Urgent": "Urgente",
|
||||
"AddTo": "Adicionar a",
|
||||
"AddTitle": "Adicionar título",
|
||||
"MyWork": "Meu trabalho",
|
||||
|
@ -31,10 +31,16 @@
|
||||
"Unplanned": "Не запланировано",
|
||||
"Planned": "Запланировано",
|
||||
"AddSlot": "Добавить слот",
|
||||
"SetPriority": "Установить приоритет",
|
||||
"NoPriority": "Без приоритета",
|
||||
"HighPriority": "Высокий приоритет",
|
||||
"MediumPriority": "Средний приоритет",
|
||||
"LowPriority": "Низкий приоритет",
|
||||
"MediumPriority": "Средний приоритет",
|
||||
"HighPriority": "Высокий приоритет",
|
||||
"UrgentPriority": "Срочный приоритет",
|
||||
"Low": "Низкий",
|
||||
"Medium": "Средний",
|
||||
"High": "Высокий",
|
||||
"Urgent": "Срочный",
|
||||
"AddTo": "Добавить в",
|
||||
"AddTitle": "Добавить заголовок",
|
||||
"MyWork": "Моя работа",
|
||||
|
@ -123,12 +123,7 @@
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="title">
|
||||
{#if object}
|
||||
<VisibilityEditor
|
||||
value={object.visibility}
|
||||
size={'small'}
|
||||
disabled={object._class === time.class.ProjectToDo}
|
||||
on:change={(e) => visibilityChange(e.detail)}
|
||||
/>
|
||||
<PriorityEditor value={object.priority} on:change={(e) => priorityChange(e.detail)} />
|
||||
<Component
|
||||
is={tags.component.DocTagsEditor}
|
||||
props={{ object, targetClass: time.class.ToDo, type: 'type-button-only' }}
|
||||
@ -136,6 +131,12 @@
|
||||
if (event.detail !== undefined) countTag = event.detail
|
||||
}}
|
||||
/>
|
||||
<VisibilityEditor
|
||||
value={object.visibility}
|
||||
size={'small'}
|
||||
disabled={object._class === time.class.ProjectToDo}
|
||||
on:change={(e) => visibilityChange(e.detail)}
|
||||
/>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="actions">
|
||||
@ -195,7 +196,6 @@
|
||||
</span>
|
||||
<div class="flex-row-center gap-2">
|
||||
<DueDateEditor value={object.dueDate} on:change={(e) => dueDateChange(e.detail)} />
|
||||
<PriorityEditor value={object.priority} on:change={(e) => priorityChange(e.detail)} />
|
||||
</div>
|
||||
</div>
|
||||
<TodoWorkslots todo={object} />
|
||||
|
@ -13,77 +13,76 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { translate } from '@hcengineering/platform'
|
||||
import { ButtonKind, Dropdown, ListItem, themeStore } from '@hcengineering/ui'
|
||||
import { ToDoPriority } from '@hcengineering/time'
|
||||
import {
|
||||
ButtonBase,
|
||||
ButtonBaseKind,
|
||||
SelectPopup,
|
||||
SelectPopupValueType,
|
||||
eventToHTMLElement,
|
||||
showPopup
|
||||
} from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { ToDoPriority } from '@hcengineering/time'
|
||||
import { defaultToDoPriorities, todoPriorities } from '../utils'
|
||||
import Priority from './icons/Priority.svelte'
|
||||
import time from '../plugin'
|
||||
|
||||
export let value: ToDoPriority = ToDoPriority.NoPriority
|
||||
export let kind: ButtonKind | undefined = 'regular'
|
||||
export let kind: ButtonBaseKind = 'secondary'
|
||||
export let onChange: (value: ToDoPriority) => void = () => {}
|
||||
|
||||
let items: ListItem[] = []
|
||||
|
||||
$: fill($themeStore.language)
|
||||
|
||||
async function fill (lang: string) {
|
||||
items = [
|
||||
{
|
||||
_id: ToDoPriority.NoPriority.toString(),
|
||||
label: await translate(time.string.NoPriority, {}, lang),
|
||||
icon: time.icon.Flag
|
||||
},
|
||||
{
|
||||
_id: ToDoPriority.High.toString(),
|
||||
label: await translate(time.string.HighPriority, {}, lang),
|
||||
icon: time.icon.FilledFlag,
|
||||
iconProps: {
|
||||
fill: '#F96E50'
|
||||
}
|
||||
},
|
||||
{
|
||||
_id: ToDoPriority.Medium.toString(),
|
||||
label: await translate(time.string.MediumPriority, {}, lang),
|
||||
icon: time.icon.FilledFlag,
|
||||
iconProps: {
|
||||
fill: '#FFCD6B'
|
||||
}
|
||||
},
|
||||
{
|
||||
_id: ToDoPriority.Low.toString(),
|
||||
label: await translate(time.string.LowPriority, {}, lang),
|
||||
icon: time.icon.FilledFlag,
|
||||
iconProps: {
|
||||
fill: '#0084FF'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$: selected = items.find((item) => item._id === value.toString())
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
function change (val: string) {
|
||||
const priority = parseInt(val)
|
||||
if (priority !== value) {
|
||||
dispatch('change', priority)
|
||||
value = priority
|
||||
onChange(priority)
|
||||
let selectPopupPriorities: SelectPopupValueType[]
|
||||
$: selectPopupPriorities = defaultToDoPriorities.map((priority) => {
|
||||
return {
|
||||
id: priority,
|
||||
label: todoPriorities[priority].label,
|
||||
icon: Priority,
|
||||
iconProps: {
|
||||
value: priority
|
||||
},
|
||||
isSelected: value === priority
|
||||
}
|
||||
})
|
||||
$: selected = selectPopupPriorities.find((item) => item.id === value)
|
||||
$: selectedLabel = selected?.label ?? time.string.NoPriority
|
||||
|
||||
$: icon = selected?.id === ToDoPriority.NoPriority ? time.icon.Flag : selected?.icon
|
||||
$: iconProps = selected?.iconProps
|
||||
|
||||
const handlePriorityUpdate = async (newPriority: ToDoPriority) => {
|
||||
if (newPriority == null || value === newPriority) {
|
||||
return
|
||||
}
|
||||
|
||||
value = newPriority
|
||||
dispatch('change', newPriority)
|
||||
onChange(newPriority)
|
||||
}
|
||||
|
||||
function handleClick (event: MouseEvent) {
|
||||
event.stopPropagation()
|
||||
|
||||
showPopup(
|
||||
SelectPopup,
|
||||
{
|
||||
value: selectPopupPriorities,
|
||||
placeholder: time.string.SetPriority,
|
||||
searchable: true
|
||||
},
|
||||
eventToHTMLElement(event),
|
||||
handlePriorityUpdate
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dropdown
|
||||
icon={time.icon.Flag}
|
||||
<ButtonBase
|
||||
type={'type-button-icon'}
|
||||
size={'small'}
|
||||
{kind}
|
||||
size={'medium'}
|
||||
placeholder={time.string.NoPriority}
|
||||
{items}
|
||||
{selected}
|
||||
withSearch={false}
|
||||
on:selected={(e) => {
|
||||
change(e.detail._id)
|
||||
}}
|
||||
{icon}
|
||||
{iconProps}
|
||||
tooltip={{ label: selectedLabel, direction: 'bottom' }}
|
||||
on:click={handleClick}
|
||||
/>
|
||||
|
@ -13,26 +13,14 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Icon } from '@hcengineering/ui'
|
||||
import { ToDoPriority } from '@hcengineering/time'
|
||||
import time from '../plugin'
|
||||
import { CheckBox } from '@hcengineering/ui'
|
||||
import { getToDoPriorityColor } from '../utils'
|
||||
|
||||
export let value: ToDoPriority
|
||||
export let checked: boolean = false
|
||||
export let priority: ToDoPriority = ToDoPriority.NoPriority
|
||||
|
||||
function getIconProps (value: ToDoPriority): string {
|
||||
switch (value) {
|
||||
case ToDoPriority.High:
|
||||
return '#F96E50'
|
||||
case ToDoPriority.Medium:
|
||||
return '#FFCD6B'
|
||||
case ToDoPriority.Low:
|
||||
return '#0084FF'
|
||||
case ToDoPriority.NoPriority:
|
||||
return '#FFFFFF'
|
||||
}
|
||||
}
|
||||
$: color = checked ? undefined : getToDoPriorityColor(priority)
|
||||
</script>
|
||||
|
||||
{#if value !== ToDoPriority.NoPriority}
|
||||
<Icon icon={time.icon.FilledFlag} size={'medium'} iconProps={{ fill: getIconProps(value) }} />
|
||||
{/if}
|
||||
<CheckBox kind={'todo'} size={'medium'} {checked} {color} on:value />
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { SortingOrder } from '@hcengineering/core'
|
||||
import { SortingOrder, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import tags from '@hcengineering/tags'
|
||||
import {
|
||||
@ -19,11 +19,12 @@
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import plugin from '../plugin'
|
||||
import EditToDo from './EditToDo.svelte'
|
||||
import PriorityPresenter from './PriorityPresenter.svelte'
|
||||
import ToDoDuration from './ToDoDuration.svelte'
|
||||
import WorkItemPresenter from './WorkItemPresenter.svelte'
|
||||
import ToDoCheckbox from './ToDoCheckbox.svelte'
|
||||
import ToDoPriority from './ToDoPriority.svelte'
|
||||
|
||||
export let todo: ToDo
|
||||
export let todo: WithLookup<ToDo>
|
||||
export let size: 'small' | 'large' = 'small'
|
||||
export let planned: boolean = true
|
||||
export let draggable: boolean = true
|
||||
@ -79,11 +80,13 @@
|
||||
}
|
||||
|
||||
$: isTodo = todo.attachedTo === time.ids.NotAttached
|
||||
$: isDone = todo.doneOn != null
|
||||
</script>
|
||||
|
||||
<button
|
||||
class="hulyToDoLine-container {size}"
|
||||
class:hovered
|
||||
class:isDone
|
||||
class:isDrag
|
||||
on:click|stopPropagation={open}
|
||||
on:contextmenu={(e) => {
|
||||
@ -104,34 +107,39 @@
|
||||
<button class="hulyToDoLine-dragbox" class:isNew on:contextmenu={onMenuClick}>
|
||||
<Icon icon={IconMoreV2} size={'small'} />
|
||||
</button>
|
||||
<div class="hulyToDoLine-checkbox" class:updating>
|
||||
{#if updating !== undefined}
|
||||
<Spinner size={'small'} />
|
||||
{:else}
|
||||
<CheckBox on:value={markDone} checked={todo.doneOn != null} kind={'todo'} size={'medium'} />
|
||||
<div class="hulyToDoLine-statusPriority">
|
||||
<div class="hulyToDoLine-checkbox" class:updating>
|
||||
{#if updating !== undefined}
|
||||
<Spinner size={'small'} />
|
||||
{:else}
|
||||
<ToDoCheckbox checked={isDone} priority={todo.priority} on:value={markDone} />
|
||||
{/if}
|
||||
</div>
|
||||
{#if size === 'small'}
|
||||
<ToDoPriority value={todo.priority} muted={isDone} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if isTodo}
|
||||
{#if size === 'small'}
|
||||
<div class="hulyToDoLine-top-align top-12 text-left font-regular-14 secondary-textColor overflow-label">
|
||||
<div class="hulyToDoLine-title hulyToDoLine-top-align top-12 text-left font-regular-14 overflow-label">
|
||||
{todo.title}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex-col flex-gap-1 flex-grow text-left">
|
||||
<div class="hulyToDoLine-top-align top-12 text-left font-regular-14 secondary-textColor">
|
||||
<div class="hulyToDoLine-title hulyToDoLine-top-align top-12 text-left font-regular-14">
|
||||
{todo.title}
|
||||
</div>
|
||||
<div class="flex-row-center flex-grow flex-gap-2">
|
||||
<Component is={tags.component.LabelsPresenter} props={{ object: todo, value: todo.labels, kind: 'todo' }} />
|
||||
<PriorityPresenter value={todo.priority} />
|
||||
<ToDoPriority value={todo.priority} muted={isDone} showLabel />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="flex-col flex-gap-1 flex-grow text-left">
|
||||
<div
|
||||
class="hulyToDoLine-top-align text-left top-12 font-bold-12 secondary-textColor"
|
||||
class="hulyToDoLine-title hulyToDoLine-top-align text-left top-12 font-bold-12 secondary-textColor"
|
||||
class:overflow-label={size === 'small'}
|
||||
>
|
||||
{todo.title}
|
||||
@ -143,7 +151,7 @@
|
||||
is={tags.component.LabelsPresenter}
|
||||
props={{ object: todo, value: todo.labels, kind: 'todo' }}
|
||||
/>
|
||||
<PriorityPresenter value={todo.priority} />
|
||||
<ToDoPriority value={todo.priority} muted={isDone} showLabel />
|
||||
</div>
|
||||
{/if}
|
||||
</WorkItemPresenter>
|
||||
@ -157,13 +165,19 @@
|
||||
is={tags.component.LabelsPresenter}
|
||||
props={{ object: todo, value: todo.labels, kind: 'todo-compact' }}
|
||||
/>
|
||||
<PriorityPresenter value={todo.priority} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-no-shrink flex-gap-3 pl-2">
|
||||
{#if events.length > 0}
|
||||
<span class="hulyToDoLine-top-align top-12 font-regular-12 secondary-textColor">
|
||||
<ToDoDuration {events} />
|
||||
</span>
|
||||
{/if}
|
||||
{#if todo.dueDate}
|
||||
<span class="hulyToDoLine-top-align top-12 font-regular-12 secondary-textColor">
|
||||
{new Date(todo.dueDate).toLocaleDateString('default', { month: 'short', day: 'numeric' })}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
|
43
plugins/time-resources/src/components/ToDoPriority.svelte
Normal file
43
plugins/time-resources/src/components/ToDoPriority.svelte
Normal file
@ -0,0 +1,43 @@
|
||||
<!--
|
||||
// Copyright © 2024 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 { ToDoPriority } from '@hcengineering/time'
|
||||
import { Label } from '@hcengineering/ui'
|
||||
import { getToDoPriorityColor, todoPriorities } from '../utils'
|
||||
import Priority from './icons/Priority.svelte'
|
||||
|
||||
export let value: ToDoPriority
|
||||
export let muted: boolean = false
|
||||
export let showLabel: boolean = false
|
||||
|
||||
$: color = muted ? undefined : getToDoPriorityColor(value)
|
||||
</script>
|
||||
|
||||
{#if value !== ToDoPriority.NoPriority}
|
||||
<div class="flex-center flex-gap-1-5">
|
||||
<Priority {value} {muted} />
|
||||
{#if showLabel}
|
||||
<span class="priority-label font-medium-12" style:color>
|
||||
<Label label={todoPriorities[value].shortLabel} />
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
.priority-label {
|
||||
color: var(--global-disabled-PriorityColor);
|
||||
}
|
||||
</style>
|
109
plugins/time-resources/src/components/icons/Priority.svelte
Normal file
109
plugins/time-resources/src/components/icons/Priority.svelte
Normal file
@ -0,0 +1,109 @@
|
||||
<!--
|
||||
// Copyright © 2024 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 type { IconSize } from '@hcengineering/ui'
|
||||
import { ToDoPriority } from '@hcengineering/time'
|
||||
import { todoPriorities } from '../../utils'
|
||||
|
||||
export let size: IconSize = 'small'
|
||||
export let fill: string = 'currentColor'
|
||||
|
||||
export let value: ToDoPriority = ToDoPriority.NoPriority
|
||||
export let muted: boolean = false
|
||||
|
||||
$: priorityClassName = todoPriorities[value].name
|
||||
</script>
|
||||
|
||||
<svg
|
||||
class="svg-{size} priority-icon {priorityClassName}"
|
||||
class:muted
|
||||
{fill}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
{#if value === ToDoPriority.Urgent}
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M2 4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2zm7 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0m-.026-6.475a.5.5 0 0 0-.5-.525h-.948a.5.5 0 0 0-.5.525l.187 3.726a.788.788 0 0 0 1.574 0z"
|
||||
/>
|
||||
{:else}
|
||||
<path class="item" d="M3 10.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z" />
|
||||
<path class="item" d="M7 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z" />
|
||||
<path class="item" d="M11 2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z" />
|
||||
{/if}
|
||||
</svg>
|
||||
|
||||
<style lang="scss">
|
||||
.priority-icon {
|
||||
color: var(--icon-disabled-IconColor);
|
||||
|
||||
&.muted {
|
||||
&.low {
|
||||
.item:nth-child(1) {
|
||||
fill: var(--global-disabled-PriorityColor);
|
||||
}
|
||||
}
|
||||
|
||||
&.medium {
|
||||
.item:nth-child(1),
|
||||
.item:nth-child(2) {
|
||||
fill: var(--global-disabled-PriorityColor);
|
||||
}
|
||||
}
|
||||
|
||||
&.high {
|
||||
.item:nth-child(1),
|
||||
.item:nth-child(2),
|
||||
.item:nth-child(3) {
|
||||
fill: var(--global-disabled-PriorityColor);
|
||||
}
|
||||
}
|
||||
|
||||
&.urgent {
|
||||
fill: var(--global-disabled-PriorityColor);
|
||||
}
|
||||
}
|
||||
|
||||
&.low {
|
||||
.item:nth-child(1) {
|
||||
fill: var(--global-low-PriorityColor);
|
||||
}
|
||||
}
|
||||
|
||||
&.medium {
|
||||
.item:nth-child(1),
|
||||
.item:nth-child(2) {
|
||||
fill: var(--global-medium-PriorityColor);
|
||||
}
|
||||
}
|
||||
|
||||
&.high {
|
||||
.item:nth-child(1),
|
||||
.item:nth-child(2),
|
||||
.item:nth-child(3) {
|
||||
fill: var(--global-high-PriorityColor);
|
||||
}
|
||||
}
|
||||
|
||||
&.urgent {
|
||||
fill: var(--global-urgent-PriorityColor);
|
||||
}
|
||||
|
||||
.item {
|
||||
fill: currentColor;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -48,10 +48,16 @@ export default mergeIds(timeId, time, {
|
||||
Unplanned: '' as IntlString,
|
||||
Planned: '' as IntlString,
|
||||
AddSlot: '' as IntlString,
|
||||
HighPriority: '' as IntlString,
|
||||
MediumPriority: '' as IntlString,
|
||||
LowPriority: '' as IntlString,
|
||||
SetPriority: '' as IntlString,
|
||||
NoPriority: '' as IntlString,
|
||||
LowPriority: '' as IntlString,
|
||||
MediumPriority: '' as IntlString,
|
||||
HighPriority: '' as IntlString,
|
||||
UrgentPriority: '' as IntlString,
|
||||
Low: '' as IntlString,
|
||||
Medium: '' as IntlString,
|
||||
High: '' as IntlString,
|
||||
Urgent: '' as IntlString,
|
||||
AddTo: '' as IntlString,
|
||||
AddTitle: '' as IntlString,
|
||||
MyWork: '' as IntlString,
|
||||
|
@ -1,7 +1,10 @@
|
||||
import { type Event } from '@hcengineering/calendar'
|
||||
import { type Person } from '@hcengineering/contact'
|
||||
import { type Ref } from '@hcengineering/core'
|
||||
import { type ToDo, type WorkSlot } from '@hcengineering/time'
|
||||
import type { WorkSlot, ToDo } from '@hcengineering/time'
|
||||
import type { IntlString } from '@hcengineering/platform'
|
||||
import type { Person } from '@hcengineering/contact'
|
||||
import type { Event } from '@hcengineering/calendar'
|
||||
import type { Ref } from '@hcengineering/core'
|
||||
import { ToDoPriority } from '@hcengineering/time'
|
||||
import time from './plugin'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -25,3 +28,52 @@ export interface EventPersonMapping {
|
||||
events: Array<Event & { overlap?: number }>
|
||||
total: number
|
||||
}
|
||||
|
||||
interface ToDoPrioritiesItem {
|
||||
label: IntlString
|
||||
shortLabel: IntlString
|
||||
name: string
|
||||
}
|
||||
|
||||
export const defaultToDoPriorities = [
|
||||
ToDoPriority.NoPriority,
|
||||
ToDoPriority.Low,
|
||||
ToDoPriority.Medium,
|
||||
ToDoPriority.High,
|
||||
ToDoPriority.Urgent
|
||||
]
|
||||
|
||||
export const todoPriorities: Record<number, ToDoPrioritiesItem> = {
|
||||
[ToDoPriority.NoPriority]: {
|
||||
label: time.string.NoPriority,
|
||||
shortLabel: time.string.NoPriority,
|
||||
name: 'no-priority'
|
||||
},
|
||||
[ToDoPriority.Low]: {
|
||||
label: time.string.LowPriority,
|
||||
shortLabel: time.string.Low,
|
||||
name: 'low'
|
||||
},
|
||||
[ToDoPriority.Medium]: {
|
||||
label: time.string.MediumPriority,
|
||||
shortLabel: time.string.Medium,
|
||||
name: 'medium'
|
||||
},
|
||||
[ToDoPriority.High]: {
|
||||
label: time.string.HighPriority,
|
||||
shortLabel: time.string.High,
|
||||
name: 'high'
|
||||
},
|
||||
[ToDoPriority.Urgent]: {
|
||||
label: time.string.UrgentPriority,
|
||||
shortLabel: time.string.Urgent,
|
||||
name: 'urgent'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function getToDoPriorityColor (priority: ToDoPriority): string {
|
||||
return `var(--global-${todoPriorities[priority].name}-PriorityColor)`
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { type Client, type Ref } from '@hcengineering/core'
|
||||
import { type DefSeparators } from '@hcengineering/ui'
|
||||
import time, { type WorkSlot, type ToDo } from '@hcengineering/time'
|
||||
import type { Client, Ref } from '@hcengineering/core'
|
||||
import type { DefSeparators } from '@hcengineering/ui'
|
||||
import type { WorkSlot, ToDo } from '@hcengineering/time'
|
||||
import time from '@hcengineering/time'
|
||||
|
||||
export * from './types'
|
||||
|
||||
export function getNearest (events: WorkSlot[]): WorkSlot | undefined {
|
||||
const now = Date.now()
|
||||
|
@ -58,7 +58,8 @@ export enum ToDoPriority {
|
||||
High,
|
||||
Medium,
|
||||
Low,
|
||||
NoPriority
|
||||
NoPriority,
|
||||
Urgent
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user