mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 03:22:19 +03:00
UBER-442,-452: Fixed login/signup layout, link, mention and backtick. (#3408)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
489351946f
commit
2a62b880ea
@ -172,7 +172,7 @@
|
|||||||
code {
|
code {
|
||||||
padding: 0 0.25rem;
|
padding: 0 0.25rem;
|
||||||
font-family: var(--mono-font);
|
font-family: var(--mono-font);
|
||||||
color: var(--theme-link-color);
|
color: var(--theme-content-color);
|
||||||
background-color: var(--theme-button-enabled);
|
background-color: var(--theme-button-enabled);
|
||||||
border: 1px solid var(--theme-button-border);
|
border: 1px solid var(--theme-button-border);
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
|
@ -156,8 +156,7 @@ export const Completion = Node.create<CompletionOptions>({
|
|||||||
mergeAttributes(
|
mergeAttributes(
|
||||||
{
|
{
|
||||||
'data-type': this.name,
|
'data-type': this.name,
|
||||||
class: 'antiButton secondary cursor-pointer',
|
class: 'antiMention'
|
||||||
style: 'width: fit-content;display: inline-flex;'
|
|
||||||
},
|
},
|
||||||
this.options.HTMLAttributes,
|
this.options.HTMLAttributes,
|
||||||
HTMLAttributes
|
HTMLAttributes
|
||||||
|
@ -101,6 +101,7 @@
|
|||||||
--theme-comp-header-color: #1F1F2C;
|
--theme-comp-header-color: #1F1F2C;
|
||||||
--theme-divider-color: rgba(255, 255, 255, .06);
|
--theme-divider-color: rgba(255, 255, 255, .06);
|
||||||
--theme-bg-divider-color: #282834;
|
--theme-bg-divider-color: #282834;
|
||||||
|
--theme-mention-bg-color: rgba(55, 122, 230, 0.1);
|
||||||
|
|
||||||
--theme-trans-color: rgba(255, 255, 255, .3);
|
--theme-trans-color: rgba(255, 255, 255, .3);
|
||||||
--theme-darker-color: rgba(255, 255, 255, .4);
|
--theme-darker-color: rgba(255, 255, 255, .4);
|
||||||
@ -108,7 +109,7 @@
|
|||||||
--theme-dark-color: rgba(255, 255, 255, .6);
|
--theme-dark-color: rgba(255, 255, 255, .6);
|
||||||
--theme-content-color: rgba(255, 255, 255, .8);
|
--theme-content-color: rgba(255, 255, 255, .8);
|
||||||
--theme-caption-color: #FFF;
|
--theme-caption-color: #FFF;
|
||||||
--theme-link-color: #EB7861;
|
--theme-link-color: #377AE6;
|
||||||
|
|
||||||
--theme-list-border-color: rgba(255, 255, 255, .05);
|
--theme-list-border-color: rgba(255, 255, 255, .05);
|
||||||
--theme-list-header-color: #C88C65;
|
--theme-list-header-color: #C88C65;
|
||||||
@ -293,6 +294,7 @@
|
|||||||
--theme-comp-header-color: #FBFBFC;
|
--theme-comp-header-color: #FBFBFC;
|
||||||
--theme-divider-color: rgba(0, 0, 0, .06);
|
--theme-divider-color: rgba(0, 0, 0, .06);
|
||||||
--theme-bg-divider-color: #E3E3E5;
|
--theme-bg-divider-color: #E3E3E5;
|
||||||
|
--theme-mention-bg-color: rgba(55, 122, 230, 0.1);
|
||||||
|
|
||||||
--theme-trans-color: rgba(0, 0, 0, .3);
|
--theme-trans-color: rgba(0, 0, 0, .3);
|
||||||
--theme-darker-color: rgba(0, 0, 0, .4);
|
--theme-darker-color: rgba(0, 0, 0, .4);
|
||||||
|
@ -347,6 +347,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.antiMention {
|
||||||
|
display: inline-flex;
|
||||||
|
padding: 0 .25rem;
|
||||||
|
width: fit-content;
|
||||||
|
color: var(--theme-link-color);
|
||||||
|
background-color: var(--theme-mention-bg-color);
|
||||||
|
border-radius: .25rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.antiDivider {
|
.antiDivider {
|
||||||
margin: .25rem 0;
|
margin: .25rem 0;
|
||||||
min-height: 1px;
|
min-height: 1px;
|
||||||
|
@ -49,7 +49,7 @@ table.proseTable {
|
|||||||
.proseCode {
|
.proseCode {
|
||||||
padding: 0 .25rem;
|
padding: 0 .25rem;
|
||||||
font-family: var(--mono-font);
|
font-family: var(--mono-font);
|
||||||
color: var(--theme-link-color);
|
color: var(--theme-content-color);
|
||||||
background-color: var(--theme-button-enabled);
|
background-color: var(--theme-button-enabled);
|
||||||
border: 1px solid var(--theme-button-border);
|
border: 1px solid var(--theme-button-border);
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
@ -57,6 +57,7 @@ table.proseTable {
|
|||||||
|
|
||||||
.proseCodeBlock {
|
.proseCodeBlock {
|
||||||
font-family: var(--mono-font);
|
font-family: var(--mono-font);
|
||||||
|
color: var(--theme-content-color);
|
||||||
background-color: var(--theme-button-enabled);
|
background-color: var(--theme-button-enabled);
|
||||||
border: 1px solid var(--theme-button-border);
|
border: 1px solid var(--theme-button-border);
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"IncorrectValue": "Incorrect value {field}. {descr}"
|
"IncorrectValue": "Incorrect value {field}. {descr}"
|
||||||
},
|
},
|
||||||
"string": {
|
"string": {
|
||||||
"LogIn": "Login",
|
"LogIn": "Log In",
|
||||||
"SignUp": "Sign Up",
|
"SignUp": "Sign Up",
|
||||||
"CreateWorkspace": "Create workspace",
|
"CreateWorkspace": "Create workspace",
|
||||||
"HaveWorkspace": "Already have a workspace?",
|
"HaveWorkspace": "Already have a workspace?",
|
||||||
|
@ -14,7 +14,14 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { StylishEdit, Label, Button, Scroller, deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
import {
|
||||||
|
getCurrentLocation,
|
||||||
|
navigate,
|
||||||
|
StylishEdit,
|
||||||
|
Label,
|
||||||
|
Button,
|
||||||
|
deviceOptionsStore as deviceInfo
|
||||||
|
} from '@hcengineering/ui'
|
||||||
import StatusControl from './StatusControl.svelte'
|
import StatusControl from './StatusControl.svelte'
|
||||||
import { OK, Status, Severity } from '@hcengineering/platform'
|
import { OK, Status, Severity } from '@hcengineering/platform'
|
||||||
import type { IntlString } from '@hcengineering/platform'
|
import type { IntlString } from '@hcengineering/platform'
|
||||||
@ -107,62 +114,95 @@
|
|||||||
function trim (field: string): void {
|
function trim (field: string): void {
|
||||||
object[field] = (object[field] as string).trim()
|
object[field] = (object[field] as string).trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const goTab = (path: string) => {
|
||||||
|
const loc = getCurrentLocation()
|
||||||
|
loc.path[1] = path
|
||||||
|
loc.path.length = 2
|
||||||
|
navigate(loc)
|
||||||
|
}
|
||||||
|
$: loginState = caption === login.string.LogIn ? 'login' : caption === login.string.SignUp ? 'signup' : 'none'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="container" style:padding={$deviceInfo.docWidth <= 480 ? '.25rem 1.25rem' : '4rem 5rem'}>
|
<form
|
||||||
<div class="grow-separator" />
|
class="container"
|
||||||
<div class="title"><Label label={caption} /></div>
|
style:padding={$deviceInfo.docWidth <= 480 ? '.25rem 1.25rem' : '4rem 5rem'}
|
||||||
|
style:min-height={$deviceInfo.docHeight > 720 ? '42rem' : '0'}
|
||||||
|
>
|
||||||
|
{#if loginState !== 'none'}
|
||||||
|
<div class="flex-row-center caption">
|
||||||
|
<a
|
||||||
|
class="title"
|
||||||
|
class:selected={loginState === 'signup'}
|
||||||
|
href="."
|
||||||
|
on:click|preventDefault={() => {
|
||||||
|
if (loginState !== 'signup') goTab('signup')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Label label={login.string.SignUp} />
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="title"
|
||||||
|
class:selected={loginState === 'login'}
|
||||||
|
href="."
|
||||||
|
on:click|preventDefault={() => {
|
||||||
|
if (loginState !== 'login') goTab('login')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Label label={login.string.LogIn} />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="title"><Label label={caption} /></div>
|
||||||
|
{/if}
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<StatusControl {status} />
|
<StatusControl {status} />
|
||||||
</div>
|
</div>
|
||||||
<Scroller padding={'.125rem 0'}>
|
<div class="form">
|
||||||
<div class="form">
|
{#each fields as field (field.name)}
|
||||||
{#each fields as field (field.name)}
|
<div class={field.short && !($deviceInfo.docWidth <= 600) ? 'form-col' : 'form-row'}>
|
||||||
<div class={field.short && !($deviceInfo.docWidth <= 600) ? 'form-col' : 'form-row'}>
|
<StylishEdit
|
||||||
<StylishEdit
|
label={field.i18n}
|
||||||
label={field.i18n}
|
name={field.id}
|
||||||
name={field.id}
|
password={field.password}
|
||||||
password={field.password}
|
bind:value={object[field.name]}
|
||||||
bind:value={object[field.name]}
|
on:input={validate}
|
||||||
on:input={validate}
|
on:blur={() => {
|
||||||
on:blur={() => {
|
trim(field.name)
|
||||||
trim(field.name)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
|
|
||||||
<div class="form-row send">
|
|
||||||
<Button
|
|
||||||
label={action.i18n}
|
|
||||||
kind={'contrast'}
|
|
||||||
shape={'round2'}
|
|
||||||
size={'x-large'}
|
|
||||||
width="100%"
|
|
||||||
loading={inAction}
|
|
||||||
disabled={status.severity !== Severity.OK && status.severity !== Severity.ERROR}
|
|
||||||
on:click={(e) => {
|
|
||||||
e.preventDefault()
|
|
||||||
performAction(action)
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{#if secondaryButtonLabel && secondaryButtonAction}
|
{/each}
|
||||||
<div class="form-row">
|
|
||||||
<Button
|
<div class="form-row send">
|
||||||
label={secondaryButtonLabel}
|
<Button
|
||||||
width="100%"
|
label={action.i18n}
|
||||||
on:click={(e) => {
|
kind={'contrast'}
|
||||||
e.preventDefault()
|
shape={'round2'}
|
||||||
secondaryButtonAction?.()
|
size={'x-large'}
|
||||||
}}
|
width="100%"
|
||||||
/>
|
loading={inAction}
|
||||||
</div>
|
disabled={status.severity !== Severity.OK && status.severity !== Severity.ERROR}
|
||||||
{/if}
|
on:click={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
performAction(action)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Scroller>
|
{#if secondaryButtonLabel && secondaryButtonAction}
|
||||||
|
<div class="form-row">
|
||||||
|
<Button
|
||||||
|
label={secondaryButtonLabel}
|
||||||
|
width="100%"
|
||||||
|
on:click={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
secondaryButtonAction?.()
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
{#if bottomActions.length}
|
{#if bottomActions.length}
|
||||||
<div class="grow-separator" />
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
{#each bottomActions as action}
|
{#each bottomActions as action}
|
||||||
<div>
|
<div>
|
||||||
@ -179,17 +219,34 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
|
||||||
// width: 100%;
|
|
||||||
// flex-grow: 1;
|
|
||||||
// height: 100%;
|
|
||||||
// padding: 5rem;
|
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-weight: 600;
|
font-weight: 500;
|
||||||
font-size: 1.5rem;
|
font-size: 1.25rem;
|
||||||
color: var(--theme-caption-color);
|
color: var(--theme-caption-color);
|
||||||
}
|
}
|
||||||
|
.caption a {
|
||||||
|
padding-bottom: 0.375rem;
|
||||||
|
border-bottom: 2px solid var(--theme-caption-color);
|
||||||
|
|
||||||
|
&:not(.selected) {
|
||||||
|
color: var(--theme-dark-color);
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.selected {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
&:first-child {
|
||||||
|
margin-right: 1.75rem;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
.status {
|
.status {
|
||||||
min-height: 7.5rem;
|
min-height: 7.5rem;
|
||||||
max-height: 7.5rem;
|
max-height: 7.5rem;
|
||||||
@ -214,19 +271,16 @@
|
|||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
margin-top: 3.5rem;
|
margin-top: 1.75rem;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
color: var(--theme-caption-color);
|
color: var(--theme-content-color);
|
||||||
span {
|
span {
|
||||||
opacity: 0.8;
|
color: var(--theme-darker-color);
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
font-weight: 500;
|
||||||
color: var(--theme-caption-color);
|
text-decoration: underline;
|
||||||
opacity: 0.8;
|
color: var(--theme-content-color);
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@
|
|||||||
background: rgba(45, 50, 160, 0.5);
|
background: rgba(45, 50, 160, 0.5);
|
||||||
|
|
||||||
.panel-base {
|
.panel-base {
|
||||||
padding-top: 4rem;
|
padding-top: 5rem;
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -95,17 +95,6 @@
|
|||||||
navigate(loc)
|
navigate(loc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const signUpAction = {
|
|
||||||
caption: login.string.DoNotHaveAnAccount,
|
|
||||||
i18n: login.string.SignUp,
|
|
||||||
func: () => {
|
|
||||||
const loc = getCurrentLocation()
|
|
||||||
loc.path[1] = 'signup'
|
|
||||||
loc.path.length = 2
|
|
||||||
navigate(loc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Form
|
<Form
|
||||||
@ -114,6 +103,6 @@
|
|||||||
{fields}
|
{fields}
|
||||||
{object}
|
{object}
|
||||||
{action}
|
{action}
|
||||||
bottomActions={[signUpAction, recoveryAction]}
|
bottomActions={[recoveryAction]}
|
||||||
ignoreInitialValidation
|
ignoreInitialValidation
|
||||||
/>
|
/>
|
||||||
|
@ -59,22 +59,4 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Form
|
<Form caption={login.string.SignUp} {status} {fields} {object} {action} />
|
||||||
caption={login.string.SignUp}
|
|
||||||
{status}
|
|
||||||
{fields}
|
|
||||||
{object}
|
|
||||||
{action}
|
|
||||||
bottomActions={[
|
|
||||||
{
|
|
||||||
caption: login.string.HaveAccount,
|
|
||||||
i18n: login.string.LogIn,
|
|
||||||
func: () => {
|
|
||||||
const loc = getCurrentLocation()
|
|
||||||
loc.path[1] = 'login'
|
|
||||||
loc.path.length = 2
|
|
||||||
navigate(loc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
|
@ -21,7 +21,7 @@ test.describe('login test', () => {
|
|||||||
await password.click()
|
await password.click()
|
||||||
await password.fill('1234')
|
await password.fill('1234')
|
||||||
|
|
||||||
const button = page.locator('button:has-text("Login")')
|
const button = page.locator('button:has-text("Log In")')
|
||||||
expect(await button.isEnabled()).toBe(true)
|
expect(await button.isEnabled()).toBe(true)
|
||||||
|
|
||||||
await button.click()
|
await button.click()
|
||||||
|
Loading…
Reference in New Issue
Block a user