mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 11:42:30 +03:00
Minor UI fixes (#6117)
Signed-off-by: Alexander Platov <alexander.platov@hardcoreeng.com>
This commit is contained in:
parent
4962367182
commit
4d3561caf8
@ -20,8 +20,7 @@
|
|||||||
import type { AnySvelteComponent } from '../types'
|
import type { AnySvelteComponent } from '../types'
|
||||||
import { getTreeCollapsed, setTreeCollapsed } from '../location'
|
import { getTreeCollapsed, setTreeCollapsed } from '../location'
|
||||||
import IconChevronRight from './icons/ChevronRight.svelte'
|
import IconChevronRight from './icons/ChevronRight.svelte'
|
||||||
import Label from './Label.svelte'
|
import { Label, Icon, formatDuration, themeStore } from '..'
|
||||||
import Icon from './Icon.svelte'
|
|
||||||
|
|
||||||
export let id: string
|
export let id: string
|
||||||
export let label: IntlString | undefined = undefined
|
export let label: IntlString | undefined = undefined
|
||||||
@ -52,6 +51,16 @@
|
|||||||
if (disabled) return
|
if (disabled) return
|
||||||
collapsed = !collapsed
|
collapsed = !collapsed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let durationLabel: string = ''
|
||||||
|
const updateDurationLabel = (dur: number | boolean): void => {
|
||||||
|
if (typeof dur === 'number') {
|
||||||
|
formatDuration(dur, $themeStore.language).then((res) => {
|
||||||
|
durationLabel = res
|
||||||
|
})
|
||||||
|
} else durationLabel = ''
|
||||||
|
}
|
||||||
|
$: updateDurationLabel(duration)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="hulyAccordionItem-container {kind}" class:nested>
|
<div class="hulyAccordionItem-container {kind}" class:nested>
|
||||||
@ -95,17 +104,17 @@
|
|||||||
{#if title}{title}{/if}
|
{#if title}{title}{/if}
|
||||||
<slot name="title" />
|
<slot name="title" />
|
||||||
</div>
|
</div>
|
||||||
{#if counter !== false || $$slots.counter}
|
{#if counter !== false && ($$slots.counter || typeof counter === 'number')}
|
||||||
<span class="hulyAccordionItem-header__separator">•</span>
|
<span class="hulyAccordionItem-header__separator">•</span>
|
||||||
<span class="hulyAccordionItem-header__counter">
|
<span class="hulyAccordionItem-header__counter">
|
||||||
{#if typeof counter === 'number'}{counter}{/if}
|
{#if typeof counter === 'number'}{counter}{/if}
|
||||||
<slot name="counter" />
|
<slot name="counter" />
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if duration !== false || $$slots.duration}
|
{#if duration !== false && ($$slots.duration || duration !== 0)}
|
||||||
<span class="hulyAccordionItem-header__separator">•</span>
|
<span class="hulyAccordionItem-header__separator">•</span>
|
||||||
<span class="hulyAccordionItem-header__duration">
|
<span class="hulyAccordionItem-header__duration">
|
||||||
{#if typeof duration === 'number'}{duration}{/if}
|
{#if typeof duration === 'number' && durationLabel !== ''}{durationLabel}{/if}
|
||||||
<slot name="duration" />
|
<slot name="duration" />
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -103,10 +103,10 @@
|
|||||||
on:keydown
|
on:keydown
|
||||||
>
|
>
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="icon animate"><Spinner size={type === 'type-button' && !hasMenu ? 'medium' : 'small'} /></div>
|
<div class="icon"><Spinner size={'small'} /></div>
|
||||||
{:else if icon}<div class="icon">
|
{:else if icon}
|
||||||
<Icon {icon} {iconProps} size={actualIconSize} />
|
<div class="icon"><Icon {icon} {iconProps} size={actualIconSize} /></div>
|
||||||
</div>{/if}
|
{/if}
|
||||||
{#if label}<span><Label {label} params={labelParams} /></span>{/if}
|
{#if label}<span><Label {label} params={labelParams} /></span>{/if}
|
||||||
{#if title}<span>{title}</span>{/if}
|
{#if title}<span>{title}</span>{/if}
|
||||||
<slot />
|
<slot />
|
||||||
@ -136,10 +136,6 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: var(--spacing-2_5);
|
width: var(--spacing-2_5);
|
||||||
height: var(--spacing-2_5);
|
height: var(--spacing-2_5);
|
||||||
|
|
||||||
&.animate {
|
|
||||||
animation: rotate 2s linear infinite;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
span {
|
span {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -262,6 +262,10 @@
|
|||||||
// &:not(.type-anchor-link) .hulyNavItem-label:not(.description) {
|
// &:not(.type-anchor-link) .hulyNavItem-label:not(.description) {
|
||||||
// font-weight: 700;
|
// font-weight: 700;
|
||||||
// }
|
// }
|
||||||
|
.hulyNavItem-actions {
|
||||||
|
order: 1;
|
||||||
|
margin-left: var(--spacing-0_5);
|
||||||
|
}
|
||||||
.hulyNavItem-count {
|
.hulyNavItem-count {
|
||||||
color: var(--global-secondary-TextColor);
|
color: var(--global-secondary-TextColor);
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,12 @@
|
|||||||
|
|
||||||
import { generateId } from '@hcengineering/core'
|
import { generateId } from '@hcengineering/core'
|
||||||
import type { IntlString, Metadata } from '@hcengineering/platform'
|
import type { IntlString, Metadata } from '@hcengineering/platform'
|
||||||
import { setMetadata } from '@hcengineering/platform'
|
import { setMetadata, translate } from '@hcengineering/platform'
|
||||||
import autolinker from 'autolinker'
|
import autolinker from 'autolinker'
|
||||||
import { writable } from 'svelte/store'
|
import { writable } from 'svelte/store'
|
||||||
import { NotificationPosition, NotificationSeverity, notificationsStore, type Notification } from '.'
|
import { NotificationPosition, NotificationSeverity, notificationsStore, type Notification } from '.'
|
||||||
import { deviceSizes, type AnyComponent, type AnySvelteComponent, type WidthType } from './types'
|
import { deviceSizes, type AnyComponent, type AnySvelteComponent, type WidthType } from './types'
|
||||||
|
import ui, { DAY, HOUR, MINUTE } from '..'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -297,3 +298,23 @@ export class ThrottledCaller {
|
|||||||
export const testing = (localStorage.getItem('#platform.testing.enabled') ?? 'false') === 'true'
|
export const testing = (localStorage.getItem('#platform.testing.enabled') ?? 'false') === 'true'
|
||||||
|
|
||||||
export const rootBarExtensions = writable<Array<['left' | 'right', AnyComponent]>>([])
|
export const rootBarExtensions = writable<Array<['left' | 'right', AnyComponent]>>([])
|
||||||
|
|
||||||
|
export async function formatDuration (duration: number, language: string): Promise<string> {
|
||||||
|
let text = ''
|
||||||
|
const days = Math.floor(duration / DAY)
|
||||||
|
if (days > 0) {
|
||||||
|
text += await translate(ui.string.DaysShort, { value: days }, language)
|
||||||
|
}
|
||||||
|
const hours = Math.floor((duration % DAY) / HOUR)
|
||||||
|
if (hours > 0) {
|
||||||
|
text += ' '
|
||||||
|
text += await translate(ui.string.HoursShort, { value: hours }, language)
|
||||||
|
}
|
||||||
|
const minutes = Math.floor((duration % HOUR) / MINUTE)
|
||||||
|
if (minutes > 0) {
|
||||||
|
text += ' '
|
||||||
|
text += await translate(ui.string.MinutesShort, { value: minutes }, language)
|
||||||
|
}
|
||||||
|
text = text.trim()
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
@ -109,7 +109,6 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-left: var(--spacing-1);
|
|
||||||
padding: var(--spacing-0_5);
|
padding: var(--spacing-0_5);
|
||||||
color: var(--global-tertiary-TextColor);
|
color: var(--global-tertiary-TextColor);
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -21,9 +21,6 @@
|
|||||||
"WorkItem": "Work Item",
|
"WorkItem": "Work Item",
|
||||||
"Inbox": "Inbox",
|
"Inbox": "Inbox",
|
||||||
"All": "All",
|
"All": "All",
|
||||||
"Days": "{days}d",
|
|
||||||
"Hours": "{hours}h",
|
|
||||||
"Minutes": "{minutes}m",
|
|
||||||
"AddToDo": "Add Action Item",
|
"AddToDo": "Add Action Item",
|
||||||
"CreateToDo": "Add Action Item, press Enter to save",
|
"CreateToDo": "Add Action Item, press Enter to save",
|
||||||
"ToDos": "Action Items",
|
"ToDos": "Action Items",
|
||||||
|
@ -21,9 +21,6 @@
|
|||||||
"WorkItem": "Elemento de trabajo",
|
"WorkItem": "Elemento de trabajo",
|
||||||
"Inbox": "Bandeja de entrada",
|
"Inbox": "Bandeja de entrada",
|
||||||
"All": "Todo",
|
"All": "Todo",
|
||||||
"Days": "{days}d",
|
|
||||||
"Hours": "{hours}h",
|
|
||||||
"Minutes": "{minutes}m",
|
|
||||||
"AddToDo": "Agregar tarea",
|
"AddToDo": "Agregar tarea",
|
||||||
"CreateToDo": "Agregar tarea, presiona Enter para guardar",
|
"CreateToDo": "Agregar tarea, presiona Enter para guardar",
|
||||||
"ToDos": "Tareas pendientes",
|
"ToDos": "Tareas pendientes",
|
||||||
|
@ -21,9 +21,6 @@
|
|||||||
"WorkItem": "Élément de travail",
|
"WorkItem": "Élément de travail",
|
||||||
"Inbox": "Boîte de réception",
|
"Inbox": "Boîte de réception",
|
||||||
"All": "Tout",
|
"All": "Tout",
|
||||||
"Days": "{days}j",
|
|
||||||
"Hours": "{hours}h",
|
|
||||||
"Minutes": "{minutes}m",
|
|
||||||
"AddToDo": "Ajouter une tâche",
|
"AddToDo": "Ajouter une tâche",
|
||||||
"CreateToDo": "Ajouter une tâche, appuyer sur Entrée pour enregistrer",
|
"CreateToDo": "Ajouter une tâche, appuyer sur Entrée pour enregistrer",
|
||||||
"ToDos": "À faire",
|
"ToDos": "À faire",
|
||||||
|
@ -21,9 +21,6 @@
|
|||||||
"WorkItem": "Item de trabalho",
|
"WorkItem": "Item de trabalho",
|
||||||
"Inbox": "Caixa de entrada",
|
"Inbox": "Caixa de entrada",
|
||||||
"All": "Tudo",
|
"All": "Tudo",
|
||||||
"Days": "{days}d",
|
|
||||||
"Hours": "{hours}h",
|
|
||||||
"Minutes": "{minutes}m",
|
|
||||||
"AddToDo": "Adicionar tarefa",
|
"AddToDo": "Adicionar tarefa",
|
||||||
"CreateToDo": "Adicionar tarefa, pressione Enter para guardar",
|
"CreateToDo": "Adicionar tarefa, pressione Enter para guardar",
|
||||||
"ToDos": "Tarefas pendentes",
|
"ToDos": "Tarefas pendentes",
|
||||||
|
@ -21,9 +21,6 @@
|
|||||||
"WorkItem": "Задача",
|
"WorkItem": "Задача",
|
||||||
"Inbox": "Входящие",
|
"Inbox": "Входящие",
|
||||||
"All": "Все",
|
"All": "Все",
|
||||||
"Days": "{days}д",
|
|
||||||
"Hours": "{hours}ч",
|
|
||||||
"Minutes": "{minutes}м",
|
|
||||||
"AddToDo": "Добавить Действие",
|
"AddToDo": "Добавить Действие",
|
||||||
"CreateToDo": "Добавьте Действие, нажмите Ввод, чтобы сохранить",
|
"CreateToDo": "Добавьте Действие, нажмите Ввод, чтобы сохранить",
|
||||||
"ToDos": "Действия",
|
"ToDos": "Действия",
|
||||||
|
@ -21,9 +21,6 @@
|
|||||||
"WorkItem": "工作项",
|
"WorkItem": "工作项",
|
||||||
"Inbox": "收件箱",
|
"Inbox": "收件箱",
|
||||||
"All": "全部",
|
"All": "全部",
|
||||||
"Days": "{days}天",
|
|
||||||
"Hours": "{hours}小时",
|
|
||||||
"Minutes": "{minutes}分钟",
|
|
||||||
"AddToDo": "添加待办",
|
"AddToDo": "添加待办",
|
||||||
"CreateToDo": "添加待办,按回车键保存",
|
"CreateToDo": "添加待办,按回车键保存",
|
||||||
"ToDos": "待办事项",
|
"ToDos": "待办事项",
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { themeStore } from '@hcengineering/ui'
|
import { themeStore, formatDuration } from '@hcengineering/ui'
|
||||||
import { WorkSlot } from '@hcengineering/time'
|
import { WorkSlot } from '@hcengineering/time'
|
||||||
import { calculateEventsDuration, formatEventsDuration } from '../utils'
|
import { calculateEventsDuration } from '../utils'
|
||||||
|
|
||||||
export let events: WorkSlot[]
|
export let events: WorkSlot[]
|
||||||
|
|
||||||
let duration: string
|
let duration: string
|
||||||
$: formatEventsDuration(calculateEventsDuration(events), $themeStore.language).then((res) => {
|
$: formatDuration(calculateEventsDuration(events), $themeStore.language).then((res) => {
|
||||||
duration = res
|
duration = res
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -24,10 +24,9 @@
|
|||||||
import { makeRank } from '@hcengineering/task'
|
import { makeRank } from '@hcengineering/task'
|
||||||
import ToDoProjectGroup from './ToDoProjectGroup.svelte'
|
import ToDoProjectGroup from './ToDoProjectGroup.svelte'
|
||||||
import ToDoDraggable from './ToDoDraggable.svelte'
|
import ToDoDraggable from './ToDoDraggable.svelte'
|
||||||
import ToDoDuration from './ToDoDuration.svelte'
|
|
||||||
import ToDoElement from './ToDoElement.svelte'
|
import ToDoElement from './ToDoElement.svelte'
|
||||||
import { dragging } from '../dragging'
|
import { dragging } from '../dragging'
|
||||||
import time from '../plugin'
|
import { calculateEventsDuration } from '../utils'
|
||||||
|
|
||||||
export let mode: ToDosMode
|
export let mode: ToDosMode
|
||||||
export let title: IntlString
|
export let title: IntlString
|
||||||
@ -89,6 +88,9 @@
|
|||||||
const newRank = makeRank(previousItem?.rank, nextItem?.rank)
|
const newRank = makeRank(previousItem?.rank, nextItem?.rank)
|
||||||
await client.update(draggingItem, { rank: newRank })
|
await client.update(draggingItem, { rank: newRank })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$: events = getAllWorkslots(todos)
|
||||||
|
$: duration = calculateEventsDuration(events)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if showTitle}
|
{#if showTitle}
|
||||||
@ -98,13 +100,10 @@
|
|||||||
size={'large'}
|
size={'large'}
|
||||||
bottomSpace={false}
|
bottomSpace={false}
|
||||||
counter={todos.length}
|
counter={todos.length}
|
||||||
duration={showDuration}
|
duration={showDuration ? duration : false}
|
||||||
fixHeader
|
fixHeader
|
||||||
background={'var(--theme-navpanel-color)'}
|
background={'var(--theme-navpanel-color)'}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="duration">
|
|
||||||
<ToDoDuration events={getAllWorkslots(todos)} />
|
|
||||||
</svelte:fragment>
|
|
||||||
{#if groups}
|
{#if groups}
|
||||||
{#each groups as group}
|
{#each groups as group}
|
||||||
<ToDoProjectGroup
|
<ToDoProjectGroup
|
||||||
|
@ -293,7 +293,6 @@
|
|||||||
on:click={togglePlannerNav}
|
on:click={togglePlannerNav}
|
||||||
/>
|
/>
|
||||||
<div class="heading-bold-20 ml-4">
|
<div class="heading-bold-20 ml-4">
|
||||||
<Label label={time.string.ToDoColon} />
|
|
||||||
{#if mode === 'date'}
|
{#if mode === 'date'}
|
||||||
{getDateStr(currentDate)}
|
{getDateStr(currentDate)}
|
||||||
{:else}
|
{:else}
|
||||||
|
@ -13,12 +13,21 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ButtonBase, ButtonIcon, IconDelete, themeStore, Hotkey, HotkeyGroup, Scroller } from '@hcengineering/ui'
|
import {
|
||||||
|
ButtonBase,
|
||||||
|
ButtonIcon,
|
||||||
|
IconDelete,
|
||||||
|
themeStore,
|
||||||
|
Hotkey,
|
||||||
|
HotkeyGroup,
|
||||||
|
Scroller,
|
||||||
|
formatDuration
|
||||||
|
} from '@hcengineering/ui'
|
||||||
import { EventTimeEditor } from '@hcengineering/calendar-resources'
|
import { EventTimeEditor } from '@hcengineering/calendar-resources'
|
||||||
import { WorkSlot } from '@hcengineering/time'
|
import { WorkSlot } from '@hcengineering/time'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import time from '../plugin'
|
import time from '../plugin'
|
||||||
import { calculateEventsDuration, formatEventsDuration } from '../utils'
|
import { calculateEventsDuration } from '../utils'
|
||||||
import Label from '@hcengineering/ui/src/components/Label.svelte'
|
import Label from '@hcengineering/ui/src/components/Label.svelte'
|
||||||
|
|
||||||
export let slots: WorkSlot[] = []
|
export let slots: WorkSlot[] = []
|
||||||
@ -28,7 +37,7 @@
|
|||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let duration: string
|
let duration: string
|
||||||
$: formatEventsDuration(calculateEventsDuration(slots), $themeStore.language).then((res) => {
|
$: formatDuration(calculateEventsDuration(slots), $themeStore.language).then((res) => {
|
||||||
duration = res
|
duration = res
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -39,9 +39,6 @@ export default mergeIds(timeId, time, {
|
|||||||
WorkSlot: '' as IntlString,
|
WorkSlot: '' as IntlString,
|
||||||
CreateToDo: '' as IntlString,
|
CreateToDo: '' as IntlString,
|
||||||
Inbox: '' as IntlString,
|
Inbox: '' as IntlString,
|
||||||
Days: '' as IntlString,
|
|
||||||
Hours: '' as IntlString,
|
|
||||||
Minutes: '' as IntlString,
|
|
||||||
All: '' as IntlString,
|
All: '' as IntlString,
|
||||||
Done: '' as IntlString,
|
Done: '' as IntlString,
|
||||||
ToDos: '' as IntlString,
|
ToDos: '' as IntlString,
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import type { WorkSlot, ToDo } from '@hcengineering/time'
|
import type { WorkSlot, ToDo } from '@hcengineering/time'
|
||||||
import type { DefSeparators } from '@hcengineering/ui'
|
import type { DefSeparators } from '@hcengineering/ui'
|
||||||
import core, { type Class, type Client, type Doc, type Ref, type Space } from '@hcengineering/core'
|
import core, { type Class, type Client, type Doc, type Ref, type Space } from '@hcengineering/core'
|
||||||
import { DAY, HOUR, MINUTE } from '@hcengineering/ui'
|
|
||||||
import { translate } from '@hcengineering/platform'
|
|
||||||
import time from '@hcengineering/time'
|
import time from '@hcengineering/time'
|
||||||
import { type TextEditorMode, type AnyExtension } from '@hcengineering/text-editor'
|
import { type TextEditorMode, type AnyExtension } from '@hcengineering/text-editor'
|
||||||
import { SvelteNodeViewRenderer } from '@hcengineering/text-editor-resources'
|
import { SvelteNodeViewRenderer } from '@hcengineering/text-editor-resources'
|
||||||
@ -11,7 +9,6 @@ import { getClient } from '@hcengineering/presentation'
|
|||||||
import ToDoItemNodeView from './components/text-editor/node-view/ToDoItemNodeView.svelte'
|
import ToDoItemNodeView from './components/text-editor/node-view/ToDoItemNodeView.svelte'
|
||||||
import ToDoListNodeView from './components/text-editor/node-view/ToDoListNodeView.svelte'
|
import ToDoListNodeView from './components/text-editor/node-view/ToDoListNodeView.svelte'
|
||||||
import { TodoItemExtension, TodoListExtension } from './text-editor-extensions'
|
import { TodoItemExtension, TodoListExtension } from './text-editor-extensions'
|
||||||
import timePlugin from './plugin'
|
|
||||||
|
|
||||||
export * from './types'
|
export * from './types'
|
||||||
|
|
||||||
@ -135,23 +132,3 @@ export function calculateEventsDuration (events: WorkSlot[]): number {
|
|||||||
|
|
||||||
return duration
|
return duration
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function formatEventsDuration (duration: number, language: string): Promise<string> {
|
|
||||||
let text = ''
|
|
||||||
const days = Math.floor(duration / DAY)
|
|
||||||
if (days > 0) {
|
|
||||||
text += await translate(timePlugin.string.Days, { days }, language)
|
|
||||||
}
|
|
||||||
const hours = Math.floor((duration % DAY) / HOUR)
|
|
||||||
if (hours > 0) {
|
|
||||||
text += ' '
|
|
||||||
text += await translate(timePlugin.string.Hours, { hours }, language)
|
|
||||||
}
|
|
||||||
const minutes = Math.floor((duration % HOUR) / MINUTE)
|
|
||||||
if (minutes > 0) {
|
|
||||||
text += ' '
|
|
||||||
text += await translate(timePlugin.string.Minutes, { minutes }, language)
|
|
||||||
}
|
|
||||||
text = text.trim()
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
{#await p then blobRef}
|
{#await p then blobRef}
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="flex justify-center">
|
<div class="flex-center w-full h-full clear-mins">
|
||||||
<Loading />
|
<Loading />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
Loading…
Reference in New Issue
Block a user