Skip to content

Commit

Permalink
UBERF-7011: Switch to Ref<Blob>
Browse files Browse the repository at this point in the history
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
  • Loading branch information
haiodo committed May 25, 2024
1 parent aeb3b64 commit 070ff5f
Show file tree
Hide file tree
Showing 158 changed files with 1,778 additions and 1,032 deletions.
61 changes: 58 additions & 3 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 15 additions & 15 deletions dev/tool/src/clean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,42 @@ import attachment from '@hcengineering/attachment'
import chunter, { type ChatMessage } from '@hcengineering/chunter'
import contact from '@hcengineering/contact'
import core, {
ClassifierKind,
DOMAIN_STATUS,
DOMAIN_TX,
type MeasureContext,
SortingOrder,
TxOperations,
TxProcessor,
generateId,
getObjectValue,
toIdMap,
type BackupClient,
type Class,
type Client as CoreClient,
type Doc,
type Domain,
type MeasureContext,
type Ref,
type TxCreateDoc,
type WorkspaceId,
type Status,
type StatusCategory,
type TxMixin,
type TxCUD,
type TxCreateDoc,
type TxMixin,
type TxUpdateDoc,
DOMAIN_STATUS,
type Status,
toIdMap,
type Class,
ClassifierKind
type WorkspaceId
} from '@hcengineering/core'
import { DOMAIN_ACTIVITY } from '@hcengineering/model-activity'
import { DOMAIN_SPACE } from '@hcengineering/model-core'
import recruitModel, { defaultApplicantStatuses } from '@hcengineering/model-recruit'
import { getWorkspaceDB } from '@hcengineering/mongo'
import recruit, { type Applicant, type Vacancy } from '@hcengineering/recruit'
import recruitModel, { defaultApplicantStatuses } from '@hcengineering/model-recruit'
import { type StorageAdapter } from '@hcengineering/server-core'
import { connect } from '@hcengineering/server-tool'
import tags, { type TagCategory, type TagElement, type TagReference } from '@hcengineering/tags'
import task, { type Task, type ProjectType, type TaskType } from '@hcengineering/task'
import task, { type ProjectType, type Task, type TaskType } from '@hcengineering/task'
import tracker from '@hcengineering/tracker'
import { deepEqual } from 'fast-equals'
import { MongoClient } from 'mongodb'
import { DOMAIN_ACTIVITY } from '@hcengineering/model-activity'
import { DOMAIN_SPACE } from '@hcengineering/model-core'

export async function cleanWorkspace (
ctx: MeasureContext,
Expand All @@ -77,7 +77,7 @@ export async function cleanWorkspace (
const contacts = await ops.findAll(contact.class.Contact, {})

const files = new Set(
attachments.map((it) => it.file).concat(contacts.map((it) => it.avatar).filter((it) => it) as string[])
attachments.map((it) => it.file as string).concat(contacts.map((it) => it.avatar).filter((it) => it) as string[])
)

const minioList = await storageAdapter.listStream(ctx, workspaceId)
Expand Down Expand Up @@ -177,7 +177,7 @@ export async function fixMinioBW (
break
}
if (obj.modifiedOn < from) continue
if ((obj._id as string).includes('%size%')) {
if ((obj._id as string).includes('%preview%')) {
await storageService.remove(ctx, workspaceId, [obj._id])
removed++
if (removed % 100 === 0) {
Expand Down
12 changes: 6 additions & 6 deletions models/attachment/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@

import activity from '@hcengineering/activity'
import type { Attachment, AttachmentMetadata, Photo, SavedAttachments } from '@hcengineering/attachment'
import { type Domain, IndexKind, type Ref } from '@hcengineering/core'
import { IndexKind, type Blob, type Domain, type Ref } from '@hcengineering/core'
import {
type Builder,
Index,
Model,
Prop,
TypeAttachment,
TypeBlob,
TypeBoolean,
TypeRef,
TypeString,
TypeTimestamp,
UX
UX,
type Builder
} from '@hcengineering/model'
import core, { TAttachedDoc } from '@hcengineering/model-core'
import preference, { TPreference } from '@hcengineering/model-preference'
Expand All @@ -46,8 +46,8 @@ export class TAttachment extends TAttachedDoc implements Attachment {
@Index(IndexKind.FullText)
name!: string

@Prop(TypeAttachment(), attachment.string.File)
file!: string
@Prop(TypeBlob(), attachment.string.File)
file!: Ref<Blob>

@Prop(TypeString(), attachment.string.Size)
size!: number
Expand Down
31 changes: 28 additions & 3 deletions models/contact/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
DOMAIN_MODEL,
DateRangeMode,
IndexKind,
type Blob,
type Class,
type Domain,
type Markup,
Expand All @@ -50,10 +51,11 @@ import {
Model,
Prop,
ReadOnly,
TypeAttachment,
TypeBlob,
TypeBoolean,
TypeCollaborativeMarkup,
TypeDate,
TypeRecord,
TypeRef,
TypeString,
TypeTimestamp,
Expand Down Expand Up @@ -104,10 +106,23 @@ export class TContact extends TDoc implements Contact {
@Index(IndexKind.FullText)
name!: string

@Prop(TypeAttachment(), contact.string.Avatar)
@Prop(TypeString(), contact.string.Avatar)
@Index(IndexKind.FullText)
@Hidden()
avatar?: string | null
avatarType!: AvatarType

@Prop(TypeBlob(), contact.string.Avatar)
@Index(IndexKind.FullText)
@Hidden()
avatar!: Ref<Blob> | null | undefined

@Prop(TypeRecord(), contact.string.Avatar)
@Index(IndexKind.FullText)
@Hidden()
avatarProps?: {
color?: string
url?: string
}

@Prop(Collection(contact.class.Channel), contact.string.ContactInfo)
channels?: number
Expand Down Expand Up @@ -709,6 +724,16 @@ export function createModel (builder: Builder): void {
contact.avatarProvider.Gravatar
)

builder.createDoc(
contact.class.AvatarProvider,
core.space.Model,
{
type: AvatarType.EXTERNAL,
getUrl: contact.function.GetExternalUrl
},
contact.avatarProvider.Color
)

builder.mixin(contact.class.Person, core.class.Class, view.mixin.ObjectPresenter, {
presenter: contact.component.PersonPresenter
})
Expand Down
60 changes: 59 additions & 1 deletion models/contact/src/migration.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
//

import { DOMAIN_TX, type Space, TxOperations, type Class, type Doc, type Domain, type Ref } from '@hcengineering/core'
import { DOMAIN_TX, TxOperations, type Class, type Doc, type Domain, type Ref, type Space } from '@hcengineering/core'
import {
createDefaultSpace,
tryMigrate,
tryUpgrade,
type MigrateOperation,
type MigrateUpdate,
type MigrationClient,
type MigrationDocumentQuery,
type MigrationUpgradeClient,
type ModelLogger
} from '@hcengineering/model'
import activity, { DOMAIN_ACTIVITY } from '@hcengineering/model-activity'
import core from '@hcengineering/model-core'
import { DOMAIN_VIEW } from '@hcengineering/model-view'

import { AvatarType, type Contact } from '@hcengineering/contact'
import contact, { DOMAIN_CONTACT, contactId } from './index'

async function createEmployeeEmail (client: TxOperations): Promise<void> {
Expand Down Expand Up @@ -48,6 +51,55 @@ async function createEmployeeEmail (client: TxOperations): Promise<void> {
}
}

const colorPrefix = 'color://'
const gravatarPrefix = 'gravatar://'

async function migrateAvatars (client: MigrationClient): Promise<void> {
const classes = client.hierarchy.getDescendants(contact.class.Contact)
const i = await client.traverse<Contact>(DOMAIN_CONTACT, {
_class: { $in: classes },
avatar: { $regex: 'color|gravatar://.*' }
})
while (true) {
const docs = await i.next(50)
if (docs === null || docs?.length === 0) {
break
}
const updates: { filter: MigrationDocumentQuery<Contact>, update: MigrateUpdate<Contact> }[] = []
for (const d of docs) {
if (d.avatar?.startsWith(colorPrefix) ?? false) {
d.avatarProps = { color: d.avatar?.slice(colorPrefix.length) ?? '' }
updates.push({
filter: { _id: d._id },
update: {
avatarType: AvatarType.COLOR,
avatar: null,
avatarProps: { color: d.avatar?.slice(colorPrefix.length) ?? '' }
}
})
} else if (d.avatar?.startsWith(gravatarPrefix) ?? false) {
updates.push({
filter: { _id: d._id },
update: {
avatarType: AvatarType.GRAVATAR,
avatar: null,
avatarProps: { url: d.avatar?.slice(gravatarPrefix.length) ?? '' }
}
})
}
}
if (updates.length > 0) {
await client.bulk(DOMAIN_CONTACT, updates)
}
}

await client.update(
DOMAIN_CONTACT,
{ _class: { $in: classes }, avatarKind: { $exists: false } },
{ avatarKind: AvatarType.IMAGE }
)
}

export const contactOperation: MigrateOperation = {
async migrate (client: MigrationClient, logger: ModelLogger): Promise<void> {
await tryMigrate(client, contactId, [
Expand Down Expand Up @@ -183,6 +235,12 @@ export const contactOperation: MigrateOperation = {
}
)
}
},
{
state: 'avatars',
func: async (client) => {
await migrateAvatars(client)
}
}
])
},
Expand Down
4 changes: 2 additions & 2 deletions models/core/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ export class TTypeString extends TType {}
export class TTypeRecord extends TType {}

@UX(core.string.String)
@Model(core.class.TypeAttachment, core.class.Type)
export class TTypeAttachment extends TType {}
@Model(core.class.TypeBlob, core.class.Type)
export class TTypeBlob extends TType {}

@UX(core.string.Hyperlink)
@Model(core.class.TypeHyperlink, core.class.Type)
Expand Down
Loading

0 comments on commit 070ff5f

Please sign in to comment.