mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
TSK-831: Edit issue fixes (#3140)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
f5bd3edc48
commit
c606a037f1
@ -95,7 +95,7 @@
|
|||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
||||||
<svelte:fragment slot="utils">
|
<svelte:fragment slot="utils">
|
||||||
<Component is={calendar.component.DocReminder} props={{ value: object, title }} />
|
<Component is={calendar.component.DocReminder} props={{ value: object, title, focusIndex: 9000 }} />
|
||||||
{#if isUtils && $$slots.utils}
|
{#if isUtils && $$slots.utils}
|
||||||
<div class="buttons-divider" />
|
<div class="buttons-divider" />
|
||||||
<slot name="utils" />
|
<slot name="utils" />
|
||||||
@ -145,7 +145,7 @@
|
|||||||
{#if !withoutActivity}
|
{#if !withoutActivity}
|
||||||
<Component
|
<Component
|
||||||
is={activity.component.Activity}
|
is={activity.component.Activity}
|
||||||
props={{ object, showCommenInput: !withoutInput, shouldScroll: embedded }}
|
props={{ object, showCommenInput: !withoutInput, shouldScroll: embedded, focusIndex: 1000 }}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@ -156,7 +156,7 @@
|
|||||||
{#if !withoutActivity}
|
{#if !withoutActivity}
|
||||||
<Component
|
<Component
|
||||||
is={activity.component.Activity}
|
is={activity.component.Activity}
|
||||||
props={{ object, showCommenInput: !withoutInput, shouldScroll: embedded }}
|
props={{ object, showCommenInput: !withoutInput, shouldScroll: embedded, focusIndex: 1000 }}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,8 +15,18 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Asset, IntlString, getResource } from '@hcengineering/platform'
|
import { Asset, IntlString, getResource } from '@hcengineering/platform'
|
||||||
import { getClient } from '@hcengineering/presentation'
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { AnySvelteComponent, IconEmoji } from '@hcengineering/ui'
|
import {
|
||||||
import { Button, EmojiPopup, Icon, Spinner, handler, showPopup, tooltip } from '@hcengineering/ui'
|
AnySvelteComponent,
|
||||||
|
Button,
|
||||||
|
EmojiPopup,
|
||||||
|
Icon,
|
||||||
|
IconEmoji,
|
||||||
|
Spinner,
|
||||||
|
handler,
|
||||||
|
registerFocus,
|
||||||
|
showPopup,
|
||||||
|
tooltip
|
||||||
|
} from '@hcengineering/ui'
|
||||||
import { AnyExtension } from '@tiptap/core'
|
import { AnyExtension } from '@tiptap/core'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import { Completion } from '../Completion'
|
import { Completion } from '../Completion'
|
||||||
@ -50,6 +60,7 @@
|
|||||||
export let placeholder: IntlString | undefined = undefined
|
export let placeholder: IntlString | undefined = undefined
|
||||||
export let extraActions: RefAction[] | undefined = undefined
|
export let extraActions: RefAction[] | undefined = undefined
|
||||||
export let loading: boolean = false
|
export let loading: boolean = false
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
let textEditor: TextEditor
|
let textEditor: TextEditor
|
||||||
@ -196,6 +207,24 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Focusable control with index
|
||||||
|
let focused = false
|
||||||
|
export let focusIndex = -1
|
||||||
|
const { idx, focusManager } = registerFocus(focusIndex, {
|
||||||
|
focus: () => {
|
||||||
|
focused = true
|
||||||
|
textEditor.focus()
|
||||||
|
return textEditor.isEditable()
|
||||||
|
},
|
||||||
|
isFocus: () => focused
|
||||||
|
})
|
||||||
|
const updateFocus = () => {
|
||||||
|
if (focusIndex !== -1) {
|
||||||
|
console.trace('focuse')
|
||||||
|
focusManager?.setFocus(idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="ref-container">
|
<div class="ref-container">
|
||||||
@ -292,6 +321,13 @@
|
|||||||
textEditor.clear()
|
textEditor.clear()
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
on:on:blur={() => {
|
||||||
|
focused = false
|
||||||
|
}}
|
||||||
|
on:focus={() => {
|
||||||
|
focused = true
|
||||||
|
updateFocus()
|
||||||
|
}}
|
||||||
extensions={editorExtensions}
|
extensions={editorExtensions}
|
||||||
on:selection-update={updateFormattingState}
|
on:selection-update={updateFormattingState}
|
||||||
on:update
|
on:update
|
||||||
|
@ -86,6 +86,9 @@
|
|||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
let focused = false
|
let focused = false
|
||||||
|
|
||||||
|
export function isFocused (): boolean {
|
||||||
|
return focused
|
||||||
|
}
|
||||||
let needFocus = false
|
let needFocus = false
|
||||||
|
|
||||||
$: if (textEditor && needFocus) {
|
$: if (textEditor && needFocus) {
|
||||||
@ -101,8 +104,9 @@
|
|||||||
export let focusIndex = -1
|
export let focusIndex = -1
|
||||||
const { idx, focusManager } = registerFocus(focusIndex, {
|
const { idx, focusManager } = registerFocus(focusIndex, {
|
||||||
focus: () => {
|
focus: () => {
|
||||||
|
focused = true
|
||||||
focus()
|
focus()
|
||||||
return false
|
return textEditor.isEditable()
|
||||||
},
|
},
|
||||||
isFocus: () => focused
|
isFocus: () => focused
|
||||||
})
|
})
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import { SvelteComponent } from 'svelte'
|
import { ComponentType, SvelteComponent } from 'svelte'
|
||||||
|
|
||||||
export class SvelteRenderer {
|
export class SvelteRenderer {
|
||||||
private readonly component: SvelteComponent
|
private readonly component: SvelteComponent
|
||||||
|
|
||||||
constructor (comp: typeof SvelteComponent, props: any) {
|
constructor (comp: typeof SvelteComponent | ComponentType, props: any) {
|
||||||
const options = { target: document.body, props }
|
const options = { target: document.body, props }
|
||||||
this.component = new (comp as any)(options)
|
this.component = new (comp as any)(options)
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IntlString, translate } from '@hcengineering/platform'
|
import { IntlString, translate } from '@hcengineering/platform'
|
||||||
|
|
||||||
import { AnyExtension, Editor, Extension, HTMLContent } from '@tiptap/core'
|
|
||||||
import type { FocusPosition } from '@tiptap/core'
|
import type { FocusPosition } from '@tiptap/core'
|
||||||
|
import { AnyExtension, Editor, Extension, HTMLContent } from '@tiptap/core'
|
||||||
// import Typography from '@tiptap/extension-typography'
|
// import Typography from '@tiptap/extension-typography'
|
||||||
|
import { Level } from '@tiptap/extension-heading'
|
||||||
import Placeholder from '@tiptap/extension-placeholder'
|
import Placeholder from '@tiptap/extension-placeholder'
|
||||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
||||||
import textEditorPlugin from '../plugin'
|
import textEditorPlugin from '../plugin'
|
||||||
import { FormatMode } from '../types'
|
import { FormatMode } from '../types'
|
||||||
import { defaultExtensions } from './extensions'
|
import { defaultExtensions } from './extensions'
|
||||||
import { Level } from '@tiptap/extension-heading'
|
|
||||||
|
|
||||||
export let content: string = ''
|
export let content: string = ''
|
||||||
export let placeholder: IntlString = textEditorPlugin.string.EditorPlaceholder
|
export let placeholder: IntlString = textEditorPlugin.string.EditorPlaceholder
|
||||||
|
@ -14,16 +14,16 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { afterUpdate, createEventDispatcher } from 'svelte'
|
import { afterUpdate, createEventDispatcher } from 'svelte'
|
||||||
|
import { deviceOptionsStore as deviceInfo } from '../../'
|
||||||
import { resizeObserver } from '../resize'
|
import { resizeObserver } from '../resize'
|
||||||
import Button from './Button.svelte'
|
import Button from './Button.svelte'
|
||||||
|
import Scroller from './Scroller.svelte'
|
||||||
import IconClose from './icons/Close.svelte'
|
import IconClose from './icons/Close.svelte'
|
||||||
import IconDetails from './icons/Details.svelte'
|
import IconDetails from './icons/Details.svelte'
|
||||||
|
import IconMaxWidth from './icons/MaxWidth.svelte'
|
||||||
|
import IconMinWidth from './icons/MinWidth.svelte'
|
||||||
import IconScale from './icons/Scale.svelte'
|
import IconScale from './icons/Scale.svelte'
|
||||||
import IconScaleFull from './icons/ScaleFull.svelte'
|
import IconScaleFull from './icons/ScaleFull.svelte'
|
||||||
import IconMinWidth from './icons/MinWidth.svelte'
|
|
||||||
import IconMaxWidth from './icons/MaxWidth.svelte'
|
|
||||||
import Scroller from './Scroller.svelte'
|
|
||||||
import { deviceOptionsStore as deviceInfo } from '../../'
|
|
||||||
|
|
||||||
export let innerWidth: number = 0
|
export let innerWidth: number = 0
|
||||||
export let panelWidth: number = 0
|
export let panelWidth: number = 0
|
||||||
@ -93,6 +93,7 @@
|
|||||||
<div class="popupPanel-title {twoRows && !withoutTitle ? 'row-top' : 'row'}">
|
<div class="popupPanel-title {twoRows && !withoutTitle ? 'row-top' : 'row'}">
|
||||||
{#if allowClose && !embedded}
|
{#if allowClose && !embedded}
|
||||||
<Button
|
<Button
|
||||||
|
focusIndex={10000}
|
||||||
icon={IconClose}
|
icon={IconClose}
|
||||||
kind={'transparent'}
|
kind={'transparent'}
|
||||||
size={'medium'}
|
size={'medium'}
|
||||||
@ -114,6 +115,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if $$slots.aside && isAside}
|
{#if $$slots.aside && isAside}
|
||||||
<Button
|
<Button
|
||||||
|
focusIndex={10008}
|
||||||
icon={IconDetails}
|
icon={IconDetails}
|
||||||
kind={'transparent'}
|
kind={'transparent'}
|
||||||
size={'medium'}
|
size={'medium'}
|
||||||
@ -125,6 +127,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if useMaxWidth !== undefined}
|
{#if useMaxWidth !== undefined}
|
||||||
<Button
|
<Button
|
||||||
|
focusIndex={10009}
|
||||||
icon={useMaxWidth ? IconMaxWidth : IconMinWidth}
|
icon={useMaxWidth ? IconMaxWidth : IconMinWidth}
|
||||||
kind={'transparent'}
|
kind={'transparent'}
|
||||||
size={'medium'}
|
size={'medium'}
|
||||||
@ -137,6 +140,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if isFullSize}
|
{#if isFullSize}
|
||||||
<Button
|
<Button
|
||||||
|
focusIndex={100010}
|
||||||
icon={fullSize ? IconScale : IconScaleFull}
|
icon={fullSize ? IconScale : IconScaleFull}
|
||||||
kind={'transparent'}
|
kind={'transparent'}
|
||||||
size={'medium'}
|
size={'medium'}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
export let showCommenInput: boolean = true
|
export let showCommenInput: boolean = true
|
||||||
export let transparent: boolean = false
|
export let transparent: boolean = false
|
||||||
export let shouldScroll: boolean = false
|
export let shouldScroll: boolean = false
|
||||||
|
export let focusIndex: number = -1
|
||||||
|
|
||||||
getResource(notification.function.GetNotificationClient).then((res) => {
|
getResource(notification.function.GetNotificationClient).then((res) => {
|
||||||
updatesStore = res().docUpdatesStore
|
updatesStore = res().docUpdatesStore
|
||||||
@ -134,7 +135,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{#if showCommenInput}
|
{#if showCommenInput}
|
||||||
<div class="ref-input">
|
<div class="ref-input">
|
||||||
<Component is={chunter.component.CommentInput} props={{ object }} />
|
<Component is={chunter.component.CommentInput} props={{ object, focusIndex }} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
export let shouldSaveDraft: boolean = false
|
export let shouldSaveDraft: boolean = false
|
||||||
export let attachments: IdMap<Attachment> = new Map()
|
export let attachments: IdMap<Attachment> = new Map()
|
||||||
export let loading = false
|
export let loading = false
|
||||||
|
export let focusIndex: number = -1
|
||||||
export function submit (): void {
|
export function submit (): void {
|
||||||
refInput.submit()
|
refInput.submit()
|
||||||
}
|
}
|
||||||
@ -278,6 +279,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<ReferenceInput
|
<ReferenceInput
|
||||||
|
{focusIndex}
|
||||||
bind:this={refInput}
|
bind:this={refInput}
|
||||||
{content}
|
{content}
|
||||||
{iconSend}
|
{iconSend}
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
export let refContainer: HTMLElement | undefined = undefined
|
export let refContainer: HTMLElement | undefined = undefined
|
||||||
export let shouldSaveDraft: boolean = false
|
export let shouldSaveDraft: boolean = false
|
||||||
export let useAttachmentPreview = false
|
export let useAttachmentPreview = false
|
||||||
export let focusIndex: number | undefined = undefined
|
export let focusIndex: number | undefined = -1
|
||||||
|
|
||||||
let draftKey = objectId ? `${objectId}_attachments` : undefined
|
let draftKey = objectId ? `${objectId}_attachments` : undefined
|
||||||
$: draftKey = objectId ? `${objectId}_attachments` : undefined
|
$: draftKey = objectId ? `${objectId}_attachments` : undefined
|
||||||
@ -50,6 +50,9 @@
|
|||||||
export function focus (): void {
|
export function focus (): void {
|
||||||
refInput.focus()
|
refInput.focus()
|
||||||
}
|
}
|
||||||
|
export function isFocused (): boolean {
|
||||||
|
return refInput.isFocused()
|
||||||
|
}
|
||||||
export function isEditable (): boolean {
|
export function isEditable (): boolean {
|
||||||
return refInput.isEditable()
|
return refInput.isEditable()
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
export let object: Doc
|
export let object: Doc
|
||||||
export let shouldSaveDraft: boolean = true
|
export let shouldSaveDraft: boolean = true
|
||||||
|
export let focusIndex: number = -1
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const _class = chunter.class.Comment
|
const _class = chunter.class.Comment
|
||||||
@ -108,6 +109,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<AttachmentRefInput
|
<AttachmentRefInput
|
||||||
|
{focusIndex}
|
||||||
bind:this={commentInputBox}
|
bind:this={commentInputBox}
|
||||||
bind:content={inputContent}
|
bind:content={inputContent}
|
||||||
{_class}
|
{_class}
|
||||||
|
@ -24,15 +24,17 @@
|
|||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
EditBox,
|
EditBox,
|
||||||
|
FocusHandler,
|
||||||
IconMixin,
|
IconMixin,
|
||||||
IconMoreH,
|
IconMoreH,
|
||||||
Label,
|
Label,
|
||||||
Spinner,
|
Spinner,
|
||||||
|
createFocusManager,
|
||||||
getCurrentResolvedLocation,
|
getCurrentResolvedLocation,
|
||||||
navigate,
|
navigate,
|
||||||
showPopup
|
showPopup
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import { ContextMenu, DocNavLink, UpDownNavigator } from '@hcengineering/view-resources'
|
import { ActionContext, ContextMenu, DocNavLink, UpDownNavigator } from '@hcengineering/view-resources'
|
||||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
||||||
import { generateIssueShortLink, getIssueId } from '../../../issues'
|
import { generateIssueShortLink, getIssueId } from '../../../issues'
|
||||||
import tracker from '../../../plugin'
|
import tracker from '../../../plugin'
|
||||||
@ -139,8 +141,23 @@
|
|||||||
onMount(() => {
|
onMount(() => {
|
||||||
dispatch('open', { ignoreKeys: ['comments', 'name', 'description', 'number'] })
|
dispatch('open', { ignoreKeys: ['comments', 'name', 'description', 'number'] })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const manager = createFocusManager()
|
||||||
|
export function canClose (): boolean {
|
||||||
|
if (descriptionBox.isFocused()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<FocusHandler {manager} />
|
||||||
|
<ActionContext
|
||||||
|
context={{
|
||||||
|
mode: 'editor'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
{#if issue !== undefined}
|
{#if issue !== undefined}
|
||||||
<Panel
|
<Panel
|
||||||
object={issue}
|
object={issue}
|
||||||
@ -181,10 +198,17 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<EditBox bind:value={title} placeholder={tracker.string.IssueTitlePlaceholder} kind="large-style" on:blur={save} />
|
<EditBox
|
||||||
|
focusIndex={1}
|
||||||
|
bind:value={title}
|
||||||
|
placeholder={tracker.string.IssueTitlePlaceholder}
|
||||||
|
kind="large-style"
|
||||||
|
on:blur={save}
|
||||||
|
/>
|
||||||
<div class="w-full mt-6">
|
<div class="w-full mt-6">
|
||||||
{#key issue._id}
|
{#key issue._id}
|
||||||
<AttachmentStyledBox
|
<AttachmentStyledBox
|
||||||
|
focusIndex={30}
|
||||||
bind:this={descriptionBox}
|
bind:this={descriptionBox}
|
||||||
useAttachmentPreview={true}
|
useAttachmentPreview={true}
|
||||||
objectId={_id}
|
objectId={_id}
|
||||||
@ -207,7 +231,12 @@
|
|||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
{#key issue._id && currentProject !== undefined}
|
{#key issue._id && currentProject !== undefined}
|
||||||
{#if currentProject !== undefined}
|
{#if currentProject !== undefined}
|
||||||
<SubIssues {issue} shouldSaveDraft projects={new Map([[currentProject?._id, currentProject]])} />
|
<SubIssues
|
||||||
|
focusIndex={50}
|
||||||
|
{issue}
|
||||||
|
shouldSaveDraft
|
||||||
|
projects={new Map([[currentProject?._id, currentProject]])}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
{/key}
|
{/key}
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Doc, DocumentQuery, Ref } from '@hcengineering/core'
|
import { Doc, DocumentQuery, Ref } from '@hcengineering/core'
|
||||||
import { Issue, Project } from '@hcengineering/tracker'
|
import { Issue, Project } from '@hcengineering/tracker'
|
||||||
|
import { registerFocus } from '@hcengineering/ui'
|
||||||
import { ViewOptions, Viewlet } from '@hcengineering/view'
|
import { ViewOptions, Viewlet } from '@hcengineering/view'
|
||||||
import {
|
import {
|
||||||
ActionContext,
|
ActionContext,
|
||||||
@ -42,6 +43,25 @@
|
|||||||
list?.select(offset, of)
|
list?.select(offset, of)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
let docs: Doc[] = []
|
||||||
|
function select () {
|
||||||
|
listProvider.update(docs)
|
||||||
|
listProvider.updateFocus(docs[0])
|
||||||
|
list?.select(0, undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Focusable control with index
|
||||||
|
let focused = false
|
||||||
|
export let focusIndex = -1
|
||||||
|
registerFocus(focusIndex, {
|
||||||
|
focus: () => {
|
||||||
|
;(window.document.activeElement as HTMLElement).blur()
|
||||||
|
focused = true
|
||||||
|
select()
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
isFocus: () => focused
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ActionContext
|
<ActionContext
|
||||||
@ -70,6 +90,7 @@
|
|||||||
listProvider.updateSelection(event.detail.docs, event.detail.value)
|
listProvider.updateSelection(event.detail.docs, event.detail.value)
|
||||||
}}
|
}}
|
||||||
on:content={(evt) => {
|
on:content={(evt) => {
|
||||||
|
docs = evt.detail
|
||||||
listProvider.update(evt.detail)
|
listProvider.update(evt.detail)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -70,6 +70,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: viewOptions = viewlet !== undefined ? getViewOptions(viewlet, $viewOptionStore) : undefined
|
$: viewOptions = viewlet !== undefined ? getViewOptions(viewlet, $viewOptionStore) : undefined
|
||||||
|
|
||||||
|
export let focusIndex = -1
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
@ -139,7 +141,13 @@
|
|||||||
{#if !isCollapsed}
|
{#if !isCollapsed}
|
||||||
<ExpandCollapse isExpanded={!isCollapsed}>
|
<ExpandCollapse isExpanded={!isCollapsed}>
|
||||||
<div class="list" class:collapsed={isCollapsed}>
|
<div class="list" class:collapsed={isCollapsed}>
|
||||||
<SubIssueList projects={_projects} {viewlet} {viewOptions} query={{ attachedTo: issue._id }} />
|
<SubIssueList
|
||||||
|
focusIndex={focusIndex === -1 ? -1 : focusIndex + 1}
|
||||||
|
projects={_projects}
|
||||||
|
{viewlet}
|
||||||
|
{viewOptions}
|
||||||
|
query={{ attachedTo: issue._id }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</ExpandCollapse>
|
</ExpandCollapse>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -156,11 +156,12 @@ async function Open (
|
|||||||
| undefined
|
| undefined
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
|
const d = Array.isArray(doc) ? doc[0] : doc
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
const panelComponent = hierarchy.classHierarchyMixin(doc._class, view.mixin.ObjectPanel)
|
const panelComponent = hierarchy.classHierarchyMixin(d._class, view.mixin.ObjectPanel)
|
||||||
const component = props?.component ?? panelComponent?.component ?? view.component.EditDoc
|
const component = props?.component ?? panelComponent?.component ?? view.component.EditDoc
|
||||||
const loc = await getObjectLinkFragment(hierarchy, doc, {}, component)
|
const loc = await getObjectLinkFragment(hierarchy, d, {}, component)
|
||||||
navigate(loc)
|
navigate(loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,15 +181,12 @@ function ShowPanel (
|
|||||||
rightSection?: AnyComponent
|
rightSection?: AnyComponent
|
||||||
}
|
}
|
||||||
): void {
|
): void {
|
||||||
if (Array.isArray(doc)) {
|
const d = Array.isArray(doc) ? doc[0] : doc
|
||||||
console.error('Wrong show Panel parameters')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
showPanel(
|
showPanel(
|
||||||
props.component ?? view.component.EditDoc,
|
props.component ?? view.component.EditDoc,
|
||||||
doc._id,
|
d._id,
|
||||||
Hierarchy.mixinOrClass(doc),
|
Hierarchy.mixinOrClass(d),
|
||||||
props.element ?? 'content',
|
props.element ?? 'content',
|
||||||
props.rightSection
|
props.rightSection
|
||||||
)
|
)
|
||||||
|
@ -39,9 +39,22 @@
|
|||||||
$: select(undefined, 0, element, 'vertical')
|
$: select(undefined, 0, element, 'vertical')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button icon={IconDownOutline} kind={'secondary'} size={'medium'} on:click={(evt) => next(evt, true)} />
|
|
||||||
<Button icon={IconUpOutline} kind={'secondary'} size={'medium'} on:click={(evt) => next(evt, false)} />
|
|
||||||
<Button
|
<Button
|
||||||
|
focusIndex={10005}
|
||||||
|
icon={IconDownOutline}
|
||||||
|
kind={'secondary'}
|
||||||
|
size={'medium'}
|
||||||
|
on:click={(evt) => next(evt, true)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
focusIndex={10006}
|
||||||
|
icon={IconUpOutline}
|
||||||
|
kind={'secondary'}
|
||||||
|
size={'medium'}
|
||||||
|
on:click={(evt) => next(evt, false)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
focusIndex={10007}
|
||||||
showTooltip={{ label: ui.string.Back, direction: 'bottom' }}
|
showTooltip={{ label: ui.string.Back, direction: 'bottom' }}
|
||||||
icon={IconNavPrev}
|
icon={IconNavPrev}
|
||||||
kind={'secondary'}
|
kind={'secondary'}
|
||||||
|
Loading…
Reference in New Issue
Block a user