UBERF-8060: Fix user statuses and workspace selection (#6512)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2024-09-10 22:59:38 +07:00 committed by GitHub
parent f16d109ed5
commit 1daec4def4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 51 additions and 28 deletions

View File

@ -0,0 +1,23 @@
{
"ACCOUNTS_URL": "https://account.huly.app/",
"UPLOAD_URL": "/files",
"FILES_URL": "/files/:workspace/:filename?file=:blobId&workspace=:workspace",
"REKONI_URL": "https://rekoni.huly.app",
"TELEGRAM_URL": "https://telegram.huly.app",
"GMAIL_URL": "https://gmail.huly.app/",
"CALENDAR_URL": "https://calendar.huly.app/",
"COLLABORATOR_URL": "wss://collaborator.huly.app",
"BRANDING_URL": "https://huly.app/huly-branding_v2.json",
"PREVIEW_CONFIG": "https://huly.app/files/:workspace?file=:blobId&size=:size",
"GITHUB_APP": "huly-for-github",
"GITHUB_CLIENTID": "Iv1.e263a087de0910e0",
"INTERCOM_APP_ID": "",
"INTERCOM_API_URL": "",
"GITHUB_URL": "https://github.huly.app",
"LIVEKIT_WS": "",
"LOVE_ENDPOINT": "https://love.huly.app/",
"SIGN_URL": "https://sign.huly.app",
"PRINT_URL": "https://print.huly.app",
"DESKTOP_UPDATES_CHANNEL": "huly",
"TELEGRAM_BOT_URL": "https://telegram-bot.huly.app"
}

View File

@ -16,51 +16,46 @@
<script lang="ts"> <script lang="ts">
import { LoginInfo, Workspace } from '@hcengineering/login' import { LoginInfo, Workspace } from '@hcengineering/login'
import { OK, Severity, Status } from '@hcengineering/platform' import { OK, Severity, Status } from '@hcengineering/platform'
import presentation, { NavLink, isAdminUser } from '@hcengineering/presentation' import presentation, { NavLink, isAdminUser, reduceCalls } from '@hcengineering/presentation'
import { import {
Button, Button,
Label, Label,
Scroller, Scroller,
SearchEdit, SearchEdit,
deviceOptionsStore as deviceInfo, deviceOptionsStore as deviceInfo,
setMetadataLocalStorage setMetadataLocalStorage,
ticker
} from '@hcengineering/ui' } from '@hcengineering/ui'
import { onMount } from 'svelte' import { onMount } from 'svelte'
import login from '../plugin' import login from '../plugin'
import { getAccount, getHref, getWorkspaces, goTo, navigateToWorkspace, selectWorkspace } from '../utils' import { getAccount, getHref, getWorkspaces, goTo, navigateToWorkspace, selectWorkspace } from '../utils'
import StatusControl from './StatusControl.svelte' import StatusControl from './StatusControl.svelte'
const CHECK_INTERVAL = 1000
export let navigateUrl: string | undefined = undefined export let navigateUrl: string | undefined = undefined
let workspaces: Workspace[] = [] let workspaces: Workspace[] = []
let flagToUpdateWorkspaces = false
let status = OK let status = OK
let account: LoginInfo | undefined = undefined let account: LoginInfo | undefined = undefined
let flagToUpdateWorkspaces = false
async function loadAccount (): Promise<void> { async function loadAccount (): Promise<void> {
account = await getAccount() account = await getAccount()
} }
async function updateWorkspaces (): Promise<void> { const updateWorkspaces = reduceCalls(async function updateWorkspaces (time: number): Promise<void> {
try { try {
workspaces = await getWorkspaces() workspaces = await getWorkspaces()
} catch (e) { } catch (e) {
// we should be able to continue from this state // we should be able to continue from this state
} }
if (flagToUpdateWorkspaces) { })
setTimeout(updateWorkspaces, CHECK_INTERVAL)
} $: if (flagToUpdateWorkspaces) updateWorkspaces($ticker)
}
onMount(() => { onMount(() => {
void loadAccount() void loadAccount()
return () => {
flagToUpdateWorkspaces = false
}
}) })
async function select (workspace: string): Promise<void> { async function select (workspace: string): Promise<void> {
@ -81,8 +76,8 @@
} }
workspaces = res workspaces = res
await updateWorkspaces(0)
flagToUpdateWorkspaces = true flagToUpdateWorkspaces = true
await updateWorkspaces()
} catch (err: any) { } catch (err: any) {
setMetadataLocalStorage(login.metadata.LastToken, null) setMetadataLocalStorage(login.metadata.LastToken, null)
setMetadataLocalStorage(presentation.metadata.Token, null) setMetadataLocalStorage(presentation.metadata.Token, null)

View File

@ -862,7 +862,7 @@ export async function backup (
addedDocuments += descrJson.length addedDocuments += descrJson.length
addedDocuments += blob.size addedDocuments += blob.size
printDownloaded(blob._id, descrJson.length) printDownloaded('', descrJson.length)
try { try {
const buffers: Buffer[] = [] const buffers: Buffer[] = []
await blobClient.writeTo(ctx, blob._id, blob.size, { await blobClient.writeTo(ctx, blob._id, blob.size, {
@ -907,7 +907,7 @@ export async function backup (
}) })
} }
printDownloaded(blob._id, blob.size) printDownloaded('', blob.size)
} catch (err: any) { } catch (err: any) {
if (err.message?.startsWith('No file for') === true) { if (err.message?.startsWith('No file for') === true) {
ctx.error('failed to download blob', { message: err.message }) ctx.error('failed to download blob', { message: err.message })
@ -925,7 +925,7 @@ export async function backup (
if (err != null) throw err if (err != null) throw err
}) })
processChanges(d) processChanges(d)
printDownloaded(d._id, data.length) printDownloaded('', data.length)
} }
} }
} }
@ -1141,6 +1141,9 @@ export async function restore (
let uploaded = 0 let uploaded = 0
const printUploaded = (msg: string, size: number): void => { const printUploaded = (msg: string, size: number): void => {
if (size == null) {
return
}
uploaded += size uploaded += size
const newDownloadedMb = Math.round(uploaded / (1024 * 1024)) const newDownloadedMb = Math.round(uploaded / (1024 * 1024))
const newId = Math.round(newDownloadedMb / 10) const newId = Math.round(newDownloadedMb / 10)
@ -1275,6 +1278,10 @@ export async function restore (
blobs.delete(name) blobs.delete(name)
const doc = d?.doc as Blob const doc = d?.doc as Blob
;(doc as any)['%hash%'] = changeset.get(doc._id) ;(doc as any)['%hash%'] = changeset.get(doc._id)
let sz = doc.size
if (Number.isNaN(sz) || sz !== bf.length) {
sz = bf.length
}
void blobClient.upload(ctx, doc._id, doc.size, doc.contentType, bf).then(() => { void blobClient.upload(ctx, doc._id, doc.size, doc.contentType, bf).then(() => {
void sendChunk(doc, bf.length).finally(() => { void sendChunk(doc, bf.length).finally(() => {
requiredDocs.delete(doc._id) requiredDocs.delete(doc._id)

View File

@ -14,7 +14,6 @@
// //
import core, { import core, {
DOMAIN_TRANSIENT,
TxProcessor, TxProcessor,
type Doc, type Doc,
type Domain, type Domain,
@ -49,13 +48,7 @@ export class DomainTxMiddleware extends BaseMiddleware implements Middleware {
for (const tx of txes) { for (const tx of txes) {
if (TxProcessor.isExtendsCUD(tx._class)) { if (TxProcessor.isExtendsCUD(tx._class)) {
const objectClass = (tx as TxCUD<Doc>).objectClass txToStore.push(tx)
if (
objectClass !== core.class.BenchmarkDoc &&
this.context.hierarchy.findDomain(objectClass) !== DOMAIN_TRANSIENT
) {
txToStore.push(tx)
}
} }
} }
let result: TxMiddlewareResult = {} let result: TxMiddlewareResult = {}

View File

@ -158,7 +158,7 @@ export function startHttpServer (
void sessions.profiling.stop().then((profile) => { void sessions.profiling.stop().then((profile) => {
ctx.warn( ctx.warn(
'---------------------------------------------PROFILING SESSION STOPPED---------------------------------------------', '---------------------------------------------PROFILING SESSION STOPPED---------------------------------------------',
{ profile } {}
) )
res.writeHead(200, { 'Content-Type': 'application/json' }) res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(profile ?? '{ error: "no profiling" }') res.end(profile ?? '{ error: "no profiling" }')
@ -205,7 +205,12 @@ export function startHttpServer (
const name = req.query.name as string const name = req.query.name as string
const contentType = req.query.contentType as string const contentType = req.query.contentType as string
const size = parseInt((req.query.size as string) ?? '-1') const size = parseInt((req.query.size as string) ?? '-1')
if (Number.isNaN(size)) {
ctx.error('/api/v1/blob put error', { message: 'invalid NaN file size' })
res.writeHead(404, {})
res.end()
return
}
ctx ctx
.with( .with(
'storage upload', 'storage upload',