mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-17 18:05:42 +02:00
Add backup/restore guide (#10945)
Signed-off-by: Artyom Savchenko <armisav@gmail.com>
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
>
|
||||
> The hosted Huly service is being discontinued because its hosting is no longer being funded. If you keep important data on the hosted platform, export and back it up, and migrate as soon as possible — we can help you move to either a [self-hosted setup](https://github.com/hcengineering/huly-selfhost) or a hosted option.
|
||||
>
|
||||
> Not sure how? Follow the [backup & restore guide](docs/guides/backup-restore.en.md) for step-by-step instructions on downloading your backup and restoring it elsewhere.
|
||||
>
|
||||
> The service shutdown is expected on **July 20**. Please make sure to export and migrate your data before then rather than wait until the last day.
|
||||
>
|
||||
> Have questions or want updates? Join the [Huly community](https://link.huly.io/slack) to discuss migration and stay informed, or email us at [artem@hardcoreeng.com](mailto:artem@hardcoreeng.com) with any questions. This affects only the hosted **Huly** service — self-hosted deployments are not affected.
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
# Backup & Restore Guide
|
||||
|
||||
Download a workspace backup and restore it into another Huly instance —
|
||||
whether that's a self-hosted deployment or one of the hosted options. This is
|
||||
the recommended way to move your data off a hosted workspace before it
|
||||
becomes unavailable.
|
||||
|
||||
> [!TIP]
|
||||
> Don't want to run your own server? You can also move to one of the
|
||||
> existing hosted Huly forks instead of self-hosting. We're glad to help
|
||||
> with the data migration either way — just keep in mind that none of these
|
||||
> hosting options are free, since keeping servers running costs real money.
|
||||
> See [Need help?](#need-help) below to get in touch.
|
||||
|
||||
## Overview
|
||||
|
||||
1. **Download** — from *Settings → Backup* in the workspace you want to move,
|
||||
grab a full copy of your data.
|
||||
2. **Restore** — replay that backup into the destination workspace using the
|
||||
platform's admin tool (`dev/tool`).
|
||||
|
||||
## Step 1. Download your backup
|
||||
|
||||
Open the workspace and go to:
|
||||
|
||||
```
|
||||
<your-workspace-url>/setting/setting/backup
|
||||
```
|
||||
|
||||
(*Settings → Backup* in the left sidebar.) The page shows when the backup was
|
||||
last taken, how many snapshots and files it contains, and its total size.
|
||||
|
||||
> [!NOTE]
|
||||
> Backups are taken periodically, not continuously, so the latest backup can
|
||||
> lag behind your live data by some time. Check **Last backup** on the page
|
||||
> before you rely on it, and give it time to catch up if you just made
|
||||
> important changes.
|
||||
|
||||
You have two ways to get the files:
|
||||
|
||||
- **Download full backup** — bundles every backup file into a single `.zip`
|
||||
you can keep on your computer. A `RESTORE.md` with restore instructions is
|
||||
included inside the archive.
|
||||
- **Copy download script** (+ **Copy token**) — copies a small shell script
|
||||
that downloads every file with `curl`. The script is safe to save or share:
|
||||
it does **not** contain your token — it reads it from the
|
||||
`HULY_BACKUP_TOKEN` environment variable, or prompts for it when you run it.
|
||||
|
||||
Either option produces a folder that the restore tool can consume directly
|
||||
(see Step 2).
|
||||
|
||||
> [!TIP]
|
||||
> **Large workspace?** Prefer the download script over the button. "Download
|
||||
> full backup" assembles the whole archive in your browser's memory before
|
||||
> saving it, which can be slow or fail outright once a workspace has a lot of
|
||||
> data. The script downloads files one by one with `curl`, so it handles
|
||||
> large backups more reliably.
|
||||
|
||||
You can also expand **Backup Snapshots** or **Backup Files** to download
|
||||
individual files, e.g. to verify access or fetch a single snapshot.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The **Not backed up** section lists blobs that are intentionally excluded
|
||||
> from the regular backup (video, audio, and any file larger than the
|
||||
> server's blob-size limit). Their content isn't in the archive or script
|
||||
> above — if you need them on the destination, download each one individually
|
||||
> from that list before you migrate.
|
||||
|
||||
## Step 2. Restore into a Huly instance
|
||||
|
||||
You'll need a Huly platform you control to restore into — either
|
||||
[huly-selfhost](https://github.com/hcengineering/huly-selfhost), a
|
||||
self-hosted deployment built from this monorepo, or another hosted instance
|
||||
where you have admin access. Create the destination workspace first if it
|
||||
doesn't exist yet.
|
||||
|
||||
Restoring is done with the `backup-restore` command of the platform admin
|
||||
tool (`@hcengineering/tool`, `dev/tool` in this repo). Exactly how you invoke
|
||||
it depends on how the destination platform is run:
|
||||
|
||||
- **Docker / self-hosted setup** — run it inside your `tool` container
|
||||
(e.g. `docker compose run --rm tool backup-restore ...` or
|
||||
`docker compose exec tool ...`, adjusted to your compose service name).
|
||||
- **Monorepo checkout with Rush** — from `dev/tool`, run it against your
|
||||
configured environment, e.g. `rushx run-local backup-restore ...` for a
|
||||
local dev stack, or your own script that sets the same environment
|
||||
variables against your real databases.
|
||||
|
||||
In both cases the command and its arguments are the same:
|
||||
|
||||
```
|
||||
backup-restore <path-to-backup-folder> <target-workspace> [date] --accounts
|
||||
```
|
||||
|
||||
- `<path-to-backup-folder>` — the folder you downloaded/unzipped in Step 1.
|
||||
- `<target-workspace>` — the destination workspace's identifier.
|
||||
- `--accounts` — also restores the original users (their profile and social
|
||||
identities) into the target workspace. Without this flag only documents are
|
||||
restored, and every member has to be invited again by email.
|
||||
- `--upgrade` — add this if the destination runs a newer model version than
|
||||
the backup.
|
||||
- `-m/--merge` — don't delete documents that are missing from the backup
|
||||
(useful when merging into a workspace that already has data).
|
||||
|
||||
> [!NOTE]
|
||||
> Restoring accounts (`--accounts`) needs its own connection to the account
|
||||
> database, configured via the `ACCOUNT_DB_URL` (and optional
|
||||
> `ACCOUNT_DB_NS`) environment variables. See
|
||||
> [`server/backup/README.md`](../../server/backup/README.md) for the full
|
||||
> reference of flags and per-entry-point environment variables.
|
||||
|
||||
Once the restore finishes, users sign in with their original email via a
|
||||
one-time code (OTP) — make sure the destination platform can send mail.
|
||||
|
||||
## Need help?
|
||||
|
||||
Our team is happy to help with migration. Join the [Huly community](https://link.huly.io/slack) to ask questions and get updates, or email us directly at [artem@hardcoreeng.com](mailto:artem@hardcoreeng.com).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **401 Unauthorized while downloading** — your token expired, or you're not
|
||||
an owner/admin of the workspace. Get a fresh token from the Backup page.
|
||||
- **Members are missing after restore** — re-run with `--accounts` and a
|
||||
valid `ACCOUNT_DB_URL`; without both, only documents are restored.
|
||||
- **A file/video is missing on the destination** — check the **Not backed
|
||||
up** list on the Backup page and download it individually; it isn't part
|
||||
of the regular backup.
|
||||
- **Restore fails with a model/version error** — add `--upgrade` if the
|
||||
destination runs a newer platform version than the source.
|
||||
|
||||
## See also
|
||||
|
||||
- [`server/backup/README.md`](../../server/backup/README.md) — full CLI
|
||||
reference for `backup-restore`, including environment variables.
|
||||
- [huly-selfhost](https://github.com/hcengineering/huly-selfhost) — official
|
||||
self-hosted distribution.
|
||||
@@ -141,6 +141,8 @@
|
||||
"BackupCopyScript": "Kopírovat skript pro stažení",
|
||||
"BackupCopyToken": "Kopírovat token",
|
||||
"BackupScriptInfo": "Shellový skript, který stáhne všechny soubory zálohy pomocí curl. Uložte jej a spusťte v terminálu; vyžádá si váš token zálohy, takže ve skriptu nejsou uložena žádná tajemství.",
|
||||
"BackupRestoreGuide": "Průvodce zálohováním a obnovou",
|
||||
"BackupRestoreGuideInfo": "Podrobný návod, jak stáhnout tuto zálohu a obnovit ji v jiné instanci Huly.",
|
||||
"NonBackupedBlobs": "Non Backed up blobs",
|
||||
"Calendar": "Kalendář",
|
||||
"StartOfTheWeek": "Začátek týdne",
|
||||
|
||||
@@ -147,6 +147,8 @@
|
||||
"BackupCopyScript": "Download-Skript kopieren",
|
||||
"BackupCopyToken": "Token kopieren",
|
||||
"BackupScriptInfo": "Ein Shell-Skript, das alle Sicherungsdateien mit curl herunterlädt. Speichere es und führe es in einem Terminal aus; es fragt nach deinem Sicherungs-Token, sodass keine Geheimnisse im Skript gespeichert werden.",
|
||||
"BackupRestoreGuide": "Anleitung zu Backup & Wiederherstellung",
|
||||
"BackupRestoreGuideInfo": "Schritt-für-Schritt-Anleitung zum Herunterladen dieses Backups und zur Wiederherstellung in einer anderen Huly-Instanz.",
|
||||
"NonBackupedBlobs": "Nicht gesicherte Blobs",
|
||||
"Calendar": "Kalender",
|
||||
"StartOfTheWeek": "Wochenstart",
|
||||
|
||||
@@ -147,6 +147,8 @@
|
||||
"BackupCopyScript": "Copy download script",
|
||||
"BackupCopyToken": "Copy token",
|
||||
"BackupScriptInfo": "A shell script that downloads every backup file with curl. Save it and run it in a terminal; it prompts for your backup token, so no secrets are stored in the script.",
|
||||
"BackupRestoreGuide": "Backup & restore guide",
|
||||
"BackupRestoreGuideInfo": "Step-by-step instructions for downloading this backup and restoring it into another Huly instance.",
|
||||
"NonBackupedBlobs": "Non Backed up blobs",
|
||||
"Calendar": "Calendar",
|
||||
"StartOfTheWeek": "Start of the week",
|
||||
|
||||
@@ -138,6 +138,8 @@
|
||||
"BackupCopyScript": "Copiar script de descarga",
|
||||
"BackupCopyToken": "Copiar token",
|
||||
"BackupScriptInfo": "Un script de shell que descarga todos los archivos de la copia de seguridad con curl. Guárdalo y ejecútalo en una terminal; te pedirá tu token de copia de seguridad, por lo que no se almacenan secretos en el script.",
|
||||
"BackupRestoreGuide": "Guía de copia de seguridad y restauración",
|
||||
"BackupRestoreGuideInfo": "Instrucciones paso a paso para descargar esta copia de seguridad y restaurarla en otra instancia de Huly.",
|
||||
"NonBackupedBlobs": "Blobs no respaldados",
|
||||
"Calendar": "Calendario",
|
||||
"StartOfTheWeek": "Inicio de la semana",
|
||||
|
||||
@@ -147,6 +147,8 @@
|
||||
"BackupCopyScript": "Copier le script de téléchargement",
|
||||
"BackupCopyToken": "Copier le jeton",
|
||||
"BackupScriptInfo": "Un script shell qui télécharge tous les fichiers de sauvegarde avec curl. Enregistrez-le et exécutez-le dans un terminal ; il demande votre jeton de sauvegarde, aucun secret n'est donc stocké dans le script.",
|
||||
"BackupRestoreGuide": "Guide de sauvegarde et restauration",
|
||||
"BackupRestoreGuideInfo": "Instructions étape par étape pour télécharger cette sauvegarde et la restaurer sur une autre instance Huly.",
|
||||
"NonBackupedBlobs": "Non Backed up blobs",
|
||||
"Calendar": "Calendrier",
|
||||
"StartOfTheWeek": "Début de semaine",
|
||||
|
||||
@@ -147,6 +147,8 @@
|
||||
"BackupCopyScript": "Copia script di download",
|
||||
"BackupCopyToken": "Copia token",
|
||||
"BackupScriptInfo": "Uno script shell che scarica tutti i file di backup con curl. Salvalo ed eseguilo in un terminale; richiederà il tuo token di backup, quindi nello script non vengono memorizzati segreti.",
|
||||
"BackupRestoreGuide": "Guida a backup e ripristino",
|
||||
"BackupRestoreGuideInfo": "Istruzioni dettagliate per scaricare questo backup e ripristinarlo in un'altra istanza di Huly.",
|
||||
"NonBackupedBlobs": "Non Backed up blobs",
|
||||
"Calendar": "Calendario",
|
||||
"StartOfTheWeek": "Inizio settimana",
|
||||
|
||||
@@ -147,6 +147,8 @@
|
||||
"BackupCopyScript": "ダウンロードスクリプトをコピー",
|
||||
"BackupCopyToken": "トークンをコピー",
|
||||
"BackupScriptInfo": "curl ですべてのバックアップファイルをダウンロードするシェルスクリプトです。保存してターミナルで実行してください。バックアップトークンの入力を求められるため、スクリプトに機密情報は保存されません。",
|
||||
"BackupRestoreGuide": "バックアップと復元ガイド",
|
||||
"BackupRestoreGuideInfo": "このバックアップをダウンロードし、別の Huly インスタンスに復元するための手順です。",
|
||||
"NonBackupedBlobs": "バックアップされていないブロブ",
|
||||
"Calendar": "カレンダー",
|
||||
"StartOfTheWeek": "週の開始",
|
||||
|
||||
@@ -147,6 +147,8 @@
|
||||
"BackupCopyScript": "다운로드 스크립트 복사",
|
||||
"BackupCopyToken": "토큰 복사",
|
||||
"BackupScriptInfo": "curl로 모든 백업 파일을 다운로드하는 셸 스크립트입니다. 저장한 후 터미널에서 실행하세요. 백업 토큰을 입력하라는 메시지가 표시되므로 스크립트에 비밀 정보가 저장되지 않습니다.",
|
||||
"BackupRestoreGuide": "백업 및 복원 가이드",
|
||||
"BackupRestoreGuideInfo": "이 백업을 다운로드하여 다른 Huly 인스턴스로 복원하는 단계별 안내입니다.",
|
||||
"NonBackupedBlobs": "백업되지 않은 Blob",
|
||||
"Calendar": "캘린더",
|
||||
"StartOfTheWeek": "주 시작일",
|
||||
|
||||
@@ -147,6 +147,8 @@
|
||||
"BackupCopyScript": "Kopiuj skrypt pobierania",
|
||||
"BackupCopyToken": "Kopiuj token",
|
||||
"BackupScriptInfo": "Skrypt powłoki, który pobiera wszystkie pliki kopii zapasowej za pomocą curl. Zapisz go i uruchom w terminalu; poprosi o token kopii zapasowej, więc w skrypcie nie są przechowywane żadne sekrety.",
|
||||
"BackupRestoreGuide": "Przewodnik po kopii zapasowej i przywracaniu",
|
||||
"BackupRestoreGuideInfo": "Instrukcja krok po kroku dotycząca pobierania tej kopii zapasowej i przywracania jej w innej instancji Huly.",
|
||||
"NonBackupedBlobs": "Pliki nieobjęte kopią zapasową",
|
||||
"Calendar": "Kalendarz",
|
||||
"StartOfTheWeek": "Początek tygodnia",
|
||||
|
||||
@@ -138,6 +138,8 @@
|
||||
"BackupCopyScript": "Copiar script de download",
|
||||
"BackupCopyToken": "Copiar token",
|
||||
"BackupScriptInfo": "Um script de shell que baixa todos os arquivos de backup com curl. Salve-o e execute-o em um terminal; ele solicitará seu token de backup, então nenhum segredo é armazenado no script.",
|
||||
"BackupRestoreGuide": "Guia de backup e restauração",
|
||||
"BackupRestoreGuideInfo": "Instruções passo a passo para baixar este backup e restaurá-lo em outra instância do Huly.",
|
||||
"NonBackupedBlobs": "Blobs sem backup",
|
||||
"Calendar": "Calendário",
|
||||
"StartOfTheWeek": "Início da semana",
|
||||
|
||||
@@ -138,6 +138,8 @@
|
||||
"BackupCopyScript": "Copiar script de transferência",
|
||||
"BackupCopyToken": "Copiar token",
|
||||
"BackupScriptInfo": "Um script de shell que transfere todos os ficheiros da cópia de segurança com curl. Guarde-o e execute-o num terminal; irá pedir o seu token da cópia de segurança, pelo que não são armazenados segredos no script.",
|
||||
"BackupRestoreGuide": "Guia de cópia de segurança e restauro",
|
||||
"BackupRestoreGuideInfo": "Instruções passo a passo para transferir esta cópia de segurança e restaurá-la noutra instância do Huly.",
|
||||
"NonBackupedBlobs": "Non Backed up blobs",
|
||||
"Calendar": "Calendário",
|
||||
"StartOfTheWeek": "Início da semana",
|
||||
|
||||
@@ -152,6 +152,8 @@
|
||||
"BackupCopyScript": "Копировать скрипт загрузки",
|
||||
"BackupCopyToken": "Копировать токен",
|
||||
"BackupScriptInfo": "Скрипт оболочки, который скачивает все файлы резервной копии с помощью curl. Сохраните его и запустите в терминале; он запросит токен резервной копии, поэтому в скрипте не хранятся секреты.",
|
||||
"BackupRestoreGuide": "Инструкция по резервному копированию и восстановлению",
|
||||
"BackupRestoreGuideInfo": "Пошаговая инструкция о том, как скачать эту резервную копию и восстановить её в другом инстансе Huly.",
|
||||
"NonBackupedBlobs": "Не резервируемые блобы",
|
||||
"Calendar": "Календарь",
|
||||
"StartOfTheWeek": "Начало недели",
|
||||
|
||||
@@ -147,6 +147,8 @@
|
||||
"BackupCopyScript": "İndirme betiğini kopyala",
|
||||
"BackupCopyToken": "Jetonu kopyala",
|
||||
"BackupScriptInfo": "Tüm yedek dosyalarını curl ile indiren bir kabuk betiği. Kaydedip bir terminalde çalıştırın; yedek jetonunuzu ister, bu nedenle betikte hiçbir gizli bilgi saklanmaz.",
|
||||
"BackupRestoreGuide": "Yedekleme ve geri yükleme kılavuzu",
|
||||
"BackupRestoreGuideInfo": "Bu yedeği indirmek ve başka bir Huly örneğine geri yüklemek için adım adım talimatlar.",
|
||||
"NonBackupedBlobs": "Yedeklenmemiş blob'lar",
|
||||
"Calendar": "Takvim",
|
||||
"StartOfTheWeek": "Haftanın başlangıcı",
|
||||
|
||||
@@ -147,6 +147,8 @@
|
||||
"BackupCopyScript": "复制下载脚本",
|
||||
"BackupCopyToken": "复制令牌",
|
||||
"BackupScriptInfo": "一个使用 curl 下载所有备份文件的 shell 脚本。保存并在终端中运行;它会提示输入您的备份令牌,因此脚本中不会存储任何机密信息。",
|
||||
"BackupRestoreGuide": "备份与恢复指南",
|
||||
"BackupRestoreGuideInfo": "关于下载此备份并将其恢复到另一个 Huly 实例的分步说明。",
|
||||
"NonBackupedBlobs": "未备份的 Blob",
|
||||
"Calendar": "日历",
|
||||
"StartOfTheWeek": "本周开始",
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
//
|
||||
|
||||
import {
|
||||
backupRestoreGuideLink,
|
||||
buildStoreZip,
|
||||
collectBackupFileNames,
|
||||
crc32,
|
||||
@@ -116,6 +117,20 @@ describe('generateRestoreReadme', () => {
|
||||
expect(readme.toLowerCase()).toContain('video')
|
||||
expect(readme.toLowerCase()).toContain('blob')
|
||||
})
|
||||
|
||||
it('mentions the --accounts flag needed to restore the original users', () => {
|
||||
expect(readme).toContain('--accounts')
|
||||
})
|
||||
|
||||
it('links to the full backup & restore guide', () => {
|
||||
expect(readme).toContain(backupRestoreGuideLink)
|
||||
})
|
||||
})
|
||||
|
||||
describe('backupRestoreGuideLink', () => {
|
||||
it('is an https link', () => {
|
||||
expect(backupRestoreGuideLink.startsWith('https://')).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('crc32', () => {
|
||||
|
||||
@@ -21,7 +21,13 @@
|
||||
import { onMount } from 'svelte'
|
||||
import setting from '../plugin'
|
||||
import { BackupInfo, BackupSnapshot } from '../types'
|
||||
import { buildStoreZip, collectBackupFileNames, generateBackupScript, generateRestoreReadme } from '../utils/backup'
|
||||
import {
|
||||
backupRestoreGuideLink,
|
||||
buildStoreZip,
|
||||
collectBackupFileNames,
|
||||
generateBackupScript,
|
||||
generateRestoreReadme
|
||||
} from '../utils/backup'
|
||||
|
||||
let loading = true
|
||||
|
||||
@@ -316,6 +322,22 @@
|
||||
<Button label={tokenCopied ? view.string.Copied : setting.string.BackupCopyToken} on:click={copyToken} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="backup-action">
|
||||
<div class="backup-action__text">
|
||||
<div class="backup-action__title">
|
||||
<Label label={setting.string.BackupRestoreGuide} />
|
||||
</div>
|
||||
<div class="backup-action__info">
|
||||
<Label label={setting.string.BackupRestoreGuideInfo} />
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
label={setting.string.BackupRestoreGuide}
|
||||
on:click={() => {
|
||||
window.open(backupRestoreGuideLink, '_blank', 'noopener,noreferrer')
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Expandable bordered>
|
||||
|
||||
@@ -15,6 +15,16 @@
|
||||
|
||||
import { type BackupInfo } from '../types'
|
||||
|
||||
/**
|
||||
* Link to the full backup & restore guide (download + restore into another
|
||||
* Huly instance). Shown on the Backup settings page and embedded in the
|
||||
* generated RESTORE.md so it travels with the backup.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const backupRestoreGuideLink =
|
||||
'https://github.com/hcengineering/platform/blob/develop/docs/guides/backup-restore.en.md'
|
||||
|
||||
/**
|
||||
* Shape of the data returned from `<backupUrl>/<workspace>/index.json`.
|
||||
* Mirrors the inline type used by the backup settings page.
|
||||
@@ -164,9 +174,12 @@ admin tool.
|
||||
3. From the platform monorepo, restore the backup into that workspace:
|
||||
|
||||
cd dev/tool
|
||||
rushx tool backup-restore <path-to-this-folder> <target-workspace>
|
||||
rushx tool backup-restore <path-to-this-folder> <target-workspace> --accounts
|
||||
|
||||
Add \`--upgrade\` if the target runs a newer model version.
|
||||
Add \`--upgrade\` if the target runs a newer model version. Add
|
||||
\`--accounts\` to also restore the original users (skip it if you'll invite
|
||||
members manually instead) — it needs its own account-database connection,
|
||||
see server/backup/README.md.
|
||||
|
||||
## Notes
|
||||
|
||||
@@ -177,6 +190,8 @@ admin tool.
|
||||
than the server's blob limit — are listed in \`blob-info.json.gz\` but their
|
||||
contents are NOT included here; they remain in the source workspace's live
|
||||
storage.
|
||||
|
||||
Full guide, including troubleshooting: ${backupRestoreGuideLink}
|
||||
`
|
||||
}
|
||||
|
||||
|
||||
@@ -306,6 +306,8 @@ export default plugin(settingId, {
|
||||
BackupCopyScript: '' as IntlString,
|
||||
BackupCopyToken: '' as IntlString,
|
||||
BackupScriptInfo: '' as IntlString,
|
||||
BackupRestoreGuide: '' as IntlString,
|
||||
BackupRestoreGuideInfo: '' as IntlString,
|
||||
NonBackupedBlobs: '' as IntlString,
|
||||
AddAttribute: '' as IntlString,
|
||||
Mailboxes: '' as IntlString,
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": ". Nezapomeňte prosím svá data exportovat a přenést ještě před tímto datem.",
|
||||
"ShutdownCommunityHint": "Máte dotazy nebo chcete dostávat novinky? Připojte se ke komunitě Huly, kde můžete probrat migraci a zůstat v obraze.",
|
||||
"JoinCommunityCta": "Připojit se ke komunitě Huly",
|
||||
"ShutdownContactPrefix": "Máte dotazy? Kontaktujte "
|
||||
"ShutdownContactPrefix": "Máte dotazy? Kontaktujte ",
|
||||
"ShutdownBackupGuideHint": "Nevíte, jak přenést svá data? Přečtěte si podrobný návod ke stažení zálohy a jejímu obnovení v jiné instanci Huly.",
|
||||
"BackupGuideCta": "Průvodce zálohováním a obnovou"
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": " erwartet. Bitte exportieren und migrieren Sie Ihre Daten unbedingt vorher.",
|
||||
"ShutdownCommunityHint": "Haben Sie Fragen oder möchten Sie auf dem Laufenden bleiben? Treten Sie der Huly-Community bei, um die Migration zu besprechen und informiert zu bleiben.",
|
||||
"JoinCommunityCta": "Der Huly-Community beitreten",
|
||||
"ShutdownContactPrefix": "Fragen? Kontaktieren Sie "
|
||||
"ShutdownContactPrefix": "Fragen? Kontaktieren Sie ",
|
||||
"ShutdownBackupGuideHint": "Nicht sicher, wie Sie Ihre Daten übertragen? Lesen Sie die Schritt-für-Schritt-Anleitung zum Herunterladen eines Backups und zur Wiederherstellung in einer anderen Huly-Instanz.",
|
||||
"BackupGuideCta": "Anleitung zu Backup & Wiederherstellung"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": ". Please make sure to export and migrate your data before then.",
|
||||
"ShutdownCommunityHint": "Have questions or want updates? Join the Huly community to discuss migration and stay informed.",
|
||||
"JoinCommunityCta": "Join the Huly community",
|
||||
"ShutdownContactPrefix": "Questions? Contact "
|
||||
"ShutdownContactPrefix": "Questions? Contact ",
|
||||
"ShutdownBackupGuideHint": "Not sure how to move your data? Read the step-by-step guide for downloading a backup and restoring it into another Huly instance.",
|
||||
"BackupGuideCta": "Backup & restore guide"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": ". Asegúrate de exportar y migrar tus datos antes de esa fecha.",
|
||||
"ShutdownCommunityHint": "¿Tienes preguntas o quieres recibir novedades? Únete a la comunidad de Huly para hablar sobre la migración y mantenerte informado.",
|
||||
"JoinCommunityCta": "Unirse a la comunidad de Huly",
|
||||
"ShutdownContactPrefix": "¿Preguntas? Contacta con "
|
||||
"ShutdownContactPrefix": "¿Preguntas? Contacta con ",
|
||||
"ShutdownBackupGuideHint": "¿No sabes cómo migrar tus datos? Lee la guía paso a paso para descargar una copia de seguridad y restaurarla en otra instancia de Huly.",
|
||||
"BackupGuideCta": "Guía de copia de seguridad y restauración"
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": ". Veuillez veiller à exporter et migrer vos données avant cette date.",
|
||||
"ShutdownCommunityHint": "Des questions ou envie de suivre les actualités ? Rejoignez la communauté Huly pour discuter de la migration et rester informé.",
|
||||
"JoinCommunityCta": "Rejoindre la communauté Huly",
|
||||
"ShutdownContactPrefix": "Des questions ? Contactez "
|
||||
"ShutdownContactPrefix": "Des questions ? Contactez ",
|
||||
"ShutdownBackupGuideHint": "Vous ne savez pas comment migrer vos données ? Consultez le guide étape par étape pour télécharger une sauvegarde et la restaurer sur une autre instance Huly.",
|
||||
"BackupGuideCta": "Guide de sauvegarde et restauration"
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,8 @@
|
||||
"ShutdownNextEventAfter": ". Assicurati di esportare e migrare i tuoi dati prima di quella data.",
|
||||
"ShutdownCommunityHint": "Hai domande o vuoi ricevere aggiornamenti? Unisciti alla community di Huly per parlare della migrazione e restare informato.",
|
||||
"JoinCommunityCta": "Unisciti alla community di Huly",
|
||||
"ShutdownContactPrefix": "Domande? Contatta "
|
||||
"ShutdownContactPrefix": "Domande? Contatta ",
|
||||
"ShutdownBackupGuideHint": "Non sai come trasferire i tuoi dati? Leggi la guida dettagliata per scaricare un backup e ripristinarlo in un'altra istanza di Huly.",
|
||||
"BackupGuideCta": "Guida a backup e ripristino"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": " に予定されています。必ずその前にデータをエクスポートして移行してください。",
|
||||
"ShutdownCommunityHint": "ご質問や最新情報が必要ですか? Huly コミュニティに参加して、移行について相談したり最新情報を受け取ったりできます。",
|
||||
"JoinCommunityCta": "Huly コミュニティに参加",
|
||||
"ShutdownContactPrefix": "ご質問は "
|
||||
"ShutdownContactPrefix": "ご質問は ",
|
||||
"ShutdownBackupGuideHint": "データの移行方法がわからない場合は、バックアップをダウンロードして別の Huly インスタンスに復元する手順ガイドをご覧ください。",
|
||||
"BackupGuideCta": "バックアップと復元ガイド"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": "로 예상됩니다. 반드시 그 전에 데이터를 내보내고 이전해 주세요.",
|
||||
"ShutdownCommunityHint": "궁금한 점이 있거나 소식을 받고 싶으신가요? Huly 커뮤니티에 참여하여 이전에 대해 논의하고 최신 소식을 확인하세요.",
|
||||
"JoinCommunityCta": "Huly 커뮤니티 참여",
|
||||
"ShutdownContactPrefix": "문의사항은 "
|
||||
"ShutdownContactPrefix": "문의사항은 ",
|
||||
"ShutdownBackupGuideHint": "데이터를 옮기는 방법을 모르시나요? 백업을 다운로드하여 다른 Huly 인스턴스로 복원하는 단계별 가이드를 확인하세요.",
|
||||
"BackupGuideCta": "백업 및 복원 가이드"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": ". Pamiętaj, aby wyeksportować i przenieść dane przed tą datą.",
|
||||
"ShutdownCommunityHint": "Masz pytania lub chcesz otrzymywać aktualności? Dołącz do społeczności Huly, aby porozmawiać o migracji i być na bieżąco.",
|
||||
"JoinCommunityCta": "Dołącz do społeczności Huly",
|
||||
"ShutdownContactPrefix": "Masz pytania? Skontaktuj się: "
|
||||
"ShutdownContactPrefix": "Masz pytania? Skontaktuj się: ",
|
||||
"ShutdownBackupGuideHint": "Nie wiesz, jak przenieść swoje dane? Zapoznaj się z instrukcją krok po kroku dotyczącą pobierania kopii zapasowej i przywracania jej w innej instancji Huly.",
|
||||
"BackupGuideCta": "Przewodnik po kopii zapasowej i przywracaniu"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": ". Certifique-se de exportar e migrar seus dados antes dessa data.",
|
||||
"ShutdownCommunityHint": "Tem dúvidas ou quer receber novidades? Junte-se à comunidade do Huly para discutir a migração e ficar por dentro.",
|
||||
"JoinCommunityCta": "Entrar na comunidade do Huly",
|
||||
"ShutdownContactPrefix": "Dúvidas? Entre em contato: "
|
||||
"ShutdownContactPrefix": "Dúvidas? Entre em contato: ",
|
||||
"ShutdownBackupGuideHint": "Não sabe como migrar seus dados? Consulte o guia passo a passo para baixar um backup e restaurá-lo em outra instância do Huly.",
|
||||
"BackupGuideCta": "Guia de backup e restauração"
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": ". Certifique-se de exportar e migrar os seus dados antes dessa data.",
|
||||
"ShutdownCommunityHint": "Tem dúvidas ou quer receber novidades? Junte-se à comunidade do Huly para discutir a migração e manter-se informado.",
|
||||
"JoinCommunityCta": "Juntar-se à comunidade do Huly",
|
||||
"ShutdownContactPrefix": "Questões? Contacte "
|
||||
"ShutdownContactPrefix": "Questões? Contacte ",
|
||||
"ShutdownBackupGuideHint": "Não sabe como migrar os seus dados? Consulte o guia passo a passo para transferir uma cópia de segurança e restaurá-la noutra instância do Huly.",
|
||||
"BackupGuideCta": "Guia de cópia de segurança e restauro"
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": ". Пожалуйста, обязательно экспортируйте и перенесите данные до этой даты.",
|
||||
"ShutdownCommunityHint": "Есть вопросы или хотите получать обновления? Присоединяйтесь к сообществу Huly, чтобы обсудить миграцию и быть в курсе.",
|
||||
"JoinCommunityCta": "Вступить в сообщество Huly",
|
||||
"ShutdownContactPrefix": "Вопросы? Пишите на "
|
||||
"ShutdownContactPrefix": "Вопросы? Пишите на ",
|
||||
"ShutdownBackupGuideHint": "Не знаете, как перенести данные? Прочитайте пошаговую инструкцию о том, как скачать резервную копию и восстановить её в другом инстансе Huly.",
|
||||
"BackupGuideCta": "Резервное копирование и восстановление"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": " tarihinde bekleniyor. Lütfen verilerinizi bu tarihten önce dışa aktarıp taşıdığınızdan emin olun.",
|
||||
"ShutdownCommunityHint": "Sorularınız mı var ya da güncellemeleri takip etmek mi istiyorsunuz? Göçü konuşmak ve haberdar olmak için Huly topluluğuna katılın.",
|
||||
"JoinCommunityCta": "Huly topluluğuna katıl",
|
||||
"ShutdownContactPrefix": "Sorularınız mı var? İletişim: "
|
||||
"ShutdownContactPrefix": "Sorularınız mı var? İletişim: ",
|
||||
"ShutdownBackupGuideHint": "Verilerinizi nasıl taşıyacağınızdan emin değil misiniz? Bir yedeği indirip başka bir Huly örneğine geri yüklemek için adım adım kılavuzu okuyun.",
|
||||
"BackupGuideCta": "Yedekleme ve geri yükleme kılavuzu"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"ShutdownNextEventAfter": "。请务必在此日期之前导出并迁移你的数据。",
|
||||
"ShutdownCommunityHint": "有疑问或想获取最新消息?加入 Huly 社区,讨论迁移并随时了解动态。",
|
||||
"JoinCommunityCta": "加入 Huly 社区",
|
||||
"ShutdownContactPrefix": "有疑问?请联系:"
|
||||
"ShutdownContactPrefix": "有疑问?请联系:",
|
||||
"ShutdownBackupGuideHint": "不知道如何迁移数据?请阅读分步指南,了解如何下载备份并将其恢复到另一个 Huly 实例。",
|
||||
"BackupGuideCta": "备份与恢复指南"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { Button, Label } from '@hcengineering/ui'
|
||||
import workbench from '../plugin'
|
||||
import { communityLink, migrationContactEmail } from '../utils'
|
||||
import { backupGuideLink, communityLink, migrationContactEmail } from '../utils'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -24,6 +24,11 @@
|
||||
dispatch('close')
|
||||
window.open(communityLink, '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
|
||||
function handleOpenBackupGuide (): void {
|
||||
dispatch('close')
|
||||
window.open(backupGuideLink, '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="shutdown-notice-popup">
|
||||
@@ -48,6 +53,10 @@
|
||||
<Label label={workbench.string.ShutdownCommunityHint} />
|
||||
</div>
|
||||
|
||||
<div class="hint">
|
||||
<Label label={workbench.string.ShutdownBackupGuideHint} />
|
||||
</div>
|
||||
|
||||
<div class="hint">
|
||||
<Label label={workbench.string.ShutdownContactPrefix} /><a href="mailto:{migrationContactEmail}"
|
||||
>{migrationContactEmail}</a
|
||||
@@ -55,6 +64,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<Button label={workbench.string.BackupGuideCta} on:click={handleOpenBackupGuide} />
|
||||
<Button kind="primary" size="medium" label={workbench.string.JoinCommunityCta} on:click={handleJoinCommunity} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -105,6 +115,7 @@
|
||||
.footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -55,7 +55,9 @@ export default mergeIds(workbenchId, workbench, {
|
||||
ShutdownNextEventAfter: '' as IntlString,
|
||||
ShutdownCommunityHint: '' as IntlString,
|
||||
JoinCommunityCta: '' as IntlString,
|
||||
ShutdownContactPrefix: '' as IntlString
|
||||
ShutdownContactPrefix: '' as IntlString,
|
||||
ShutdownBackupGuideHint: '' as IntlString,
|
||||
BackupGuideCta: '' as IntlString
|
||||
},
|
||||
component: {
|
||||
SpacePanel: '' as AnyComponent,
|
||||
|
||||
@@ -59,6 +59,15 @@ export const communityLink = 'https://link.huly.io/slack'
|
||||
*/
|
||||
export const migrationContactEmail = 'artem@hardcoreeng.com'
|
||||
|
||||
/**
|
||||
* Step-by-step guide for downloading a workspace backup and restoring it into
|
||||
* another Huly instance, linked from the hosting shutdown notice so users can
|
||||
* migrate their data themselves.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const backupGuideLink = 'https://github.com/hcengineering/platform/blob/develop/docs/guides/backup-restore.en.md'
|
||||
|
||||
export function getSpecialSpaceClass (model: NavigatorModel): Array<Ref<Class<Space>>> {
|
||||
const spaceResult = model.spaces.map((x) => x.spaceClass)
|
||||
const result = (model.specials ?? [])
|
||||
|
||||
Reference in New Issue
Block a user