mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-14 20:39:03 +00:00
Chunter: attachments and format updates (#1410)
Signed-off-by: Ruslan Izhitsky <ruslan.izhitskiy@xored.com>
This commit is contained in:
parent
a0d67cb888
commit
e67a7c0464
@ -37,10 +37,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<a
|
<a class="flex-presenter" href={link}>
|
||||||
class="flex-presenter"
|
|
||||||
href="{link}"
|
|
||||||
>
|
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
{#if icon}
|
{#if icon}
|
||||||
<Icon {icon} size={'small'} />
|
<Icon {icon} size={'small'} />
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import attachment, { Attachment } from '@anticrm/attachment'
|
import attachment, { Attachment } from '@anticrm/attachment'
|
||||||
import { AttachmentPresenter } from '@anticrm/attachment-resources'
|
import { AttachmentPresenter } from '@anticrm/attachment-resources'
|
||||||
import { Channel } from '@anticrm/chunter'
|
import { Channel } from '@anticrm/chunter'
|
||||||
import type { Doc } from '@anticrm/core'
|
import { Doc, SortingOrder } from '@anticrm/core'
|
||||||
import { createQuery } from '@anticrm/presentation'
|
import { createQuery } from '@anticrm/presentation'
|
||||||
import { Menu } from '@anticrm/view-resources'
|
import { Menu } from '@anticrm/view-resources'
|
||||||
import { showPopup, IconMoreV, Label } from '@anticrm/ui'
|
import { showPopup, IconMoreV, Label } from '@anticrm/ui'
|
||||||
@ -25,9 +25,11 @@
|
|||||||
export let channel: Channel | undefined
|
export let channel: Channel | undefined
|
||||||
|
|
||||||
const query = createQuery()
|
const query = createQuery()
|
||||||
let attachments: Attachment[] | undefined
|
let visibleAttachments: Attachment[] | undefined
|
||||||
let selectedRowNumber: number | undefined
|
let totalAttachments = 0
|
||||||
let attachmentsLimit: number | undefined = 5
|
let attachmentsLimit: number | undefined = 5
|
||||||
|
let selectedRowNumber: number | undefined
|
||||||
|
const sort = { modifiedOn: SortingOrder.Descending }
|
||||||
|
|
||||||
const showMenu = async (ev: MouseEvent, object: Doc, rowNumber: number): Promise<void> => {
|
const showMenu = async (ev: MouseEvent, object: Doc, rowNumber: number): Promise<void> => {
|
||||||
selectedRowNumber = rowNumber
|
selectedRowNumber = rowNumber
|
||||||
@ -43,17 +45,25 @@
|
|||||||
space: channel._id
|
space: channel._id
|
||||||
},
|
},
|
||||||
(res) => {
|
(res) => {
|
||||||
attachments = res
|
visibleAttachments = res
|
||||||
|
totalAttachments = res.total
|
||||||
},
|
},
|
||||||
attachmentsLimit ? { limit: attachmentsLimit } : undefined
|
attachmentsLimit
|
||||||
|
? {
|
||||||
|
limit: attachmentsLimit,
|
||||||
|
sort: sort
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
sort: sort
|
||||||
|
}
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="group">
|
<div class="group">
|
||||||
<div class="eGroupTitle"><Label label={attachment.string.Files} /></div>
|
<div class="eGroupTitle"><Label label={attachment.string.Files} /></div>
|
||||||
{#if attachments?.length}
|
{#if visibleAttachments?.length}
|
||||||
<div class="flex-col">
|
<div class="flex-col">
|
||||||
{#each attachments as attachment, i}
|
{#each visibleAttachments as attachment, i}
|
||||||
<div class="flex-between attachmentRow" class:fixed={i === selectedRowNumber}>
|
<div class="flex-between attachmentRow" class:fixed={i === selectedRowNumber}>
|
||||||
<div class="item flex">
|
<div class="item flex">
|
||||||
<AttachmentPresenter value={attachment} />
|
<AttachmentPresenter value={attachment} />
|
||||||
@ -65,7 +75,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
{#if attachmentsLimit && attachments.length === attachmentsLimit}
|
{#if attachmentsLimit && visibleAttachments.length < totalAttachments}
|
||||||
<div
|
<div
|
||||||
class="showMoreAttachmentsButton"
|
class="showMoreAttachmentsButton"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
|
@ -82,6 +82,6 @@
|
|||||||
focus
|
focus
|
||||||
on:change={onDescriptionChange}
|
on:change={onDescriptionChange}
|
||||||
/>
|
/>
|
||||||
<EditChannelDescriptionAttachments channel={channel} />
|
<EditChannelDescriptionAttachments {channel} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
import { Action } from '@anticrm/view'
|
import { Action } from '@anticrm/view'
|
||||||
import { getActions } from '@anticrm/view-resources'
|
import { getActions } from '@anticrm/view-resources'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import { UnpinMessage } from '../index';
|
import { UnpinMessage } from '../index'
|
||||||
import chunter from '../plugin'
|
import chunter from '../plugin'
|
||||||
import { getTime } from '../utils'
|
import { getTime } from '../utils'
|
||||||
// import Share from './icons/Share.svelte'
|
// import Share from './icons/Share.svelte'
|
||||||
@ -71,17 +71,17 @@
|
|||||||
action: chunter.actionImpl.PinMessage
|
action: chunter.actionImpl.PinMessage
|
||||||
} as Action)
|
} as Action)
|
||||||
|
|
||||||
$: isEditing = false;
|
$: isEditing = false
|
||||||
|
|
||||||
const editAction = {
|
const editAction = {
|
||||||
label: chunter.string.EditMessage,
|
label: chunter.string.EditMessage,
|
||||||
action: () => isEditing = true
|
action: () => (isEditing = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteAction = {
|
const deleteAction = {
|
||||||
label: chunter.string.DeleteMessage,
|
label: chunter.string.DeleteMessage,
|
||||||
action: async () => {
|
action: async () => {
|
||||||
(await client.findAll(chunter.class.ThreadMessage, { attachedTo: message._id as Ref<Message> })).forEach(c => {
|
;(await client.findAll(chunter.class.ThreadMessage, { attachedTo: message._id as Ref<Message> })).forEach((c) => {
|
||||||
UnpinMessage(c)
|
UnpinMessage(c)
|
||||||
})
|
})
|
||||||
UnpinMessage(message)
|
UnpinMessage(message)
|
||||||
@ -123,13 +123,10 @@
|
|||||||
const { message: newContent, attachments: newAttachments } = event.detail
|
const { message: newContent, attachments: newAttachments } = event.detail
|
||||||
|
|
||||||
if (newContent !== message.content || newAttachments !== attachments) {
|
if (newContent !== message.content || newAttachments !== attachments) {
|
||||||
await client.update(
|
await client.update(message, {
|
||||||
message,
|
content: newContent,
|
||||||
{
|
attachments: newAttachments
|
||||||
content: newContent,
|
})
|
||||||
attachments: newAttachments
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
isEditing = false
|
isEditing = false
|
||||||
}
|
}
|
||||||
@ -157,12 +154,12 @@
|
|||||||
<span>{getTime(message.createOn)}</span>
|
<span>{getTime(message.createOn)}</span>
|
||||||
</div>
|
</div>
|
||||||
{#if isEditing}
|
{#if isEditing}
|
||||||
<AttachmentRefInput
|
<AttachmentRefInput
|
||||||
space={message.space}
|
space={message.space}
|
||||||
_class={chunter.class.Comment}
|
_class={chunter.class.Comment}
|
||||||
objectId={message._id}
|
objectId={message._id}
|
||||||
content={message.content}
|
content={message.content}
|
||||||
on:message={onMessageEdit}
|
on:message={onMessageEdit}
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="text"><MessageViewer message={message.content} /></div>
|
<div class="text"><MessageViewer message={message.content} /></div>
|
||||||
|
@ -63,8 +63,7 @@
|
|||||||
<div
|
<div
|
||||||
class="cross"
|
class="cross"
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
if (pinnedIds.length === 1)
|
if (pinnedIds.length === 1) dispatch('close')
|
||||||
dispatch('close')
|
|
||||||
UnpinMessage(message)
|
UnpinMessage(message)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -105,13 +105,19 @@
|
|||||||
))
|
))
|
||||||
)
|
)
|
||||||
|
|
||||||
async function getParticipants (comments: ThreadMessage[], parent: Message | undefined, employees: Map<Ref<Employee>, Employee>): Promise<string[]> {
|
async function getParticipants (
|
||||||
|
comments: ThreadMessage[],
|
||||||
|
parent: Message | undefined,
|
||||||
|
employees: Map<Ref<Employee>, Employee>
|
||||||
|
): Promise<string[]> {
|
||||||
const refs = new Set(comments.map((p) => p.createBy))
|
const refs = new Set(comments.map((p) => p.createBy))
|
||||||
if (parent !== undefined) {
|
if (parent !== undefined) {
|
||||||
refs.add(parent.createBy)
|
refs.add(parent.createBy)
|
||||||
}
|
}
|
||||||
refs.delete(getCurrentAccount()._id)
|
refs.delete(getCurrentAccount()._id)
|
||||||
const accounts = await client.findAll(contact.class.EmployeeAccount, { _id: { $in: Array.from(refs) as Ref<EmployeeAccount>[] } })
|
const accounts = await client.findAll(contact.class.EmployeeAccount, {
|
||||||
|
_id: { $in: Array.from(refs) as Ref<EmployeeAccount>[] }
|
||||||
|
})
|
||||||
const res: string[] = []
|
const res: string[] = []
|
||||||
for (const account of accounts) {
|
for (const account of accounts) {
|
||||||
const employee = employees.get(account.employee)
|
const employee = employees.get(account.employee)
|
||||||
@ -174,13 +180,25 @@
|
|||||||
{#if parent}
|
{#if parent}
|
||||||
<MsgView message={parent} {employees} thread />
|
<MsgView message={parent} {employees} thread />
|
||||||
{#if total > comments.length}
|
{#if total > comments.length}
|
||||||
<div class="label pb-2 pt-2 pl-8 over-underline" on:click={() => { showAll = true }}><Label label={chunter.string.ShowMoreReplies} params={{ count: total - comments.length }} /></div>
|
<div
|
||||||
|
class="label pb-2 pt-2 pl-8 over-underline"
|
||||||
|
on:click={() => {
|
||||||
|
showAll = true
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Label label={chunter.string.ShowMoreReplies} params={{ count: total - comments.length }} />
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#each comments as comment (comment._id)}
|
{#each comments as comment (comment._id)}
|
||||||
<MsgView message={comment} {employees} thread />
|
<MsgView message={comment} {employees} thread />
|
||||||
{/each}
|
{/each}
|
||||||
<div class="mr-4 ml-4 mb-4 mt-2">
|
<div class="mr-4 ml-4 mb-4 mt-2">
|
||||||
<AttachmentRefInput space={parent.space} _class={chunter.class.Comment} objectId={commentId} on:message={onMessage} />
|
<AttachmentRefInput
|
||||||
|
space={parent.space}
|
||||||
|
_class={chunter.class.Comment}
|
||||||
|
objectId={commentId}
|
||||||
|
on:message={onMessage}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import attachment from '@anticrm/attachment'
|
import attachment from '@anticrm/attachment'
|
||||||
import { AttachmentRefInput } from '@anticrm/attachment-resources'
|
import { AttachmentRefInput } from '@anticrm/attachment-resources'
|
||||||
import type { ThreadMessage, Message, ChunterMessage, Channel } from '@anticrm/chunter'
|
import type { ThreadMessage, Message, ChunterMessage } from '@anticrm/chunter'
|
||||||
import contact, { Employee } from '@anticrm/contact'
|
import contact, { Employee } from '@anticrm/contact'
|
||||||
import core, { Doc, generateId, getCurrentAccount, Ref, Space, TxFactory } from '@anticrm/core'
|
import core, { Doc, generateId, getCurrentAccount, Ref, Space, TxFactory } from '@anticrm/core'
|
||||||
import { NotificationClientImpl } from '@anticrm/notification-resources'
|
import { NotificationClientImpl } from '@anticrm/notification-resources'
|
||||||
@ -98,7 +98,7 @@
|
|||||||
lookup
|
lookup
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
pinnedQuery.query(
|
pinnedQuery.query(
|
||||||
chunter.class.Channel,
|
chunter.class.Channel,
|
||||||
{ _id: currentSpace },
|
{ _id: currentSpace },
|
||||||
|
@ -25,16 +25,21 @@
|
|||||||
|
|
||||||
let threads: Ref<Message>[] = []
|
let threads: Ref<Message>[] = []
|
||||||
|
|
||||||
query.query(chunter.class.ThreadMessage, {
|
query.query(
|
||||||
createBy: me
|
chunter.class.ThreadMessage,
|
||||||
}, (res) => {
|
{
|
||||||
const ids = new Set(res.map((c) => c.attachedTo))
|
createBy: me
|
||||||
threads = Array.from(ids)
|
},
|
||||||
}, {
|
(res) => {
|
||||||
sort: {
|
const ids = new Set(res.map((c) => c.attachedTo))
|
||||||
createOn: SortingOrder.Descending
|
threads = Array.from(ids)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sort: {
|
||||||
|
createOn: SortingOrder.Descending
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="ac-header full divide">
|
<div class="ac-header full divide">
|
||||||
@ -44,7 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<Scroller>
|
<Scroller>
|
||||||
{#each threads as thread (thread)}
|
{#each threads as thread (thread)}
|
||||||
<div class="item"><Thread _id={thread}/></div>
|
<div class="item"><Thread _id={thread} /></div>
|
||||||
{/each}
|
{/each}
|
||||||
</Scroller>
|
</Scroller>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user