mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-11 21:11:57 +00:00
parent
0800f97f3c
commit
c26c92023e
@ -140,16 +140,14 @@ class ActivityImpl implements Activity {
|
|||||||
|
|
||||||
const parents = new Map<Ref<Doc>, DisplayTx>()
|
const parents = new Map<Ref<Doc>, DisplayTx>()
|
||||||
|
|
||||||
const results: DisplayTx[] = []
|
let results: DisplayTx[] = []
|
||||||
|
|
||||||
for (const tx of txCUD) {
|
for (const tx of txCUD) {
|
||||||
const { collectionCUD, updateCUD, result, tx: ntx } = this.createDisplayTx(tx, parents)
|
const { collectionCUD, updateCUD, result, tx: ntx } = this.createDisplayTx(tx, parents)
|
||||||
// We do not need collection object updates, in main list of displayed transactions.
|
// We do not need collection object updates, in main list of displayed transactions.
|
||||||
if (this.isDisplayTxRequired(collectionCUD, updateCUD, ntx, object)) {
|
if (this.isDisplayTxRequired(collectionCUD, updateCUD, ntx, object)) {
|
||||||
// Combine previous update transaction for same field and if same operation and time treshold is ok
|
// Combine previous update transaction for same field and if same operation and time treshold is ok
|
||||||
this.checkIntegratePreviousTx(results, result)
|
results = this.integrateTxWithResults(results, result)
|
||||||
results.push(result)
|
|
||||||
|
|
||||||
this.updateRemovedState(result, results)
|
this.updateRemovedState(result, results)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,7 +186,7 @@ class ActivityImpl implements Activity {
|
|||||||
let updateCUD = false
|
let updateCUD = false
|
||||||
const hierarchy = this.client.getHierarchy()
|
const hierarchy = this.client.getHierarchy()
|
||||||
if (hierarchy.isDerived(tx._class, core.class.TxCollectionCUD)) {
|
if (hierarchy.isDerived(tx._class, core.class.TxCollectionCUD)) {
|
||||||
tx = getCollectionTx((tx as TxCollectionCUD<Doc, AttachedDoc>))
|
tx = getCollectionTx(tx as TxCollectionCUD<Doc, AttachedDoc>)
|
||||||
collectionCUD = true
|
collectionCUD = true
|
||||||
}
|
}
|
||||||
let firstTx = parents.get(tx.objectId)
|
let firstTx = parents.get(tx.objectId)
|
||||||
@ -237,24 +235,27 @@ class ActivityImpl implements Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkIntegratePreviousTx (results: DisplayTx[], result: DisplayTx): void {
|
integrateTxWithResults (results: DisplayTx[], result: DisplayTx): DisplayTx[] {
|
||||||
if (results.length > 0) {
|
const curUpdate = result.tx as unknown as TxUpdateDoc<Doc>
|
||||||
const prevTx = results[results.length - 1]
|
|
||||||
|
const newResult = results.filter((prevTx) => {
|
||||||
if (this.isSameKindTx(prevTx, result)) {
|
if (this.isSameKindTx(prevTx, result)) {
|
||||||
const prevUpdate = prevTx.tx as unknown as TxUpdateDoc<Doc>
|
const prevUpdate = prevTx.tx as unknown as TxUpdateDoc<Doc>
|
||||||
const curUpdate = result.tx as unknown as TxUpdateDoc<Doc>
|
|
||||||
if (
|
if (
|
||||||
isEqualOps(prevUpdate.operations, curUpdate.operations) &&
|
result.tx.modifiedOn - prevUpdate.modifiedOn < combineThreshold &&
|
||||||
result.tx.modifiedOn - prevUpdate.modifiedOn < combineThreshold
|
isEqualOps(prevUpdate.operations, curUpdate.operations)
|
||||||
) {
|
) {
|
||||||
// we have same keys, l
|
// we have same keys,
|
||||||
// Remember previous transactions
|
// Remember previous transactions
|
||||||
result.txes.push(...prevTx.txes, prevTx.tx)
|
result.txes.push(...prevTx.txes, prevTx.tx)
|
||||||
// Remove last item
|
return false
|
||||||
results.splice(results.length - 1, 1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
newResult.push(result)
|
||||||
|
return newResult
|
||||||
}
|
}
|
||||||
|
|
||||||
isSameKindTx (prevTx: DisplayTx, result: DisplayTx): boolean {
|
isSameKindTx (prevTx: DisplayTx, result: DisplayTx): boolean {
|
||||||
|
@ -20,7 +20,18 @@
|
|||||||
import core, { Class, Doc, Ref, TxCUD, TxUpdateDoc } from '@anticrm/core'
|
import core, { Class, Doc, Ref, TxCUD, TxUpdateDoc } from '@anticrm/core'
|
||||||
import { getResource, IntlString } from '@anticrm/platform'
|
import { getResource, IntlString } from '@anticrm/platform'
|
||||||
import { getClient } from '@anticrm/presentation'
|
import { getClient } from '@anticrm/presentation'
|
||||||
import { AnyComponent, AnySvelteComponent, Component, Icon, IconEdit, IconMoreH, Label, Menu, showPopup, TimeSince } from '@anticrm/ui'
|
import {
|
||||||
|
AnyComponent,
|
||||||
|
AnySvelteComponent,
|
||||||
|
Component,
|
||||||
|
Icon,
|
||||||
|
IconEdit,
|
||||||
|
IconMoreH,
|
||||||
|
Label,
|
||||||
|
Menu,
|
||||||
|
showPopup,
|
||||||
|
TimeSince
|
||||||
|
} from '@anticrm/ui'
|
||||||
import type { Action, AttributeModel } from '@anticrm/view'
|
import type { Action, AttributeModel } from '@anticrm/view'
|
||||||
import { buildModel, getActions, getObjectPresenter } from '@anticrm/view-resources'
|
import { buildModel, getActions, getObjectPresenter } from '@anticrm/view-resources'
|
||||||
import { activityKey, ActivityKey, DisplayTx } from '../activity'
|
import { activityKey, ActivityKey, DisplayTx } from '../activity'
|
||||||
@ -29,7 +40,9 @@
|
|||||||
export let viewlets: Map<ActivityKey, TxViewlet>
|
export let viewlets: Map<ActivityKey, TxViewlet>
|
||||||
|
|
||||||
type TxDisplayViewlet =
|
type TxDisplayViewlet =
|
||||||
| (Pick<TxViewlet, 'icon' | 'label' | 'display'|'editable' | 'hideOnRemove'> & { component?: AnyComponent | AnySvelteComponent })
|
| (Pick<TxViewlet, 'icon' | 'label' | 'display' | 'editable' | 'hideOnRemove'> & {
|
||||||
|
component?: AnyComponent | AnySvelteComponent
|
||||||
|
})
|
||||||
| undefined
|
| undefined
|
||||||
|
|
||||||
let ptx: DisplayTx | undefined
|
let ptx: DisplayTx | undefined
|
||||||
@ -102,7 +115,7 @@
|
|||||||
const ops = {
|
const ops = {
|
||||||
client,
|
client,
|
||||||
_class: tx.updateTx.objectClass,
|
_class: tx.updateTx.objectClass,
|
||||||
keys: Object.keys(tx.updateTx.operations).filter(id => !id.startsWith('$')),
|
keys: Object.keys(tx.updateTx.operations).filter((id) => !id.startsWith('$')),
|
||||||
ignoreMissing: true
|
ignoreMissing: true
|
||||||
}
|
}
|
||||||
buildModel(ops).then((m) => {
|
buildModel(ops).then((m) => {
|
||||||
@ -118,24 +131,30 @@
|
|||||||
return (utx.operations as any)[key]
|
return (utx.operations as any)[key]
|
||||||
}
|
}
|
||||||
const showMenu = async (ev: MouseEvent): Promise<void> => {
|
const showMenu = async (ev: MouseEvent): Promise<void> => {
|
||||||
showPopup(Menu, {
|
showPopup(
|
||||||
actions: [{
|
Menu,
|
||||||
label: activity.string.Edit,
|
{
|
||||||
icon: IconEdit,
|
actions: [
|
||||||
action: () => {
|
{
|
||||||
edit = true
|
label: activity.string.Edit,
|
||||||
props = { ...props, edit }
|
icon: IconEdit,
|
||||||
}
|
action: () => {
|
||||||
}, ...actions.map(a => ({
|
edit = true
|
||||||
label: a.label,
|
props = { ...props, edit }
|
||||||
icon: a.icon,
|
}
|
||||||
action: async () => {
|
},
|
||||||
const impl = await getResource(a.action)
|
...actions.map((a) => ({
|
||||||
await impl(tx.doc as Doc)
|
label: a.label,
|
||||||
}
|
icon: a.icon,
|
||||||
}))
|
action: async () => {
|
||||||
]
|
const impl = await getResource(a.action)
|
||||||
}, ev.target as HTMLElement)
|
await impl(tx.doc as Doc)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
]
|
||||||
|
},
|
||||||
|
ev.target as HTMLElement
|
||||||
|
)
|
||||||
}
|
}
|
||||||
const onCancelEdit = () => {
|
const onCancelEdit = () => {
|
||||||
edit = false
|
edit = false
|
||||||
@ -164,23 +183,21 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if viewlet && viewlet?.editable}
|
{#if viewlet && viewlet?.editable}
|
||||||
<div class='edited'>
|
<div class="edited">
|
||||||
{#if viewlet.label}
|
{#if viewlet.label}
|
||||||
<Label label={viewlet.label} />
|
<Label label={viewlet.label} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if tx.updated}
|
{#if tx.updated}
|
||||||
<Label label={activity.string.Edited}/>
|
<Label label={activity.string.Edited} />
|
||||||
{/if}
|
{/if}
|
||||||
<div class="menuOptions" on:click={(ev) => showMenu(ev)}>
|
<div class="menuOptions" on:click={(ev) => showMenu(ev)}>
|
||||||
<IconMoreH size={'small'} />
|
<IconMoreH size={'small'} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else if viewlet && viewlet.label}
|
||||||
{#if viewlet && viewlet.label}
|
<div>
|
||||||
<div>
|
<Label label={viewlet.label} />
|
||||||
<Label label={viewlet.label} />
|
</div>
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
{/if}
|
||||||
{#if viewlet === undefined && model.length > 0 && tx.updateTx}
|
{#if viewlet === undefined && model.length > 0 && tx.updateTx}
|
||||||
{#each model as m}
|
{#each model as m}
|
||||||
@ -237,10 +254,12 @@
|
|||||||
// :global(.msgactivity-container > *:last-child::after) { content: none; }
|
// :global(.msgactivity-container > *:last-child::after) { content: none; }
|
||||||
|
|
||||||
.menuOptions {
|
.menuOptions {
|
||||||
margin-left: .5rem;
|
margin-left: 0.5rem;
|
||||||
opacity: .6;
|
opacity: 0.6;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
&:hover { opacity: 1; }
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.icon {
|
.icon {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user