diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 4b2259c3f3..f1a9e94f48 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -548,6 +548,15 @@ dependencies: '@rush-temp/notification-resources': specifier: file:./projects/notification-resources.tgz version: file:projects/notification-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2) + '@rush-temp/onboard': + specifier: file:./projects/onboard.tgz + version: file:projects/onboard.tgz(@types/node@20.11.19)(esbuild@0.20.1)(ts-node@10.9.2) + '@rush-temp/onboard-assets': + specifier: file:./projects/onboard-assets.tgz + version: file:projects/onboard-assets.tgz(esbuild@0.20.1)(ts-node@10.9.2) + '@rush-temp/onboard-resources': + specifier: file:./projects/onboard-resources.tgz + version: file:projects/onboard-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(file-loader@6.2.0)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2)(webpack@5.90.3) '@rush-temp/openai': specifier: file:./projects/openai.tgz version: file:projects/openai.tgz(esbuild@0.20.1)(ts-node@10.9.2) @@ -25154,7 +25163,7 @@ packages: dev: false file:projects/desktop.tgz(bufferutil@4.0.8)(sass@1.71.1)(utf-8-validate@6.0.4): - resolution: {integrity: sha512-ttUpcNZ8VKqQjGhZ6u9UwTTCOpXBKD8BC7CziczYCzKpTCjdwEJh9agnt8uJU6eETt57hJY2c8BU/aIESyYMZA==, tarball: file:projects/desktop.tgz} + resolution: {integrity: sha512-Zqlhi9UprYvF9L0ANw8sSkxTuqMYWTDmIUV6wYDTHd+NMt8NKshXy9J39mll8dW0h93TeY538RePwutrdvM4kA==, tarball: file:projects/desktop.tgz} id: file:projects/desktop.tgz name: '@rush-temp/desktop' version: 0.0.0 @@ -28371,6 +28380,114 @@ packages: - ts-node dev: false + file:projects/onboard-assets.tgz(esbuild@0.20.1)(ts-node@10.9.2): + resolution: {integrity: sha512-W5Ci7+hkutP59Tt2Gp+5tElU0Ix6cptU7EQAYxwnuPQD+EPL51V5XzfIz1Kpf2mnicgb/TB2MFDX+uBjY5hq1A==, tarball: file:projects/onboard-assets.tgz} + id: file:projects/onboard-assets.tgz + name: '@rush-temp/onboard-assets' + version: 0.0.0 + dependencies: + '@types/jest': 29.5.12 + '@types/node': 20.11.19 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: 3.2.5 + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + dev: false + + file:projects/onboard-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(file-loader@6.2.0)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2)(webpack@5.90.3): + resolution: {integrity: sha512-3Gt9PEcA7T44mLBBC0KwwZQ6Qs7pXYbqQaagWFjfT+4MTvR9XVk4L+67U0yFYqpS/EeODSc+dJklk3QBY2O36g==, tarball: file:projects/onboard-resources.tgz} + id: file:projects/onboard-resources.tgz + name: '@rush-temp/onboard-resources' + version: 0.0.0 + dependencies: + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + eslint-plugin-svelte: 2.35.1(eslint@8.56.0)(svelte@4.2.12)(ts-node@10.9.2) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.2(prettier@3.2.5)(svelte@4.2.12) + sass: 1.71.1 + svelte: 4.2.12 + svelte-check: 3.6.9(postcss-load-config@4.0.2)(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.12) + svelte-eslint-parser: 0.33.1(svelte@4.2.12) + svelte-loader: 3.2.0(svelte@4.2.12) + svelte-preprocess: 5.1.3(postcss-load-config@4.0.2)(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.12)(typescript@5.3.3) + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.3.3) + typescript: 5.3.3 + url-loader: 4.1.1(file-loader@6.2.0)(webpack@5.90.3) + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - coffeescript + - esbuild + - file-loader + - less + - node-notifier + - postcss + - postcss-load-config + - pug + - stylus + - sugarss + - supports-color + - ts-node + - webpack + dev: false + + file:projects/onboard.tgz(@types/node@20.11.19)(esbuild@0.20.1)(ts-node@10.9.2): + resolution: {integrity: sha512-9KGKUTn0xaR5BXCSR0PDirFhStjot+g2QvBO1FDlehb2HWedfln6oswEUtM5n6VJwKS0UUKDwhpm5wLPo7KUMg==, tarball: file:projects/onboard.tgz} + id: file:projects/onboard.tgz + name: '@rush-temp/onboard' + version: 0.0.0 + dependencies: + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: 3.2.5 + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + dev: false + file:projects/openai.tgz(esbuild@0.20.1)(ts-node@10.9.2): resolution: {integrity: sha512-FTxDecAefUxIdNRC3gHwqZrNJpHI6Mi/fDduPFKm4YCxy3jpzFgWTKeRRpIQ2AZTQ6Cw4cWANh0VAI2DyTo8Ig==, tarball: file:projects/openai.tgz} id: file:projects/openai.tgz @@ -29436,7 +29553,7 @@ packages: dev: false file:projects/prod.tgz(bufferutil@4.0.8)(sass@1.71.1)(ts-node@10.9.2)(utf-8-validate@6.0.4): - resolution: {integrity: sha512-nTK4PWGg4h8wB67Ax8fO8iqUg1fOr8JhCgNTuz2o6VqTFnk7cDEc2k9FuYkdSho6HelRqEFcKGkmXsZEAungXQ==, tarball: file:projects/prod.tgz} + resolution: {integrity: sha512-U0i5q0YgmqM+29OoNKE5F7SYHLenVyjGDEus4MgN7CqMIC1n6n2gtztzRm2O6/j8hba5E6asgHgGF+ljESlbGw==, tarball: file:projects/prod.tgz} id: file:projects/prod.tgz name: '@rush-temp/prod' version: 0.0.0 diff --git a/desktop/package.json b/desktop/package.json index 6314c15e04..686f32fe53 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -69,6 +69,9 @@ "@hcengineering/login": "^0.6.12", "@hcengineering/login-assets": "^0.6.0", "@hcengineering/login-resources": "^0.6.2", + "@hcengineering/onboard": "^0.6.0", + "@hcengineering/onboard-assets": "^0.6.0", + "@hcengineering/onboard-resources": "^0.6.0", "@hcengineering/client": "^0.6.18", "@hcengineering/workbench": "^0.6.16", "@hcengineering/workbench-resources": "^0.6.1", diff --git a/desktop/src/ui/platform.ts b/desktop/src/ui/platform.ts index 8006d2a9e9..aaca275732 100644 --- a/desktop/src/ui/platform.ts +++ b/desktop/src/ui/platform.ts @@ -28,6 +28,7 @@ import { inventoryId } from '@hcengineering/inventory' import { leadId } from '@hcengineering/lead' import login, { loginId } from '@hcengineering/login' import notification, { notificationId } from '@hcengineering/notification' +import onboard, { onboardId } from '@hcengineering/onboard' import { recruitId } from '@hcengineering/recruit' import rekoni from '@hcengineering/rekoni' import { requestId } from '@hcengineering/request' @@ -143,6 +144,7 @@ function configureI18n (): void { notificationId, async (lang: string) => await import(`@hcengineering/notification-assets/lang/${lang}.json`) ) + addStringsLoader(onboardId, async (lang: string) => await import(`@hcengineering/onboard-assets/lang/${lang}.json`)) addStringsLoader( preferenceId, async (lang: string) => await import(`@hcengineering/preference-assets/lang/${lang}.json`) @@ -240,6 +242,7 @@ export async function configurePlatform (): Promise { new Map([ [workbenchId, workbench.component.WorkbenchApp], [loginId, login.component.LoginApp], + [onboardId, onboard.component.OnboardApp], [calendarId, calendar.component.ConnectApp], [guestId, guest.component.GuestApp] ]) @@ -250,6 +253,7 @@ export async function configurePlatform (): Promise { addLocation(clientId, async () => await import('@hcengineering/client-resources')) addLocation(loginId, async () => await import('@hcengineering/login-resources')) + addLocation(onboardId, async () => await import('@hcengineering/onboard-resources')) addLocation(workbenchId, async () => await import('@hcengineering/workbench-resources')) addLocation(viewId, async () => await import('@hcengineering/view-resources')) addLocation(taskId, async () => await import('@hcengineering/task-resources')) diff --git a/dev/prod/package.json b/dev/prod/package.json index c9054deed5..0273ec1c23 100644 --- a/dev/prod/package.json +++ b/dev/prod/package.json @@ -59,6 +59,9 @@ "@hcengineering/login": "^0.6.12", "@hcengineering/login-assets": "^0.6.0", "@hcengineering/login-resources": "^0.6.2", + "@hcengineering/onboard": "^0.6.0", + "@hcengineering/onboard-assets": "^0.6.0", + "@hcengineering/onboard-resources": "^0.6.0", "@hcengineering/client": "^0.6.18", "@hcengineering/workbench": "^0.6.16", "@hcengineering/workbench-resources": "^0.6.1", diff --git a/dev/prod/src/platform.ts b/dev/prod/src/platform.ts index f6f301c85f..02732ab600 100644 --- a/dev/prod/src/platform.ts +++ b/dev/prod/src/platform.ts @@ -32,6 +32,7 @@ import { inventoryId } from '@hcengineering/inventory' import { leadId } from '@hcengineering/lead' import login, { loginId } from '@hcengineering/login' import notification, { notificationId } from '@hcengineering/notification' +import onboard, { onboardId } from '@hcengineering/onboard' import { recruitId } from '@hcengineering/recruit' import rekoni from '@hcengineering/rekoni' import { requestId } from '@hcengineering/request' @@ -192,6 +193,7 @@ function configureI18n(): void { addStringsLoader(leadId, async (lang: string) => await import(`@hcengineering/lead-assets/lang/${lang}.json`)) addStringsLoader(loginId, async (lang: string) => await import(`@hcengineering/login-assets/lang/${lang}.json`)) addStringsLoader(notificationId, async (lang: string) => await import(`@hcengineering/notification-assets/lang/${lang}.json`)) + addStringsLoader(onboardId, async (lang: string) => await import(`@hcengineering/onboard-assets/lang/${lang}.json`)) addStringsLoader(preferenceId, async (lang: string) => await import(`@hcengineering/preference-assets/lang/${lang}.json`)) addStringsLoader(recruitId, async (lang: string) => await import(`@hcengineering/recruit-assets/lang/${lang}.json`)) addStringsLoader(requestId, async (lang: string) => await import(`@hcengineering/request-assets/lang/${lang}.json`)) @@ -326,6 +328,7 @@ export async function configurePlatform() { new Map([ [workbenchId, workbench.component.WorkbenchApp], [loginId, login.component.LoginApp], + [onboardId, onboard.component.OnboardApp], [githubId, github.component.ConnectApp], [calendarId, calendar.component.ConnectApp], [guestId, guest.component.GuestApp] @@ -337,6 +340,7 @@ export async function configurePlatform() { addLocation(clientId, () => import(/* webpackChunkName: "client" */ '@hcengineering/client-resources')) addLocation(loginId, () => import(/* webpackChunkName: "login" */ '@hcengineering/login-resources')) + addLocation(onboardId, () => import(/* webpackChunkName: "onboard" */ '@hcengineering/onboard-resources')) addLocation(workbenchId, () => import(/* webpackChunkName: "workbench" */ '@hcengineering/workbench-resources')) addLocation(viewId, () => import(/* webpackChunkName: "view" */ '@hcengineering/view-resources')) addLocation(taskId, () => import(/* webpackChunkName: "task" */ '@hcengineering/task-resources')) diff --git a/plugins/login-resources/src/components/Auth.svelte b/plugins/login-resources/src/components/Auth.svelte index 56b4fbf7a0..44c64d32a0 100644 --- a/plugins/login-resources/src/components/Auth.svelte +++ b/plugins/login-resources/src/components/Auth.svelte @@ -18,7 +18,7 @@ setMetadataLocalStorage(login.metadata.LastToken, result.token) setMetadataLocalStorage(login.metadata.LoginEndpoint, result.endpoint) setMetadataLocalStorage(login.metadata.LoginEmail, result.email) - await afterConfirm('onboard') + await afterConfirm() } else { goTo('login') } diff --git a/plugins/login-resources/src/components/LoginApp.svelte b/plugins/login-resources/src/components/LoginApp.svelte index bdea1b058c..77174900fa 100644 --- a/plugins/login-resources/src/components/LoginApp.svelte +++ b/plugins/login-resources/src/components/LoginApp.svelte @@ -51,7 +51,6 @@ import loginBackWebp from '../../img/login_back.webp' import loginBack2xWebp from '../../img/login_back_2x.webp' import login from '../plugin' - import OnboardForm from './OnboardForm.svelte' export let page: Pages = 'signup' @@ -138,8 +137,6 @@ {:else if page === 'signup'} - {:else if page === 'onboard'} - {:else if page === 'createWorkspace'} {:else if page === 'password'} diff --git a/plugins/login-resources/src/components/OnboardForm.svelte b/plugins/login-resources/src/components/OnboardForm.svelte index 333d14a7f7..413ffdb09f 100644 --- a/plugins/login-resources/src/components/OnboardForm.svelte +++ b/plugins/login-resources/src/components/OnboardForm.svelte @@ -13,7 +13,7 @@ // limitations under the License. --> + + diff --git a/plugins/onboard-resources/src/components/BottomAction.svelte b/plugins/onboard-resources/src/components/BottomAction.svelte new file mode 100644 index 0000000000..dfc9a9e6ce --- /dev/null +++ b/plugins/onboard-resources/src/components/BottomAction.svelte @@ -0,0 +1,45 @@ + + + + +
+ {#if action.caption} + + {/if} + {#if action.page} + + {:else} + + {/if} +
+ + diff --git a/plugins/onboard-resources/src/components/Form.svelte b/plugins/onboard-resources/src/components/Form.svelte new file mode 100644 index 0000000000..637c2be2f3 --- /dev/null +++ b/plugins/onboard-resources/src/components/Form.svelte @@ -0,0 +1,258 @@ + + + + +
720 ? '42rem' : '0'} + on:keydown={(evt) => { + if (evt.key === 'Enter') { + evt.preventDefault() + evt.stopPropagation() + if (!inAction) { + void validate($themeStore.language).then((res) => { + if (res) { + performAction(action) + } + }) + } + } + }} +> + {#if subtitle !== undefined} +
+ {subtitle} +
+ {/if} +
+
+ {#each fields as field (field.name)} +
+ validate($themeStore.language)} + on:blur={() => { + trim(field.name) + }} + /> +
+ {/each} + +
+ +
+ +
+
+ {#if secondaryButtonLabel && secondaryButtonAction} +
+
+ {/if} +
+ {#if bottomActions.length} + + {/if} +
+ + diff --git a/plugins/onboard-resources/src/components/OnboardApp.svelte b/plugins/onboard-resources/src/components/OnboardApp.svelte new file mode 100644 index 0000000000..17e33e29c4 --- /dev/null +++ b/plugins/onboard-resources/src/components/OnboardApp.svelte @@ -0,0 +1,228 @@ + + + +
+
768} class:p-4={$deviceInfo.docWidth > 768}> + + + + + + + +
+ {getMetadata(workbench.metadata.PlatformTitle)} +
+ +
768} class:white={!$themeStore.dark}> + +
+ {#if page === 'onboard'} + + {:else if page === 'auth'} + + {/if} +
+
+
+ + +
+
+ + diff --git a/plugins/onboard-resources/src/components/OnboardForm.svelte b/plugins/onboard-resources/src/components/OnboardForm.svelte new file mode 100644 index 0000000000..22c211a748 --- /dev/null +++ b/plugins/onboard-resources/src/components/OnboardForm.svelte @@ -0,0 +1,92 @@ + + + +{#if account} + {#if step === OnboardSteps.Workspace} + + {:else if step === OnboardSteps.User} + + {:else if step === OnboardSteps.Finish} +
+ {/if} +{/if} diff --git a/plugins/onboard-resources/src/components/OnboardUserForm.svelte b/plugins/onboard-resources/src/components/OnboardUserForm.svelte new file mode 100644 index 0000000000..08d79c8bde --- /dev/null +++ b/plugins/onboard-resources/src/components/OnboardUserForm.svelte @@ -0,0 +1,67 @@ + + + + { + dispatch('step') + } + } + ]} +/> diff --git a/plugins/onboard-resources/src/components/OnboardWorkspaceForm.svelte b/plugins/onboard-resources/src/components/OnboardWorkspaceForm.svelte new file mode 100644 index 0000000000..bd58c1b913 --- /dev/null +++ b/plugins/onboard-resources/src/components/OnboardWorkspaceForm.svelte @@ -0,0 +1,52 @@ + + + + diff --git a/plugins/onboard-resources/src/components/StatusControl.svelte b/plugins/onboard-resources/src/components/StatusControl.svelte new file mode 100644 index 0000000000..49afb6c5f2 --- /dev/null +++ b/plugins/onboard-resources/src/components/StatusControl.svelte @@ -0,0 +1,44 @@ + + + +{#if status.severity !== Severity.OK} +
+ +
+{/if} + + diff --git a/plugins/onboard-resources/src/components/icons/OnboardIcon.svelte b/plugins/onboard-resources/src/components/icons/OnboardIcon.svelte new file mode 100644 index 0000000000..b07bc20092 --- /dev/null +++ b/plugins/onboard-resources/src/components/icons/OnboardIcon.svelte @@ -0,0 +1,6 @@ + + + diff --git a/plugins/onboard-resources/src/index.ts b/plugins/onboard-resources/src/index.ts new file mode 100644 index 0000000000..ed2819ffe1 --- /dev/null +++ b/plugins/onboard-resources/src/index.ts @@ -0,0 +1,42 @@ +// +// 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. +// + +import type { IntlString, Resources } from '@hcengineering/platform' +import OnboardApp from './components/OnboardApp.svelte' + +export default async (): Promise => ({ + component: { + OnboardApp + } +}) + +export const pages = ['auth', 'onboard'] as const + +export enum OnboardSteps { + Workspace = 'workspace', + User = 'user', + Finish = 'finish' +} + +export type Pages = (typeof pages)[number] + +export interface BottomAction { + i18n: IntlString + page?: Pages + func: () => void + caption?: IntlString +} + +export * from './utils' diff --git a/plugins/onboard-resources/src/plugin.ts b/plugins/onboard-resources/src/plugin.ts new file mode 100644 index 0000000000..7adcf8d5b0 --- /dev/null +++ b/plugins/onboard-resources/src/plugin.ts @@ -0,0 +1,38 @@ +/*! +// 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. +*/ + +import onboard, { onboardId } from '@hcengineering/onboard' +import type { IntlString, StatusCode } from '@hcengineering/platform' +import { mergeIds } from '@hcengineering/platform' + +export default mergeIds(onboardId, onboard, { + status: { + RequiredField: '' as StatusCode<{ field: string }>, + FieldsDoNotMatch: '' as StatusCode<{ field: string, field2: string }>, + ConnectingToServer: '' as StatusCode + }, + string: { + CreateWorkspace: '' as IntlString, + LastName: '' as IntlString, + FirstName: '' as IntlString, + Workspace: '' as IntlString, + FillInProfile: '' as IntlString, + SetUpPassword: '' as IntlString, + Next: '' as IntlString, + Skip: '' as IntlString, + SignUpCompleted: '' as IntlString, + StartUsingHuly: '' as IntlString + } +}) diff --git a/plugins/onboard-resources/src/utils.ts b/plugins/onboard-resources/src/utils.ts new file mode 100644 index 0000000000..df0c390ed9 --- /dev/null +++ b/plugins/onboard-resources/src/utils.ts @@ -0,0 +1,84 @@ +// +// 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. +// + +import { type LoginInfo } from '@hcengineering/login' +import { + getWorkspaces, + navigateToWorkspace, + selectWorkspace, + type Pages as LoginPages +} from '@hcengineering/login-resources' +import { getMetadata } from '@hcengineering/platform' +import presentation from '@hcengineering/presentation' +import { type Location, getCurrentLocation, locationToUrl, navigate } from '@hcengineering/ui' + +import { type Pages } from './index' + +export function getLoc (path: Pages): Location { + const loc = getCurrentLocation() + loc.path[1] = path + loc.path.length = 2 + return loc +} + +export function goTo (path: Pages, clearQuery: boolean = false): void { + const loc = getLoc(path) + if (clearQuery) { + loc.query = undefined + } + navigate(loc) +} + +export function goToLogin (page: LoginPages, clearQuery: boolean = false): void { + const loc = getCurrentLocation() + loc.path[0] = 'login' + loc.path[1] = page + loc.path.length = 2 + if (clearQuery) { + loc.query = undefined + } + navigate(loc) +} + +export function getHref (path: Pages): string { + const url = locationToUrl(getLoc(path)) + const frontUrl = getMetadata(presentation.metadata.FrontUrl) + const host = frontUrl ?? document.location.origin + return host + url +} + +export async function ensureConfirmed (account: LoginInfo): Promise { + if (!account.confirmed) { + const loc = getCurrentLocation() + loc.path[0] = 'login' + loc.path[1] = 'confirmationSend' + loc.path.length = 2 + navigate(loc) + } +} + +export async function afterConfirm (): Promise { + const joinedWS = await getWorkspaces() + if (joinedWS.length === 0) { + goTo('onboard') + } else if (joinedWS.length === 1) { + const result = (await selectWorkspace(joinedWS[0].workspace, null))[1] + if (result !== undefined) { + navigateToWorkspace(joinedWS[0].workspace, result) + } + } else { + goToLogin('selectWorkspace') + } +} diff --git a/plugins/onboard-resources/svelte.config.js b/plugins/onboard-resources/svelte.config.js new file mode 100644 index 0000000000..944a06f73e --- /dev/null +++ b/plugins/onboard-resources/svelte.config.js @@ -0,0 +1,5 @@ +const sveltePreprocess = require('svelte-preprocess') + +module.exports = { + preprocess: sveltePreprocess() +}; \ No newline at end of file diff --git a/plugins/onboard-resources/tsconfig.json b/plugins/onboard-resources/tsconfig.json new file mode 100644 index 0000000000..fb6ccb2d18 --- /dev/null +++ b/plugins/onboard-resources/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/ui/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types" + } +} \ No newline at end of file diff --git a/plugins/onboard/.eslintrc.js b/plugins/onboard/.eslintrc.js new file mode 100644 index 0000000000..72235dc283 --- /dev/null +++ b/plugins/onboard/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/plugins/onboard/.npmignore b/plugins/onboard/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/plugins/onboard/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/plugins/onboard/config/rig.json b/plugins/onboard/config/rig.json new file mode 100644 index 0000000000..0110930f55 --- /dev/null +++ b/plugins/onboard/config/rig.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig" +} diff --git a/plugins/onboard/jest.config.js b/plugins/onboard/jest.config.js new file mode 100644 index 0000000000..2cfd408b67 --- /dev/null +++ b/plugins/onboard/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/plugins/onboard/package.json b/plugins/onboard/package.json new file mode 100644 index 0000000000..623649acb7 --- /dev/null +++ b/plugins/onboard/package.json @@ -0,0 +1,49 @@ +{ + "name": "@hcengineering/onboard", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "files": [ + "lib/**/*", + "types/**/*", + "tsconfig.json" + ], + "author": "Hardcore Engineering Inc.", + "license": "EPL-2.0", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "test": "jest --passWithNoTests --silent", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "typescript": "^5.3.3", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5" + }, + "dependencies": { + "@hcengineering/core": "^0.6.32", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/ui": "^0.6.15", + "@hcengineering/login": "^0.6.12" + }, + "repository": "https://github.com/hcenginneing/anticrm", + "publishConfig": { + "registry": "https://npm.pkg.github.com" + } +} diff --git a/plugins/onboard/src/index.ts b/plugins/onboard/src/index.ts new file mode 100644 index 0000000000..ad142d986b --- /dev/null +++ b/plugins/onboard/src/index.ts @@ -0,0 +1,27 @@ +// +// 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. +// + +import type { Plugin } from '@hcengineering/platform' +import { plugin } from '@hcengineering/platform' +import type { AnyComponent } from '@hcengineering/ui' + +/** @public */ +export const onboardId = 'onboard' as Plugin + +export default plugin(onboardId, { + component: { + OnboardApp: '' as AnyComponent + } +}) diff --git a/plugins/onboard/tsconfig.json b/plugins/onboard/tsconfig.json new file mode 100644 index 0000000000..59e4fd4297 --- /dev/null +++ b/plugins/onboard/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/pods/authProviders/src/token.ts b/pods/authProviders/src/token.ts index 727844f7d1..2c5c79ad3c 100644 --- a/pods/authProviders/src/token.ts +++ b/pods/authProviders/src/token.ts @@ -55,7 +55,7 @@ export function registerToken ( measureCtx.info('Success auth, redirect', { email: user.email, type: 'token' }) // Successful authentication, redirect to your application - ctx.redirect(concatLink(branding?.front ?? frontUrl, '/login/auth')) + ctx.redirect(concatLink(branding?.front ?? frontUrl, '/onboard/auth')) } await next() } diff --git a/rush.json b/rush.json index 456ad418d8..792cd39999 100644 --- a/rush.json +++ b/rush.json @@ -576,6 +576,21 @@ "projectFolder": "plugins/login-resources", "shouldPublish": false }, + { + "packageName": "@hcengineering/onboard", + "projectFolder": "plugins/onboard", + "shouldPublish": true + }, + { + "packageName": "@hcengineering/onboard-assets", + "projectFolder": "plugins/onboard-assets", + "shouldPublish": false + }, + { + "packageName": "@hcengineering/onboard-resources", + "projectFolder": "plugins/onboard-resources", + "shouldPublish": false + }, { "packageName": "@hcengineering/workbench", "projectFolder": "plugins/workbench", diff --git a/server/server-pipeline/package.json b/server/server-pipeline/package.json index b36444b30e..a35d5dc2be 100644 --- a/server/server-pipeline/package.json +++ b/server/server-pipeline/package.json @@ -104,6 +104,7 @@ "@hcengineering/openai": "^0.6.0", "@hcengineering/translate": "^0.6.0", "@hcengineering/login-assets": "^0.6.0", + "@hcengineering/onboard-assets": "^0.6.0", "@hcengineering/view-assets": "^0.6.11", "@hcengineering/task-assets": "^0.6.19", "@hcengineering/chunter-assets": "^0.6.18", @@ -134,6 +135,7 @@ "@hcengineering/products-assets": "^0.1.0", "@hcengineering/training-assets": "^0.1.0", "@hcengineering/login": "^0.6.12", + "@hcengineering/onboard": "^0.6.0", "@hcengineering/view": "^0.6.13", "@hcengineering/task": "^0.6.20", "@hcengineering/chunter": "^0.6.20", diff --git a/server/server-pipeline/src/internationalization.ts b/server/server-pipeline/src/internationalization.ts index 265df55a1a..0a19bc82ed 100644 --- a/server/server-pipeline/src/internationalization.ts +++ b/server/server-pipeline/src/internationalization.ts @@ -18,6 +18,7 @@ import { leadId } from '@hcengineering/lead' import { loginId } from '@hcengineering/login' import { loveId } from '@hcengineering/love' import { notificationId } from '@hcengineering/notification' +import { onboardId } from '@hcengineering/onboard' import { preferenceId } from '@hcengineering/preference' import { productsId } from '@hcengineering/products' import { recruitId } from '@hcengineering/recruit' @@ -52,6 +53,7 @@ import inventoryEn from '@hcengineering/inventory-assets/lang/en.json' import leadEn from '@hcengineering/lead-assets/lang/en.json' import loveEn from '@hcengineering/love-assets/lang/en.json' import notificationEn from '@hcengineering/notification-assets/lang/en.json' +import onboardEn from '@hcengineering/onboard-assets/lang/en.json' import preferenceEn from '@hcengineering/preference-assets/lang/en.json' import productsEn from '@hcengineering/products-assets/lang/en.json' import recruitEn from '@hcengineering/recruit-assets/lang/en.json' @@ -70,6 +72,7 @@ import workbenchEn from '@hcengineering/workbench-assets/lang/en.json' export function registerStringLoaders (): void { addStringsLoader(coreId, async (lang: string) => coreEng) addStringsLoader(loginId, async (lang: string) => loginEng) + addStringsLoader(onboardId, async (lang: string) => onboardEn) addStringsLoader(platformId, async (lang: string) => platformEng) addStringsLoader(taskId, async (lang: string) => taskEn)