Update Telegram, Panel, top bars layouts. Fix vacancy cards and components (#534)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2021-12-06 12:12:58 +03:00 committed by GitHub
parent d3b9c1ca96
commit c6082fdcf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 154 additions and 195 deletions

View File

@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "esnext",
"target": "ES2018",
"module": "commonjs",
"declaration": true,
"strict": true,

View File

@ -19,7 +19,7 @@
import type { Doc } from '@anticrm/core'
import type { Asset } from '@anticrm/platform'
import type { AnyComponent, AnySvelteComponent } from '@anticrm/ui'
import { Icon,IconClose,IconExpand, Component } from '@anticrm/ui'
import { Icon, IconClose, IconExpand, IconMoreH, Component, ActionIcon } from '@anticrm/ui'
import { createEventDispatcher } from 'svelte'
export let title: string
@ -36,15 +36,13 @@
{#if fullSize}
<div class="leftSection">
<div class="flex-row-center header">
<div class="icon">
{#if typeof (icon) === 'string'}
<Icon {icon} size={'small'} />
{:else}
<svelte:component this={icon} size={'small'} />
{/if}
<div class="flex-between header">
<Icon {icon} size={'large'} />
<div class="flex-grow ml-4 flex-col">
<div class="fs-title">{title}</div>
<div class="small-text content-dark-color">Candidate pool name</div>
</div>
<div class="title">{title}</div>
<ActionIcon icon={IconMoreH} size={'small'} />
</div>
{#if $$slots.subtitle}<div class="flex-row-center subtitle"><slot name="subtitle" /></div>{/if}
<div class="flex-col scroll-container">
@ -59,14 +57,14 @@
{:else}
<div class="unionSection">
<div class="flex-row-center header">
<div class="icon">
{#if typeof (icon) === 'string'}
<Icon {icon} size={'small'} />
{:else}
<svelte:component this={icon} size={'small'} />
{/if}
<div class="content-color">
<Icon {icon} size={'large'} />
</div>
<div class="title">{title}</div>
<div class="flex-grow ml-4 flex-col">
<div class="fs-title">{title}</div>
<div class="small-text content-dark-color">Candidate pool name</div>
</div>
<ActionIcon icon={IconMoreH} size={'small'} />
</div>
{#if $$slots.subtitle}<div class="flex-row-center subtitle"><slot name="subtitle" /></div>{/if}
@ -101,19 +99,10 @@
.header {
flex-shrink: 0;
padding: 0 2.5rem 0 2rem;
padding: 0 2rem 0 2.5rem;
height: 4rem;
color: var(--theme-content-accent-color);
border-bottom: 1px solid var(--theme-dialog-divider);
.icon { opacity: .6; }
.title {
flex-grow: 1;
margin-left: .5rem;
font-weight: 500;
font-size: 1rem;
color: var(--theme-caption-color);
user-select: none;
}
}
.subtitle {
@ -129,7 +118,9 @@
display: flex;
flex-direction: column;
height: max-content;
height: max-content;
.header { padding: 0 6rem 0 2.5rem; }
}
.fullSize {
@ -164,15 +155,10 @@
right: 2rem;
.tool {
margin-left: .75rem;
opacity: .4;
margin-left: 1rem;
color: var(--theme-content-accent-color);
cursor: pointer;
.icon {
transform-origin: center center;
transform: scale(.75);
}
&:hover { opacity: 1; }
&:hover { color: var(--theme-caption-color); }
}
}

View File

@ -82,7 +82,7 @@
{#each displayItems as item}
<div on:click|stopPropagation={() => { dispatch('click', item) }}>
<Tooltip component={ChannelsPopup} props={{ value: item }} label={undefined} anchor={divHTML}>
<CircleButton icon={item.icon} {size} />
<CircleButton icon={item.icon} {size} primary={item.label === 'Telegram'} />
</Tooltip>
</div>
{/each}

View File

@ -74,6 +74,8 @@
--theme-border-modal: rgba(0, 0, 0, 0.2);
--theme-chat-selection: radial-gradient(135.96% 3333.35% at -2.36% -27.63%, rgba(210, 183, 156, 0.11) 0%, rgba(204, 196, 184, 0.0785128) 20.8%, rgba(104, 104, 114, 0.11) 100%);
--theme-chat-divider: rgb(36, 36, 41);
--theme-incoming-msg: rgba(67, 67, 72, .3);
--theme-outcoming-msg: rgba(67, 67, 72, .6);
--theme-card-bg: rgba(222, 222, 240, .2);
--theme-card-bg-dark: rgba(222, 222, 240, .1);
@ -150,6 +152,8 @@
--theme-border-modal: rgba(0, 0, 0, 0.2);
--theme-chat-selection: radial-gradient(135.96% 3333.35% at -2.36% -27.63%, rgba(210, 183, 156, 0.11) 0%, rgba(204, 196, 184, 0.0785128) 20.8%, rgba(104, 104, 114, 0.11) 100%);
--theme-chat-divider: rgb(66, 65, 76);
--theme-incoming-msg: rgba(67, 67, 72, .3);
--theme-outcoming-msg: rgba(67, 67, 72, .6);
--theme-card-bg: rgba(222, 222, 240, .2);
--theme-card-bg-dark: rgba(222, 222, 240, .1);
@ -225,6 +229,8 @@
--theme-border-modal: rgba(0, 0, 0, 0.2);
--theme-chat-selection: radial-gradient(135.96% 3333.35% at -2.36% -27.63%, rgba(210, 183, 156, 0.11) 0%, rgba(204, 196, 184, 0.0785128) 20.8%, rgba(104, 104, 114, 0.11) 100%);
--theme-chat-divider: rgb(233, 233, 233);
--theme-incoming-msg: rgba(67, 67, 72, .3);
--theme-outcoming-msg: rgba(67, 67, 72, .6);
--theme-card-bg: rgba(255, 255, 255, .6);
--theme-card-bg-dark: rgba(255, 255, 255, .3);

View File

@ -143,6 +143,7 @@ p:last-child { margin-block-end: 0; }
align-items: stretch;
}
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
.safari-gap-1 {
& > * { margin-right: .25rem; }
@ -186,9 +187,11 @@ p:last-child { margin-block-end: 0; }
.ml-2 { margin-left: .5rem; }
.ml-3 { margin-left: .75rem; }
.ml-4 { margin-left: 1rem; }
.ml-6 { margin-left: 1.5rem; }
.mr-1 { margin-right: .25rem; }
.mr-2 { margin-right: .5rem; }
.mr-4 { margin-right: 1rem; }
.mr-6 { margin-right: 1.5rem; }
.mr-8 { margin-right: 2rem; }
.mt-2 { margin-top: .5rem; }
.mt-5 { margin-top: 1.25rem; }

View File

@ -20,48 +20,44 @@
import Icon from './Icon.svelte'
import Tooltip from './Tooltip.svelte'
export let label: IntlString
export let label: IntlString = '' as IntlString
export let direction: TooltipAligment | undefined = undefined
export let icon: Asset | AnySvelteComponent
export let size: 'small' | 'medium' | 'large'
export let action: (ev?: Event) => Promise<void> | void
export let action: (ev?: Event) => Promise<void> | void = async () => { }
export let invisible: boolean = false
</script>
<Tooltip {label} {direction}>
<button class="button {size}" on:click|stopPropagation={action}>
<div class="icon {size}" class:invisible={invisible}>
{#if typeof (icon) === 'string'}
<Icon {icon} {size}/>
{:else}
<svelte:component this={icon} size={size} />
{/if}
<Icon {icon} {size}/>
</div>
</button>
</Tooltip>
<style lang="scss">
.button {
color: var(--theme-caption-color);
color: inherit;
border-radius: .125rem;
cursor: pointer;
.icon {
// transform-origin: center center;
// transform: scale(.75);
color: var(--theme-content-trans-color);
&.invisible {
opacity: 0;
}
// color: var(--theme-content-trans-color);
&.invisible { opacity: 0; }
}
&:hover .icon {
color: var(--theme-caption-color);
opacity: 1;
}
&:focus {
border: 1px solid var(--primary-button-focused-border);
box-shadow: 0 0 0 3px var(--primary-button-outline);
.icon {
color: var(--theme-caption-color);
opacity: 1;
}
}
}

View File

@ -17,25 +17,30 @@
export let checked: boolean = false
export let symbol: 'check' | 'minus' = 'check'
export let circle: boolean = false
export let primaryColor: boolean = false
export let primary: boolean = false
</script>
<label class="checkbox">
<label class="checkbox" class:circle class:primary class:checked>
<input class="chBox" type="checkbox" bind:checked={checked}>
<svg class="checkSVG" class:circle class:primaryColor viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path class="back" d="M4,0h8c2.2,0,4,1.8,4,4v8c0,2.2-1.8,4-4,4H4c-2.2,0-4-1.8-4-4V4C0,1.8,1.8,0,4,0z"/>
{#if symbol === 'minus'}
<rect class="check" x="4" y="7.4" width="8" height="1.2"/>
{:else}
<polygon class="check" points="7.3,11.5 4,8.3 5,7.4 7.3,9.7 11.8,5.1 12.7,6.1 "/>
<svg class="checkSVG" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
{#if !circle}
<path class="back" class:primary d="M4,0h8c2.2,0,4,1.8,4,4v8c0,2.2-1.8,4-4,4H4c-2.2,0-4-1.8-4-4V4C0,1.8,1.8,0,4,0z"/>
{/if}
{#if symbol === 'minus'}
<rect class="check" class:primary x="4" y="7.4" width="8" height="1.2"/>
{:else}
<polygon class="check" class:primary points="7.3,11.5 4,8.3 5,7.4 7.3,9.7 11.8,5.1 12.7,6.1 "/>
{/if}
<path class="border" d="M12,16H4c-2.2,0-4-1.8-4-4V4c0-2.2,1.8-4,4-4h8c2.2,0,4,1.8,4,4v8C16,14.2,14.2,16,12,16z M4,1 C2.3,1,1,2.3,1,4v8c0,1.7,1.3,3,3,3h8c1.7,0,3-1.3,3-3V4c0-1.7-1.3-3-3-3H4z"/>
</svg>
</label>
<style lang="scss">
.checkbox {
display: inline-block;
flex-shrink: 0;
display: inline-flex;
justify-content: center;
align-items: center;
width: 1rem;
height: 1rem;
@ -50,53 +55,43 @@
overflow: hidden;
&:checked + .checkSVG {
& > .back {
& .back {
fill: var(--theme-bg-check);
&.primary { fill: var(--primary-button-enabled); }
}
& > .check {
& .check {
visibility: visible;
fill: var(--theme-button-bg-enabled);
}
&.primaryColor > .back {
fill: var(--trans-primary-button-bg);
}
&.primaryColor > .check {
fill: var(--theme-caption-color);
}
& > .border {
visibility: hidden;
&.primary { fill: var(--primary-button-color); }
}
}
&:not(:disabled) + .checkSVG {
cursor: pointer;
}
&:disabled + .checkSVG {
filter: grayscale(70%);
}
&:focus-within + .checkSVG {
border: 1px solid var(--primary-button-focused-border);
box-shadow: 0 0 0 2px var(--primary-button-outline);
}
&:not(:disabled) + .checkSVG { cursor: pointer; }
&:disabled + .checkSVG { filter: grayscale(70%); }
}
.checkSVG {
width: 1rem;
height: 1rem;
border-radius: .25rem;
&.circle {
border-radius: 50%;
}
.back {
fill: var(--theme-button-bg-hovered);
}
.back { fill: var(--theme-button-bg-hovered); }
.check {
visibility: hidden;
fill: var(--theme-button-bg-enabled);
}
.border {
fill: var(--theme-button-border-enabled);
}
}
}
.circle {
width: 1.25rem;
height: 1.25rem;
background-color: var(--theme-button-bg-hovered);
border: 1px solid var(--theme-bg-focused-color);
border-radius: 50%;
&.checked { background-color: var(--theme-bg-check); }
&.primary {
border-color: transparent;
&.checked { background-color: var(--primary-button-enabled); }
}
}
</style>

View File

@ -61,6 +61,7 @@
&.selected { background-color: var(--theme-button-bg-hovered); }
&.transparent { background-color: rgba(31, 31, 37, .3); }
&.primary {
color: var(--primary-button-color);
background-color: var(--primary-button-enabled);
border-color: var(--primary-button-border);
&:hover { background-color: var(--primary-button-hovered); }

View File

@ -1,6 +1,6 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'var(--theme-caption-color)'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">

View File

@ -1,6 +1,6 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'var(--theme-caption-color)'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">

View File

@ -56,8 +56,8 @@
{#if fullSize}
<div class="flex-row-center header">
<div class="icon"><IconActivity size={'small'} /></div>
<div class="title">Activity</div>
<div class="flex-center icon"><IconActivity size={'small'} /></div>
<div class="fs-title">Activity</div>
</div>
<div class="flex-col h-full right-content">
<ScrollBox vertical stretch>
@ -78,8 +78,8 @@
<slot />
</div>
<div class="flex-row-center activity header">
<div class="icon"><IconActivity size={'small'} /></div>
<div class="title">Activity</div>
<div class="flex-center icon"><IconActivity size={'small'} /></div>
<div class="fs-title">Activity</div>
</div>
<div class="flex-col activity content">
{#if txes}
@ -103,15 +103,12 @@
border-bottom: 1px solid var(--theme-card-divider);
.icon {
opacity: 0.6;
}
.title {
flex-grow: 1;
margin-left: 0.5rem;
font-weight: 500;
font-size: 1rem;
margin-right: 1rem;
width: 2.25rem;
height: 2.25rem;
color: var(--theme-caption-color);
user-select: none;
background-color: var(--primary-button-enabled);
border-radius: 50%;
}
}
.activity {
@ -133,7 +130,7 @@
.right-content {
flex-grow: 1;
padding: 2.25rem 2.5rem 0;
padding: 1.5rem 2.5rem 0;
background-color: var(--theme-dialog-accent);
}

View File

@ -27,8 +27,8 @@
<Avatar avatar={candidate.avatar} size={'large'} />
{#if candidate}
<div class="name">{formatName(candidate.name)}</div>
<div class="description">{candidate.title}</div>
<div class="description">{candidate.city}</div>
<div class="description">{candidate.title ?? ''}</div>
<div class="description">{candidate.city ?? ''}</div>
<div class="footer"><Channels value={candidate.channels} size={'small'} /></div>
{/if}
</div>

View File

@ -27,7 +27,7 @@
</div>
{#if vacancy}
<div class="name">{vacancy.name}</div>
<div class="description">{vacancy.description}</div>
<div class="description">{vacancy.description ?? ''}</div>
{/if}
</div>

View File

@ -16,7 +16,7 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'var(--theme-caption-color)'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">

View File

@ -21,7 +21,7 @@
import type { TelegramMessage } from '@anticrm/telegram'
import type { Contact, EmployeeAccount } from '@anticrm/contact'
import contact from '@anticrm/contact'
import { ActionIcon, IconShare, Button, Grid, ScrollBox, showPopup } from '@anticrm/ui'
import { ActionIcon, IconShare, Button, Grid, ScrollBox, showPopup, CircleButton } from '@anticrm/ui'
import Message from './Message.svelte'
import TelegramIcon from './icons/Telegram.svelte'
import { getCurrentAccount, Ref, Space } from '@anticrm/core'
@ -181,15 +181,14 @@
</script>
<div class="flex-between header">
<div class="flex">
<div class="icon"><TelegramIcon size={'small'} /></div>
<div class="title">Telegram</div>
</div>
<div>
<ActionIcon icon={IconShare} size='medium' label='Share messages' direction='bottom' action={() => { selectable = !selectable }} />
<div class="flex-center icon"><div class="scale-75"><TelegramIcon size={'small'} /></div></div>
<div class="flex-grow flex-col">
<div class="fs-title">Telegram</div>
<div class="small-text content-dark-color">You and Anastasia</div>
</div>
<ActionIcon icon={IconShare} size={'medium'} label={'Share messages'} direction={'bottom'} action={async () => { selectable = !selectable }} />
</div>
<div class="flex-col h-full right-content">
<div class="h-full right-content">
<ScrollBox vertical stretch>
{#if messages}
<Grid column={1} rowGap={.3}>
@ -210,18 +209,18 @@
<span>{selected.length} messages selected</span>
<div class="flex">
<div>
<Button label='Cancel' on:click={clear} />
<Button label={'Cancel'} size={'small'} on:click={clear} />
</div>
<div class="ml-3">
<Button label='Publish selected' primary disabled={!selected.length} on:click={share} />
<Button label={'Publish selected'} size={'small'} primary disabled={!selected.length} on:click={share} />
</div>
</div>
</div>
{:else if enabled}
<ReferenceInput on:message={onMessage}/>
<ReferenceInput on:message={onMessage}/>
{:else}
<div class="flex-center">
<Button label='Connect' primary on:click={(e) => {
<Button label={'Connect'} primary on:click={(e) => {
showPopup(Connect, {}, e.target)
}} />
</div>
@ -231,34 +230,34 @@
<style lang="scss">
.header {
flex-shrink: 0;
padding: 0 5.5rem 0 2.5rem;
padding: 0 6rem 0 2.5rem;
height: 4rem;
color: var(--theme-content-accent-color);
border-bottom: 1px solid var(--theme-card-divider);
.icon {
opacity: 0.6;
}
.title {
flex-grow: 1;
margin-left: 0.5rem;
font-weight: 500;
font-size: 1rem;
margin-right: 1rem;
width: 2.25rem;
height: 2.25rem;
color: var(--theme-caption-color);
user-select: none;
background-color: var(--primary-button-enabled);
border-radius: 50%;
}
}
.ref-input {
padding: 1.5rem 2.5rem;
padding: 0 2.5rem 1.5rem;
&.selectable {
padding: .75rem 1.25rem .75rem 2.5rem;
color: var(--theme-caption-color);
border-top: 1px solid var(--theme-card-divider);
}
}
.right-content {
flex-grow: 1;
padding: 2.5rem 2.5rem 0;
padding: 1.5rem 1rem;
}
</style>

View File

@ -20,18 +20,18 @@
</script>
<div class="message">
<div class="datetime-container">
{new Intl.DateTimeFormat('default', { day: 'numeric', month: 'long' }).format(message.modifiedOn)}
</div>
<style lang="scss">
.message {
background-color: var(--theme-menu-divider);
border-radius: .75rem;
padding: .5rem;
width: fit-content;
.datetime-container {
justify-self: center;
text-transform: capitalize;
margin: .3rem 0;
padding: .25rem .75rem;
width: fit-content;
color: var(--theme-content-accent-color);
background-color: var(--theme-menu-divider);
border-radius: 1.25rem;
}
</style>

View File

@ -41,48 +41,32 @@
const dispatch = createEventDispatcher()
</script>
<div class={message.incoming ? "flex-between" : "flex-row-center"} class:outcoming={!message.incoming} on:click={() => { dispatch('select', message) }}>
<div class="message" class:incoming={message.incoming} class:mr-4={selectable} class:selected>
{#if name}
<div class="name" style="color: {getNameColor(name)}">{formatName(name)}</div>
{/if}
<div class="flex">
<div class="text"><MessageViewer message={message.content}/></div>
<div class="time">{new Date(message.modifiedOn).toLocaleString('default', { hour: 'numeric', minute: 'numeric'})}</div>
<div class="flex-between" class:selectable on:click|preventDefault={() => { dispatch('select', message) }}>
<div class="flex-grow ml-6 flex" class:mr-6={!selectable} class:justify-end={!message.incoming}>
<div class="message" class:outcoming={!message.incoming} class:selected>
<!-- {#if name}
<div class="name" style="color: {getNameColor(name)}">{formatName(name)}</div>
{/if} -->
<div class="flex">
<div class="caption-color mr-4"><MessageViewer message={message.content}/></div>
<div class="time">{new Date(message.modifiedOn).toLocaleString('default', { hour: 'numeric', minute: 'numeric'})}</div>
</div>
</div>
</div>
{#if selectable}
<div class="check">
<CheckBox circle primaryColor bind:checked={selected} />
</div>
<div class="ml-4 mr-1"><CheckBox circle primary bind:checked={selected} /></div>
{/if}
</div>
<style lang="scss">
.outcoming {
justify-content: end;
}
.message {
padding: .5rem .75rem;
max-width: 66%;
border-radius: .75rem;
padding: .75rem;
width: fit-content;
background-color: rgba(67, 67, 72, .6);
&.incoming {
background-color: rgba(67, 67, 72, .3);
}
&.selected {
background-color: var(--primary-button-enabled) !important;
}
.text {
color: var(--theme-caption-color);
margin-right: 1.25rem;
}
background-color: var(--theme-incoming-msg);
border-radius: .75rem;
&.outcoming { background-color: var(--theme-outcoming-msg); }
.time {
align-self: flex-end;
margin-left: auto;
@ -92,8 +76,9 @@
}
}
.check {
justify-self: flex-end;
.selectable {
margin: 0 .25rem 0 0;
cursor: pointer;
.selected { background-color: var(--primary-button-enabled); }
}
</style>

View File

@ -16,7 +16,7 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'var(--theme-caption-color)'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">

View File

@ -19,26 +19,17 @@
import workbench from '../plugin'
export let label: IntlString
export let action: () => Promise<void> | void
// export let action: () => Promise<void> | void
</script>
<div class="container">
<span class="overflow-label label"><Label {label}></Label></span>
<ActionIcon label={workbench.string.More} icon={IconMoreH} size={'small'} {action}/>
<div class="flex-between navheader-container">
<span class="fs-title overflow-label"><Label {label}></Label></span>
<!-- <ActionIcon label={workbench.string.More} icon={IconMoreH} size={'small'} {action}/> -->
</div>
<style lang="scss">
.container {
display: flex;
justify-content: space-between;
align-items: center;
.navheader-container {
padding: 0 1.75rem;
height: 4.5rem;
.label {
font-weight: 500;
font-size: 1rem;
color: var(--theme-caption-color);
}
height: 4rem;
}
</style>

View File

@ -61,8 +61,8 @@
grid-auto-columns: min-content;
gap: .75rem;
align-items: center;
padding: 0 2rem 0 2.5rem;
height: 4.5rem;
min-height: 4.5rem;
padding: 0 1.75rem 0 2.5rem;
height: 4rem;
min-height: 4rem;
}
</style>

View File

@ -113,7 +113,7 @@
{#if navigator && visibileNav}
<div class="panel-navigator">
{#if currentApplication}
<NavHeader label={currentApplication.label} action={() => {}} />
<NavHeader label={currentApplication.label} />
{/if}
<Navigator model={navigatorModel} />
</div>