mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-27 10:49:44 +00:00
Keyboard edit action (#1487)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
04ed6e0e25
commit
299d9a9541
@ -289,6 +289,9 @@ export function createModel (builder: Builder): void {
|
|||||||
singleInput: true
|
singleInput: true
|
||||||
})
|
})
|
||||||
actionTarget(builder, view.action.ShowPreview, core.class.Doc, { mode: 'browser' })
|
actionTarget(builder, view.action.ShowPreview, core.class.Doc, { mode: 'browser' })
|
||||||
|
|
||||||
|
createAction(builder, view.action.Edit, view.string.Edit, view.actionImpl.Edit, { keyBinding: ['Enter'], singleInput: true })
|
||||||
|
actionTarget(builder, view.action.Edit, core.class.Doc, { mode: ['browser', 'context'] })
|
||||||
}
|
}
|
||||||
|
|
||||||
export default view
|
export default view
|
||||||
|
@ -34,7 +34,10 @@ export default mergeIds(viewId, view, {
|
|||||||
SelectDown: '' as Ref<Action>,
|
SelectDown: '' as Ref<Action>,
|
||||||
|
|
||||||
ShowPreview: '' as Ref<Action>,
|
ShowPreview: '' as Ref<Action>,
|
||||||
ShowActions: '' as Ref<Action>
|
ShowActions: '' as Ref<Action>,
|
||||||
|
|
||||||
|
// Edit document
|
||||||
|
Edit: '' as Ref<Action>
|
||||||
},
|
},
|
||||||
actionImpl: {
|
actionImpl: {
|
||||||
Delete: '' as ViewAction,
|
Delete: '' as ViewAction,
|
||||||
@ -51,7 +54,9 @@ export default mergeIds(viewId, view, {
|
|||||||
SelectDown: '' as ViewAction,
|
SelectDown: '' as ViewAction,
|
||||||
|
|
||||||
ShowPreview: '' as ViewAction,
|
ShowPreview: '' as ViewAction,
|
||||||
ShowActions: '' as ViewAction
|
ShowActions: '' as ViewAction,
|
||||||
|
|
||||||
|
Edit: '' as ViewAction
|
||||||
},
|
},
|
||||||
component: {
|
component: {
|
||||||
StringEditor: '' as AnyComponent,
|
StringEditor: '' as AnyComponent,
|
||||||
@ -84,6 +89,7 @@ export default mergeIds(viewId, view, {
|
|||||||
SelectUp: '' as IntlString,
|
SelectUp: '' as IntlString,
|
||||||
SelectDown: '' as IntlString,
|
SelectDown: '' as IntlString,
|
||||||
ShowPreview: '' as IntlString,
|
ShowPreview: '' as IntlString,
|
||||||
ShowActions: '' as IntlString
|
ShowActions: '' as IntlString,
|
||||||
|
Edit: '' as IntlString
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -32,18 +32,26 @@
|
|||||||
|
|
||||||
let innerWidth = 0
|
let innerWidth = 0
|
||||||
|
|
||||||
$: allowFullSize = innerWidth > 900 && position === 'full'
|
$: allowFullSize = innerWidth > 900 && (position === 'full' || position === 'content')
|
||||||
$: isFullSize = allowFullSize && fullSize
|
$: isFullSize = allowFullSize && fullSize
|
||||||
</script>
|
</script>
|
||||||
<svelte:window bind:innerWidth />
|
|
||||||
<Panel {title} {subtitle} {icon} on:close rightSection={isFullSize}>
|
<Panel {title} {subtitle} {icon} on:close rightSection={isFullSize} bind:innerWidth>
|
||||||
<svelte:fragment slot="subtitle">
|
<svelte:fragment slot="subtitle">
|
||||||
<slot name="subtitle" />
|
<slot name="subtitle" />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot='navigate-actions'>
|
||||||
|
<slot name='navigate-actions'/>
|
||||||
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="commands">
|
<svelte:fragment slot="commands">
|
||||||
<Component is={calendar.component.DocReminder} props={{ value: object, title }} />
|
<div class='flex-row-center'>
|
||||||
<div class="ml-2">
|
<slot name="actions" />
|
||||||
<Component is={notification.component.LastViewEditor} props={{ value: object }} />
|
</div>
|
||||||
|
<div class='flex-row-center flex-grow gap-2'>
|
||||||
|
<Component is={calendar.component.DocReminder} props={{ value: object, title }} />
|
||||||
|
<div class="ml-2">
|
||||||
|
<Component is={notification.component.LastViewEditor} props={{ value: object }} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
||||||
@ -77,4 +85,3 @@
|
|||||||
</Component>
|
</Component>
|
||||||
{/if}
|
{/if}
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
}
|
}
|
||||||
&.mirror {
|
&.mirror {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 2.5rem;
|
padding: 0 0.5rem;
|
||||||
|
|
||||||
&-tool {
|
&-tool {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
top: 1.375rem;
|
top: 1.375rem;
|
||||||
right: 2rem;
|
right: 2rem;
|
||||||
&.grow-reverse {
|
&.grow-reverse {
|
||||||
left: 0px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
@ -26,16 +26,28 @@
|
|||||||
export let rightSection: boolean = false
|
export let rightSection: boolean = false
|
||||||
export let reverseCommands = false
|
export let reverseCommands = false
|
||||||
export let showHeader = true
|
export let showHeader = true
|
||||||
|
export let innerWidth: number = 0
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="antiPanel antiComponent">
|
<div class="antiPanel antiComponent" bind:clientWidth={innerWidth}>
|
||||||
<div class:panel-content={!rightSection} class:ad-section-50={rightSection} class:divide={rightSection}>
|
<div class:panel-content={!rightSection} class:ad-section-50={rightSection} class:divide={rightSection}>
|
||||||
{#if showHeader}
|
{#if showHeader}
|
||||||
<div class="ac-header short mirror divide">
|
<div class="ac-header short mirror divide">
|
||||||
<div class="ac-header__wrap-title">
|
<div class="tool flex-row-center">
|
||||||
|
<ActionIcon
|
||||||
|
icon={IconClose}
|
||||||
|
size={'medium'}
|
||||||
|
action={() => {
|
||||||
|
dispatch('close')
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
{#if $$slots['navigate-actions']}
|
||||||
|
<slot name="navigate-actions" />
|
||||||
|
{/if}
|
||||||
|
<div class="ac-header__wrap-title flex-grow">
|
||||||
{#if icon}
|
{#if icon}
|
||||||
<div class="ac-header__icon">
|
<div class="ac-header__icon">
|
||||||
<Icon {icon} size={'large'} />
|
<Icon {icon} size={'large'} />
|
||||||
@ -52,6 +64,20 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="ac-header short mirror divide">
|
||||||
|
<div class="tool flex-row-center">
|
||||||
|
<ActionIcon
|
||||||
|
icon={IconClose}
|
||||||
|
size={'medium'}
|
||||||
|
action={() => {
|
||||||
|
dispatch('close')
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
{#if $$slots['navigate-actions']}
|
||||||
|
<slot name="navigate-actions" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $$slots.subtitle}
|
{#if $$slots.subtitle}
|
||||||
<div class="ac-subtitle">
|
<div class="ac-subtitle">
|
||||||
@ -69,21 +95,13 @@
|
|||||||
<slot name="rightSection" />
|
<slot name="rightSection" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="ad-tools" class:grow-reverse={reverseCommands}>
|
<div class="ad-tools flex-row-center flex-grow h-4" class:grow-reverse={reverseCommands}>
|
||||||
{#if !rightSection && $$slots.commands}
|
{#if !rightSection && $$slots.commands}
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<slot name="commands" />
|
<slot name="commands" />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<slot name="actions" />
|
<slot name="actions" />
|
||||||
<div class="tool">
|
|
||||||
<ActionIcon
|
|
||||||
icon={IconClose}
|
|
||||||
size={'medium'}
|
|
||||||
action={() => {
|
|
||||||
dispatch('close')
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -70,6 +70,9 @@
|
|||||||
afterUpdate(() => {
|
afterUpdate(() => {
|
||||||
if (props) fitPopup(props, contentPanel)
|
if (props) fitPopup(props, contentPanel)
|
||||||
})
|
})
|
||||||
|
export function fitPopupInstance (): void {
|
||||||
|
if (props) fitPopup(props, contentPanel)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window
|
<svelte:window
|
||||||
|
@ -189,9 +189,9 @@ export function fitPopupElement (modalHTML: HTMLElement, element?: PopupAlignmen
|
|||||||
} else if (element === 'content' && contentPanel !== undefined) {
|
} else if (element === 'content' && contentPanel !== undefined) {
|
||||||
const rect = contentPanel.getBoundingClientRect()
|
const rect = contentPanel.getBoundingClientRect()
|
||||||
modalHTML.style.top = `calc(${rect.top}px)`
|
modalHTML.style.top = `calc(${rect.top}px)`
|
||||||
modalHTML.style.height = `${rect.height}px`
|
modalHTML.style.height = `${Math.min(rect.height, window.innerHeight - rect.top)}px`
|
||||||
modalHTML.style.left = `calc(${rect.left}px)`
|
modalHTML.style.left = `calc(${rect.left}px)`
|
||||||
modalHTML.style.width = `${rect.width}px`
|
modalHTML.style.width = `${Math.min(rect.width, window.innerWidth - rect.left)}px`
|
||||||
} else if (element === 'middle') {
|
} else if (element === 'middle') {
|
||||||
if (contentPanel !== undefined) {
|
if (contentPanel !== undefined) {
|
||||||
const rect = contentPanel.getBoundingClientRect()
|
const rect = contentPanel.getBoundingClientRect()
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<a
|
<a
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'full')}"
|
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'content')}"
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={board.icon.Board} size={'small'} />
|
<Icon icon={board.icon.Board} size={'small'} />
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<a
|
<a
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'full')}"
|
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'content')}"
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={board.icon.Card} size={'small'} />
|
<Icon icon={board.icon.Card} size={'small'} />
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
$: persons = Array.isArray(value) ? value : [value]
|
$: persons = Array.isArray(value) ? value : [value]
|
||||||
|
|
||||||
async function onClick (p: Person) {
|
async function onClick (p: Person) {
|
||||||
showPanel(view.component.EditDoc, p._id, Hierarchy.mixinOrClass(p), 'full')
|
showPanel(view.component.EditDoc, p._id, Hierarchy.mixinOrClass(p), 'content')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
export let value: Reminder
|
export let value: Reminder
|
||||||
|
|
||||||
function click (): void {
|
function click (): void {
|
||||||
showPanel(view.component.EditDoc, value._id, value._class, 'full')
|
showPanel(view.component.EditDoc, value._id, value._class, 'content')
|
||||||
}
|
}
|
||||||
|
|
||||||
const objectPresenter = getResource(view.component.ObjectPresenter)
|
const objectPresenter = getResource(view.component.ObjectPresenter)
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function click (event: Event): void {
|
function click (event: Event): void {
|
||||||
showPanel(view.component.EditDoc, event._id, event._class, 'full')
|
showPanel(view.component.EditDoc, event._id, event._class, 'content')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
async function onClick () {
|
async function onClick () {
|
||||||
if (employee !== undefined) {
|
if (employee !== undefined) {
|
||||||
showPopup(EditDoc, { _id: employee._id, _class: employee._class }, 'full')
|
showPopup(EditDoc, { _id: employee._id, _class: employee._class }, 'content')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<a
|
<a
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'full')}"
|
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'content')}"
|
||||||
>
|
>
|
||||||
<div class="icon circle"><Company size={'small'} /></div>
|
<div class="icon circle"><Company size={'small'} /></div>
|
||||||
<span class="label">{value.name}</span>
|
<span class="label">{value.name}</span>
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<a
|
<a
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
href="#{getPanelURI(view.component.EditDoc, value._id, Hierarchy.mixinOrClass(value), 'full')}"
|
href="#{getPanelURI(view.component.EditDoc, value._id, Hierarchy.mixinOrClass(value), 'content')}"
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Avatar size={avatarSize} avatar={value?.avatar} />
|
<Avatar size={avatarSize} avatar={value?.avatar} />
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<a
|
<a
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'full')}"
|
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'content')}"
|
||||||
>
|
>
|
||||||
<div class="icon"><Icon icon={inventory.icon.Products} size={'small'} /></div>
|
<div class="icon"><Icon icon={inventory.icon.Products} size={'small'} /></div>
|
||||||
<span class="label">{value.name}</span>
|
<span class="label">{value.name}</span>
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showLead () {
|
function showLead () {
|
||||||
showPanel(view.component.EditDoc, object._id, object._class, 'full')
|
showPanel(view.component.EditDoc, object._id, object._class, 'content')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<a
|
<a
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'full')}"
|
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'content')}"
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={lead.icon.Lead} size={'small'} />
|
<Icon icon={lead.icon.Lead} size={'small'} />
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<a
|
<a
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'full')}"
|
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'content')}"
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={recruit.icon.Application} size={'small'} />
|
<Icon icon={recruit.icon.Application} size={'small'} />
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
<Avatar avatar={candidate.avatar} size={'large'} />
|
<Avatar avatar={candidate.avatar} size={'large'} />
|
||||||
{#if candidate}
|
{#if candidate}
|
||||||
<div class="name lines-limit-2" class:over-underline={!disabled} on:click={() => {
|
<div class="name lines-limit-2" class:over-underline={!disabled} on:click={() => {
|
||||||
if (!disabled) showPanel(view.component.EditDoc, candidate._id, candidate._class, 'full')
|
if (!disabled) showPanel(view.component.EditDoc, candidate._id, candidate._class, 'content')
|
||||||
}}>{formatName(candidate.name)}</div>
|
}}>{formatName(candidate.name)}</div>
|
||||||
<div class="description lines-limit-2">{candidate.title ?? ''}</div>
|
<div class="description lines-limit-2">{candidate.title ?? ''}</div>
|
||||||
<div class="description overflow-label">{candidate.city ?? ''}</div>
|
<div class="description overflow-label">{candidate.city ?? ''}</div>
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
import { Avatar } from '@anticrm/presentation'
|
import { Avatar } from '@anticrm/presentation'
|
||||||
import type { Applicant } from '@anticrm/recruit'
|
import type { Applicant } from '@anticrm/recruit'
|
||||||
import task, { TodoItem } from '@anticrm/task'
|
import task, { TodoItem } from '@anticrm/task'
|
||||||
import { ActionIcon, Component, IconMoreH, showPanel, Tooltip } from '@anticrm/ui'
|
import { Component, showPanel, Tooltip } from '@anticrm/ui'
|
||||||
import view from '@anticrm/view'
|
import view from '@anticrm/view'
|
||||||
import ApplicationPresenter from './ApplicationPresenter.svelte'
|
import ApplicationPresenter from './ApplicationPresenter.svelte'
|
||||||
|
|
||||||
@ -29,7 +29,7 @@
|
|||||||
export let dragged: boolean
|
export let dragged: boolean
|
||||||
|
|
||||||
function showCandidate () {
|
function showCandidate () {
|
||||||
showPanel(view.component.EditDoc, object.attachedTo, object.attachedToClass, 'full')
|
showPanel(view.component.EditDoc, object.attachedTo, object.attachedToClass, 'content')
|
||||||
}
|
}
|
||||||
|
|
||||||
$: todoItems = (object.$lookup?.todoItems as TodoItem[]) ?? []
|
$: todoItems = (object.$lookup?.todoItems as TodoItem[]) ?? []
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
/>
|
/>
|
||||||
<div class="clear-mins" on:click={() => {
|
<div class="clear-mins" on:click={() => {
|
||||||
if (candidate !== undefined) {
|
if (candidate !== undefined) {
|
||||||
showPanel(view.component.EditDoc, candidate._id, candidate._class, 'full')
|
showPanel(view.component.EditDoc, candidate._id, candidate._class, 'content')
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
<UserBox
|
<UserBox
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
$: persons = Array.isArray(value) ? value : [value]
|
$: persons = Array.isArray(value) ? value : [value]
|
||||||
|
|
||||||
async function onClick (p: Person) {
|
async function onClick (p: Person) {
|
||||||
showPanel(view.component.EditDoc, p._id, Hierarchy.mixinOrClass(p), 'full')
|
showPanel(view.component.EditDoc, p._id, Hierarchy.mixinOrClass(p), 'content')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
<a
|
<a
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'right')}"
|
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'content')}"
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={recruit.icon.Application} size={'small'} />
|
<Icon icon={recruit.icon.Application} size={'small'} />
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<a
|
<a
|
||||||
class="flex-presenter"
|
class="flex-presenter"
|
||||||
class:inline-presenter={inline}
|
class:inline-presenter={inline}
|
||||||
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'full')}"
|
href="#{getPanelURI(view.component.EditDoc, value._id, value._class, 'content')}"
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={task.icon.Task} size={'small'} />
|
<Icon icon={task.icon.Task} size={'small'} />
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
<IssuePresenter value={object} {currentTeam} />
|
<IssuePresenter value={object} {currentTeam} />
|
||||||
{/if}
|
{/if}
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="actions">
|
<svelte:fragment slot="navigate-actions">
|
||||||
<div class="tool flex gap-1">
|
<div class="tool flex gap-1">
|
||||||
<Button icon={IconDown}/>
|
<Button icon={IconDown}/>
|
||||||
<Button icon={IconUp}/>
|
<Button icon={IconUp}/>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Doc } from '@anticrm/core'
|
import { Doc, Hierarchy } from '@anticrm/core'
|
||||||
import { getClient, MessageBox } from '@anticrm/presentation'
|
import { getClient, MessageBox } from '@anticrm/presentation'
|
||||||
import { showPopup } from '@anticrm/ui'
|
import { showPanel, showPopup } from '@anticrm/ui'
|
||||||
import MoveView from './components/Move.svelte'
|
import MoveView from './components/Move.svelte'
|
||||||
import view from './plugin'
|
import view from './plugin'
|
||||||
import { FocusSelection, focusStore, SelectDirection, selectionStore, previewDocument } from './selection'
|
import { FocusSelection, focusStore, SelectDirection, selectionStore, previewDocument } from './selection'
|
||||||
@ -37,6 +37,10 @@ focusStore.subscribe((it) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function selPrev (doc: Doc | undefined, evt: Event, dir: SelectDirection): void {
|
function selPrev (doc: Doc | undefined, evt: Event, dir: SelectDirection): void {
|
||||||
|
selectPrevItem(dir)
|
||||||
|
evt.preventDefault()
|
||||||
|
}
|
||||||
|
export function selectPrevItem (dir: SelectDirection): void {
|
||||||
if ($focusStore.provider?.prev !== undefined) {
|
if ($focusStore.provider?.prev !== undefined) {
|
||||||
$focusStore.provider?.prev(dir)
|
$focusStore.provider?.prev(dir)
|
||||||
previewDocument.update(old => {
|
previewDocument.update(old => {
|
||||||
@ -44,10 +48,15 @@ function selPrev (doc: Doc | undefined, evt: Event, dir: SelectDirection): void
|
|||||||
return $focusStore.focus
|
return $focusStore.focus
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
evt.preventDefault()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selNext (doc: Doc|undefined, evt: Event, dir: SelectDirection): void {
|
function selNext (doc: Doc|undefined, evt: Event, dir: SelectDirection): void {
|
||||||
|
selectNextItem(dir)
|
||||||
|
evt.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectNextItem (dir: SelectDirection): void {
|
||||||
if ($focusStore.provider?.next !== undefined) {
|
if ($focusStore.provider?.next !== undefined) {
|
||||||
$focusStore.provider?.next(dir)
|
$focusStore.provider?.next(dir)
|
||||||
previewDocument.update(old => {
|
previewDocument.update(old => {
|
||||||
@ -55,7 +64,6 @@ function selNext (doc: Doc|undefined, evt: Event, dir: SelectDirection): void {
|
|||||||
return $focusStore.focus
|
return $focusStore.focus
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
evt.preventDefault()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +111,12 @@ function ShowPreview (doc: Doc | undefined, evt: Event): void {
|
|||||||
})
|
})
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Edit (doc: Doc, evt: Event): void {
|
||||||
|
evt.preventDefault()
|
||||||
|
showPanel(view.component.EditDoc, doc._id, Hierarchy.mixinOrClass(doc), 'content')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -117,5 +131,6 @@ export const actionImpl = {
|
|||||||
SelectItemNone,
|
SelectItemNone,
|
||||||
SelectItemAll,
|
SelectItemAll,
|
||||||
ShowActions,
|
ShowActions,
|
||||||
ShowPreview
|
ShowPreview,
|
||||||
|
Edit
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import { ViewContext } from '@anticrm/view'
|
import { ViewContext } from '@anticrm/view'
|
||||||
import { onDestroy } from 'svelte'
|
import { onDestroy } from 'svelte'
|
||||||
import { contextStore } from '../context'
|
import { contextStore } from '../context'
|
||||||
import { previewDocument } from '../selection';
|
import { previewDocument } from '../selection'
|
||||||
|
|
||||||
export let context: ViewContext
|
export let context: ViewContext
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
async function handleKeys (evt: KeyboardEvent): Promise<void> {
|
async function handleKeys (evt: KeyboardEvent): Promise<void> {
|
||||||
const targetTagName = (evt.target as any)?.tagName?.toLowerCase()
|
const targetTagName = (evt.target as any)?.tagName?.toLowerCase()
|
||||||
if (targetTagName === 'input' || targetTagName === 'button' || targetTagName === 'textarea') {
|
if (targetTagName === 'input' || targetTagName === 'button' || targetTagName === 'textarea') {
|
||||||
|
console.log('no keyboard because', targetTagName, evt.target)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lastKey = evt
|
lastKey = evt
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
getClient,
|
getClient,
|
||||||
KeyedAttribute
|
KeyedAttribute
|
||||||
} from '@anticrm/presentation'
|
} from '@anticrm/presentation'
|
||||||
import { AnyComponent, Component, Label, PopupAlignment } from '@anticrm/ui'
|
import { AnyComponent, Button, Component, IconDown, IconUp, Label, PopupAlignment, showPanel } from '@anticrm/ui'
|
||||||
import view from '@anticrm/view'
|
import view from '@anticrm/view'
|
||||||
import { createEventDispatcher, onDestroy } from 'svelte'
|
import { createEventDispatcher, onDestroy } from 'svelte'
|
||||||
import ActionContext from './ActionContext.svelte'
|
import ActionContext from './ActionContext.svelte'
|
||||||
import { getCollectionCounter, getMixinStyle } from '../utils'
|
import { getCollectionCounter, getMixinStyle } from '../utils'
|
||||||
|
import { selectNextItem, selectPrevItem } from '../actionImpl'
|
||||||
|
import { tick } from 'svelte'
|
||||||
|
import { focusStore } from '../selection'
|
||||||
|
|
||||||
export let _id: Ref<Doc>
|
export let _id: Ref<Doc>
|
||||||
export let _class: Ref<Class<Doc>>
|
export let _class: Ref<Class<Doc>>
|
||||||
@ -238,6 +241,17 @@
|
|||||||
headerLoading = false
|
headerLoading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
async function next (pn: boolean): Promise<void> {
|
||||||
|
if (pn) {
|
||||||
|
selectNextItem('vertical')
|
||||||
|
} else {
|
||||||
|
selectPrevItem('vertical')
|
||||||
|
}
|
||||||
|
await tick()
|
||||||
|
if ($focusStore.focus !== undefined) {
|
||||||
|
showPanel(view.component.EditDoc, $focusStore.focus._id, $focusStore.focus._class, 'content')
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<ActionContext context={{
|
<ActionContext context={{
|
||||||
mode: 'editor'
|
mode: 'editor'
|
||||||
@ -255,6 +269,12 @@
|
|||||||
dispatch('close')
|
dispatch('close')
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<svelte:fragment slot="navigate-actions">
|
||||||
|
<div class="tool flex-row-center gap-1 mr-4">
|
||||||
|
<Button icon={IconDown} kind={'no-border'} on:click={() => next(true)}/>
|
||||||
|
<Button icon={IconUp} kind={'no-border'} on:click={() => next(false)}/>
|
||||||
|
</div>
|
||||||
|
</svelte:fragment>
|
||||||
<div class="w-full" slot="subtitle">
|
<div class="w-full" slot="subtitle">
|
||||||
{#if !headerLoading}
|
{#if !headerLoading}
|
||||||
{#if headerEditor !== undefined}
|
{#if headerEditor !== undefined}
|
||||||
|
@ -62,7 +62,6 @@ export function updateFocus (selection?: FocusSelection): void {
|
|||||||
cur.focus = selection?.focus
|
cur.focus = selection?.focus
|
||||||
cur.provider = selection?.provider
|
cur.provider = selection?.provider
|
||||||
;(cur as any).now = now
|
;(cur as any).now = now
|
||||||
console.log('update focus', selection?.focus)
|
|
||||||
previewDocument.update(old => {
|
previewDocument.update(old => {
|
||||||
if (old !== undefined) {
|
if (old !== undefined) {
|
||||||
return selection?.focus
|
return selection?.focus
|
||||||
|
@ -130,6 +130,9 @@ export interface ActionTarget<T extends Doc = Doc> extends Doc {
|
|||||||
action: Ref<Action>
|
action: Ref<Action>
|
||||||
query?: DocumentQuery<T>
|
query?: DocumentQuery<T>
|
||||||
context: ViewContext
|
context: ViewContext
|
||||||
|
|
||||||
|
// If specified, will be used instead of action from Action.
|
||||||
|
override?: ViewAction
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
} from '@anticrm/ui'
|
} from '@anticrm/ui'
|
||||||
import { ActionContext, ActionHandler } from '@anticrm/view-resources'
|
import { ActionContext, ActionHandler } from '@anticrm/view-resources'
|
||||||
import type { Application, NavigatorModel, SpecialNavModel, ViewConfiguration } from '@anticrm/workbench'
|
import type { Application, NavigatorModel, SpecialNavModel, ViewConfiguration } from '@anticrm/workbench'
|
||||||
import { onDestroy } from 'svelte'
|
import { onDestroy, tick } from 'svelte'
|
||||||
import workbench from '../plugin'
|
import workbench from '../plugin'
|
||||||
import AccountPopup from './AccountPopup.svelte'
|
import AccountPopup from './AccountPopup.svelte'
|
||||||
import AppItem from './AppItem.svelte'
|
import AppItem from './AppItem.svelte'
|
||||||
@ -75,10 +75,16 @@
|
|||||||
apps = result
|
apps = result
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let panelInstance: PanelInstance
|
||||||
|
|
||||||
let visibileNav: boolean = true
|
let visibileNav: boolean = true
|
||||||
async function toggleNav (): Promise<void> {
|
async function toggleNav (): Promise<void> {
|
||||||
visibileNav = !visibileNav
|
visibileNav = !visibileNav
|
||||||
closeTooltip()
|
closeTooltip()
|
||||||
|
if (currentApplication && navigatorModel && navigator) {
|
||||||
|
await tick()
|
||||||
|
panelInstance.fitPopupInstance()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const account = getCurrentAccount() as EmployeeAccount
|
const account = getCurrentAccount() as EmployeeAccount
|
||||||
@ -262,7 +268,7 @@
|
|||||||
|
|
||||||
const resizing = (event: MouseEvent): void => {
|
const resizing = (event: MouseEvent): void => {
|
||||||
if (isResizing && aside) {
|
if (isResizing && aside) {
|
||||||
let X = event.clientX - dX
|
const X = event.clientX - dX
|
||||||
const newWidth = asideWidth + oldX - X
|
const newWidth = asideWidth + oldX - X
|
||||||
if (newWidth > 320 && componentWidth - (oldX - X) > 320) {
|
if (newWidth > 320 && componentWidth - (oldX - X) > 320) {
|
||||||
aside.style.width = aside.style.maxWidth = aside.style.minWidth = newWidth + 'px'
|
aside.style.width = aside.style.maxWidth = aside.style.minWidth = newWidth + 'px'
|
||||||
@ -313,16 +319,16 @@
|
|||||||
</clipPath>
|
</clipPath>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="workbench-container">
|
<div class="workbench-container">
|
||||||
<div class="antiPanel-application" on:click={toggleNav}>
|
<div class="antiPanel-application">
|
||||||
<div class="flex-col mt-1">
|
<div class="flex-col mt-1">
|
||||||
<!-- <ActivityStatus status="active" /> -->
|
<!-- <ActivityStatus status="active" /> -->
|
||||||
<AppItem
|
<AppItem
|
||||||
icon={TopMenu}
|
icon={TopMenu}
|
||||||
label={visibileNav ? workbench.string.HideMenu : workbench.string.ShowMenu}
|
label={visibileNav ? workbench.string.HideMenu : workbench.string.ShowMenu}
|
||||||
selected={!visibileNav}
|
selected={!visibileNav}
|
||||||
action={toggleNav}
|
action={toggleNav}
|
||||||
notify={false}
|
notify={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Applications
|
<Applications
|
||||||
{apps}
|
{apps}
|
||||||
@ -413,7 +419,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div bind:this={cover} class="cover" />
|
<div bind:this={cover} class="cover" />
|
||||||
<PanelInstance {contentPanel} >
|
<PanelInstance bind:this={panelInstance} {contentPanel} >
|
||||||
<svelte:fragment slot='panel-header'>
|
<svelte:fragment slot='panel-header'>
|
||||||
<ActionContext
|
<ActionContext
|
||||||
context={{ mode: 'panel' }}
|
context={{ mode: 'panel' }}
|
||||||
|
Loading…
Reference in New Issue
Block a user