Merge remote-tracking branch 'origin/develop' into staging

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2024-12-26 15:57:54 +07:00
commit f4fc1074f5
No known key found for this signature in database
GPG Key ID: BD80F68D68D8F7F2
14 changed files with 138 additions and 74 deletions

View File

@ -7,5 +7,6 @@
"CALENDAR_URL": "https://calendar.hc.engineering",
"REKONI_URL": "https://rekoni.hc.engineering",
"COLLABORATOR_URL": "wss://collaborator.hc.engineering",
"STATS_URL": "https://stats.hc.engineering"
"STATS_URL": "https://stats.hc.engineering",
"PRESENCE_URL": "wss://presence.hc.engineering"
}

View File

@ -62,9 +62,9 @@ import {
createBackupPipeline,
getConfig,
getWorkspaceDestroyAdapter,
registerAdapterFactry,
registerDestroyFactry,
registerTxAdapterFactry
registerAdapterFactory,
registerDestroyFactory,
registerTxAdapterFactory
} from '@hcengineering/server-pipeline'
import serverToken, { decodeToken, generateToken } from '@hcengineering/server-token'
import { FileModelLogger } from '@hcengineering/server-tool'
@ -173,13 +173,13 @@ export function devTool (
): void {
const toolCtx = new MeasureMetricsContext('tool', {})
registerTxAdapterFactry('mongodb', createMongoTxAdapter)
registerAdapterFactry('mongodb', createMongoAdapter)
registerDestroyFactry('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactory('mongodb', createMongoTxAdapter)
registerAdapterFactory('mongodb', createMongoAdapter)
registerDestroyFactory('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactry('postgresql', createPostgresTxAdapter, true)
registerAdapterFactry('postgresql', createPostgresAdapter, true)
registerDestroyFactry('postgresql', createPostgreeDestroyAdapter, true)
registerTxAdapterFactory('postgresql', createPostgresTxAdapter, true)
registerAdapterFactory('postgresql', createPostgresAdapter, true)
registerDestroyFactory('postgresql', createPostgreeDestroyAdapter, true)
const serverSecret = process.env.SERVER_SECRET
if (serverSecret === undefined) {

View File

@ -122,7 +122,7 @@
<svelte:fragment slot="presence">
{#if withPresence && object}
<PresenceAvatars {object} size="x-small" limit={3} />
<PresenceAvatars {object} size="x-small" limit={4} />
{/if}
</svelte:fragment>

View File

@ -81,7 +81,7 @@ export const storePromise = writable<Promise<void>>(new Promise((resolve) => {})
function fillStores (): void {
const client = getClient()
if (client !== undefined) {
if (client !== undefined || getCurrentAccount() != null) {
const query = createQuery(true)
const roomPromise = new Promise<void>((resolve) =>
query.query(love.class.Room, {}, (res) => {

View File

@ -15,35 +15,47 @@
<script lang="ts">
import { type Doc } from '@hcengineering/core'
import contact, { formatName } from '@hcengineering/contact'
import { Avatar, CombineAvatars, personByIdStore } from '@hcengineering/contact-resources'
import { type Person, formatName } from '@hcengineering/contact'
import { Avatar, personByIdStore } from '@hcengineering/contact-resources'
import { getEmbeddedLabel } from '@hcengineering/platform'
import { IconSize, tooltip } from '@hcengineering/ui'
import PresenceList from './PresenceList.svelte'
import { presenceByObjectId } from '../store'
export let object: Doc
export let size: IconSize = 'small'
export let limit: number = 5
export let hideLimit: boolean = false
export let combine = false
export let limit: number = 4
$: presence = $presenceByObjectId?.get(object._id) ?? []
$: items = presence.map((it) => it.person)
$: persons = presence
.map((it) => it.person)
.map((p) => $personByIdStore.get(p))
.filter((p): p is Person => p !== undefined)
$: overLimit = persons.length > limit
</script>
{#if items.length > 0}
{#if combine}
<CombineAvatars _class={contact.mixin.Employee} {items} {size} {limit} {hideLimit} />
{#if persons.length > 0}
{#if overLimit}
<div
class="hulyCombineAvatars-container"
use:tooltip={{ component: PresenceList, props: { persons, size }, direction: 'bottom' }}
>
{#each persons.slice(0, limit) as person, i}
<div
class="hulyCombineAvatar tiny"
data-over={i === limit - 1 && overLimit ? `+${persons.length - limit + 1}` : undefined}
>
<Avatar name={person.name} {size} {person} />
</div>
{/each}
</div>
{:else}
<div class="flex-row-center flex-gap-0-5">
{#each items as item}
{@const person = $personByIdStore.get(item)}
{#if person}
<div use:tooltip={{ label: getEmbeddedLabel(formatName(person.name)) }}>
<Avatar name={person.name} {size} {person} />
</div>
{/if}
<div class="flex-row-center flex-gap-1">
{#each persons as person}
<div use:tooltip={{ label: getEmbeddedLabel(formatName(person.name)) }}>
<Avatar name={person.name} {size} {person} />
</div>
{/each}
</div>
{/if}

View File

@ -0,0 +1,33 @@
<!--
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { Person, formatName } from '@hcengineering/contact'
import { Avatar } from '@hcengineering/contact-resources'
import { IconSize, Scroller } from '@hcengineering/ui'
export let persons: Person[]
export let size: IconSize
</script>
<Scroller padding={'.25rem'} gap={'flex-gap-2'}>
{#each persons as person}
<div class="flex-row-center flex-no-shrink flex-gap-2">
<div class="min-w-6">
<Avatar name={person.name} {size} {person} />
</div>
{formatName(person.name)}
</div>
{/each}
</Scroller>

View File

@ -367,7 +367,7 @@ export const joinedProjectsStore = writable<Project[]>()
function fillStores (): void {
const client = getClient()
if (client !== undefined) {
if (client !== undefined && getCurrentAccount() != null) {
const query = createQuery(true)
query.query(task.class.ProjectType, {}, (res) => {
typeStore.set(toIdMap(res))

View File

@ -60,6 +60,8 @@
"dotenv": "~16.0.0",
"@hcengineering/backup-service": "^0.6.0",
"@hcengineering/analytics": "^0.6.0",
"@hcengineering/analytics-service": "^0.6.0"
"@hcengineering/analytics-service": "^0.6.0",
"@hcengineering/mongo": "^0.6.1",
"@hcengineering/postgres": "^0.6.0"
}
}

View File

@ -18,10 +18,18 @@ import { configureAnalytics, SplitLogger } from '@hcengineering/analytics-servic
import { startBackup } from '@hcengineering/backup-service'
import { MeasureMetricsContext, newMetrics, type Tx } from '@hcengineering/core'
import { initStatisticsContext, type PipelineFactory } from '@hcengineering/server-core'
import { createBackupPipeline, getConfig } from '@hcengineering/server-pipeline'
import {
createBackupPipeline,
getConfig,
registerAdapterFactory,
registerDestroyFactory,
registerTxAdapterFactory
} from '@hcengineering/server-pipeline'
import { join } from 'path'
import { readFileSync } from 'node:fs'
import { createMongoTxAdapter, createMongoAdapter, createMongoDestroyAdapter } from '@hcengineering/mongo'
import { createPostgresTxAdapter, createPostgresAdapter, createPostgreeDestroyAdapter } from '@hcengineering/postgres'
const model = JSON.parse(readFileSync(process.env.MODEL_JSON ?? 'model.json').toString()) as Tx[]
const metricsContext = initStatisticsContext('backup', {
@ -43,6 +51,14 @@ const sentryDSN = process.env.SENTRY_DSN
configureAnalytics(sentryDSN, {})
Analytics.setTag('application', 'backup-service')
registerTxAdapterFactory('mongodb', createMongoTxAdapter)
registerAdapterFactory('mongodb', createMongoAdapter)
registerDestroyFactory('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactory('postgresql', createPostgresTxAdapter, true)
registerAdapterFactory('postgresql', createPostgresAdapter, true)
registerDestroyFactory('postgresql', createPostgreeDestroyAdapter, true)
startBackup(
metricsContext,
(mongoUrl, storageAdapter) => {

View File

@ -47,11 +47,11 @@ import serverCore, {
import { FullTextIndexPipeline, searchFulltext, type FulltextDBConfiguration } from '@hcengineering/server-indexer'
import {
getConfig,
registerAdapterFactry,
registerDestroyFactry,
registerAdapterFactory,
registerDestroyFactory,
registerServerPlugins,
registerStringLoaders,
registerTxAdapterFactry
registerTxAdapterFactory
} from '@hcengineering/server-pipeline'
import serverToken, { decodeToken, generateToken, type Token } from '@hcengineering/server-token'
import cors from '@koa/cors'
@ -207,13 +207,13 @@ export async function startIndexer (
setMetadata(serverCore.metadata.ElasticIndexName, opt.elasticIndexName)
setMetadata(serverClientPlugin.metadata.Endpoint, opt.accountsUrl)
registerTxAdapterFactry('mongodb', createMongoTxAdapter)
registerAdapterFactry('mongodb', createMongoAdapter)
registerDestroyFactry('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactory('mongodb', createMongoTxAdapter)
registerAdapterFactory('mongodb', createMongoAdapter)
registerDestroyFactory('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactry('postgresql', createPostgresTxAdapter, true)
registerAdapterFactry('postgresql', createPostgresAdapter, true)
registerDestroyFactry('postgresql', createPostgreeDestroyAdapter, true)
registerTxAdapterFactory('postgresql', createPostgresTxAdapter, true)
registerAdapterFactory('postgresql', createPostgresAdapter, true)
registerDestroyFactory('postgresql', createPostgreeDestroyAdapter, true)
registerServerPlugins()
registerStringLoaders()

View File

@ -35,11 +35,11 @@ import { type Token } from '@hcengineering/server-token'
import {
createServerPipeline,
registerAdapterFactry,
registerDestroyFactry,
registerAdapterFactory,
registerDestroyFactory,
registerServerPlugins,
registerStringLoaders,
registerTxAdapterFactry
registerTxAdapterFactory
} from '@hcengineering/server-pipeline'
import { readFileSync } from 'node:fs'
@ -74,13 +74,13 @@ export function start (
mongoUrl?: string
}
): { shutdown: () => Promise<void>, sessionManager: SessionManager } {
registerTxAdapterFactry('mongodb', createMongoTxAdapter)
registerAdapterFactry('mongodb', createMongoAdapter)
registerDestroyFactry('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactory('mongodb', createMongoTxAdapter)
registerAdapterFactory('mongodb', createMongoAdapter)
registerDestroyFactory('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactry('postgresql', createPostgresTxAdapter, true)
registerAdapterFactry('postgresql', createPostgresAdapter, true)
registerDestroyFactry('postgresql', createPostgreeDestroyAdapter, true)
registerTxAdapterFactory('postgresql', createPostgresTxAdapter, true)
registerAdapterFactory('postgresql', createPostgresAdapter, true)
registerDestroyFactory('postgresql', createPostgreeDestroyAdapter, true)
registerServerPlugins()

View File

@ -210,21 +210,21 @@ const txAdapterFactories: Record<string, DbAdapterFactory> = {}
const adapterFactories: Record<string, DbAdapterFactory> = {}
const destroyFactories: Record<string, (url: string) => WorkspaceDestroyAdapter> = {}
export function registerTxAdapterFactry (name: string, factory: DbAdapterFactory, useAsDefault: boolean = true): void {
export function registerTxAdapterFactory (name: string, factory: DbAdapterFactory, useAsDefault: boolean = true): void {
txAdapterFactories[name] = factory
if (useAsDefault) {
txAdapterFactories[''] = factory
}
}
export function registerAdapterFactry (name: string, factory: DbAdapterFactory, useAsDefault: boolean = true): void {
export function registerAdapterFactory (name: string, factory: DbAdapterFactory, useAsDefault: boolean = true): void {
adapterFactories[name] = factory
if (useAsDefault) {
adapterFactories[''] = factory
}
}
export function registerDestroyFactry (
export function registerDestroyFactory (
name: string,
factory: (url: string) => WorkspaceDestroyAdapter,
useAsDefault: boolean = true

View File

@ -21,11 +21,11 @@ import { SessionDataImpl, wrapPipeline, type Pipeline, type StorageAdapter } fro
import {
getServerPipeline,
getTxAdapterFactory,
registerAdapterFactry,
registerDestroyFactry,
registerAdapterFactory,
registerDestroyFactory,
registerServerPlugins,
registerStringLoaders,
registerTxAdapterFactry
registerTxAdapterFactory
} from '@hcengineering/server-pipeline'
import { buildStorageFromConfig, storageConfigFromEnv } from '@hcengineering/server-storage'
import { generateToken } from '@hcengineering/server-token'
@ -82,13 +82,13 @@ export async function createWorkspace (
const hierarchy = new Hierarchy()
const modelDb = new ModelDb(hierarchy)
registerTxAdapterFactry('mongodb', createMongoTxAdapter)
registerAdapterFactry('mongodb', createMongoAdapter)
registerDestroyFactry('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactory('mongodb', createMongoTxAdapter)
registerAdapterFactory('mongodb', createMongoAdapter)
registerDestroyFactory('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactry('postgresql', createPostgresTxAdapter, true)
registerAdapterFactry('postgresql', createPostgresAdapter, true)
registerDestroyFactry('postgresql', createPostgreeDestroyAdapter, true)
registerTxAdapterFactory('postgresql', createPostgresTxAdapter, true)
registerAdapterFactory('postgresql', createPostgresAdapter, true)
registerDestroyFactory('postgresql', createPostgreeDestroyAdapter, true)
registerServerPlugins()
registerStringLoaders()
@ -173,13 +173,13 @@ export async function upgradeWorkspace (
): Promise<void> {
const { dbUrl } = prepareTools([])
let pipeline: Pipeline | undefined
registerTxAdapterFactry('mongodb', createMongoTxAdapter)
registerAdapterFactry('mongodb', createMongoAdapter)
registerDestroyFactry('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactory('mongodb', createMongoTxAdapter)
registerAdapterFactory('mongodb', createMongoAdapter)
registerDestroyFactory('mongodb', createMongoDestroyAdapter)
registerTxAdapterFactry('postgresql', createPostgresTxAdapter, true)
registerAdapterFactry('postgresql', createPostgresAdapter, true)
registerDestroyFactry('postgresql', createPostgreeDestroyAdapter, true)
registerTxAdapterFactory('postgresql', createPostgresTxAdapter, true)
registerAdapterFactory('postgresql', createPostgresAdapter, true)
registerDestroyFactory('postgresql', createPostgreeDestroyAdapter, true)
registerServerPlugins()
registerStringLoaders()

View File

@ -38,11 +38,11 @@ import { gzip } from 'zlib'
import { createPostgreeDestroyAdapter, createPostgresAdapter, createPostgresTxAdapter } from '@hcengineering/postgres'
import {
createServerPipeline,
registerAdapterFactry,
registerDestroyFactry,
registerAdapterFactory,
registerDestroyFactory,
registerServerPlugins,
registerStringLoaders,
registerTxAdapterFactry
registerTxAdapterFactory
} from '@hcengineering/server-pipeline'
import model from './model.json'
@ -65,9 +65,9 @@ export class Transactor extends DurableObject<Env> {
constructor (ctx: DurableObjectState, env: Env) {
super(ctx, env)
registerTxAdapterFactry('postgresql', createPostgresTxAdapter, true)
registerAdapterFactry('postgresql', createPostgresAdapter, true)
registerDestroyFactry('postgresql', createPostgreeDestroyAdapter, true)
registerTxAdapterFactory('postgresql', createPostgresTxAdapter, true)
registerAdapterFactory('postgresql', createPostgresAdapter, true)
registerDestroyFactory('postgresql', createPostgreeDestroyAdapter, true)
registerStringLoaders()
registerServerPlugins()