mirror of
https://github.com/hcengineering/platform.git
synced 2025-01-23 12:05:36 +00:00
TextEditor: Refactor attachments (#3833)
Signed-off-by: Anna No <anna.no@xored.com>
This commit is contained in:
parent
72db5745ab
commit
b439809138
@ -19,11 +19,8 @@
|
||||
AnySvelteComponent,
|
||||
Button,
|
||||
ButtonKind,
|
||||
EmojiPopup,
|
||||
IconEmoji,
|
||||
handler,
|
||||
registerFocus,
|
||||
showPopup,
|
||||
deviceOptionsStore as deviceInfo,
|
||||
checkAdaptiveMatching
|
||||
} from '@hcengineering/ui'
|
||||
@ -35,9 +32,8 @@
|
||||
import { completionConfig } from './extensions'
|
||||
import { EmojiExtension } from './extension/emoji'
|
||||
import { IsEmptyContentExtension } from './extension/isEmptyContent'
|
||||
import Attach from './icons/Attach.svelte'
|
||||
import RIMention from './icons/RIMention.svelte'
|
||||
import Send from './icons/Send.svelte'
|
||||
import { generateDefaultActions } from './editor/actions'
|
||||
|
||||
export let content: string = ''
|
||||
export let showHeader = false
|
||||
@ -48,7 +44,7 @@
|
||||
export let kindSend: ButtonKind = 'ghost'
|
||||
export let haveAttachment = false
|
||||
export let placeholder: IntlString | undefined = undefined
|
||||
export let extraActions: RefAction[] | undefined = undefined
|
||||
export let extraActions: RefAction[] = []
|
||||
export let loading: boolean = false
|
||||
export let focusable: boolean = false
|
||||
export let boundary: HTMLElement | undefined = undefined
|
||||
@ -57,7 +53,7 @@
|
||||
const dispatch = createEventDispatcher()
|
||||
const buttonSize = 'medium'
|
||||
|
||||
let textEditor: TextEditor
|
||||
let textEditor: TextEditor | undefined = undefined
|
||||
|
||||
let isEmpty = true
|
||||
|
||||
@ -68,42 +64,22 @@
|
||||
function setContent (content: string) {
|
||||
textEditor?.setContent(content)
|
||||
}
|
||||
const defActions: RefAction[] = [
|
||||
{
|
||||
label: textEditorPlugin.string.Attach,
|
||||
icon: Attach,
|
||||
action: () => {
|
||||
dispatch('attach')
|
||||
},
|
||||
order: 1001
|
||||
},
|
||||
{
|
||||
label: textEditorPlugin.string.Mention,
|
||||
icon: RIMention,
|
||||
action: () => textEditor.insertText('@'),
|
||||
order: 3000
|
||||
},
|
||||
{
|
||||
label: textEditorPlugin.string.Emoji,
|
||||
icon: IconEmoji,
|
||||
action: (element) => {
|
||||
showPopup(
|
||||
EmojiPopup,
|
||||
{},
|
||||
element,
|
||||
(emoji) => {
|
||||
if (!emoji) return
|
||||
textEditor.insertText(emoji)
|
||||
textEditor.focus()
|
||||
},
|
||||
() => {}
|
||||
)
|
||||
},
|
||||
order: 4001
|
||||
}
|
||||
]
|
||||
|
||||
let actions: RefAction[] = []
|
||||
const editorHandler: TextEditorHandler = {
|
||||
insertText: (text) => {
|
||||
textEditor?.insertText(text)
|
||||
},
|
||||
insertTemplate: (name, text) => {
|
||||
textEditor?.insertText(text)
|
||||
},
|
||||
focus: () => {
|
||||
textEditor?.focus()
|
||||
}
|
||||
}
|
||||
|
||||
let actions: RefAction[] = generateDefaultActions(editorHandler)
|
||||
.concat(...extraActions)
|
||||
.sort((a, b) => a.order - b.order)
|
||||
client.findAll<RefInputActionItem>(textEditorPlugin.class.RefInputActionItem, {}).then(async (res) => {
|
||||
const cont: RefAction[] = []
|
||||
for (const r of res) {
|
||||
@ -114,21 +90,13 @@
|
||||
action: await getResource(r.action)
|
||||
})
|
||||
}
|
||||
actions = defActions.concat(...cont).sort((a, b) => a.order - b.order)
|
||||
actions = actions.concat(...cont).sort((a, b) => a.order - b.order)
|
||||
})
|
||||
|
||||
export function submit (): void {
|
||||
textEditor.submit()
|
||||
textEditor?.submit()
|
||||
}
|
||||
|
||||
const editorHandler: TextEditorHandler = {
|
||||
insertText: (text) => {
|
||||
textEditor.insertText(text)
|
||||
},
|
||||
insertTemplate: (name, text) => {
|
||||
textEditor.insertText(text)
|
||||
}
|
||||
}
|
||||
function handleAction (a: RefAction, evt?: Event): void {
|
||||
a.action(evt?.target as HTMLElement, editorHandler)
|
||||
}
|
||||
@ -138,10 +106,10 @@
|
||||
export let focusIndex = -1
|
||||
const { idx, focusManager } = registerFocus(focusIndex, {
|
||||
focus: () => {
|
||||
const editable = textEditor?.isEditable()
|
||||
const editable = textEditor?.isEditable() ?? false
|
||||
if (editable) {
|
||||
focused = true
|
||||
textEditor.focus()
|
||||
textEditor?.focus()
|
||||
}
|
||||
return editable
|
||||
},
|
||||
@ -175,7 +143,7 @@
|
||||
if (!isEmpty || haveAttachment) {
|
||||
dispatch('message', ev.detail)
|
||||
content = ''
|
||||
textEditor.clear()
|
||||
textEditor?.clear()
|
||||
}
|
||||
}}
|
||||
on:blur={() => {
|
||||
@ -205,42 +173,28 @@
|
||||
</div>
|
||||
{#if showActions || showSend}
|
||||
<div class="buttons-panel flex-between clear-mins">
|
||||
{#if showActions}
|
||||
<div class="buttons-group xsmall-gap">
|
||||
<div class="buttons-group {shrinkButtons ? 'xxsmall-gap' : 'xsmall-gap'}">
|
||||
{#if showActions}
|
||||
{#each actions as a}
|
||||
<Button
|
||||
disabled={a.disabled}
|
||||
icon={a.icon}
|
||||
iconProps={{ size: buttonSize }}
|
||||
kind="ghost"
|
||||
showTooltip={{ label: a.label }}
|
||||
size={buttonSize}
|
||||
on:click={handler(a, (a, evt) => handleAction(a, evt))}
|
||||
on:click={handler(a, (a, evt) => {
|
||||
if (!a.disabled) {
|
||||
handleAction(a, evt)
|
||||
}
|
||||
})}
|
||||
/>
|
||||
{#if a.order % 10 === 1}
|
||||
<div class="buttons-divider" />
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{#if extraActions && extraActions.length > 0}
|
||||
<div class="buttons-group {shrinkButtons ? 'xsmall-gap' : 'small-gap'}">
|
||||
{#each extraActions as a}
|
||||
<Button
|
||||
disabled={a.disabled}
|
||||
icon={a.icon}
|
||||
iconProps={{ size: buttonSize }}
|
||||
kind="ghost"
|
||||
showTooltip={{ label: a.label }}
|
||||
size={buttonSize}
|
||||
on:click={handler(a, (a, evt) => {
|
||||
if (!a.disabled) {
|
||||
handleAction(a, evt)
|
||||
}
|
||||
})}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if showSend}
|
||||
<Button
|
||||
|
@ -84,9 +84,6 @@
|
||||
}}
|
||||
>
|
||||
<slot />
|
||||
<svelte:fragment slot="right">
|
||||
<slot name="right" />
|
||||
</svelte:fragment>
|
||||
</StyledTextEditor>
|
||||
</div>
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
import { ImageRef, FileAttachFunction } from './imageExt'
|
||||
import { Node as ProseMirrorNode } from '@tiptap/pm/model'
|
||||
import { RefAction } from '../types'
|
||||
|
||||
export let label: IntlString | undefined = undefined
|
||||
export let content: string
|
||||
@ -33,8 +34,8 @@
|
||||
|
||||
export let kind: 'normal' | 'emphasized' | 'indented' = 'normal'
|
||||
export let alwaysEdit: boolean = false
|
||||
export let extraActions: RefAction[] = []
|
||||
export let showButtons: boolean = true
|
||||
export let hideAttachments: boolean = false
|
||||
export let buttonSize: ButtonSize = 'medium'
|
||||
export let formatButtonSize: IconSize = 'small'
|
||||
export let hideExtraButtons: boolean = false
|
||||
@ -225,7 +226,6 @@
|
||||
<StyledTextEditor
|
||||
{placeholder}
|
||||
{showButtons}
|
||||
{hideAttachments}
|
||||
{buttonSize}
|
||||
{formatButtonSize}
|
||||
{maxHeight}
|
||||
@ -233,10 +233,10 @@
|
||||
{autofocus}
|
||||
{isScrollable}
|
||||
{extensions}
|
||||
{extraActions}
|
||||
{boundary}
|
||||
bind:content={rawValue}
|
||||
bind:this={textEditor}
|
||||
on:attach
|
||||
on:value={(evt) => {
|
||||
rawValue = evt.detail
|
||||
if (alwaysEdit) {
|
||||
|
@ -16,22 +16,12 @@
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { AnyExtension, mergeAttributes } from '@tiptap/core'
|
||||
import { Node as ProseMirrorNode } from '@tiptap/pm/model'
|
||||
import { Asset, getResource, IntlString } from '@hcengineering/platform'
|
||||
import { getResource, IntlString } from '@hcengineering/platform'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import {
|
||||
AnySvelteComponent,
|
||||
Button,
|
||||
ButtonSize,
|
||||
EmojiPopup,
|
||||
IconEmoji,
|
||||
IconSize,
|
||||
Scroller,
|
||||
showPopup
|
||||
} from '@hcengineering/ui'
|
||||
|
||||
import { Button, ButtonSize, IconSize, Scroller } from '@hcengineering/ui'
|
||||
import textEditorPlugin from '../plugin'
|
||||
import { RefInputAction, RefInputActionItem, TextEditorHandler, TextFormatCategory } from '../types'
|
||||
import Attach from './icons/Attach.svelte'
|
||||
import { RefAction, RefInputActionItem, TextEditorHandler, TextFormatCategory } from '../types'
|
||||
import { generateDefaultActions } from './editor/actions'
|
||||
import TextEditor from './TextEditor.svelte'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
@ -39,7 +29,6 @@
|
||||
export let content: string = ''
|
||||
export let placeholder: IntlString = textEditorPlugin.string.EditorPlaceholder
|
||||
export let showButtons: boolean = true
|
||||
export let hideAttachments: boolean = false
|
||||
export let buttonSize: ButtonSize = 'medium'
|
||||
export let formatButtonSize: IconSize = 'small'
|
||||
export let isScrollable: boolean = true
|
||||
@ -49,6 +38,7 @@
|
||||
export let full = false
|
||||
export let extensions: AnyExtension[] = []
|
||||
export let editorAttributes: { [name: string]: string } = {}
|
||||
export let extraActions: RefAction[] = []
|
||||
export let boundary: HTMLElement | undefined = undefined
|
||||
export let textFormatCategories: TextFormatCategory[] = [
|
||||
TextFormatCategory.Heading,
|
||||
@ -60,30 +50,30 @@
|
||||
TextFormatCategory.Table
|
||||
]
|
||||
|
||||
let textEditor: TextEditor
|
||||
let textEditor: TextEditor | undefined = undefined
|
||||
|
||||
let contentHeight: number
|
||||
|
||||
export function submit (): void {
|
||||
textEditor.submit()
|
||||
textEditor?.submit()
|
||||
}
|
||||
export function focus (): void {
|
||||
textEditor.focus()
|
||||
textEditor?.focus()
|
||||
}
|
||||
export function isEditable (): boolean {
|
||||
return textEditor.isEditable()
|
||||
return textEditor?.isEditable() ?? false
|
||||
}
|
||||
export function setEditable (editable: boolean): void {
|
||||
textEditor.setEditable(editable)
|
||||
textEditor?.setEditable(editable)
|
||||
}
|
||||
export function getContent (): string {
|
||||
return content
|
||||
}
|
||||
export function setContent (data: string): void {
|
||||
textEditor.setContent(data)
|
||||
textEditor?.setContent(data)
|
||||
}
|
||||
export function insertText (text: string): void {
|
||||
textEditor.insertText(text)
|
||||
textEditor?.insertText(text)
|
||||
}
|
||||
|
||||
$: varsStyle =
|
||||
@ -95,44 +85,22 @@
|
||||
? 'max-content'
|
||||
: maxHeight
|
||||
|
||||
interface RefAction {
|
||||
label: IntlString
|
||||
icon: Asset | AnySvelteComponent
|
||||
action: RefInputAction
|
||||
order: number
|
||||
hidden?: boolean
|
||||
}
|
||||
const defActions: RefAction[] = [
|
||||
{
|
||||
label: textEditorPlugin.string.Attach,
|
||||
icon: Attach,
|
||||
action: () => {
|
||||
dispatch('attach')
|
||||
},
|
||||
order: 1001
|
||||
},
|
||||
{
|
||||
label: textEditorPlugin.string.Emoji,
|
||||
icon: IconEmoji,
|
||||
action: (element) => {
|
||||
showPopup(
|
||||
EmojiPopup,
|
||||
{},
|
||||
element,
|
||||
(emoji) => {
|
||||
if (!emoji) return
|
||||
textEditor.insertText(emoji)
|
||||
textEditor.focus()
|
||||
},
|
||||
() => {}
|
||||
)
|
||||
},
|
||||
order: 4001
|
||||
}
|
||||
]
|
||||
|
||||
const client = getClient()
|
||||
let actions: RefAction[] = []
|
||||
const editorHandler: TextEditorHandler = {
|
||||
insertText: (text) => {
|
||||
textEditor?.insertText(text)
|
||||
},
|
||||
insertTemplate: (name, text) => {
|
||||
textEditor?.insertText(text)
|
||||
dispatch('template', name)
|
||||
},
|
||||
focus: () => {
|
||||
textEditor?.focus()
|
||||
}
|
||||
}
|
||||
let actions: RefAction[] = generateDefaultActions(editorHandler)
|
||||
.concat(...extraActions)
|
||||
.sort((a, b) => a.order - b.order)
|
||||
client.findAll<RefInputActionItem>(textEditorPlugin.class.RefInputActionItem, {}).then(async (res) => {
|
||||
const cont: RefAction[] = []
|
||||
for (const r of res) {
|
||||
@ -143,7 +111,7 @@
|
||||
action: await getResource(r.action)
|
||||
})
|
||||
}
|
||||
actions = defActions.concat(...cont).sort((a, b) => a.order - b.order)
|
||||
actions = actions.concat(...cont).sort((a, b) => a.order - b.order)
|
||||
})
|
||||
|
||||
const mergedEditorAttributes = mergeAttributes(
|
||||
@ -151,15 +119,6 @@
|
||||
full ? { class: 'text-editor-view_full-height' } : { class: 'text-editor-view_compact' }
|
||||
)
|
||||
|
||||
const editorHandler: TextEditorHandler = {
|
||||
insertText: (text) => {
|
||||
textEditor.insertText(text)
|
||||
},
|
||||
insertTemplate: (name, text) => {
|
||||
textEditor.insertText(text)
|
||||
dispatch('template', name)
|
||||
}
|
||||
}
|
||||
function handleAction (a: RefAction, evt?: Event): void {
|
||||
a.action(evt?.target as HTMLElement, editorHandler)
|
||||
}
|
||||
@ -185,7 +144,7 @@
|
||||
* @public
|
||||
*/
|
||||
export function removeNode (nde: ProseMirrorNode): void {
|
||||
textEditor.removeNode(nde)
|
||||
textEditor?.removeNode(nde)
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -218,7 +177,7 @@
|
||||
on:content={(ev) => {
|
||||
dispatch('message', ev.detail)
|
||||
content = ''
|
||||
textEditor.clear()
|
||||
textEditor?.clear()
|
||||
}}
|
||||
on:blur
|
||||
on:focus
|
||||
@ -237,7 +196,7 @@
|
||||
on:content={(ev) => {
|
||||
dispatch('message', ev.detail)
|
||||
content = ''
|
||||
textEditor.clear()
|
||||
textEditor?.clear()
|
||||
}}
|
||||
on:blur
|
||||
on:focus
|
||||
@ -250,7 +209,7 @@
|
||||
{#if showButtons}
|
||||
<div class="flex-between">
|
||||
<div class="buttons-group {buttonsGap} mt-3">
|
||||
{#each actions.filter((it) => it.hidden !== true) as a}
|
||||
{#each actions as a}
|
||||
<Button
|
||||
icon={a.icon}
|
||||
iconProps={{ size: buttonSize }}
|
||||
@ -265,11 +224,6 @@
|
||||
{/each}
|
||||
<slot />
|
||||
</div>
|
||||
{#if $$slots.right}
|
||||
<div class="buttons-group {buttonsGap} mt-3">
|
||||
<slot name="right" />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
36
packages/text-editor/src/components/editor/actions.ts
Normal file
36
packages/text-editor/src/components/editor/actions.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { EmojiPopup, IconEmoji, showPopup } from '@hcengineering/ui'
|
||||
import RiMention from '../icons/RIMention.svelte'
|
||||
import textEditorPlugin from '../../plugin'
|
||||
import { RefAction, TextEditorHandler } from '../../types'
|
||||
|
||||
export const generateDefaultActions = (editorHandler: TextEditorHandler): RefAction[] => {
|
||||
return [
|
||||
{
|
||||
label: textEditorPlugin.string.Mention,
|
||||
icon: RiMention,
|
||||
action: () => editorHandler.insertText('@'),
|
||||
order: 3000
|
||||
},
|
||||
{
|
||||
label: textEditorPlugin.string.Emoji,
|
||||
icon: IconEmoji,
|
||||
action: (element) => {
|
||||
showPopup(
|
||||
EmojiPopup,
|
||||
{},
|
||||
element,
|
||||
(emoji) => {
|
||||
if (emoji === null || emoji === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
editorHandler.insertText(emoji)
|
||||
editorHandler.focus()
|
||||
},
|
||||
() => {}
|
||||
)
|
||||
},
|
||||
order: 4001
|
||||
}
|
||||
]
|
||||
}
|
@ -28,6 +28,7 @@ export { default as StyledTextBox } from './components/StyledTextBox.svelte'
|
||||
export { default as StyledTextEditor } from './components/StyledTextEditor.svelte'
|
||||
export { default as TextEditor } from './components/TextEditor.svelte'
|
||||
export { default as TextEditorStyleToolbar } from './components/TextEditorStyleToolbar.svelte'
|
||||
export { default as AttachIcon } from './components/icons/Attach.svelte'
|
||||
export { default } from './plugin'
|
||||
export * from './types'
|
||||
|
||||
|
@ -8,6 +8,7 @@ import type { AnySvelteComponent } from '@hcengineering/ui'
|
||||
export interface TextEditorHandler {
|
||||
insertText: (html: string) => void
|
||||
insertTemplate: (name: string, html: string) => void
|
||||
focus: () => void
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
|
@ -661,6 +661,7 @@ input.search {
|
||||
.h-14 { height: 3.5rem; }
|
||||
.h-16 { height: 4rem; }
|
||||
.h-18 { height: 4.5rem; }
|
||||
.h-32 { height: 8rem; }
|
||||
.h-50 { height: 12.5rem; }
|
||||
.h-60 { height: 15.0rem; }
|
||||
.w-min { width: min-content; }
|
||||
|
@ -13,16 +13,15 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, onDestroy, tick } from 'svelte'
|
||||
import { Attachment } from '@hcengineering/attachment'
|
||||
import { Account, Class, Doc, generateId, IdMap, Ref, Space, toIdMap } from '@hcengineering/core'
|
||||
import { IntlString, setPlatformStatus, unknownError, Asset } from '@hcengineering/platform'
|
||||
import { createQuery, DraftController, draftsStore, getClient } from '@hcengineering/presentation'
|
||||
import { ReferenceInput } from '@hcengineering/text-editor'
|
||||
import type { RefAction } from '@hcengineering/text-editor'
|
||||
import textEditor, { AttachIcon, type RefAction, ReferenceInput } from '@hcengineering/text-editor'
|
||||
import { Loading, type AnySvelteComponent } from '@hcengineering/ui'
|
||||
import { deleteFile, uploadFile } from '../utils'
|
||||
import attachment from '../plugin'
|
||||
import { IntlString, setPlatformStatus, unknownError, Asset } from '@hcengineering/platform'
|
||||
import { createEventDispatcher, onDestroy, tick } from 'svelte'
|
||||
import { Account, Class, Doc, generateId, IdMap, Ref, Space, toIdMap } from '@hcengineering/core'
|
||||
import { Loading, type AnySvelteComponent } from '@hcengineering/ui'
|
||||
import { Attachment } from '@hcengineering/attachment'
|
||||
import AttachmentPresenter from './AttachmentPresenter.svelte'
|
||||
|
||||
export let objectId: Ref<Doc>
|
||||
@ -40,7 +39,7 @@
|
||||
refInput.submit()
|
||||
}
|
||||
export let placeholder: IntlString | undefined = undefined
|
||||
export let extraActions: RefAction[] | undefined = undefined
|
||||
export let extraActions: RefAction[] = []
|
||||
export let boundary: HTMLElement | undefined = undefined
|
||||
|
||||
let refInput: ReferenceInput
|
||||
@ -284,20 +283,27 @@
|
||||
{iconSend}
|
||||
{labelSend}
|
||||
{showSend}
|
||||
showHeader={attachments.size > 0 || progress}
|
||||
{loading}
|
||||
{boundary}
|
||||
extraActions={[
|
||||
...extraActions,
|
||||
{
|
||||
label: textEditor.string.Attach,
|
||||
icon: AttachIcon,
|
||||
action: () => {
|
||||
dispatch('focus')
|
||||
inputFile.click()
|
||||
},
|
||||
order: 1001
|
||||
}
|
||||
]}
|
||||
showHeader={attachments.size > 0 || progress}
|
||||
haveAttachment={attachments.size > 0}
|
||||
on:focus
|
||||
on:blur
|
||||
on:message={onMessage}
|
||||
haveAttachment={attachments.size > 0}
|
||||
on:attach={() => {
|
||||
dispatch('focus')
|
||||
inputFile.click()
|
||||
}}
|
||||
on:update={onUpdate}
|
||||
{placeholder}
|
||||
{extraActions}
|
||||
>
|
||||
<div slot="header">
|
||||
{#if attachments.size || progress}
|
||||
|
@ -13,19 +13,18 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, onDestroy } from 'svelte'
|
||||
import { Attachment } from '@hcengineering/attachment'
|
||||
import { Account, Class, Doc, generateId, Ref, Space, toIdMap } from '@hcengineering/core'
|
||||
import { IntlString, setPlatformStatus, unknownError } from '@hcengineering/platform'
|
||||
import { createQuery, DraftController, draftsStore, getClient } from '@hcengineering/presentation'
|
||||
import { StyledTextBox } from '@hcengineering/text-editor'
|
||||
import { ButtonSize, IconSize, updatePopup } from '@hcengineering/ui'
|
||||
import { createEventDispatcher, onDestroy } from 'svelte'
|
||||
import textEditor, { AttachIcon, type RefAction, StyledTextBox } from '@hcengineering/text-editor'
|
||||
import { ButtonSize, IconSize, Loading, updatePopup } from '@hcengineering/ui'
|
||||
import { ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
|
||||
import attachment from '../plugin'
|
||||
import { deleteFile, uploadFile } from '../utils'
|
||||
import AttachmentPresenter from './AttachmentPresenter.svelte'
|
||||
import AttachmentPreview from './AttachmentPreview.svelte'
|
||||
import { ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
|
||||
import Loading from '@hcengineering/ui/src/components/Loading.svelte'
|
||||
|
||||
export let objectId: Ref<Doc> | undefined = undefined
|
||||
export let space: Ref<Space> | undefined = undefined
|
||||
@ -84,7 +83,7 @@
|
||||
export function setContent (data: string): void {
|
||||
refInput.setContent(data)
|
||||
}
|
||||
export function attach (): void {
|
||||
export function handleAttach (): void {
|
||||
inputFile.click()
|
||||
}
|
||||
|
||||
@ -92,6 +91,7 @@
|
||||
refInput.submit()
|
||||
}
|
||||
let refInput: StyledTextBox
|
||||
let extraActions: RefAction[] = []
|
||||
|
||||
let inputFile: HTMLInputElement
|
||||
let saved = false
|
||||
@ -346,6 +346,19 @@
|
||||
values: attachments.size === 0 ? true : attachments
|
||||
})
|
||||
|
||||
$: if (enableAttachments) {
|
||||
extraActions = [
|
||||
{
|
||||
label: textEditor.string.Attach,
|
||||
icon: AttachIcon,
|
||||
action: handleAttach,
|
||||
order: 1001
|
||||
}
|
||||
]
|
||||
} else {
|
||||
extraActions = []
|
||||
}
|
||||
|
||||
let element: HTMLElement
|
||||
let progressItems: Ref<Doc>[] = []
|
||||
</script>
|
||||
@ -377,7 +390,6 @@
|
||||
{placeholder}
|
||||
{alwaysEdit}
|
||||
{showButtons}
|
||||
hideAttachments={!enableAttachments}
|
||||
{buttonSize}
|
||||
{formatButtonSize}
|
||||
{maxHeight}
|
||||
@ -386,14 +398,12 @@
|
||||
{enableBackReferences}
|
||||
{isScrollable}
|
||||
{boundary}
|
||||
{extraActions}
|
||||
on:changeSize
|
||||
on:changeContent
|
||||
on:blur
|
||||
on:focus
|
||||
on:open-document
|
||||
on:attach={() => {
|
||||
attach()
|
||||
}}
|
||||
attachFile={async (file) => {
|
||||
return createAttachment(file)
|
||||
}}
|
||||
|
Loading…
Reference in New Issue
Block a user