Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into staging
Browse files Browse the repository at this point in the history
Signed-off-by: Andrey Sobolev <[email protected]>
  • Loading branch information
haiodo committed Dec 3, 2024
2 parents 4ef6258 + abdf257 commit f0e7af4
Show file tree
Hide file tree
Showing 97 changed files with 873 additions and 475 deletions.
2 changes: 1 addition & 1 deletion desktop/src/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ window.addEventListener('DOMContentLoaded', () => {
}
} else {
showPopup(MessageBox, {
label: settings.string.OwnerOrMainteinerRequired
label: settings.string.OwnerOrMaintainerRequired
})
}
})
Expand Down
58 changes: 27 additions & 31 deletions models/core/src/migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.
//

import { saveCollabJson, saveCollabYdoc, yDocFromBuffer } from '@hcengineering/collaboration'
import { saveCollabJson } from '@hcengineering/collaboration'
import core, {
coreId,
DOMAIN_MODEL_TX,
Expand Down Expand Up @@ -348,10 +348,6 @@ async function processMigrateJsonForDoc (
? `${attribute.attributeOf}.${attribute.name}`
: attribute.name

// Name of existing ydoc document
// original value here looks like '65b7f82f4d422b89d4cbdd6f:HEAD:0'
// where the first part is the blob id
const currentYdocId = value.split(':')[0] as Ref<Blob>
const collabId = makeDocCollabId(doc, attribute.name)

if (value.startsWith('{')) {
Expand All @@ -361,34 +357,34 @@ async function processMigrateJsonForDoc (
continue
}

try {
const stat = await storageAdapter.stat(ctx, workspaceId, currentYdocId)
if (stat !== undefined) {
if (stat.contentType.includes('application/ydoc')) {
const buffer = await storageAdapter.read(ctx, workspaceId, currentYdocId)
const ydoc = yDocFromBuffer(Buffer.concat(buffer as any))

// If document id has changed, save it with new name to ensure we will be able to load it later
const ydocId = makeCollabYdocId(collabId)
if (ydocId !== currentYdocId) {
ctx.info('saving collaborative doc with new name', { collabId, ydocId, currentYdocId })
await saveCollabYdoc(ctx, storageAdapter, workspaceId, collabId, ydoc)
// do not bother with deletion so we can restore content is something goes wrong
// await storageAdapter.remove(ctx, client.workspaceId, [currentYdocId])
}
if (!value.includes(':')) {
// not a collaborative document, skip
continue
}

// Save document as JSON and save blob Id
const jsonId = await saveCollabJson(ctx, storageAdapter, workspaceId, collabId, ydoc)
update[attributeName] = jsonId
} else {
// it is not ydoc, do nothing
continue
}
} else {
// document is empty, unset
const unset = update.$unset ?? {}
update.$unset = { ...unset, [attribute.name]: 1 }
// Name of existing ydoc document
// original value here looks like '65b7f82f4d422b89d4cbdd6f:HEAD:0'
// where the first part is the blob id
const currentYdocId = value.split(':')[0] as Ref<Blob>

try {
// If document id has changed, save it with new name to ensure we will be able to load it later
const ydocId = makeCollabYdocId(collabId)
if (ydocId !== currentYdocId) {
ctx.info('saving collaborative doc with new name', { collabId, ydocId, currentYdocId })
const buffer = await storageAdapter.read(ctx, workspaceId, currentYdocId)
await storageAdapter.put(
ctx,
workspaceId,
ydocId,
Buffer.concat(buffer as any),
'application/ydoc',
buffer.length
)
}

const unset = update.$unset ?? {}
update.$unset = { ...unset, [attribute.name]: 1 }
} catch (err) {
ctx.warn('failed to process collaborative doc', { workspaceId, collabId, currentYdocId, err })
}
Expand Down
13 changes: 10 additions & 3 deletions models/test-management/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export function createModel (builder: Builder): void {
defineTestSuite(builder)
defineTestCase(builder)
defineTestRun(builder)
defineTestResult(builder)

definePresenters(builder)

Expand Down Expand Up @@ -261,7 +262,7 @@ function defineTestSuite (builder: Builder): void {
// Actions

builder.mixin(testManagement.class.TestSuite, core.class.Class, view.mixin.IgnoreActions, {
actions: [print.action.Print, tracker.action.EditRelatedTargets]
actions: [print.action.Print, tracker.action.EditRelatedTargets, tracker.action.NewRelatedIssue]
})

createAction(
Expand Down Expand Up @@ -331,7 +332,7 @@ function defineTestCase (builder: Builder): void {

builder.mixin(testManagement.class.TestCase, core.class.Class, view.mixin.ClassFilters, {
filters: ['priority', 'status'],
ignoreKeys: ['createdBy', 'modifiedBy', 'createdOn', 'modifiedOn']
ignoreKeys: ['createdBy', 'modifiedBy', 'createdOn', 'modifiedOn', 'name']
})

builder.createDoc(
Expand Down Expand Up @@ -419,6 +420,12 @@ function defineTestRun (builder: Builder): void {
component: testManagement.component.TestResultStatusPresenter
})

builder.mixin(testManagement.class.TestRun, core.class.Class, view.mixin.IgnoreActions, {
actions: [print.action.Print, tracker.action.EditRelatedTargets, tracker.action.NewRelatedIssue]
})
}

function defineTestResult (builder: Builder): void {
builder.mixin(testManagement.class.TestResult, core.class.Class, view.mixin.ObjectPresenter, {
presenter: testManagement.component.TestResultPresenter
})
Expand Down Expand Up @@ -448,7 +455,7 @@ function defineTestRun (builder: Builder): void {

builder.mixin(testManagement.class.TestResult, core.class.Class, view.mixin.ClassFilters, {
filters: ['assignee', 'status', 'testSuite'],
ignoreKeys: ['createdBy', 'modifiedBy', 'createdOn', 'modifiedOn']
ignoreKeys: ['createdBy', 'modifiedBy', 'createdOn', 'modifiedOn', 'name', 'attachedTo']
})

const viewOptions: ViewOptionsModel = {
Expand Down
3 changes: 2 additions & 1 deletion models/test-management/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import type { ActionCategory } from '@hcengineering/view'
export default mergeIds(testManagementId, testManganement, {
category: {
TestSuite: '' as Ref<ActionCategory>,
TestCase: '' as Ref<ActionCategory>
TestCase: '' as Ref<ActionCategory>,
TestResult: '' as Ref<ActionCategory>
},
component: {
CreateTestCase: '' as AnyComponent,
Expand Down
3 changes: 3 additions & 0 deletions models/test-management/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,15 @@ export class TTestResult extends TAttachedDoc implements TestResult {
testCase!: Ref<TestCase>

@Prop(TypeRef(testManagement.class.TestSuite), testManagement.string.TestSuite)
@Index(IndexKind.Indexed)
testSuite?: Ref<TestSuite>

@Prop(TypeTestRunStatus(), testManagement.string.TestRunStatus)
@Index(IndexKind.Indexed)
status?: TestRunStatus

@Prop(TypeRef(contact.mixin.Employee), testManagement.string.TestAssignee)
@Index(IndexKind.Indexed)
assignee?: Ref<Employee>

@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files })
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/components/Section.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import Icon from './Icon.svelte'
import Label from './Label.svelte'
export let id: string | undefined = undefined
export let label: IntlString
export let icon: Asset | AnySvelteComponent | undefined = undefined
Expand All @@ -27,7 +28,7 @@
export let invisible: boolean = false
</script>

<div class="antiSection">
<div class="antiSection" {id}>
{#if showHeader}
<div class="antiSection-header" class:high class:invisible>
{#if icon}
Expand Down
142 changes: 73 additions & 69 deletions plugins/activity-resources/src/components/Activity.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
} from '@hcengineering/activity'
import { Doc, Ref, SortingOrder } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { Grid, Label, Spinner, location, Lazy } from '@hcengineering/ui'
import { Grid, Label, Section, Spinner, location, Lazy } from '@hcengineering/ui'
import { onDestroy, onMount } from 'svelte'
import ActivityExtensionComponent from './ActivityExtension.svelte'
Expand Down Expand Up @@ -235,77 +235,81 @@
$: void updateActivityMessages(object._id, isNewestFirst ? SortingOrder.Descending : SortingOrder.Ascending)
</script>

<div class="antiSection-header high mt-9" class:invisible={transparent}>
<span class="antiSection-header__title flex-row-center">
<Label label={activity.string.Activity} />
{#if isLoading}
<div class="ml-1">
<Spinner size="small" />
</div>
{/if}
</span>
<ActivityFilter
messages={allMessages}
{object}
on:update={(e) => {
filteredMessages = e.detail
}}
bind:isNewestFirst
/>
</div>
{#if isNewestFirst && showCommenInput}
<div class="ref-input newest-first">
<ActivityExtensionComponent
kind="input"
{extensions}
props={{ object, boundary, focusIndex, withTypingInfo: true }}
/>
</div>
{/if}
<div
class="p-activity select-text"
id={activity.string.Activity}
class:newest-first={isNewestFirst}
bind:this={activityBox}
>
{#if filteredMessages.length}
<Grid column={1} rowGap={0}>
{#each filteredMessages as message, index}
{@const canGroup = canGroupMessages(message, filteredMessages[index - 1])}
{#if selectedMessageId}
<ActivityMessagePresenter
value={message}
doc={object}
hideLink={true}
type={canGroup ? 'short' : 'default'}
isHighlighted={selectedMessageId === message._id}
withShowMore
<div class="step-tb-6">
<Section label={activity.string.Activity} icon={activity.icon.Activity}>
<svelte:fragment slot="header">
{#if isLoading}
<div class="ml-1">
<Spinner size="small" />
</div>
{/if}
<ActivityFilter
messages={allMessages}
{object}
on:update={(e) => {
filteredMessages = e.detail
}}
bind:isNewestFirst
/>
</svelte:fragment>

<svelte:fragment slot="content">
{#if isNewestFirst && showCommenInput}
<div class="ref-input newest-first">
<ActivityExtensionComponent
kind="input"
{extensions}
props={{ object, boundary, focusIndex, withTypingInfo: true }}
/>
{:else}
<Lazy>
<ActivityMessagePresenter
value={message}
doc={object}
hideLink={true}
type={canGroup ? 'short' : 'default'}
isHighlighted={selectedMessageId === message._id}
withShowMore
/>
</Lazy>
</div>
{/if}
<div
class="p-activity select-text"
id={activity.string.Activity}
class:newest-first={isNewestFirst}
bind:this={activityBox}
>
{#if filteredMessages.length}
<Grid column={1} rowGap={0}>
{#each filteredMessages as message, index}
{@const canGroup = canGroupMessages(message, filteredMessages[index - 1])}
{#if selectedMessageId}
<ActivityMessagePresenter
value={message}
doc={object}
hideLink={true}
type={canGroup ? 'short' : 'default'}
isHighlighted={selectedMessageId === message._id}
withShowMore
/>
{:else}
<Lazy>
<ActivityMessagePresenter
value={message}
doc={object}
hideLink={true}
type={canGroup ? 'short' : 'default'}
isHighlighted={selectedMessageId === message._id}
withShowMore
/>
</Lazy>
{/if}
{/each}
</Grid>
{/if}
{/each}
</Grid>
{/if}
</div>
{#if showCommenInput && !isNewestFirst}
<div class="ref-input oldest-first">
<ActivityExtensionComponent
kind="input"
{extensions}
props={{ object, boundary, focusIndex, withTypingInfo: true }}
/>
</div>
{/if}
</svelte:fragment>
</Section>
</div>
{#if showCommenInput && !isNewestFirst}
<div class="ref-input oldest-first">
<ActivityExtensionComponent
kind="input"
{extensions}
props={{ object, boundary, focusIndex, withTypingInfo: true }}
/>
</div>
{/if}

<style lang="scss">
.ref-input {
Expand Down
10 changes: 6 additions & 4 deletions plugins/activity-resources/src/components/ActivityFilter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { ActivityMessage, ActivityMessagesFilter } from '@hcengineering/activity'
import { Doc, Ref, SortingOrder } from '@hcengineering/core'
import { getResource } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation'
import { ActionIcon, eventToHTMLElement, Icon, Label, showPopup } from '@hcengineering/ui'
import { ActivityMessage, ActivityMessagesFilter } from '@hcengineering/activity'
import { Button, eventToHTMLElement, Icon, Label, showPopup } from '@hcengineering/ui'
import view from '@hcengineering/view'
import activity from '../plugin'
import FilterPopup from './FilterPopup.svelte'
import IconClose from './icons/Close.svelte'
import IconFilter from './icons/Filter.svelte'
import { sortActivityMessages } from '../activityMessagesUtils'
export let messages: ActivityMessage[]
Expand Down Expand Up @@ -146,4 +146,6 @@
{/if}
{/if}
<div class="w-4 min-w-4 max-w-4" />
<ActionIcon icon={IconFilter} size={'medium'} action={handleOptions} />
<div class="buttons-group small-gap pr-2">
<Button icon={view.icon.Configure} size={'small'} kind={'ghost'} on:click={handleOptions} />
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@
</div>

{#if withActions && !readonly}
<div class="actions" class:pending class:opened={isActionsOpened}>
<div class="actions" class:pending class:opened={isActionsOpened} class:isShort>
<ActivityMessageActions
message={isReactionMessage(message) ? parentMessage : message}
{actions}
Expand Down Expand Up @@ -326,6 +326,9 @@
&.opened:not(.pending) {
visibility: visible;
}
&.isShort {
top: -1.875rem;
}
}
&:hover > .actions {
Expand Down
Loading

0 comments on commit f0e7af4

Please sign in to comment.