Merge branch 'staging' into develop

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev
2025-02-06 13:52:19 +07:00
14 changed files with 123 additions and 70 deletions
+8
View File
@@ -74,6 +74,14 @@ export function createModel (builder: Builder): void {
}
})
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverTracker.trigger.OnProjectRemove,
txMatch: {
_class: core.class.TxRemoveDoc,
objectClass: tracker.class.Project
}
})
builder.mixin(
tracker.ids.AssigneeNotification,
notification.class.NotificationType,
+7 -5
View File
@@ -7,7 +7,7 @@ import {
navigate,
languageStore
} from '@hcengineering/ui'
import { type Ref, type Doc, type Class, generateId } from '@hcengineering/core'
import { type Ref, type Doc, type Class, generateId, concatLink } from '@hcengineering/core'
import activity, { type ActivityMessage } from '@hcengineering/activity'
import {
type Channel,
@@ -19,10 +19,10 @@ import {
import { type DocNotifyContext, notificationId } from '@hcengineering/notification'
import workbench, { type Widget, workbenchId, type LocationData } from '@hcengineering/workbench'
import { classIcon, getObjectLinkId, parseLinkId } from '@hcengineering/view-resources'
import { getClient } from '@hcengineering/presentation'
import presentation, { getClient } from '@hcengineering/presentation'
import view, { encodeObjectURI, decodeObjectURI } from '@hcengineering/view'
import { createWidgetTab, isElementFromSidebar, sidebarStore } from '@hcengineering/workbench-resources'
import { type Asset, type IntlString, translate } from '@hcengineering/platform'
import { type Asset, getMetadata, type IntlString, translate } from '@hcengineering/platform'
import contact from '@hcengineering/contact'
import { get } from 'svelte/store'
@@ -113,8 +113,10 @@ export async function getMessageLink (message: ActivityMessage): Promise<string>
}
const id = encodeURIComponent(encodeObjectURI(_id, _class))
return `${window.location.protocol}//${window.location.host}/${workbenchId}/${location.path[1]}/${chunterId}/${id}${threadParent}?message=${message._id}`
const frontUrl = getMetadata(presentation.metadata.FrontUrl)
const protocolAndHost = frontUrl ?? `${window.location.protocol}//${window.location.host}`
const path = `${workbenchId}/${location.path[1]}/${chunterId}/${id}${threadParent}?message=${message._id}`
return concatLink(protocolAndHost, path)
}
export async function chunterSpaceLinkFragmentProvider (doc: ChunterSpace): Promise<Location> {
+4
View File
@@ -44,5 +44,9 @@
"@hcengineering/notification": "^0.6.23",
"@hcengineering/attachment": "^0.6.14",
"@hcengineering/preference": "^0.6.13"
},
"repository": "https://github.com/hcengineering/platform",
"publishConfig": {
"registry": "https://npm.pkg.github.com"
}
}
@@ -13,7 +13,9 @@
// limitations under the License.
-->
<script lang="ts">
import { NavLink } from '@hcengineering/presentation'
import { concatLink } from '@hcengineering/core'
import { getMetadata } from '@hcengineering/platform'
import presentation, { NavLink } from '@hcengineering/presentation'
import { trackerId, type Issue, type IssueParentInfo } from '@hcengineering/tracker'
import { getCurrentLocation, locationToUrl } from '@hcengineering/ui'
@@ -26,7 +28,8 @@
loc.path[2] = trackerId
loc.path[3] = parentInfo.identifier
loc.path.length = 4
return `${window.location.origin}${locationToUrl(loc)}`
const frontUrl = getMetadata(presentation.metadata.FrontUrl) ?? window.location.origin
return concatLink(frontUrl, locationToUrl(loc))
}
</script>
+1 -50
View File
@@ -14,17 +14,13 @@
//
import { Analytics } from '@hcengineering/analytics'
import core, {
type AttachedDoc,
import {
type Attribute,
type Class,
ClassifierKind,
type Client,
type Doc,
type DocManager,
type DocumentQuery,
DOMAIN_CONFIGURATION,
DOMAIN_MODEL,
getCurrentAccount,
type Ref,
type RelatedDocument,
@@ -275,52 +271,7 @@ async function deleteProject (project: Project | undefined): Promise<void> {
labelProps: { name: project.name },
message: tracker.string.DeleteProjectConfirm,
action: async () => {
// void client.update(project, { archived: true })
const client = getClient()
const classes = await client.findAll(core.class.Class, {})
const h = client.getHierarchy()
for (const c of classes) {
if (c.kind !== ClassifierKind.CLASS) {
continue
}
const d = h.findDomain(c._id)
if (d !== undefined && d !== DOMAIN_MODEL && d !== DOMAIN_CONFIGURATION) {
try {
while (true) {
const docs = await client.findAll(c._id, { space: project._id }, { limit: 50 })
if (docs.length === 0) {
break
}
const ops = client.apply(undefined, 'delete-project')
for (const object of docs) {
if (client.getHierarchy().isDerived(object._class, core.class.AttachedDoc)) {
const adoc = object as AttachedDoc
await ops
.removeCollection(
object._class,
object.space,
adoc._id,
adoc.attachedTo,
adoc.attachedToClass,
adoc.collection
)
.catch((err) => {
console.error(err)
})
} else {
await ops.removeDoc(object._class, object.space, object._id).catch((err) => {
console.error(err)
})
}
}
await ops.commit()
}
} catch (err: any) {
console.error(err)
Analytics.handleError(err)
}
}
}
await client.remove(project)
}
})
@@ -16,16 +16,20 @@
-->
<script lang="ts">
import { NavLink } from '@hcengineering/presentation'
import presentation, { NavLink } from '@hcengineering/presentation'
import { locationToUrl } from '@hcengineering/ui'
import { Document } from '@hcengineering/controlled-documents'
import { documentRoute } from '../routing/routes/documentRoute'
import { getMetadata } from '@hcengineering/platform'
import { concatLink } from '@hcengineering/core'
export let value: Document
const frontUrl = getMetadata(presentation.metadata.FrontUrl) ?? window.location.origin
let href: string | undefined
$: {
href = `${window.location.origin}${locationToUrl(documentRoute.build({ id: value._id }))}`
href = concatLink(frontUrl, locationToUrl(documentRoute.build({ id: value._id })))
}
</script>
@@ -13,11 +13,12 @@
// limitations under the License.
-->
<script lang="ts">
import { Doc, Hierarchy } from '@hcengineering/core'
import { NavLink, getClient } from '@hcengineering/presentation'
import { concatLink, Doc, Hierarchy } from '@hcengineering/core'
import presentation, { NavLink, getClient } from '@hcengineering/presentation'
import { AnyComponent, getPanelURI, locationToUrl } from '@hcengineering/ui'
import view from '../plugin'
import { getObjectLinkFragment, restrictionStore } from '../utils'
import { getMetadata } from '@hcengineering/platform'
export let object: Doc | undefined
export let disabled: boolean = false
@@ -50,7 +51,8 @@
const panelComponent = hierarchy.classHierarchyMixin(object._class, view.mixin.ObjectPanel)
const comp = panelComponent?.component ?? component
const loc = await getObjectLinkFragment(hierarchy, object, props, comp)
href = `${window.location.origin}${locationToUrl(loc)}`
const frontUrl = getMetadata(presentation.metadata.FrontUrl) ?? window.location.origin
href = concatLink(frontUrl, locationToUrl(loc))
}
$: if (object !== undefined) getHref(object)
+29 -6
View File
@@ -16,10 +16,11 @@
import chunter, { ChatMessage } from '@hcengineering/chunter'
import { Person } from '@hcengineering/contact'
import core, {
PersonId,
AccountRole,
concatLink,
Doc,
DocumentUpdate,
PersonId,
Ref,
Space,
Tx,
@@ -28,16 +29,15 @@ import core, {
TxProcessor,
TxRemoveDoc,
TxUpdateDoc,
WithLookup,
AccountRole
WithLookup
} from '@hcengineering/core'
import { NotificationContent } from '@hcengineering/notification'
import { getMetadata, IntlString } from '@hcengineering/platform'
import { getSocialStrings } from '@hcengineering/server-contact'
import serverCore, { TriggerControl } from '@hcengineering/server-core'
import { NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification'
import { getSocialStrings } from '@hcengineering/server-contact'
import { stripTags } from '@hcengineering/text'
import tracker, { Component, Issue, IssueParentInfo, TimeSpendReport, trackerId } from '@hcengineering/tracker'
import tracker, { Component, Issue, IssueParentInfo, TimeSpendReport, trackerId, type Project } from '@hcengineering/tracker'
import { workbenchId } from '@hcengineering/workbench'
async function updateSubIssues (
@@ -176,6 +176,28 @@ export async function OnSocialIdentityCreate (_txes: Tx[], control: TriggerContr
return []
}
/**
* @public
*/
export async function OnProjectRemove (txes: Tx[], control: TriggerControl): Promise<Tx[]> {
const result: Tx[] = []
for (const tx of txes) {
const ctx = tx as TxRemoveDoc<Project>
const classes = [tracker.class.Issue, tracker.class.Component, tracker.class.Milestone, tracker.class.IssueTemplate]
for (const cls of classes) {
const docs = await control.findAll(control.ctx, cls, { space: ctx.objectId })
for (const doc of docs) {
const tx = control.txFactory.createTxRemoveDoc(cls, doc.space, doc._id)
result.push(tx)
}
}
}
control.ctx.contextData.broadcast.targets.projectRemove = (it) => {
return []
}
return result
}
/**
* @public
*/
@@ -516,6 +538,7 @@ export default async () => ({
trigger: {
OnSocialIdentityCreate,
OnIssueUpdate,
OnComponentRemove
OnComponentRemove,
OnProjectRemove
}
})
+2 -1
View File
@@ -37,6 +37,7 @@ export default plugin(serverTrackerId, {
trigger: {
OnSocialIdentityCreate: '' as Resource<TriggerFunc>,
OnIssueUpdate: '' as Resource<TriggerFunc>,
OnComponentRemove: '' as Resource<TriggerFunc>
OnComponentRemove: '' as Resource<TriggerFunc>,
OnProjectRemove: '' as Resource<TriggerFunc>
}
})
+1 -1
View File
@@ -326,7 +326,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
private handleRemove (tx: TxCUD<Space>): void {
const removeTx = tx as TxRemoveDoc<Space>
if (!this.context.hierarchy.isDerived(removeTx.objectClass, core.class.Space)) return
if (removeTx._class !== core.class.TxCreateDoc) return
if (removeTx._class !== core.class.TxRemoveDoc) return
this.removeSpace(tx.objectId)
}
@@ -34,6 +34,7 @@
"@hcengineering/server-github": "^0.6.0",
"@hcengineering/server-core": "^0.6.1",
"@hcengineering/github": "^0.6.0",
"@hcengineering/tracker": "^0.6.24",
"@hcengineering/notification": "^0.6.23",
"@hcengineering/server-notification": "^0.6.1",
"@hcengineering/time": "^0.6.0"
@@ -8,6 +8,7 @@ import core from '@hcengineering/core'
import serverCore from '@hcengineering/server-core'
import serverGithub from '@hcengineering/server-github'
import time from '@hcengineering/time'
import tracker from '@hcengineering/tracker'
export { serverGithubId } from '@hcengineering/server-github'
@@ -16,6 +17,15 @@ export function createModel (builder: Builder): void {
trigger: serverGithub.trigger.OnProjectChanges,
isAsync: true
})
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverGithub.trigger.OnProjectRemove,
txMatch: {
_class: core.class.TxRemoveDoc,
objectClass: tracker.class.Project
}
})
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverGithub.trigger.OnGithubBroadcast,
isAsync: false
@@ -97,10 +97,53 @@ export async function OnProjectChanges (txes: Tx[], control: TriggerControl): Pr
return result
}
/**
* @public
*/
export async function OnProjectRemove (txes: Tx[], control: TriggerControl): Promise<Tx[]> {
const result: Tx[] = []
for (const ltx of txes) {
if (ltx._class === core.class.TxRemoveDoc) {
const cud = ltx as TxCUD<Doc>
if (control.hierarchy.isDerived(cud.objectClass, tracker.class.Project)) {
const project = control.removedMap.get(cud.objectId)
if (project === undefined) {
continue
}
if (control.hierarchy.hasMixin(project, github.mixin.GithubProject)) {
const repos = await control.findAll(control.ctx, github.class.GithubIntegrationRepository, {
githubProject: cud.objectId as Ref<GithubProject>
})
for (const repo of repos) {
result.push(
control.txFactory.createTxUpdateDoc(repo._class, repo.space, repo._id, {
enabled: false,
githubProject: null
})
)
}
const syncDocs = control.modelDb.findAllSync(github.class.DocSyncInfo, {
space: cud.objectId as Ref<Space>
})
for (const syncDoc of syncDocs) {
result.push(control.txFactory.createTxRemoveDoc(syncDoc._class, syncDoc.space, syncDoc._id))
}
}
}
}
}
if (result.length > 0) {
await OnGithubBroadcast(txes, control)
}
return result
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export default async () => ({
trigger: {
OnProjectChanges,
OnProjectRemove,
OnGithubBroadcast
},
functions: {
@@ -21,6 +21,7 @@ export const serverGithubId = 'server-github' as Plugin
export default plugin(serverGithubId, {
trigger: {
OnProjectChanges: '' as Resource<TriggerFunc>,
OnProjectRemove: '' as Resource<TriggerFunc>,
OnGithubBroadcast: '' as Resource<TriggerFunc>
},
functions: {