Make inbox messages more compact (#4378)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina 2024-01-18 12:52:59 +04:00 committed by GitHub
parent f40548f0c1
commit cf8ff1be31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 116 additions and 118 deletions

View File

@ -37,6 +37,7 @@
export let shouldScroll: boolean = false export let shouldScroll: boolean = false
export let embedded: boolean = false export let embedded: boolean = false
export let withActions: boolean = true export let withActions: boolean = true
export let withFlatActions: boolean = true
export let excludedActions: string[] = [] export let excludedActions: string[] = []
export let actions: Action[] = [] export let actions: Action[] = []
export let onClick: (() => void) | undefined = undefined export let onClick: (() => void) | undefined = undefined
@ -70,6 +71,7 @@
{withActions} {withActions}
{actions} {actions}
{excludedActions} {excludedActions}
{withFlatActions}
viewlet={undefined} viewlet={undefined}
{onClick} {onClick}
> >

View File

@ -31,6 +31,7 @@
export let skipLabel = false export let skipLabel = false
export let actions: Action[] = [] export let actions: Action[] = []
export let excludedActions: string[] = [] export let excludedActions: string[] = []
export let withFlatActions: boolean = true
export let onClick: (() => void) | undefined = undefined export let onClick: (() => void) | undefined = undefined
export let onReply: (() => void) | undefined = undefined export let onReply: (() => void) | undefined = undefined
@ -56,6 +57,7 @@
hideReplies, hideReplies,
actions, actions,
excludedActions, excludedActions,
withFlatActions,
onClick, onClick,
onReply onReply
}} }}

View File

@ -46,8 +46,10 @@
export let shouldScroll: boolean = false export let shouldScroll: boolean = false
export let embedded: boolean = false export let embedded: boolean = false
export let withActions: boolean = true export let withActions: boolean = true
export let withFlatActions: boolean = true
export let showEmbedded = false export let showEmbedded = false
export let hideReplies = false export let hideReplies = false
export let skipLabel = false
export let onClick: (() => void) | undefined = undefined export let onClick: (() => void) | undefined = undefined
export let onReply: (() => void) | undefined = undefined export let onReply: (() => void) | undefined = undefined
@ -150,8 +152,9 @@
</div> </div>
{/if} {/if}
<slot name="header" /> {#if !skipLabel}
<slot name="header" />
{/if}
<span class="text-sm">{getDisplayTime(message.createdOn ?? 0)}</span> <span class="text-sm">{getDisplayTime(message.createdOn ?? 0)}</span>
</div> </div>
@ -175,17 +178,19 @@
class:opened={isActionMenuOpened || message.isPinned} class:opened={isActionMenuOpened || message.isPinned}
> >
{#if withActions} {#if withActions}
<AddReactionAction object={message} /> {#if withFlatActions}
<PinMessageAction object={message} /> <AddReactionAction object={message} />
<SaveMessageAction object={message} /> <PinMessageAction object={message} />
<SaveMessageAction object={message} />
<ActivityMessageExtensionComponent <ActivityMessageExtensionComponent
kind="action" kind="action"
{extensions} {extensions}
props={{ object: message }} props={{ object: message }}
on:close={handleActionMenuClosed} on:close={handleActionMenuClosed}
on:open={handleActionMenuOpened} on:open={handleActionMenuOpened}
/> />
{/if}
{#if withActionMenu} {#if withActionMenu}
<ActionIcon icon={IconMoreH} size="small" action={showMenu} /> <ActionIcon icon={IconMoreH} size="small" action={showMenu} />
{/if} {/if}

View File

@ -46,6 +46,8 @@
export let showEmbedded = false export let showEmbedded = false
export let hideReplies = false export let hideReplies = false
export let actions: Action[] = [] export let actions: Action[] = []
export let skipLabel = false
export let withFlatActions: boolean = true
export let excludedActions: string[] = [] export let excludedActions: string[] = []
export let onClick: (() => void) | undefined = undefined export let onClick: (() => void) | undefined = undefined
export let onReply: (() => void) | undefined = undefined export let onReply: (() => void) | undefined = undefined
@ -157,6 +159,8 @@
{showEmbedded} {showEmbedded}
{hideReplies} {hideReplies}
{actions} {actions}
{skipLabel}
{withFlatActions}
{onClick} {onClick}
{onReply} {onReply}
> >

View File

@ -41,6 +41,7 @@
export let skipLabel = false export let skipLabel = false
export let actions: Action[] = [] export let actions: Action[] = []
export let excludedActions: string[] = [] export let excludedActions: string[] = []
export let withFlatActions: boolean = true
export let onClick: (() => void) | undefined = undefined export let onClick: (() => void) | undefined = undefined
export let onReply: (() => void) | undefined = undefined export let onReply: (() => void) | undefined = undefined
@ -164,6 +165,7 @@
actions={additionalActions} actions={additionalActions}
{showEmbedded} {showEmbedded}
{hideReplies} {hideReplies}
{withFlatActions}
{onClick} {onClick}
{onReply} {onReply}
> >

View File

@ -25,6 +25,7 @@
export let withActions: boolean = true export let withActions: boolean = true
export let showEmbedded = false export let showEmbedded = false
export let skipLabel = false export let skipLabel = false
export let withFlatActions: boolean = true
export let onClick: (() => void) | undefined = undefined export let onClick: (() => void) | undefined = undefined
export let onReply: (() => void) | undefined = undefined export let onReply: (() => void) | undefined = undefined
</script> </script>
@ -39,6 +40,7 @@
{showEmbedded} {showEmbedded}
{embedded} {embedded}
{skipLabel} {skipLabel}
{withFlatActions}
{onClick} {onClick}
{onReply} {onReply}
/> />

View File

@ -23,7 +23,7 @@
} from '@hcengineering/notification' } from '@hcengineering/notification'
import { ActivityMessagePresenter, combineActivityMessages } from '@hcengineering/activity-resources' import { ActivityMessagePresenter, combineActivityMessages } from '@hcengineering/activity-resources'
import activity, { ActivityMessage, DisplayActivityMessage } from '@hcengineering/activity' import activity, { ActivityMessage, DisplayActivityMessage } from '@hcengineering/activity'
import { location, Action, CheckBox, getLocation, navigate, Component } from '@hcengineering/ui' import { location, Action, getLocation, navigate, Component } from '@hcengineering/ui'
import { getActions } from '@hcengineering/view-resources' import { getActions } from '@hcengineering/view-resources'
import { getResource } from '@hcengineering/platform' import { getResource } from '@hcengineering/platform'
import chunter from '@hcengineering/chunter' import chunter from '@hcengineering/chunter'
@ -35,7 +35,6 @@
export let skipLabel = false export let skipLabel = false
export let viewlets: ActivityNotificationViewlet[] = [] export let viewlets: ActivityNotificationViewlet[] = []
export let onClick: (() => void) | undefined = undefined export let onClick: (() => void) | undefined = undefined
export let onCheck: ((isChecked: boolean) => void) | undefined = undefined
const client = getClient() const client = getClient()
const messagesQuery = createQuery() const messagesQuery = createQuery()
@ -120,43 +119,23 @@
</script> </script>
{#if displayMessage !== undefined} {#if displayMessage !== undefined}
<div class="notification gap-2 ml-2"> {#if viewlet}
{#if !embedded} <Component is={viewlet.presenter} props={{ message: displayMessage, notification: value, embedded, onClick }} />
<div class="mt-6"> {:else}
<CheckBox <ActivityMessagePresenter
circle value={displayMessage}
kind="primary" showNotify={!value.isViewed && !embedded}
on:value={(event) => { isSelected={displayMessage._id === selectedMessageId}
if (onCheck) { excludedActions={[chunter.action.ReplyToThread]}
onCheck(event.detail) showEmbedded
} {embedded}
}} {skipLabel}
/> {actions}
</div> withFlatActions={false}
{/if} onReply={() => {
{#if viewlet} handleReply(displayMessage)
<Component is={viewlet.presenter} props={{ message: displayMessage, notification: value, embedded, onClick }} /> }}
{:else} {onClick}
<ActivityMessagePresenter />
value={displayMessage} {/if}
showNotify={!value.isViewed && !embedded}
isSelected={displayMessage._id === selectedMessageId}
excludedActions={[chunter.action.ReplyToThread]}
showEmbedded
{embedded}
{skipLabel}
{actions}
onReply={() => {
handleReply(displayMessage)
}}
{onClick}
/>
{/if}
</div>
{/if} {/if}
<style lang="scss">
.notification {
display: flex;
}
</style>

View File

@ -29,15 +29,14 @@
import { ActionIcon, CheckBox, IconMoreH, Label, showPopup } from '@hcengineering/ui' import { ActionIcon, CheckBox, IconMoreH, Label, showPopup } from '@hcengineering/ui'
import { getDocLinkTitle, Menu } from '@hcengineering/view-resources' import { getDocLinkTitle, Menu } from '@hcengineering/view-resources'
import { ActivityDocLink } from '@hcengineering/activity-resources' import { ActivityDocLink } from '@hcengineering/activity-resources'
import activity from '@hcengineering/activity'
import view from '@hcengineering/view' import view from '@hcengineering/view'
import { InboxNotificationsClientImpl } from '../../inboxNotificationsClient' import { InboxNotificationsClientImpl } from '../../inboxNotificationsClient'
export let value: CommonInboxNotification export let value: CommonInboxNotification
export let embedded = false export let embedded = false
export let skipLabel = false
export let onClick: (() => void) | undefined = undefined export let onClick: (() => void) | undefined = undefined
export let onCheck: ((isChecked: boolean) => void) | undefined = undefined
const objectQuery = createQuery() const objectQuery = createQuery()
const client = getClient() const client = getClient()
@ -92,48 +91,35 @@
} }
</script> </script>
<div class="flex-presenter gap-2 ml-2"> <!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="root clear-mins flex-grow" on:click={onClick}>
{#if !embedded} {#if !embedded}
<CheckBox {#if !value.isViewed}
circle <div class="notify" />
kind="primary"
on:value={(event) => {
if (onCheck) {
onCheck(event.detail)
}
}}
/>
{/if}
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="root clear-mins flex-grow" on:click={onClick}>
{#if !embedded}
{#if !value.isViewed}
<div class="notify" />
{/if}
{#if value.icon}
<SystemAvatar size="medium" icon={value.icon} iconProps={value.iconProps} />
{:else if person}
<Avatar size="medium" avatar={person.avatar} name={person.name} />
{:else}
<SystemAvatar size="medium" />
{/if}
{:else}
<div class="embeddedMarker" />
{/if} {/if}
<div class="content ml-2 w-full clear-mins">
<div class="header clear-mins"> {#if value.icon}
{#if person} <SystemAvatar size="medium" icon={value.icon} iconProps={value.iconProps} />
<EmployeePresenter value={person} shouldShowAvatar={false} /> {:else if person}
{:else} <Avatar size="medium" avatar={person.avatar} name={person.name} />
<div class="strong"> {:else}
<Label label={core.string.System} /> <SystemAvatar size="medium" />
</div> {/if}
{/if} {:else}
{#if value.header} <div class="embeddedMarker" />
<span class="text-sm lower"><Label label={value.header} /></span> {/if}
{/if} <div class="content ml-2 w-full clear-mins">
<div class="header clear-mins">
{#if person}
<EmployeePresenter value={person} shouldShowAvatar={false} />
{:else}
<div class="strong">
<Label label={core.string.System} />
</div>
{/if}
{#if !skipLabel && value.header}
<span class="text-sm lower"><Label label={value.header} /></span>
{#if object} {#if object}
{#await getDocLinkTitle(client, object._id, object._class, object) then linkTitle} {#await getDocLinkTitle(client, object._id, object._class, object) then linkTitle}
@ -144,23 +130,23 @@
/> />
{/await} {/await}
{/if} {/if}
{/if}
<span class="text-sm">{getDisplayTime(value.createdOn ?? 0)}</span> <span class="text-sm">{getDisplayTime(value.createdOn ?? 0)}</span>
</div>
<div class="flex-row-center">
<div class="customContent">
<MessageViewer message={content} />
</div>
</div>
</div> </div>
{#if !embedded} <div class="flex-row-center">
<div class="actions clear-mins flex flex-gap-2 items-center" class:opened={isActionMenuOpened}> <div class="customContent">
<ActionIcon icon={IconMoreH} size="small" action={showMenu} /> <MessageViewer message={content} />
</div> </div>
{/if} </div>
</div> </div>
{#if !embedded}
<div class="actions clear-mins flex flex-gap-2 items-center" class:opened={isActionMenuOpened}>
<ActionIcon icon={IconMoreH} size="small" action={showMenu} />
</div>
{/if}
</div> </div>
<style lang="scss"> <style lang="scss">

View File

@ -41,17 +41,33 @@
<Scroller> <Scroller>
{#each notifications as notification (notification._id)} {#each notifications as notification (notification._id)}
<div animate:flip={{ duration: 500 }}> <div animate:flip={{ duration: 500 }}>
<InboxNotificationPresenter <div class="notification gap-2 ml-2">
value={notification} <!-- <div class="mt-6">-->
{viewlets} <!-- <CheckBox-->
onCheck={(isChecked) => handleCheck(notification, isChecked)} <!-- circle-->
onClick={() => { <!-- kind="primary"-->
dispatch('click', { <!-- on:value={(event) => {-->
context: $notifyContextsStore.find(({ _id }) => _id === notification.docNotifyContext), <!-- handleCheck(notification, event.detail)-->
notification <!-- }}-->
}) <!-- />-->
}} <!-- </div>-->
/> <InboxNotificationPresenter
value={notification}
{viewlets}
onClick={() => {
dispatch('click', {
context: $notifyContextsStore.find(({ _id }) => _id === notification.docNotifyContext),
notification
})
}}
/>
</div>
</div> </div>
{/each} {/each}
</Scroller> </Scroller>
<style lang="scss">
.notification {
display: flex;
}
</style>