mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-13 03:40:48 +00:00
parent
b3ae99c537
commit
4341f0161a
30
plugins/login-resources/src/actions.ts
Normal file
30
plugins/login-resources/src/actions.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { goTo } from './utils'
|
||||
import login from './plugin'
|
||||
import { type BottomAction } from '.'
|
||||
|
||||
export const signUpAction: BottomAction = {
|
||||
caption: login.string.DoNotHaveAnAccount,
|
||||
i18n: login.string.SignUp,
|
||||
page: 'signup',
|
||||
func: () => {
|
||||
goTo('signup')
|
||||
}
|
||||
}
|
||||
|
||||
export const loginAction: BottomAction = {
|
||||
caption: login.string.AlreadyJoined,
|
||||
i18n: login.string.LogIn,
|
||||
page: 'login',
|
||||
func: () => {
|
||||
goTo('login', true)
|
||||
}
|
||||
}
|
||||
|
||||
export const recoveryAction: BottomAction = {
|
||||
caption: login.string.ForgotPassword,
|
||||
i18n: login.string.Recover,
|
||||
page: 'password',
|
||||
func: () => {
|
||||
goTo('password', true)
|
||||
}
|
||||
}
|
@ -13,32 +13,16 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { OK, setMetadata, Severity, Status } from '@hcengineering/platform'
|
||||
import { OK, Severity, Status, setMetadata } from '@hcengineering/platform'
|
||||
|
||||
import { getCurrentLocation, navigate, setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import { confirm } from '../utils'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import { getCurrentLocation, setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import { onMount } from 'svelte'
|
||||
import login from '../plugin'
|
||||
import { afterConfirm, confirm, goTo } from '../utils'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
|
||||
export let status: Status<any> = OK
|
||||
|
||||
function goToWorkspaces () {
|
||||
const loc = getCurrentLocation()
|
||||
loc.query = undefined
|
||||
loc.path[1] = 'selectWorkspace'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
}
|
||||
|
||||
function goToLogin (): void {
|
||||
const loc = getCurrentLocation()
|
||||
loc.query = undefined
|
||||
loc.path[1] = 'login'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
}
|
||||
|
||||
async function check (): Promise<void> {
|
||||
const location = getCurrentLocation()
|
||||
if (location.query?.id === undefined || location.query?.id === null) return
|
||||
@ -53,13 +37,13 @@
|
||||
setMetadataLocalStorage(login.metadata.LastToken, result.token)
|
||||
setMetadataLocalStorage(login.metadata.LoginEndpoint, result.endpoint)
|
||||
setMetadataLocalStorage(login.metadata.LoginEmail, result.email)
|
||||
goToWorkspaces()
|
||||
await afterConfirm()
|
||||
} else {
|
||||
goToLogin()
|
||||
goTo('login')
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
check()
|
||||
void check()
|
||||
})
|
||||
</script>
|
||||
|
@ -13,26 +13,23 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Label, getCurrentLocation, navigate } from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import { getAccount } from '../utils'
|
||||
import { Label } from '@hcengineering/ui'
|
||||
import { onMount } from 'svelte'
|
||||
import login from '../plugin'
|
||||
import { afterConfirm, getAccount } from '../utils'
|
||||
|
||||
const CHECK_INTERVAL = 1000
|
||||
|
||||
async function checkAccountStatus () {
|
||||
async function checkAccountStatus (): Promise<void> {
|
||||
const account = await getAccount()
|
||||
if (account?.confirmed === true) {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'selectWorkspace'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
await afterConfirm()
|
||||
}
|
||||
}
|
||||
|
||||
let weAreHere = false
|
||||
|
||||
async function check () {
|
||||
async function check (): Promise<void> {
|
||||
try {
|
||||
await checkAccountStatus()
|
||||
} catch (e) {
|
||||
@ -45,7 +42,7 @@
|
||||
|
||||
onMount(() => {
|
||||
weAreHere = true
|
||||
check()
|
||||
void check()
|
||||
return () => {
|
||||
weAreHere = false
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { Status, Severity, OK, setMetadata } from '@hcengineering/platform'
|
||||
|
||||
import Form from './Form.svelte'
|
||||
import { createWorkspace, getAccount } from '../utils'
|
||||
import { createWorkspace, getAccount, goTo } from '../utils'
|
||||
import { fetchMetadataLocalStorage, getCurrentLocation, navigate, setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import { workbenchId } from '@hcengineering/workbench'
|
||||
@ -26,6 +26,7 @@
|
||||
|
||||
const fields = [
|
||||
{
|
||||
id: 'workspace',
|
||||
name: 'workspace',
|
||||
i18n: login.string.Workspace,
|
||||
rules: []
|
||||
@ -40,7 +41,7 @@
|
||||
|
||||
onMount(async () => {
|
||||
const account = await getAccount()
|
||||
if (account?.confirmed !== true) {
|
||||
if (account?.confirmed === false) {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'confirmationSend'
|
||||
loc.path.length = 2
|
||||
@ -60,7 +61,7 @@
|
||||
setMetadata(presentation.metadata.Token, result.token)
|
||||
setMetadataLocalStorage(login.metadata.LastToken, result.token)
|
||||
const tokens: Record<string, string> = fetchMetadataLocalStorage(login.metadata.LoginTokens) ?? {}
|
||||
tokens[object.workspace] = result.token
|
||||
tokens[result.workspace] = result.token
|
||||
setMetadataLocalStorage(login.metadata.LoginTokens, tokens)
|
||||
setMetadataLocalStorage(login.metadata.LoginEndpoint, result.endpoint)
|
||||
setMetadataLocalStorage(login.metadata.LoginEmail, result.email)
|
||||
@ -80,11 +81,9 @@
|
||||
{
|
||||
caption: login.string.HaveWorkspace,
|
||||
i18n: login.string.SelectWorkspace,
|
||||
page: 'selectWorkspace',
|
||||
func: () => {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'selectWorkspace'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
goTo('selectWorkspace')
|
||||
}
|
||||
}
|
||||
]}
|
||||
|
@ -14,21 +14,23 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { IntlString } from '@hcengineering/platform'
|
||||
import { OK, Severity, Status, translate } from '@hcengineering/platform'
|
||||
import {
|
||||
Button,
|
||||
Label,
|
||||
StylishEdit,
|
||||
deviceOptionsStore as deviceInfo,
|
||||
getCurrentLocation,
|
||||
navigate,
|
||||
StylishEdit,
|
||||
Label,
|
||||
Button,
|
||||
deviceOptionsStore as deviceInfo,
|
||||
themeStore
|
||||
} from '@hcengineering/ui'
|
||||
import StatusControl from './StatusControl.svelte'
|
||||
import { OK, Status, Severity, translate } from '@hcengineering/platform'
|
||||
import type { IntlString } from '@hcengineering/platform'
|
||||
|
||||
import login from '../plugin'
|
||||
import { NavLink } from '@hcengineering/presentation'
|
||||
import { onMount } from 'svelte'
|
||||
import { BottomAction, getHref } from '..'
|
||||
import login from '../plugin'
|
||||
|
||||
interface Field {
|
||||
id?: string
|
||||
@ -49,12 +51,6 @@
|
||||
func: () => Promise<void>
|
||||
}
|
||||
|
||||
interface BottomAction {
|
||||
i18n: IntlString
|
||||
func: () => void
|
||||
caption: IntlString
|
||||
}
|
||||
|
||||
export let caption: IntlString
|
||||
export let status: Status
|
||||
export let fields: Field[]
|
||||
@ -107,7 +103,7 @@
|
||||
|
||||
let inAction = false
|
||||
|
||||
function performAction (action: Action) {
|
||||
function performAction (action: Action): void {
|
||||
for (const field of fields) {
|
||||
trim(field.name)
|
||||
}
|
||||
@ -223,7 +219,11 @@
|
||||
{#each bottomActions as action}
|
||||
<div>
|
||||
<span><Label label={action.caption} /></span>
|
||||
<a href="." on:click|preventDefault={action.func}><Label label={action.i18n} /></a>
|
||||
{#if action.page}
|
||||
<NavLink href={getHref(action.page)}><Label label={action.i18n} /></NavLink>
|
||||
{:else}
|
||||
<a href="." on:click|preventDefault={action.func}><Label label={action.i18n} /></a>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
@ -61,7 +61,7 @@
|
||||
}
|
||||
})
|
||||
|
||||
function setToDefault () {
|
||||
function setToDefault (): void {
|
||||
expHours = defaultValues.expirationTime
|
||||
emailMask = defaultValues.emailMask
|
||||
limit = defaultValues.limit
|
||||
|
@ -23,6 +23,8 @@
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import { workbenchId } from '@hcengineering/workbench'
|
||||
import { onMount } from 'svelte'
|
||||
import { BottomAction } from '..'
|
||||
import { loginAction, recoveryAction } from '../actions'
|
||||
import login from '../plugin'
|
||||
|
||||
const location = getCurrentLocation()
|
||||
@ -88,46 +90,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: bottom = page === 'login' ? [signUpAction] : [loginJoinAction]
|
||||
$: secondaryButtonLabel = page === 'login' ? login.string.SignUp : undefined
|
||||
$: secondaryButtonAction = () => {
|
||||
page = 'signUp'
|
||||
}
|
||||
|
||||
const signUpAction = {
|
||||
const signUpAction: BottomAction = {
|
||||
caption: login.string.DoNotHaveAnAccount,
|
||||
i18n: login.string.SignUp,
|
||||
func: () => (page = 'signUp')
|
||||
}
|
||||
|
||||
const loginJoinAction = {
|
||||
const loginJoinAction: BottomAction = {
|
||||
caption: login.string.HaveAccount,
|
||||
i18n: login.string.LogIn,
|
||||
func: () => (page = 'login')
|
||||
}
|
||||
|
||||
const loginAction = {
|
||||
caption: login.string.AlreadyJoined,
|
||||
i18n: login.string.LogIn,
|
||||
func: () => {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'login'
|
||||
loc.query = undefined
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
}
|
||||
}
|
||||
|
||||
const recoveryAction = {
|
||||
caption: login.string.ForgotPassword,
|
||||
i18n: login.string.Recover,
|
||||
func: () => {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'password'
|
||||
loc.query = undefined
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
}
|
||||
$: bottom = page === 'login' ? [signUpAction] : [loginJoinAction]
|
||||
$: secondaryButtonLabel = page === 'login' ? login.string.SignUp : undefined
|
||||
$: secondaryButtonAction = () => {
|
||||
page = 'signUp'
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Popup, Scroller, deviceOptionsStore as deviceInfo, location, ticker, themeStore } from '@hcengineering/ui'
|
||||
import { Popup, Scroller, deviceOptionsStore as deviceInfo, location, themeStore } from '@hcengineering/ui'
|
||||
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
@ -37,40 +37,23 @@
|
||||
import loginBackAvif from '../../img/login_back.avif'
|
||||
import loginBack2xAvif from '../../img/login_back_2x.avif'
|
||||
|
||||
import { Pages, pages } from '..'
|
||||
import loginBackWebp from '../../img/login_back.webp'
|
||||
import loginBack2xWebp from '../../img/login_back_2x.webp'
|
||||
|
||||
export let page: string = 'login'
|
||||
export let page: Pages = 'login'
|
||||
|
||||
let navigateUrl: string | undefined
|
||||
|
||||
function getToken (timer: number): string | undefined {
|
||||
return getMetadata(presentation.metadata.Token)
|
||||
}
|
||||
$: token = getToken($ticker)
|
||||
|
||||
const pages = [
|
||||
'login',
|
||||
'signup',
|
||||
'createWorkspace',
|
||||
'password',
|
||||
'recovery',
|
||||
'selectWorkspace',
|
||||
'join',
|
||||
'confirm',
|
||||
'confirmationSend'
|
||||
]
|
||||
onDestroy(
|
||||
location.subscribe((loc) => {
|
||||
void (async (loc) => {
|
||||
token = getMetadata(presentation.metadata.Token)
|
||||
page = loc.path[1] ?? (token ? 'selectWorkspace' : 'login')
|
||||
if (!pages.includes(page)) {
|
||||
page = 'login'
|
||||
}
|
||||
const token = getMetadata(presentation.metadata.Token)
|
||||
page = (loc.path[1] as Pages) ?? (token != null ? 'selectWorkspace' : 'login')
|
||||
if (!pages.includes(page)) {
|
||||
page = 'login'
|
||||
}
|
||||
|
||||
navigateUrl = loc.query?.navigateUrl ?? undefined
|
||||
})(loc)
|
||||
navigateUrl = loc.query?.navigateUrl ?? undefined
|
||||
})
|
||||
)
|
||||
</script>
|
||||
|
@ -30,6 +30,7 @@
|
||||
import Form from './Form.svelte'
|
||||
|
||||
import { LoginInfo } from '@hcengineering/login'
|
||||
import { recoveryAction } from '../actions'
|
||||
import login from '../plugin'
|
||||
|
||||
export let navigateUrl: string | undefined = undefined
|
||||
@ -51,15 +52,11 @@
|
||||
|
||||
async function doLoginNavigate (
|
||||
result: LoginInfo | undefined,
|
||||
updateStatus: (status: Status<any>) => void,
|
||||
token?: string
|
||||
updateStatus: (status: Status<any>) => void
|
||||
): Promise<boolean> {
|
||||
if (result !== undefined) {
|
||||
if (result.token != null && getMetadata(presentation.metadata.Token) === result.token) {
|
||||
return false
|
||||
}
|
||||
setMetadata(presentation.metadata.Token, token ?? result.token)
|
||||
setMetadataLocalStorage(login.metadata.LastToken, token ?? result.token)
|
||||
setMetadata(presentation.metadata.Token, result.token)
|
||||
setMetadataLocalStorage(login.metadata.LastToken, result.token)
|
||||
setMetadataLocalStorage(login.metadata.LoginEndpoint, result.endpoint)
|
||||
setMetadataLocalStorage(login.metadata.LoginEmail, result.email)
|
||||
|
||||
@ -108,16 +105,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
const recoveryAction = {
|
||||
caption: login.string.ForgotPassword,
|
||||
i18n: login.string.Recover,
|
||||
func: () => {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'password'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
}
|
||||
}
|
||||
let loading = true
|
||||
|
||||
async function chooseToken (time: number): Promise<void> {
|
||||
@ -125,15 +112,11 @@
|
||||
const lastToken = fetchMetadataLocalStorage(login.metadata.LastToken)
|
||||
if (lastToken != null) {
|
||||
try {
|
||||
const info = await getAccount(false, lastToken)
|
||||
const info = await getAccount(false)
|
||||
if (info !== undefined) {
|
||||
await doLoginNavigate(
|
||||
info,
|
||||
(st) => {
|
||||
status = st
|
||||
},
|
||||
lastToken
|
||||
)
|
||||
await doLoginNavigate(info, (st) => {
|
||||
status = st
|
||||
})
|
||||
}
|
||||
} catch (err: any) {
|
||||
setMetadataLocalStorage(login.metadata.LastToken, null)
|
||||
|
@ -16,10 +16,12 @@
|
||||
import { OK, Severity, Status } from '@hcengineering/platform'
|
||||
import { MessageBox } from '@hcengineering/presentation'
|
||||
|
||||
import { getCurrentLocation, navigate, showPopup } from '@hcengineering/ui'
|
||||
import { showPopup } from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import { requestPassword } from '../utils'
|
||||
import { goTo, requestPassword } from '../utils'
|
||||
import Form from './Form.svelte'
|
||||
import { BottomAction } from '..'
|
||||
import { signUpAction } from '../actions'
|
||||
|
||||
const fields = [{ id: 'email', name: 'username', i18n: login.string.Email }]
|
||||
|
||||
@ -46,35 +48,20 @@
|
||||
},
|
||||
undefined,
|
||||
() => {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'login'
|
||||
navigate(loc)
|
||||
goTo('login')
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const signUpAction = {
|
||||
caption: login.string.DoNotHaveAnAccount,
|
||||
i18n: login.string.SignUp,
|
||||
func: () => {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'signup'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
}
|
||||
}
|
||||
|
||||
const bottomActions = [
|
||||
const bottomActions: BottomAction[] = [
|
||||
{
|
||||
caption: login.string.KnowPassword,
|
||||
i18n: login.string.LogIn,
|
||||
page: 'login',
|
||||
func: () => {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'login'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
goTo('login')
|
||||
}
|
||||
},
|
||||
signUpAction
|
||||
|
@ -15,11 +15,11 @@
|
||||
<script lang="ts">
|
||||
import { OK, setMetadata, Severity, Status } from '@hcengineering/platform'
|
||||
|
||||
import { getCurrentLocation, navigate, setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import { restorePassword } from '../utils'
|
||||
import Form from './Form.svelte'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import { getCurrentLocation, setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import { goTo, restorePassword } from '../utils'
|
||||
import Form from './Form.svelte'
|
||||
|
||||
const fields = [
|
||||
{ id: 'new-password', name: 'password', i18n: login.string.Password, password: true },
|
||||
@ -48,10 +48,7 @@
|
||||
setMetadata(presentation.metadata.Token, result.token)
|
||||
setMetadataLocalStorage(login.metadata.LoginEndpoint, result.endpoint)
|
||||
setMetadataLocalStorage(login.metadata.LoginEmail, result.email)
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'selectWorkspace'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
goTo('selectWorkspace')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,22 +14,14 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { OK, Severity, Status } from '@hcengineering/platform'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import {
|
||||
Button,
|
||||
Label,
|
||||
Scroller,
|
||||
deviceOptionsStore as deviceInfo,
|
||||
getCurrentLocation,
|
||||
navigate,
|
||||
setMetadataLocalStorage
|
||||
} from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import { getAccount, getWorkspaces, navigateToWorkspace, selectWorkspace } from '../utils'
|
||||
import StatusControl from './StatusControl.svelte'
|
||||
import { LoginInfo, Workspace } from '@hcengineering/login'
|
||||
import { OK, Severity, Status } from '@hcengineering/platform'
|
||||
import presentation, { NavLink } from '@hcengineering/presentation'
|
||||
import { Button, Label, Scroller, deviceOptionsStore as deviceInfo, setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import { onMount } from 'svelte'
|
||||
import login from '../plugin'
|
||||
import { getAccount, getHref, getWorkspaces, goTo, navigateToWorkspace, selectWorkspace } from '../utils'
|
||||
import StatusControl from './StatusControl.svelte'
|
||||
|
||||
const CHECK_INTERVAL = 1000
|
||||
|
||||
@ -41,11 +33,11 @@
|
||||
|
||||
let account: LoginInfo | undefined = undefined
|
||||
|
||||
async function loadAccount () {
|
||||
async function loadAccount (): Promise<void> {
|
||||
account = await getAccount()
|
||||
}
|
||||
|
||||
async function updateWorkspaces () {
|
||||
async function updateWorkspaces (): Promise<void> {
|
||||
try {
|
||||
workspaces = await getWorkspaces()
|
||||
} catch (e) {
|
||||
@ -57,14 +49,14 @@
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
loadAccount()
|
||||
void loadAccount()
|
||||
|
||||
return () => {
|
||||
flagToUpdateWorkspaces = false
|
||||
}
|
||||
})
|
||||
|
||||
async function select (workspace: string) {
|
||||
async function select (workspace: string): Promise<void> {
|
||||
status = new Status(Severity.INFO, login.status.ConnectingToServer, {})
|
||||
|
||||
const [loginStatus, result] = await selectWorkspace(workspace)
|
||||
@ -73,42 +65,25 @@
|
||||
navigateToWorkspace(workspace, result, navigateUrl)
|
||||
}
|
||||
|
||||
async function _getWorkspaces () {
|
||||
async function _getWorkspaces (): Promise<void> {
|
||||
try {
|
||||
const res = await getWorkspaces()
|
||||
|
||||
if (res.length === 0 && account?.confirmed === false) {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'confirmationSend'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
goTo('confirmationSend')
|
||||
}
|
||||
|
||||
workspaces = res
|
||||
flagToUpdateWorkspaces = true
|
||||
updateWorkspaces()
|
||||
await updateWorkspaces()
|
||||
} catch (err: any) {
|
||||
setMetadataLocalStorage(presentation.metadata.Token, null)
|
||||
setMetadataLocalStorage(login.metadata.LoginEndpoint, null)
|
||||
setMetadataLocalStorage(login.metadata.LoginEmail, null)
|
||||
changeAccount()
|
||||
goTo('login')
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
function createWorkspace (): void {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'createWorkspace'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
}
|
||||
|
||||
function changeAccount (): void {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'login'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
}
|
||||
</script>
|
||||
|
||||
<form class="container" style:padding={$deviceInfo.docWidth <= 480 ? '1.25rem' : '5rem'}>
|
||||
@ -134,7 +109,14 @@
|
||||
{/each}
|
||||
{#if workspaces.length === 0 && account?.confirmed === true}
|
||||
<div class="form-row send">
|
||||
<Button label={login.string.CreateWorkspace} kind={'primary'} width="100%" on:click={createWorkspace} />
|
||||
<Button
|
||||
label={login.string.CreateWorkspace}
|
||||
kind={'primary'}
|
||||
width="100%"
|
||||
on:click={() => {
|
||||
goTo('createWorkspace')
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@ -144,12 +126,12 @@
|
||||
{#if workspaces.length}
|
||||
<div>
|
||||
<span><Label label={login.string.WantAnotherWorkspace} /></span>
|
||||
<a href="." on:click|preventDefault={createWorkspace}><Label label={login.string.CreateWorkspace} /></a>
|
||||
<NavLink href={getHref('createWorkspace')}><Label label={login.string.CreateWorkspace} /></NavLink>
|
||||
</div>
|
||||
{/if}
|
||||
<div>
|
||||
<span><Label label={login.string.NotSeeingWorkspace} /></span>
|
||||
<a href="." on:click|preventDefault={changeAccount}><Label label={login.string.ChangeAccount} /></a>
|
||||
<NavLink href={getHref('login')}><Label label={login.string.ChangeAccount} /></NavLink>
|
||||
</div>
|
||||
</div>
|
||||
{/await}
|
||||
|
@ -16,9 +16,9 @@
|
||||
<script lang="ts">
|
||||
import { OK, Severity, Status, setMetadata } from '@hcengineering/platform'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import { getCurrentLocation, navigate, setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import { setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import { signUp } from '../utils'
|
||||
import { goTo, signUp } from '../utils'
|
||||
import Form from './Form.svelte'
|
||||
|
||||
const fields = [
|
||||
@ -51,10 +51,7 @@
|
||||
if (result !== undefined) {
|
||||
setMetadata(presentation.metadata.Token, result.token)
|
||||
setMetadataLocalStorage(login.metadata.LastToken, result.token)
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = 'confirmationSend'
|
||||
loc.path.length = 2
|
||||
navigate(loc)
|
||||
goTo('confirmationSend')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { type IntlString } from '@hcengineering/platform'
|
||||
import InviteLink from './components/InviteLink.svelte'
|
||||
import LoginApp from './components/LoginApp.svelte'
|
||||
import { changePassword, getWorkspaces, leaveWorkspace, selectWorkspace, sendInvite } from './utils'
|
||||
@ -38,4 +39,25 @@ export default async () => ({
|
||||
}
|
||||
})
|
||||
|
||||
export const pages = [
|
||||
'login',
|
||||
'signup',
|
||||
'createWorkspace',
|
||||
'password',
|
||||
'recovery',
|
||||
'selectWorkspace',
|
||||
'join',
|
||||
'confirm',
|
||||
'confirmationSend'
|
||||
] as const
|
||||
|
||||
export type Pages = (typeof pages)[number]
|
||||
|
||||
export interface BottomAction {
|
||||
i18n: IntlString
|
||||
page?: Pages
|
||||
func: () => void
|
||||
caption: IntlString
|
||||
}
|
||||
|
||||
export * from './utils'
|
||||
|
@ -20,21 +20,23 @@ import {
|
||||
PlatformError,
|
||||
getMetadata,
|
||||
setMetadata,
|
||||
translate,
|
||||
unknownError,
|
||||
unknownStatus,
|
||||
type Status,
|
||||
translate
|
||||
type Status
|
||||
} from '@hcengineering/platform'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import {
|
||||
fetchMetadataLocalStorage,
|
||||
getCurrentLocation,
|
||||
locationStorageKeyId,
|
||||
locationToUrl,
|
||||
navigate,
|
||||
setMetadataLocalStorage,
|
||||
type Location
|
||||
} from '@hcengineering/ui'
|
||||
import { workbenchId } from '@hcengineering/workbench'
|
||||
import { type Pages } from './index'
|
||||
|
||||
const DEV_WORKSPACE = 'DEV WORKSPACE'
|
||||
|
||||
@ -239,7 +241,7 @@ export async function getWorkspaces (): Promise<Workspace[]> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAccount (doNavigate: boolean = true, token?: string): Promise<LoginInfo | undefined> {
|
||||
export async function getAccount (doNavigate: boolean = true): Promise<LoginInfo | undefined> {
|
||||
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
||||
|
||||
if (accountsUrl === undefined) {
|
||||
@ -255,7 +257,7 @@ export async function getAccount (doNavigate: boolean = true, token?: string): P
|
||||
}
|
||||
}
|
||||
|
||||
token = token ?? getMetadata(presentation.metadata.Token)
|
||||
const token = getMetadata(presentation.metadata.Token) ?? fetchMetadataLocalStorage(login.metadata.LastToken)
|
||||
if (token === undefined) {
|
||||
if (doNavigate) {
|
||||
const loc = getCurrentLocation()
|
||||
@ -770,3 +772,47 @@ async function handleStatusError (message: string, err: Status): Promise<void> {
|
||||
const label = await translate(err.code, err.params, 'en')
|
||||
Analytics.handleError(new Error(`${message}: ${label}`))
|
||||
}
|
||||
|
||||
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 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 afterConfirm (): Promise<void> {
|
||||
const joinedWS = await getWorkspaces()
|
||||
if (joinedWS.length === 0) {
|
||||
goTo('createWorkspace')
|
||||
} else if (joinedWS.length === 1) {
|
||||
const result = (await selectWorkspace(joinedWS[0].workspace))[1]
|
||||
if (result !== undefined) {
|
||||
setMetadata(presentation.metadata.Token, result.token)
|
||||
setMetadataLocalStorage(login.metadata.LastToken, result.token)
|
||||
setMetadataLocalStorage(login.metadata.LoginEndpoint, result.endpoint)
|
||||
setMetadataLocalStorage(login.metadata.LoginEmail, result.email)
|
||||
const tokens: Record<string, string> = fetchMetadataLocalStorage(login.metadata.LoginTokens) ?? {}
|
||||
tokens[result.workspace] = result.token
|
||||
setMetadataLocalStorage(login.metadata.LoginTokens, tokens)
|
||||
|
||||
navigateToWorkspace(joinedWS[0].workspace, result)
|
||||
}
|
||||
} else {
|
||||
goTo('selectWorkspace')
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,7 @@
|
||||
if (loginInfo !== undefined) {
|
||||
tokens[ws] = loginInfo?.token
|
||||
}
|
||||
setMetadataLocalStorage(login.metadata.LoginTokens, tokens)
|
||||
}
|
||||
const last = localStorage.getItem(`${locationStorageKeyId}_${ws}`)
|
||||
if (last !== null) {
|
||||
|
@ -787,7 +787,7 @@ export const createUserWorkspace =
|
||||
if (info === null) {
|
||||
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, { account: email }))
|
||||
}
|
||||
if (info.confirmed !== true) {
|
||||
if (info.confirmed === false) {
|
||||
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotConfirmed, { account: email }))
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ export class SelectWorkspacePage extends CommonPage {
|
||||
}
|
||||
|
||||
async createWorkspace (workspaceName: string): Promise<void> {
|
||||
await this.buttonCreateWorkspace.waitFor({ state: 'visible' })
|
||||
await this.buttonWorkspaceName.fill(workspaceName)
|
||||
expect(await this.buttonCreateNewWorkspace.isEnabled()).toBe(true)
|
||||
await this.buttonCreateNewWorkspace.click()
|
||||
|
@ -29,7 +29,6 @@ test.describe('Workspace tests', () => {
|
||||
await signUpPage.signUp(newUser)
|
||||
|
||||
const selectWorkspacePage = new SelectWorkspacePage(page)
|
||||
await selectWorkspacePage.buttonCreateWorkspace.click()
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
|
||||
const leftSideMenuPage = new LeftSideMenuPage(page)
|
||||
@ -67,7 +66,6 @@ test.describe('Workspace tests', () => {
|
||||
await signUpPage.signUp(newUser)
|
||||
|
||||
const selectWorkspacePage = new SelectWorkspacePage(page)
|
||||
await selectWorkspacePage.buttonCreateWorkspace.click()
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
|
||||
const leftSideMenuPage = new LeftSideMenuPage(page)
|
||||
@ -118,7 +116,6 @@ test.describe('Workspace tests', () => {
|
||||
await signUpPage.buttonSignUp.click()
|
||||
|
||||
const selectWorkspacePage = new SelectWorkspacePage(page)
|
||||
await selectWorkspacePage.buttonCreateWorkspace.click()
|
||||
await selectWorkspacePage.checkInfo(page, 'Required field Workspace name')
|
||||
await selectWorkspacePage.buttonWorkspaceName.fill(newWorkspaceName)
|
||||
await selectWorkspacePage.checkInfoSectionNotExist(page)
|
||||
@ -141,7 +138,6 @@ test.describe('Workspace tests', () => {
|
||||
await signUpPage.signUp(newUser)
|
||||
|
||||
const selectWorkspacePage = new SelectWorkspacePage(page)
|
||||
await selectWorkspacePage.buttonCreateWorkspace.click()
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
|
||||
const leftSideMenuPage = new LeftSideMenuPage(page)
|
||||
@ -191,7 +187,6 @@ test.describe('Workspace tests', () => {
|
||||
await signUpPage.signUp(newUser)
|
||||
|
||||
const selectWorkspacePage = new SelectWorkspacePage(page)
|
||||
await selectWorkspacePage.buttonCreateWorkspace.click()
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
|
||||
const leftSideMenuPage = new LeftSideMenuPage(page)
|
||||
|
Loading…
Reference in New Issue
Block a user