Fillable templates (#2667)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov
2023-02-21 13:40:03 +07:00
committed by GitHub
parent a088b51e24
commit af09bb3ead
38 changed files with 626 additions and 122 deletions
@@ -14,17 +14,15 @@
// limitations under the License.
-->
<script lang="ts">
import { createQuery, getClient } from '@hcengineering/presentation'
import contact, { Channel, Contact, EmployeeAccount, formatName } from '@hcengineering/contact'
import { Ref, SortingOrder } from '@hcengineering/core'
import { Message, SharedMessage } from '@hcengineering/gmail'
import gmail from '../plugin'
import { Channel, Contact, EmployeeAccount, formatName } from '@hcengineering/contact'
import contact from '@hcengineering/contact'
import plugin, { IconShare, Button, Icon, Label, Scroller } from '@hcengineering/ui'
import { getCurrentAccount, Ref, SortingOrder, Space } from '@hcengineering/core'
import setting from '@hcengineering/setting'
import Messages from './Messages.svelte'
import { NotificationClientImpl } from '@hcengineering/notification-resources'
import { createQuery, getClient } from '@hcengineering/presentation'
import plugin, { Button, Icon, IconShare, Label, Scroller } from '@hcengineering/ui'
import gmail from '../plugin'
import IconInbox from './icons/Inbox.svelte'
import Messages from './Messages.svelte'
export let object: Contact
export let channel: Channel
@@ -41,8 +39,7 @@
const messagesQuery = createQuery()
const accauntsQuery = createQuery()
const settingsQuery = createQuery()
const accountId = getCurrentAccount()._id
const notificationClient = NotificationClientImpl.getClient()
function updateMessagesQuery (channelId: Ref<Channel>): void {
@@ -67,13 +64,6 @@
})
}
settingsQuery.query(
setting.class.Integration,
{ type: gmail.integrationType.Gmail, space: accountId as string as Ref<Space> },
(res) => {
enabled = res.length > 0
}
)
const client = getClient()
async function share (): Promise<void> {
@@ -15,12 +15,15 @@
-->
<script lang="ts">
import contact, { Channel, formatName } from '@hcengineering/contact'
import { Class, Doc, Ref } from '@hcengineering/core'
import { Class, Doc, getCurrentAccount, Ref, Space } from '@hcengineering/core'
import { SharedMessage } from '@hcengineering/gmail'
import { NotificationClientImpl } from '@hcengineering/notification-resources'
import { getResource } from '@hcengineering/platform'
import { createQuery } from '@hcengineering/presentation'
import setting, { Integration } from '@hcengineering/setting'
import templates, { TemplateDataProvider } from '@hcengineering/templates'
import { Button, eventToHTMLElement, Icon, Label, Panel, showPopup } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import { createEventDispatcher, onDestroy } from 'svelte'
import gmail from '../plugin'
import Chats from './Chats.svelte'
import Connect from './Connect.svelte'
@@ -35,7 +38,7 @@
let currentMessage: SharedMessage | undefined = undefined
let channel: Channel | undefined = undefined
const notificationClient = NotificationClientImpl.getClient()
let enabled: boolean
let integration: Integration | undefined
const channelQuery = createQuery()
const dispatch = createEventDispatcher()
@@ -71,6 +74,29 @@
await notificationClient.updateLastView(channel._id, channel._class, undefined, true)
}
}
const settingsQuery = createQuery()
const accountId = getCurrentAccount()._id
let templateProvider: TemplateDataProvider | undefined
getResource(templates.function.GetTemplateDataProvider).then((p) => {
templateProvider = p()
})
onDestroy(() => {
templateProvider?.destroy()
})
$: templateProvider && integration && templateProvider.set(setting.templateFieldCategory.Integration, integration)
settingsQuery.query(
setting.class.Integration,
{ type: gmail.integrationType.Gmail, space: accountId as string as Ref<Space> },
(res) => {
integration = res[0]
}
)
</script>
{#if channel && object}
@@ -97,7 +123,7 @@
</svelte:fragment>
<svelte:fragment slot="utils">
{#if !enabled}
{#if !integration}
<Button
label={gmail.string.Connect}
kind={'primary'}
@@ -113,7 +139,7 @@
{:else if currentMessage}
<FullMessage {currentMessage} bind:newMessage on:close={back} />
{:else}
<Chats {object} {channel} bind:newMessage bind:enabled on:select={selectHandler} />
<Chats {object} {channel} bind:newMessage enabled={integration !== undefined} on:select={selectHandler} />
{/if}
</Panel>
{/if}
@@ -15,16 +15,16 @@
<script lang="ts">
import attachmentP, { Attachment } from '@hcengineering/attachment'
import { AttachmentPresenter } from '@hcengineering/attachment-resources'
import { Channel, Contact, formatName } from '@hcengineering/contact'
import contact, { Channel, Contact, formatName } from '@hcengineering/contact'
import { Data, generateId } from '@hcengineering/core'
import { NewMessage, SharedMessage } from '@hcengineering/gmail'
import { NotificationClientImpl } from '@hcengineering/notification-resources'
import { getResource, setPlatformStatus, unknownError } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import { TextEditor } from '@hcengineering/text-editor'
import { Scroller, IconArrowLeft, IconAttachment, Label } from '@hcengineering/ui'
import Button from '@hcengineering/ui/src/components/Button.svelte'
import EditBox from '@hcengineering/ui/src/components/EditBox.svelte'
import templates, { TemplateDataProvider } from '@hcengineering/templates'
import { StyledTextEditor } from '@hcengineering/text-editor'
import { Button, EditBox, IconArrowLeft, IconAttachment, Label, Scroller } from '@hcengineering/ui'
import { onDestroy } from 'svelte'
import { createEventDispatcher } from 'svelte'
import plugin from '../plugin'
@@ -35,7 +35,7 @@
const notificationClient = NotificationClientImpl.getClient()
let objectId = generateId()
let editor: TextEditor
let editor: StyledTextEditor
let copy: string = ''
const obj: Data<NewMessage> = {
@@ -46,6 +46,18 @@
status: 'new'
}
let templateProvider: TemplateDataProvider | undefined
getResource(templates.function.GetTemplateDataProvider).then((p) => {
templateProvider = p()
})
onDestroy(() => {
templateProvider?.destroy()
})
$: templateProvider && templateProvider.set(contact.templateFieldCategory.Contact, object)
async function sendMsg () {
await client.createDoc(
plugin.class.NewMessage,
@@ -202,7 +214,7 @@
</div>
{/if}
<div class="input mt-4 clear-mins">
<TextEditor bind:this={editor} bind:content={obj.content} on:blur={editor.submit} />
<StyledTextEditor bind:this={editor} full bind:content={obj.content} maxHeight="panel" on:blur={editor.submit} />
</div>
</div>
</Scroller>
@@ -230,7 +242,8 @@
color: #d6d6d6;
caret-color: var(--caret-color);
min-height: 0;
height: calc(100% - 12rem);
margin-bottom: 2rem;
height: 100%;
border-radius: 0.25rem;
:global(.ProseMirror) {
@@ -16,21 +16,31 @@
import attachmentP, { Attachment } from '@hcengineering/attachment'
import { AttachmentPresenter } from '@hcengineering/attachment-resources'
import contact, { Channel, Contact, formatName } from '@hcengineering/contact'
import { generateId, Ref, toIdMap } from '@hcengineering/core'
import { generateId, getCurrentAccount, Ref, Space, toIdMap } from '@hcengineering/core'
import { NotificationClientImpl } from '@hcengineering/notification-resources'
import { getResource, setPlatformStatus, unknownError } from '@hcengineering/platform'
import setting, { Integration } from '@hcengineering/setting'
import { createQuery, getClient } from '@hcengineering/presentation'
import { TextEditor } from '@hcengineering/text-editor'
import { Icon, IconAttachment, Label, Panel, Scroller } from '@hcengineering/ui'
import Button from '@hcengineering/ui/src/components/Button.svelte'
import EditBox from '@hcengineering/ui/src/components/EditBox.svelte'
import { createEventDispatcher } from 'svelte'
import {
Button,
EditBox,
eventToHTMLElement,
Icon,
IconAttachment,
Label,
Panel,
Scroller,
showPopup
} from '@hcengineering/ui'
import { createEventDispatcher, onDestroy } from 'svelte'
import plugin from '../plugin'
import templates, { TemplateDataProvider } from '@hcengineering/templates'
import Connect from './Connect.svelte'
import { StyledTextEditor } from '@hcengineering/text-editor'
export let value: Contact[] | Contact
const contacts = Array.isArray(value) ? value : [value]
console.log(contacts)
const contactMap = toIdMap(contacts)
const query = createQuery()
@@ -51,17 +61,23 @@
const attachmentParentId = generateId()
let editor: TextEditor
let editor: StyledTextEditor
let subject: string = ''
let content: string = ''
let copy: string = ''
let saved = false
async function sendMsg () {
const templateProvider = (await getResource(templates.function.GetTemplateDataProvider))()
if (templateProvider === undefined) return
for (const channel of channels) {
const target = contacts.find((p) => p._id === channel.attachedTo)
if (target === undefined) continue
templateProvider.set(contact.templateFieldCategory.Contact, target)
const message = await templateProvider.fillTemplate(content)
const id = await client.createDoc(plugin.class.NewMessage, plugin.space.Gmail, {
subject,
content,
content: message,
to: channel.value,
status: 'new',
copy: copy
@@ -86,6 +102,7 @@
}
)
}
templateProvider.destroy()
}
saved = true
dispatch('close')
@@ -166,6 +183,30 @@
if (contact === undefined) return channel.value
return `${formatName(contact.name)} (${channel.value})`
}
const settingsQuery = createQuery()
const accountId = getCurrentAccount()._id
let templateProvider: TemplateDataProvider | undefined
let integration: Integration | undefined
getResource(templates.function.GetTemplateDataProvider).then((p) => {
templateProvider = p()
})
onDestroy(() => {
templateProvider?.destroy()
})
$: templateProvider && integration && templateProvider.set(setting.templateFieldCategory.Integration, integration)
settingsQuery.query(
setting.class.Integration,
{ type: plugin.integrationType.Gmail, space: accountId as string as Ref<Space> },
(res) => {
integration = res[0]
}
)
</script>
<Panel
@@ -189,6 +230,18 @@
</div>
</svelte:fragment>
<svelte:fragment slot="utils">
{#if !integration}
<Button
label={plugin.string.Connect}
kind={'primary'}
on:click={(e) => {
showPopup(Connect, {}, eventToHTMLElement(e))
}}
/>
{/if}
</svelte:fragment>
<input
bind:this={inputFile}
multiple
@@ -223,13 +276,15 @@
inputFile.click()
}}
/>
<Button
label={plugin.string.Send}
size={'small'}
kind={'primary'}
disabled={channels.length === 0}
on:click={sendMsg}
/>
{#if integration}
<Button
label={plugin.string.Send}
size={'small'}
kind={'primary'}
disabled={channels.length === 0}
on:click={sendMsg}
/>
{/if}
</div>
</div>
</div>
@@ -262,7 +317,7 @@
</div>
{/if}
<div class="input mt-4 clear-mins">
<TextEditor bind:this={editor} bind:content on:blur={editor.submit} />
<StyledTextEditor bind:this={editor} full bind:content on:blur={editor.submit} />
</div>
</div>
</Scroller>
@@ -291,7 +346,8 @@
color: #d6d6d6;
caret-color: var(--caret-color);
min-height: 0;
height: calc(100% - 12rem);
height: 100%;
margin-bottom: 2rem;
border-radius: 0.25rem;
:global(.ProseMirror) {