mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-17 18:05:42 +02:00
UBERF-8288: Fix archiving a channel (#6750)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
@@ -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'
|
||||
|
||||
@@ -285,7 +285,7 @@ export const coreOperation: MigrateOperation = {
|
||||
func: migrateAllSpaceToTyped
|
||||
},
|
||||
{
|
||||
state: 'add-spaces-owner',
|
||||
state: 'add-spaces-owner-v1',
|
||||
func: migrateSpacesOwner
|
||||
},
|
||||
{
|
||||
|
||||
+2
@@ -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">
|
||||
|
||||
+2
@@ -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
|
||||
}}
|
||||
/>
|
||||
|
||||
+3
-2
@@ -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 }, () => {
|
||||
|
||||
+2
@@ -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}
|
||||
|
||||
+2
@@ -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}
|
||||
|
||||
@@ -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, it’s archived for everyone.<br/><br/>No one will be able to send messages, but they’ll still have access to the channel’s history.<br/><br/>You’ll still be able to find the channel’s 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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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é"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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": "Вы просматриваете архивированный канал"
|
||||
}
|
||||
}
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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>,
|
||||
|
||||
Reference in New Issue
Block a user