Fixed navigation in ProjectEditor. Updated layout CreateTaskType. UI fixes. (#4457)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2024-01-26 06:49:40 +03:00 committed by GitHub
parent 631a61ca1d
commit 960842863b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 71 additions and 35 deletions

View File

@ -201,6 +201,7 @@
flex-direction: column; flex-direction: column;
// height: 100vh; // height: 100vh;
height: 100%; height: 100%;
height: 100dvh;
// height: var(--app-height); // height: var(--app-height);
.antiStatusBar { .antiStatusBar {

View File

@ -1027,7 +1027,7 @@
<style lang="scss"> <style lang="scss">
.calendar-container { .calendar-container {
will-change: transform; will-change: scroll-position;
position: relative; position: relative;
display: grid; display: grid;
@ -1165,7 +1165,7 @@
.sticky-header { .sticky-header {
position: sticky; position: sticky;
background-color: var(--theme-comp-header-color); background-color: var(--theme-comp-header-color);
z-index: 10; z-index: 15;
&:not(.head) { &:not(.head) {
top: 3.5rem; top: 3.5rem;

View File

@ -126,7 +126,7 @@
<div class="hulyChip-item font-medium-12"> <div class="hulyChip-item font-medium-12">
<Label label={setting.string.Custom} /> <Label label={setting.string.Custom} />
</div> </div>
<ModernEditbox bind:value={name} label={core.string.Name} size={'large'} kind={'ghost'} /> <ModernEditbox bind:value={name} label={core.string.Name} size={'large'} kind={'ghost'} autoFocus />
</div> </div>
<div class="hulyModal-content__settingsSet"> <div class="hulyModal-content__settingsSet">
<div class="hulyModal-content__settingsSet-line"> <div class="hulyModal-content__settingsSet-line">

View File

@ -53,7 +53,7 @@
import { ContextMenu } from '@hcengineering/view-resources' import { ContextMenu } from '@hcengineering/view-resources'
import plugin from '../../plugin' import plugin from '../../plugin'
import setting from '@hcengineering/setting' import setting from '@hcengineering/setting'
import { ClassAttributes, clearSettingsStore } from '@hcengineering/setting-resources' import { ClassAttributes, clearSettingsStore, settingsStore } from '@hcengineering/setting-resources'
import CreateTaskType from '../taskTypes/CreateTaskType.svelte' import CreateTaskType from '../taskTypes/CreateTaskType.svelte'
import TaskTypeEditor from '../taskTypes/TaskTypeEditor.svelte' import TaskTypeEditor from '../taskTypes/TaskTypeEditor.svelte'
import TaskTypeIcon from '../taskTypes/TaskTypeIcon.svelte' import TaskTypeIcon from '../taskTypes/TaskTypeIcon.svelte'
@ -161,9 +161,11 @@
] ]
: [{ label: plugin.string.ProjectType, icon: descriptor?.icon }] : [{ label: plugin.string.ProjectType, icon: descriptor?.icon }]
let scroller: Scroller
const navigator: { const navigator: {
id: string id: string
label: IntlString label: IntlString
element?: HTMLElement
}[] = [ }[] = [
{ id: 'properties', label: setting.string.Properties }, { id: 'properties', label: setting.string.Properties },
{ id: 'tasktypes', label: setting.string.TaskTypes }, { id: 'tasktypes', label: setting.string.TaskTypes },
@ -228,14 +230,21 @@
<ButtonIcon kind={'tertiary'} icon={IconDescription} size={'small'} inheritColor /> <ButtonIcon kind={'tertiary'} icon={IconDescription} size={'small'} inheritColor />
</div> </div>
</div> </div>
{#each navigator as navItem (navItem.id)} {#each navigator as navItem, i (navItem.id)}
<NavItem type={'type-anchor-link'} label={navItem.label} /> <NavItem
type={'type-anchor-link'}
label={navItem.label}
on:click={() => {
if (i === 0) scroller.scroll(0)
else navItem.element?.scrollIntoView()
}}
/>
{/each} {/each}
</div> </div>
<Separator name={'typeSettings'} index={0} color={'transparent'} /> <Separator name={'typeSettings'} index={0} color={'transparent'} />
{/if} {/if}
<div class="hulyComponent-content__column content"> <div class="hulyComponent-content__column content">
<Scroller align={'center'} padding={'var(--spacing-3)'} bottomPadding={'var(--spacing-3)'}> <Scroller bind:this={scroller} align={'center'} padding={'var(--spacing-3)'} bottomPadding={'var(--spacing-3)'}>
<div class="hulyComponent-content gap"> <div class="hulyComponent-content gap">
{#if selectedTaskType === undefined} {#if selectedTaskType === undefined}
<div class="hulyComponent-content__column-group"> <div class="hulyComponent-content__column-group">
@ -278,7 +287,7 @@
<ClassAttributes ofClass={descriptor.baseClass} _class={type.targetClass} showHierarchy /> <ClassAttributes ofClass={descriptor.baseClass} _class={type.targetClass} showHierarchy />
<div class="hulyTableAttr-container"> <div bind:this={navigator[1].element} class="hulyTableAttr-container">
<div class="hulyTableAttr-header font-medium-12"> <div class="hulyTableAttr-header font-medium-12">
<IconLayers size={'small'} /> <IconLayers size={'small'} />
<span><Label label={setting.string.TaskTypes} /></span> <span><Label label={setting.string.TaskTypes} /></span>
@ -287,7 +296,8 @@
icon={IconAdd} icon={IconAdd}
size={'small'} size={'small'}
on:click={(ev) => { on:click={(ev) => {
showPopup(CreateTaskType, { type, descriptor }, 'top') $settingsStore = { id: 'createTaskType', component: CreateTaskType, props: { type, descriptor } }
// showPopup(CreateTaskType, { type, descriptor }, 'top')
}} }}
/> />
</div> </div>
@ -317,9 +327,11 @@
{/if} {/if}
</div> </div>
<ComponentExtensions extension={task.extensions.ProjectEditorExtension} props={{ type }} /> <div bind:this={navigator[2].element} class="flex-col">
<ComponentExtensions extension={task.extensions.ProjectEditorExtension} props={{ type }} />
</div>
<div class="hulyTableAttr-container"> <div bind:this={navigator[3].element} class="hulyTableAttr-container">
<div class="hulyTableAttr-header font-medium-12"> <div class="hulyTableAttr-header font-medium-12">
<IconFolder size={'small'} /> <IconFolder size={'small'} />
<span><Label label={setting.string.Collections} /></span> <span><Label label={setting.string.Collections} /></span>

View File

@ -15,7 +15,7 @@
<script lang="ts"> <script lang="ts">
import core, { Class, ClassifierKind, Data, Ref, RefTo, Status, generateId, toIdMap } from '@hcengineering/core' import core, { Class, ClassifierKind, Data, Ref, RefTo, Status, generateId, toIdMap } from '@hcengineering/core'
import { Resource, getEmbeddedLabel, getResource } from '@hcengineering/platform' import { Resource, getEmbeddedLabel, getResource } from '@hcengineering/platform'
import presentation, { Card, getClient, hasResource } from '@hcengineering/presentation' import presentation, { getClient, hasResource } from '@hcengineering/presentation'
import { import {
ProjectType, ProjectType,
ProjectTypeDescriptor, ProjectTypeDescriptor,
@ -25,12 +25,11 @@
createState, createState,
findStatusAttr findStatusAttr
} from '@hcengineering/task' } from '@hcengineering/task'
import { DropdownIntlItem, DropdownLabelsIntl, EditBox, getColorNumberByText } from '@hcengineering/ui' import { DropdownIntlItem, Modal, ModernEditbox, Label, ButtonMenu } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import task from '../../plugin' import task from '../../plugin'
import TaskTypeKindEditor from './TaskTypeKindEditor.svelte' import TaskTypeKindEditor from './TaskTypeKindEditor.svelte'
import { clearSettingsStore } from '@hcengineering/setting-resources'
const dispatch = createEventDispatcher()
const client = getClient() const client = getClient()
export let type: ProjectType export let type: ProjectType
export let descriptor: ProjectTypeDescriptor export let descriptor: ProjectTypeDescriptor
@ -74,12 +73,12 @@
} }
} }
let taskTypeDescriptor: Ref<TaskTypeDescriptor> = taskTypeDescriptors[0]._id let taskTypeDescriptor: TaskTypeDescriptor = taskTypeDescriptors[0]
async function save (): Promise<void> { async function save (): Promise<void> {
if (type === undefined) return if (type === undefined) return
const descr = taskTypeDescriptors.find((it) => it._id === taskTypeDescriptor) const descr = taskTypeDescriptors.find((it) => it._id === taskTypeDescriptor._id)
if (descr === undefined) return if (descr === undefined) return
const ofClass = descr.baseClass const ofClass = descr.baseClass
@ -87,7 +86,7 @@
kind, kind,
name, name,
ofClass, ofClass,
descriptor: taskTypeDescriptor, descriptor: taskTypeDescriptor._id,
targetClass, targetClass,
statusCategories, statusCategories,
statuses, statuses,
@ -146,31 +145,55 @@
await client.update(type, { $push: { tasks: taskTypeId } }) await client.update(type, { $push: { tasks: taskTypeId } })
} }
dispatch('close') clearSettingsStore()
} }
const descriptorItems: DropdownIntlItem[] = taskTypeDescriptors.map((it) => ({ id: it._id, label: it.name })) const descriptorItems: DropdownIntlItem[] = taskTypeDescriptors.map((it) => ({
id: it._id,
icon: it.icon,
label: it.name
}))
</script> </script>
<Card <Modal
label={task.string.TaskType} label={task.string.TaskType}
type={'type-aside'}
okAction={save} okAction={save}
canSave canSave
okLabel={taskType !== undefined ? presentation.string.Save : presentation.string.Create} okLabel={taskType !== undefined ? presentation.string.Save : presentation.string.Create}
on:changeContent on:changeContent
onCancel={() => dispatch('close')} onCancel={() => {
clearSettingsStore()
}}
> >
<EditBox <div class="hulyModal-content__titleGroup">
focusIndex={1} <ModernEditbox bind:value={name} label={task.string.TaskName} size={'large'} kind={'ghost'} autoFocus />
bind:value={name}
placeholder={task.string.TaskName}
kind={'large-style'}
autoFocus
fullSize
/>
<div class="p-1 flex-row-center mt-4">
<TaskTypeKindEditor bind:kind />
<DropdownLabelsIntl kind={'regular'} size={'large'} items={descriptorItems} bind:selected={taskTypeDescriptor} />
</div> </div>
</Card> <div class="hulyModal-content__settingsSet">
<div class="hulyModal-content__settingsSet-line">
<span class="label">
<Label label={task.string.TaskType} />
</span>
<TaskTypeKindEditor bind:kind />
</div>
<div class="hulyModal-content__settingsSet-line">
<span class="label">
<Label label={task.string.Type} />
</span>
<ButtonMenu
selected={taskTypeDescriptor._id}
items={descriptorItems}
icon={taskTypeDescriptor.icon}
label={taskTypeDescriptor.name}
kind={'secondary'}
size={'large'}
on:selected={(evt) => {
if (evt.detail != null) {
const tt = taskTypeDescriptors.find((tt) => tt._id === evt.detail)
if (tt) taskTypeDescriptor = tt
}
}}
/>
</div>
</div>
</Modal>