Update activity layout (#430)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2021-11-30 14:12:14 +03:00 committed by GitHub
parent c06d48e0b0
commit c72376987e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 195 additions and 139 deletions

View File

@ -36,11 +36,11 @@
action.action()
}}>
{#if action.icon}
<div class="icon">
<Icon icon={action.icon} size={'large'} />
<div class="scale-75">
<Icon icon={action.icon} size={'medium'} />
</div>
{/if}
<div class="label"><Label label={action.label} /></div>
<div class="ml-3"><Label label={action.label} /></div>
</div>
{/each}
</div>
@ -59,19 +59,13 @@
display: flex;
align-items: center;
padding: .375rem 1rem .375rem .5rem;
color: var(--theme-content-color);
border-radius: .5rem;
cursor: pointer;
.icon {
margin-right: .75rem;
transform-origin: center center;
transform: scale(.75);
opacity: .3;
&:hover {
background-color: var(--theme-button-bg-hovered);
color: var(--theme-caption-color);
}
.label {
flex-grow: 1;
color: var(--theme-content-accent-color);
}
&:hover { background-color: var(--theme-button-bg-hovered); }
}
</style>

View File

@ -3,6 +3,8 @@
"Delete": "Delete",
"Edit": "Edit",
"Options": "Options",
"Edited": "edited"
"Edited": "edited",
"ShowMore": "Show more",
"ShowLess": "Show less"
}
}

View File

@ -133,7 +133,7 @@
.right-content {
flex-grow: 1;
padding: 2.5rem 2.5rem 0;
padding: 2.25rem 2.5rem 0;
background-color: var(--theme-dialog-accent);
}

View File

@ -13,6 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import type { TxViewlet } from '@anticrm/activity'
import activity from '@anticrm/activity'
@ -34,6 +35,7 @@
} from '@anticrm/ui'
import type { Action, AttributeModel } from '@anticrm/view'
import { buildModel, getActions, getObjectPresenter } from '@anticrm/view-resources'
import { afterUpdate } from 'svelte'
import { activityKey, ActivityKey, DisplayTx } from '../activity'
export let tx: DisplayTx
@ -54,6 +56,20 @@
let actions: Action[] = []
let edit = false
let contentHTML: HTMLElement
let bigMsg: boolean | undefined = undefined
let outterBtn: boolean | undefined = undefined
const showContent = (): void => { bigMsg = outterBtn = true }
const hideContent = (): void => { bigMsg = outterBtn = false }
const toggleContent = (): void => bigMsg ? hideContent() : showContent()
afterUpdate(() => {
if (contentHTML) {
if (contentHTML.scrollHeight !== contentHTML.clientHeight) (edit) ? showContent() : hideContent()
if (contentHTML.clientHeight < 240) bigMsg = outterBtn = undefined
}
})
$: if (tx.tx._id !== ptx?.tx._id) {
viewlet = undefined
@ -163,68 +179,80 @@
</script>
{#if (viewlet !== undefined && !((viewlet?.hideOnRemove ?? false) && tx.removed)) || model.length > 0}
<div class="flex-col msgactivity-container">
<div class="flex-between">
<div class="flex-center icon">
<div class="scale-75">
{#if viewlet}
<Icon icon={viewlet.icon} size="medium" />
{:else}
<Icon icon={activity.icon.Activity} size="medium" />
{/if}
</div>
</div>
<div class="flex-grow label">
<div class="bold">
{#if employee}
{formatName(employee.name)}
{:else}
No employee
{/if}
</div>
{#if viewlet && viewlet?.editable}
<div class="edited">
{#if viewlet.label}
<Label label={viewlet.label} />
{/if}
{#if tx.updated}
<Label label={activity.string.Edited} />
{/if}
<div class="menuOptions" on:click={(ev) => showMenu(ev)}>
<IconMoreH size={'small'} />
</div>
</div>
{:else if viewlet && viewlet.label}
<div>
<Label label={viewlet.label} />
</div>
{/if}
{#if viewlet === undefined && model.length > 0 && tx.updateTx}
{#each model as m}
<span>changed {m.label} to</span>
<div class="strong"><svelte:component this={m.presenter} value={getValue(tx.updateTx, m.key)} /></div>
{/each}
{:else if viewlet && viewlet.display === 'inline' && viewlet.component}
<div>
{#if typeof viewlet.component === 'string'}
<Component is={viewlet.component} {props} on:close={onCancelEdit} />
{:else}
<svelte:component this={viewlet.component} {...props} on:close={onCancelEdit} />
{/if}
</div>
{/if}
</div>
<div class="time"><TimeSince value={tx.tx.modifiedOn} /></div>
</div>
{#if viewlet && viewlet.component && viewlet.display !== 'inline'}
<div class="content" class:emphasize={viewlet.display === 'emphasized'}>
{#if typeof viewlet.component === 'string'}
<Component is={viewlet.component} {props} on:close={onCancelEdit} />
<div class="flex-between msgactivity-container">
<div class="flex-center icon">
<div class="scale-75">
{#if viewlet}
<Icon icon={viewlet.icon} size="medium" />
{:else}
<svelte:component this={viewlet.component} {...props} on:close={onCancelEdit} />
<Icon icon={activity.icon.Activity} size="medium" />
{/if}
</div>
{/if}
</div>
<div class="flex-grow flex-col relative">
<div class="flex-between">
<div class="flex-grow label">
<div class="bold">
{#if employee}
{formatName(employee.name)}
{:else}
No employee
{/if}
</div>
{#if viewlet && viewlet?.editable}
<div class="edited">
{#if viewlet.label}
<Label label={viewlet.label} />
{/if}
{#if tx.updated}
<Label label={activity.string.Edited} />
{/if}
<div class="menuOptions" on:click={(ev) => showMenu(ev)}>
<IconMoreH size={'medium'} />
</div>
</div>
{:else if viewlet && viewlet.label}
<div>
<Label label={viewlet.label} />
</div>
{/if}
{#if viewlet === undefined && model.length > 0 && tx.updateTx}
{#each model as m}
<span>changed {m.label} to</span>
<div class="strong"><svelte:component this={m.presenter} value={getValue(tx.updateTx, m.key)} /></div>
{/each}
{:else if viewlet && viewlet.display === 'inline' && viewlet.component}
<div>
{#if typeof viewlet.component === 'string'}
<Component is={viewlet.component} {props} on:close={onCancelEdit} />
{:else}
<svelte:component this={viewlet.component} {...props} on:close={onCancelEdit} />
{/if}
</div>
{/if}
</div>
<div class="time"><TimeSince value={tx.tx.modifiedOn} /></div>
</div>
{#if viewlet && viewlet.component && viewlet.display !== 'inline'}
<div bind:this={contentHTML} class={viewlet.display} class:full={bigMsg || edit} class:mask={bigMsg === false && !edit}>
{#if typeof viewlet.component === 'string'}
<Component is={viewlet.component} {props} on:close={onCancelEdit} />
{:else}
<svelte:component this={viewlet.component} {...props} on:close={onCancelEdit} />
{/if}
</div>
{#if typeof outterBtn !== 'undefined' && !edit}
<div class="showMore" class:outter={outterBtn} on:click={toggleContent}>
<Label label={(bigMsg) ? activity.string.ShowLess : activity.string.ShowMore} />
</div>
{/if}
{/if}
</div>
</div>
{/if}
@ -254,12 +282,10 @@
// :global(.msgactivity-container > *:last-child::after) { content: none; }
.menuOptions {
margin-left: 0.5rem;
opacity: 0.6;
margin-left: .5rem;
opacity: .6;
cursor: pointer;
&:hover {
opacity: 1;
}
&:hover { opacity: 1; }
}
.icon {
flex-shrink: 0;
@ -272,20 +298,6 @@
border-radius: 50%;
}
.content {
margin: 0.5rem 0 0.5rem 3.25rem;
}
.emphasize {
background-color: var(--theme-bg-accent-color);
border: 1px solid var(--theme-bg-accent-color);
border-radius: 0.75rem;
padding: 1rem;
}
.time {
margin-left: 1rem;
color: var(--theme-content-trans-color);
}
.edited {
display: flex;
align-items: center;
@ -297,12 +309,8 @@
align-items: center;
flex-wrap: wrap;
& > * {
margin-right: 0.5rem;
}
& > *:last-child {
margin-right: 0;
}
& > * { margin-right: .5rem; }
& > *:last-child { margin-right: 0; }
.bold {
font-weight: 500;
color: var(--theme-caption-color);
@ -312,4 +320,61 @@
color: var(--theme-content-accent-color);
}
}
.time {
margin-left: 1rem;
color: var(--theme-content-trans-color);
}
.content {
flex-shrink: 0;
overflow: hidden;
margin-top: .5rem;
height: max-content;
max-height: 15rem;
&.full { max-height: max-content; }
&.mask { mask: linear-gradient(to top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 75%); }
}
.showMore {
position: absolute;
left: 0;
right: 0;
bottom: 0;
margin: 0 auto;
padding: .5rem 1rem;
width: fit-content;
font-size: .75rem;
color: var(--theme-caption-color);
background: var(--theme-card-bg);
border: .5px solid var(--theme-card-divider);
box-shadow: 0px 8px 15px rgba(0, 0, 0, .1);
backdrop-filter: blur(120px);
border-radius: 2.5rem;
cursor: pointer;
opacity: .3;
transform: scale(.9);
transition: opacity .1s ease-in-out, transform .1s ease-in-out;
&:hover {
opacity: 1;
transform: scale(1);
}
&:active {
opacity: .9;
transform: scale(.95);
}
&.outter { bottom: -1.5rem; }
}
.emphasized {
margin-top: .5rem;
background-color: var(--theme-bg-accent-color);
border: 1px solid var(--theme-bg-accent-color);
border-radius: .75rem;
padding: 1rem 1.25rem;
}
</style>

View File

@ -52,7 +52,9 @@ export default plugin(activityId, {
Delete: '' as IntlString,
Edit: '' as IntlString,
Options: '' as IntlString,
Edited: '' as IntlString
Edited: '' as IntlString,
ShowMore: '' as IntlString,
ShowLess: '' as IntlString
},
icon: {
Activity: '' as Asset

View File

@ -110,23 +110,23 @@
}
}
.buttons {
position: absolute;
visibility: hidden;
top: -.5rem;
right: -.5rem;
display: flex;
flex-direction: row-reverse;
user-select: none;
// .buttons {
// position: absolute;
// visibility: hidden;
// top: -.5rem;
// right: -.5rem;
// display: flex;
// flex-direction: row-reverse;
// user-select: none;
.tool + .tool {
margin-right: .5rem;
}
}
// .tool + .tool {
// margin-right: .5rem;
// }
// }
&:hover > .buttons {
visibility: visible;
}
// &:hover > .buttons {
// visibility: visible;
// }
&:hover::before {
content: '';
}

View File

@ -14,8 +14,8 @@
-->
<script lang="ts">
import type { Comment } from "@anticrm/chunter";
import type { TxCreateDoc } from "@anticrm/core";
import type { Comment } from "@anticrm/chunter"
import type { TxCreateDoc } from "@anticrm/core"
import { getClient, MessageViewer } from '@anticrm/presentation'
import { ReferenceInput } from "@anticrm/text-editor"
import { Button } from "@anticrm/ui"
@ -39,30 +39,23 @@
}
let refInput: ReferenceInput
</script>
<div class='container' class:editing={editing}>
<div class="text">
{#if edit}
<ReferenceInput bind:this={refInput} content={value.message} on:message={onMessage} showSend={false}/>
<div class='flex-row-reverse flex-grab'>
<Button label={chunter.string.EditCancel} on:click={() => {
dispatch('close', false)
}}/>
<Button label={chunter.string.EditUpdate} on:click={() => refInput.submit()} />
</div>
{:else}
<MessageViewer message={value.message}/>
{/if}
</div>
<div class:editing={editing}>
{#if edit}
<ReferenceInput bind:this={refInput} content={value.message} on:message={onMessage} showSend={false}/>
<div class='flex-row-reverse safari-gap-2 reverse'>
<Button label={chunter.string.EditCancel} on:click={() => {
dispatch('close', false)
}}/>
<Button label={chunter.string.EditUpdate} on:click={() => refInput.submit()} />
</div>
{:else}
<MessageViewer message={value.message}/>
{/if}
</div>
<style lang="scss">
.container {
.text {
line-height: 150%;
color: var(--theme-content-color);
}
.editing {
border: 1px solid var(--primary-button-focused-border);
}
.editing {
border: 1px solid var(--primary-button-focused-border);
}
</style>