UBERF-8288: Fix archiving a channel (#6750)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina
2024-09-27 01:34:25 +07:00
committed by GitHub
parent d284414f2b
commit b359d080ac
28 changed files with 235 additions and 76 deletions
+2
View File
@@ -206,6 +206,8 @@ function defineChannelActions (builder: Builder): void {
query: {
archived: false
},
override: [view.action.Archive],
visibilityTester: view.function.CanArchiveSpace,
context: {
mode: 'context',
group: 'remove'
+1 -1
View File
@@ -285,7 +285,7 @@ export const coreOperation: MigrateOperation = {
func: migrateAllSpaceToTyped
},
{
state: 'add-spaces-owner',
state: 'add-spaces-owner-v1',
func: migrateSpacesOwner
},
{
@@ -41,6 +41,7 @@
export let hoverable = true
export let hoverStyles: 'borderedHover' | 'filledHover' = 'borderedHover'
export let hideLink = false
export let readonly: boolean = false
export let onClick: (() => void) | undefined = undefined
$: personAccount = $personAccountByIdStore.get((value.createdBy ?? value.modifiedBy) as Ref<PersonAccount>)
@@ -74,6 +75,7 @@
{hoverable}
{hoverStyles}
viewlet={undefined}
{readonly}
{onClick}
>
<svelte:fragment slot="icon">
@@ -39,6 +39,7 @@
export let videoPreload = true
export let hideLink = false
export let compact = false
export let readonly = false
export let onClick: (() => void) | undefined = undefined
const client = getClient()
@@ -72,6 +73,7 @@
hideLink,
type,
compact,
readonly,
onClick
}}
/>
@@ -61,6 +61,7 @@
export let type: ActivityMessageViewType = 'default'
export let inlineActions: MessageInlineAction[] = []
export let excludedActions: Ref<ViewAction>[] = []
export let readonly: boolean = false
export let onClick: (() => void) | undefined = undefined
export let socialIcon: Asset | undefined = undefined
@@ -107,8 +108,7 @@
$: isHidden = !!viewlet?.onlyWithParent && parentMessage === undefined
$: withActionMenu = withActions && !embedded && (actions.length > 0 || menuActionIds.length > 0)
let readonly: boolean = false
$: readonly = $restrictionStore.disableComments
$: readonly = readonly || $restrictionStore.disableComments
function canDisplayShort (type: ActivityMessageViewType, isSaved: boolean): boolean {
return type === 'short' && !isSaved && (message.replies ?? 0) === 0
@@ -143,6 +143,7 @@
}
function handleContextMenu (event: MouseEvent): void {
if (readonly) return
const showCustomPopup = !isTextClicked(event.target as HTMLElement, event.clientX, event.clientY)
if (showCustomPopup) {
showMenu(event, { object: message, baseMenuClass: activity.class.ActivityMessage }, () => {
@@ -42,6 +42,7 @@
export let hoverStyles: 'borderedHover' | 'filledHover' = 'borderedHover'
export let hideLink = false
export let compact = false
export let readonly: boolean = false
export let onClick: (() => void) | undefined = undefined
const client = getClient()
@@ -96,6 +97,7 @@
<ActivityMessageTemplate
message={value}
{readonly}
{person}
{showNotify}
{isHighlighted}
@@ -54,6 +54,7 @@
export let hoverStyles: 'borderedHover' | 'filledHover' = 'borderedHover'
export let hideLink = false
export let type: ActivityMessageViewType = 'default'
export let readonly = false
export let space: Ref<Space> | undefined = undefined
export let onClick: (() => void) | undefined = undefined
@@ -195,6 +196,7 @@
{skipLabel}
{hoverable}
{hoverStyles}
{readonly}
type={viewlet?.label || getIsTextType(attributeModel) ? 'default' : type}
showDatePreposition={hideLink}
{onClick}
+4 -2
View File
@@ -47,7 +47,7 @@
"Settings": "Settings",
"ArchiveChannel": "Archive channel",
"UnarchiveChannel": "Unarchive channel",
"ArchiveConfirm": "Do you want to archive channel?",
"ArchiveConfirm": "When you archive a channel, its archived for everyone.<br/><br/>No one will be able to send messages, but theyll still have access to the channels history.<br/><br/>Youll still be able to find the channels contents via search.<br/>And you can always unarchive the channel in the future, if needed.\n",
"UnarchiveConfirm": "Do you want to unarchive channel?",
"AddToSaved": "Add to saved",
"RemoveFromSaved": "Remove from saved",
@@ -127,6 +127,8 @@
"Translate": "Translate",
"ShowOriginal": "Show original",
"Translating": "Translating...",
"StartConversation": "Start conversation"
"StartConversation": "Start conversation",
"ViewingThreadFromArchivedChannel": "You are viewing a thread from an archived channel",
"ViewingArchivedChannel": "You are viewing an archived channel"
}
}
+4 -2
View File
@@ -47,7 +47,7 @@
"Settings": "Ajustes",
"ArchiveChannel": "Archivar canal",
"UnarchiveChannel": "Desarchivar canal",
"ArchiveConfirm": "¿Quieres archivar el canal?",
"ArchiveConfirm": "Cuando archivas un canal, se archiva para todos.<br/><br/>Nadie podrá enviar mensajes, pero seguirán teniendo acceso al historial del canal.<br/><br/>Todavía podrás encontrar el contenido del canal a través de la búsqueda.<br/>Y siempre puedes desarchivar el canal en el futuro, si es necesario.\n",
"UnarchiveConfirm": "¿Quieres desarchivar el canal?",
"AddToSaved": "Añadir a guardados",
"RemoveFromSaved": "Eliminar de guardados",
@@ -127,6 +127,8 @@
"Translate": "Traducir",
"ShowOriginal": "Mostrar original",
"Translating": "Traduciendo...",
"StartConversation": "Iniciar conversación"
"StartConversation": "Iniciar conversación",
"ViewingThreadFromArchivedChannel": "Estás viendo un hilo de un canal archivado",
"ViewingArchivedChannel": "Estás viendo un canal archivado"
}
}
+4 -2
View File
@@ -47,7 +47,7 @@
"Settings": "Paramètres",
"ArchiveChannel": "Archiver le canal",
"UnarchiveChannel": "Désarchiver le canal",
"ArchiveConfirm": "Voulez-vous archiver le canal ?",
"ArchiveConfirm": "Lorsque vous archivez un canal, il est archivé pour tout le monde.<br/><br/>Personne ne pourra envoyer de messages, mais ils auront toujours accès à l'historique du canal.<br/><br/>Vous pourrez toujours trouver le contenu du canal via la recherche.<br/>Et vous pourrez toujours désarchiver le canal à l'avenir, si nécessaire.\n",
"UnarchiveConfirm": "Voulez-vous désarchiver le canal ?",
"AddToSaved": "Ajouter aux favoris",
"RemoveFromSaved": "Retirer des favoris",
@@ -127,6 +127,8 @@
"Translate": "Traduire",
"ShowOriginal": "Afficher l'original",
"Translating": "Traduction en cours...",
"StartConversation": "Démarrer la conversation"
"StartConversation": "Démarrer la conversation",
"ViewingThreadFromArchivedChannel": "Vous consultez un fil de discussion d'un canal archivé",
"ViewingArchivedChannel": "Vous consultez un canal archivé"
}
}
+4 -2
View File
@@ -47,7 +47,7 @@
"Settings": "Definições",
"ArchiveChannel": "Arquivar canal",
"UnarchiveChannel": "Desarquivar canal",
"ArchiveConfirm": "Deseja arquivar o canal?",
"ArchiveConfirm": "Quando arquivar um canal, ele é arquivado para todos.<br/><br/>Ninguém poderá enviar mensagens, mas ainda terão acesso ao histórico do canal.<br/><br/>Ainda poderá encontrar o conteúdo do canal através da pesquisa.<br/>E poderá sempre desarquivar o canal no futuro, se necessário.\n",
"UnarchiveConfirm": "Deseja desarquivar o canal?",
"AddToSaved": "Adicionar aos guardados",
"RemoveFromSaved": "Remover dos guardados",
@@ -127,6 +127,8 @@
"Translate": "Traduzir",
"ShowOriginal": "Mostrar original",
"Translating": "A traduzir...",
"StartConversation": "Iniciar conversa"
"StartConversation": "Iniciar conversa",
"ViewingThreadFromArchivedChannel": "Está a visualizar uma conversa em cadeia de um canal arquivado",
"ViewingArchivedChannel": "Está a visualizar um canal arquivado"
}
}
+4 -2
View File
@@ -47,7 +47,7 @@
"Settings": "Настройки",
"ArchiveChannel": "Архивировать канал",
"UnarchiveChannel": "Разархивировать канал",
"ArchiveConfirm": "Вы действительно хотите архивировать канал?",
"ArchiveConfirm": "При архивации канала он архивируется для всех.<br/><br/>Никто не сможет отправлять сообщения, но у них все равно будет доступ к истории канала.<br/><br/>Вы все равно сможете найти содержимое канала через поиск.<br/>И вы всегда сможете разархивировать канал в будущем, если это понадобится.\n",
"UnarchiveConfirm": "Вы действительно хотите разархивировать канал?",
"AddToSaved": "Добавить в сохраненные",
"RemoveFromSaved": "Удалить из сохраненных",
@@ -127,6 +127,8 @@
"Translate": "Перевести",
"ShowOriginal": "Показать оригинал",
"Translating": "Перевод...",
"StartConversation": "Начать диалог"
"StartConversation": "Начать диалог",
"ViewingThreadFromArchivedChannel": "Вы просматриваете обсуждение из архивированного канала",
"ViewingArchivedChannel": "Вы просматриваете архивированный канал"
}
}
+4 -2
View File
@@ -47,7 +47,7 @@
"Settings": "设置",
"ArchiveChannel": "归档频道",
"UnarchiveChannel": "取消归档频道",
"ArchiveConfirm": "你想要归档频道吗?",
"ArchiveConfirm": "当你归档频道时,它会对所有人进行归档。<br/><br/>没有人能够发送消息,但他们仍然可以访问频道的历史记录。<br/><br/>你仍然可以通过搜索找到频道的内容。<br/>如果需要,你可以随时取消归档频道。\n",
"UnarchiveConfirm": "你想要取消归档频道吗?",
"AddToSaved": "添加到已保存",
"RemoveFromSaved": "从已保存中移除",
@@ -127,6 +127,8 @@
"Translate": "翻译",
"ShowOriginal": "显示原文",
"Translating": "翻译中...",
"StartConversation": "开始对话"
"StartConversation": "开始对话",
"ViewingThreadFromArchivedChannel": "你正在查看已归档频道的线程",
"ViewingArchivedChannel": "你正在查看已归档频道"
}
}
@@ -103,6 +103,7 @@
{#if dataProvider}
<ChannelScrollView
{object}
channel={object}
skipLabels={!isDocChannel}
selectedFilters={filters}
startFromBottom
@@ -0,0 +1,118 @@
<!--
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { ActivityExtension as ActivityExtensionComponent } from '@hcengineering/activity-resources'
import { Class, Doc, Ref } from '@hcengineering/core'
import activity, { ActivityExtension } from '@hcengineering/activity'
import { getClient } from '@hcengineering/presentation'
import { AnySvelteComponent, Icon, Label } from '@hcengineering/ui'
import { Asset, getResource, translate } from '@hcengineering/platform'
import view from '@hcengineering/view'
import { getChannelName, getObjectIcon } from '../utils'
import chunter from '../plugin'
export let object: Doc
export let readonly = false
export let boundary: HTMLElement | undefined | null = undefined
export let collection: string | undefined
export let isThread = false
const client = getClient()
const hierarchy = client.getHierarchy()
let extensions: ActivityExtension[] = []
$: extensions = client.getModel().findAllSync(activity.class.ActivityExtension, { ofClass: object._class })
let icon: Asset | AnySvelteComponent | undefined = undefined
let name: string | undefined = undefined
$: void updateIcon(object._class)
$: void updateName(object)
async function updateIcon (_class: Ref<Class<Doc>>): Promise<void> {
if (isThread) {
return
}
const iconMixin = hierarchy.classHierarchyMixin(_class, view.mixin.ObjectIcon)
let result: AnySvelteComponent | Asset | undefined = undefined
if (iconMixin?.component) {
result = await getResource(iconMixin.component)
} else {
result = getObjectIcon(_class)
}
icon = result
}
async function updateName (object: Doc): Promise<void> {
const titleIntl = client.getHierarchy().getClass(object._class).label
name = (await getChannelName(object._id, object._class, object)) ?? (await translate(titleIntl, {}))
}
</script>
{#if !readonly}
<div class="ref-input flex-col">
<ActivityExtensionComponent
kind="input"
{extensions}
props={{ object, boundary, collection, autofocus: true, withTypingInfo: true }}
/>
</div>
{:else}
<div class="message">
{#if isThread}
<Label label={chunter.string.ViewingThreadFromArchivedChannel} />
{:else}
<Label label={chunter.string.ViewingArchivedChannel} />
<span class="info">
{#if icon}
<Icon {icon} size="x-small" />
{/if}
{#if name}
{name}
{/if}
</span>
{/if}
</div>
{/if}
<style lang="scss">
.ref-input {
flex-shrink: 0;
margin: 1.25rem 1rem 0;
max-height: 18.75rem;
}
.message {
display: flex;
align-items: center;
justify-content: center;
margin: 1rem;
padding: 0.5rem 0;
color: var(--global-primary-TextColor);
background: var(--global-ui-BorderColor);
border-radius: 0.5rem;
}
.info {
display: flex;
align-items: center;
justify-content: center;
margin-left: 0.25rem;
gap: 0.125rem;
font-weight: 600;
}
</style>
@@ -23,6 +23,7 @@
export let ids: Ref<Person>[] = []
export let disableRemoveFor: Ref<Person>[] = []
export let readonly = false
const dispatch = createEventDispatcher()
@@ -36,22 +37,24 @@
</script>
<div class="root">
<div class="item" style:padding="var(--spacing-1_5)" class:withoutBorder={persons.length === 0}>
<ModernButton
label={chunter.string.AddMembers}
icon={IconAddMember}
iconSize="small"
kind="secondary"
size="small"
on:click={() => dispatch('add')}
/>
</div>
{#if !readonly}
<div class="item" style:padding="var(--spacing-1_5)" class:withoutBorder={persons.length === 0}>
<ModernButton
label={chunter.string.AddMembers}
icon={IconAddMember}
iconSize="small"
kind="secondary"
size="small"
on:click={() => dispatch('add')}
/>
</div>
{/if}
<Scroller>
{#each persons as person, index (person._id)}
<div class="item" class:withoutBorder={index === persons.length - 1}>
<div class="item__content" class:disabled={disableRemoveFor.includes(person._id)}>
<div class="item__content" class:disabled={readonly || disableRemoveFor.includes(person._id)}>
<UserDetails {person} showStatus />
{#if !disableRemoveFor.includes(person._id)}
{#if !readonly && !disableRemoveFor.includes(person._id)}
<div class="item__action">
<ButtonIcon
icon={IconDelete}
@@ -13,20 +13,14 @@
// limitations under the License.
-->
<script lang="ts">
import activity, {
ActivityExtension,
ActivityMessage,
ActivityMessagesFilter,
DisplayActivityMessage
} from '@hcengineering/activity'
import activity, { ActivityMessage, ActivityMessagesFilter, DisplayActivityMessage } from '@hcengineering/activity'
import {
ActivityExtension as ActivityExtensionComponent,
ActivityMessagePresenter,
canGroupMessages,
messageInFocus,
sortActivityMessages
} from '@hcengineering/activity-resources'
import { Doc, getCurrentAccount, getDay, Ref, Timestamp } from '@hcengineering/core'
import core, { Doc, getCurrentAccount, getDay, Ref, Space, Timestamp } from '@hcengineering/core'
import { DocNotifyContext } from '@hcengineering/notification'
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
import { getResource } from '@hcengineering/platform'
@@ -48,9 +42,11 @@
import ActivityMessagesSeparator from './ChannelMessagesSeparator.svelte'
import JumpToDateSelector from './JumpToDateSelector.svelte'
import HistoryLoading from './LoadingHistory.svelte'
import ChannelInput from './ChannelInput.svelte'
export let provider: ChannelDataProvider
export let object: Doc
export let channel: Doc
export let selectedMessageId: Ref<ActivityMessage> | undefined = undefined
export let scrollElement: HTMLDivElement | undefined | null = undefined
export let startFromBottom = false
@@ -74,6 +70,7 @@
const me = getCurrentAccount()
const client = getClient()
const hierarchy = client.getHierarchy()
const inboxClient = InboxNotificationsClientImpl.getClient()
const contextByDocStore = inboxClient.contextByDoc
const notificationsByContextStore = inboxClient.inboxNotificationsByContext
@@ -94,7 +91,6 @@
let messages: ActivityMessage[] = []
let displayMessages: DisplayActivityMessage[] = []
let extensions: ActivityExtension[] = []
let scroller: Scroller | undefined | null = undefined
let separatorElement: HTMLDivElement | undefined = undefined
@@ -118,9 +114,8 @@
$: messages = $messagesStore
$: isLoading = $isLoadingStore
$: extensions = client.getModel().findAllSync(activity.class.ActivityExtension, { ofClass: doc._class })
$: notifyContext = $contextByDocStore.get(doc._id)
$: readonly = hierarchy.isDerived(channel._class, core.class.Space) ? (channel as Space).archived : false
void client
.getModel()
@@ -809,7 +804,7 @@
{/if}
<slot name="header" />
{#if displayMessages.length === 0 && !embedded}
{#if displayMessages.length === 0 && !embedded && !readonly}
<BlankView
icon={chunter.icon.Thread}
header={chunter.string.NoMessagesInChannel}
@@ -840,17 +835,12 @@
attachmentImageSize="x-large"
type={canGroup ? 'short' : 'default'}
hideLink
{readonly}
/>
{/each}
{#if !fixedInput}
<div class="ref-input flex-col">
<ActivityExtensionComponent
kind="input"
{extensions}
props={{ object, boundary: scrollElement, collection, autofocus: true, withTypingInfo: true }}
/>
</div>
<ChannelInput {object} {readonly} boundary={scrollElement} {collection} isThread={embedded} />
{/if}
{#if loadMoreAllowed && $canLoadNextForwardStore}
@@ -859,7 +849,7 @@
</Scroller>
{#if !embedded && showScrollDownButton}
<div class="down-button absolute">
<div class="down-button absolute" class:readonly>
<ModernButton
label={chunter.string.LatestMessages}
shape="round"
@@ -870,14 +860,8 @@
</div>
{/if}
</div>
{#if fixedInput && object}
<div class="ref-input flex-col">
<ActivityExtensionComponent
kind="input"
{extensions}
props={{ object, boundary: scrollElement, collection, autofocus: true, withTypingInfo: true }}
/>
</div>
{#if fixedInput}
<ChannelInput {object} {readonly} boundary={scrollElement} {collection} isThread={embedded} />
{/if}
{/if}
@@ -887,13 +871,6 @@
flex-shrink: 5;
}
.ref-input {
flex-shrink: 0;
margin: 1.25rem 1rem 1rem;
margin-bottom: 0;
max-height: 18.75rem;
}
.overlay {
width: 100%;
height: 100%;
@@ -920,6 +897,10 @@
animation: 0.5s fadeIn;
animation-fill-mode: forwards;
visibility: hidden;
&.readonly {
bottom: 0.25rem;
}
}
@keyframes fadeIn {
@@ -55,6 +55,7 @@
isThreadOpened = newLocation.path[4] != null
})
$: readonly = hierarchy.isDerived(object._class, core.class.Space) ? (object as Space).archived : false
$: showJoinOverlay = shouldShowJoinOverlay(object)
$: isDocChat = !hierarchy.isDerived(object._class, chunter.class.ChunterSpace)
$: withAside =
@@ -114,7 +115,7 @@
<div class="popupPanel-body" class:asideShown={withAside && isAsideShown}>
<div class="popupPanel-body__main">
{#key object._id}
{#if shouldShowJoinOverlay(object)}
{#if !readonly && shouldShowJoinOverlay(object)}
<div class="body h-full w-full clear-mins flex-center">
<div class="joinOverlay">
<div class="an-element__label header">
@@ -52,6 +52,7 @@
export let videoPreload = true
export let hideLink = false
export let compact = false
export let readonly = false
export let type: ActivityMessageViewType = 'default'
export let onClick: (() => void) | undefined = undefined
@@ -245,6 +246,7 @@
{skipLabel}
{pending}
{stale}
{readonly}
excludedActions={$shownTranslatedMessagesStore.has(value._id)
? [chunter.action.TranslateMessage]
: [chunter.action.ShowOriginalMessage]}
@@ -115,6 +115,7 @@
}
)
}
$: readonly = object?.archived ?? false
</script>
<DocAside {_class} {object}>
@@ -146,6 +147,7 @@
<ChannelMembers
ids={Array.from(members)}
disableRemoveFor={disabledRemoveFor}
{readonly}
on:add={openSelectUsersPopup}
on:remove={removeMember}
/>
@@ -13,7 +13,7 @@
// limitations under the License.
-->
<script lang="ts">
import { Class, Doc, Mixin, Ref } from '@hcengineering/core'
import core, { Class, Doc, Mixin, Ref, Space } from '@hcengineering/core'
import {
AttributeBarEditor,
getClient,
@@ -50,6 +50,8 @@
)
return filtredKeys.filter((key) => !isCollectionAttr(hierarchy, key))
}
$: readonly = hierarchy.isDerived(_class, core.class.Space) ? (object as Space).archived : false
</script>
<Scroller>
@@ -59,7 +61,7 @@
{object}
ignoreKeys={objectChatPanel?.ignoreKeys ?? []}
showHeader={false}
readonly={false}
{readonly}
on:update
/>
<div class="popupPanel-body__aside-grid">
@@ -65,7 +65,8 @@
private: selectedVisibilityId === 'private',
archived: false,
members: [account._id],
topic: description
topic: description,
owners: [account._id]
})
openChannel(channelId, chunter.class.Channel)
@@ -39,7 +39,6 @@
const client = getClient()
const hierarchy = client.getHierarchy()
const inboxClient = InboxNotificationsClientImpl.getClient()
const contextByDocStore = inboxClient.contextByDoc
const contextsStore = inboxClient.contexts
const objectsQueryByClass = new Map<Ref<Class<Doc>>, { query: LiveQuery, limit: number }>()
@@ -70,18 +69,17 @@
sections = res
})
$: shouldPushObject =
object !== undefined && getObjectGroup(object) === model.id && !$contextByDocStore.has(object._id)
$: shouldPushObject = object !== undefined && getObjectGroup(object) === model.id
function loadObjects (contexts: DocNotifyContext[]): void {
const contextsByClass = groupByArray(contexts, ({ objectClass }) => objectClass)
for (const [_class, ctx] of contextsByClass.entries()) {
const isChunterSpace = hierarchy.isDerived(_class, chunter.class.ChunterSpace)
const isSpace = hierarchy.isDerived(_class, core.class.Space)
const ids = ctx.map(({ objectId }) => objectId)
const { query, limit } = objectsQueryByClass.get(_class) ?? {
query: createQuery(),
limit: isChunterSpace ? -1 : model.maxSectionItems ?? 5
limit: isSpace ? -1 : model.maxSectionItems ?? 5
}
objectsQueryByClass.set(_class, { query, limit: limit ?? model.maxSectionItems ?? 5 })
@@ -90,7 +88,7 @@
_class,
{
_id: { $in: limit !== -1 ? ids.slice(0, limit) : ids },
...(isChunterSpace ? { space: core.space.Space } : {})
...(isSpace ? { space: core.space.Space, archived: false } : {})
},
(res) => {
objectsByClass = objectsByClass.set(_class, { docs: res, total: res.total })
@@ -3,15 +3,31 @@
import ThreadParentMessage from './ThreadParentPresenter.svelte'
import { Label } from '@hcengineering/ui'
import ChannelScrollView from '../ChannelScrollView.svelte'
import { Ref } from '@hcengineering/core'
import core, { Doc, Ref, Space } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { ChannelDataProvider } from '../../channelDataProvider'
import chunter from '../../plugin'
export let selectedMessageId: Ref<ActivityMessage> | undefined = undefined
export let message: ActivityMessage
const query = createQuery()
const client = getClient()
const hierarchy = client.getHierarchy()
let channel: Doc | undefined = undefined
let dataProvider: ChannelDataProvider | undefined = undefined
$: query.query(
message.attachedToClass,
{ _id: message.attachedTo },
(res) => {
channel = res[0]
},
{ limit: 1 }
)
$: if (message !== undefined && dataProvider === undefined) {
dataProvider = new ChannelDataProvider(
undefined,
@@ -24,22 +40,26 @@
}
$: messagesStore = dataProvider?.messagesStore
$: readonly = hierarchy.isDerived(message.attachedToClass, core.class.Space)
? (channel as Space)?.archived ?? false
: false
</script>
<div class="hulyComponent-content hulyComponent-content__container noShrink">
{#if dataProvider !== undefined}
{#if dataProvider !== undefined && channel !== undefined}
<ChannelScrollView
bind:selectedMessageId
embedded
skipLabels
object={message}
{channel}
provider={dataProvider}
fullHeight={false}
fixedInput={false}
>
<svelte:fragment slot="header">
<div class="mt-3">
<ThreadParentMessage {message} />
<ThreadParentMessage {message} {readonly} />
</div>
{#if (message.replies ?? $messagesStore?.length ?? 0) > 0}
@@ -39,6 +39,7 @@
export let hoverStyles: 'borderedHover' | 'filledHover' = 'borderedHover'
export let attachmentImageSize: AttachmentImageSize = 'x-large'
export let videoPreload = true
export let readonly = false
export let onClick: (() => void) | undefined = undefined
const client = getClient()
@@ -74,5 +75,6 @@
{attachmentImageSize}
{videoPreload}
{onClick}
{readonly}
/>
{/if}
@@ -17,6 +17,7 @@
import { ActivityMessage } from '@hcengineering/activity'
export let message: ActivityMessage
export let readonly = false
</script>
<ActivityMessagePresenter
@@ -26,4 +27,5 @@
withShowMore={false}
attachmentImageSize="x-large"
skipLabel
{readonly}
/>
+1
View File
@@ -92,6 +92,7 @@ export async function ArchiveChannel (channel: Channel, evt: any, props?: { afte
showPopup(MessageBox, {
label: chunter.string.ArchiveChannel,
message: chunter.string.ArchiveConfirm,
richMessage: true,
action: async () => {
const client = getClient()
+3 -1
View File
@@ -215,7 +215,9 @@ export default plugin(chunterId, {
Translate: '' as IntlString,
ShowOriginal: '' as IntlString,
Translating: '' as IntlString,
StartConversation: '' as IntlString
StartConversation: '' as IntlString,
ViewingThreadFromArchivedChannel: '' as IntlString,
ViewingArchivedChannel: '' as IntlString
},
ids: {
DMNotification: '' as Ref<NotificationType>,