mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 03:22:19 +03:00
Prepare UI for mobile (#2277)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
9290942a56
commit
ec0795e687
@ -20,6 +20,7 @@
|
||||
import notification from '@hcengineering/notification'
|
||||
import type { Asset } from '@hcengineering/platform'
|
||||
import { AnySvelteComponent, Component, Panel, Icon, Scroller } from '@hcengineering/ui'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
export let title: string | undefined = undefined
|
||||
export let subtitle: string | undefined = undefined
|
||||
@ -35,13 +36,16 @@
|
||||
</script>
|
||||
|
||||
<Panel bind:isAside isHeader={$$slots.header || isHeader} bind:panelWidth bind:innerWidth on:close>
|
||||
<svelte:fragment slot="title">
|
||||
<div class="popupPanel-title__content-container antiTitle">
|
||||
<svelte:fragment slot="navigator">
|
||||
{#if $$slots.navigator}
|
||||
<div class="buttons-group xsmall-gap mr-4">
|
||||
<div class="buttons-group xsmall-gap mx-2">
|
||||
<slot name="navigator" />
|
||||
</div>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="title">
|
||||
<div class="popupPanel-title__content-container antiTitle">
|
||||
{#if $$slots.title}
|
||||
<slot name="title" />
|
||||
{:else}
|
||||
@ -102,6 +106,12 @@
|
||||
|
||||
{#if withoutActivity}
|
||||
<slot />
|
||||
{:else if $deviceInfo.isMobile}
|
||||
<div class="popupPanel-body__mobile-content clear-mins">
|
||||
<Component is={activity.component.Activity} props={{ object, integrate: true }}>
|
||||
<slot />
|
||||
</Component>
|
||||
</div>
|
||||
{:else}
|
||||
<Scroller>
|
||||
<div class="popupPanel-body__main-content py-8 clear-mins">
|
||||
|
@ -18,6 +18,7 @@
|
||||
import { Button, IconClose, Label, MiniToggle } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import presentation from '..'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
export let label: IntlString
|
||||
export let labelProps: any | undefined = undefined
|
||||
@ -31,7 +32,7 @@
|
||||
let okProcessing = false
|
||||
</script>
|
||||
|
||||
<form id={label} class="antiCard dialog" on:submit|preventDefault={() => {}}>
|
||||
<form id={label} class="antiCard {$deviceInfo.isMobile ? 'mobile' : 'dialog'}" on:submit|preventDefault={() => {}}>
|
||||
<div class="antiCard-header">
|
||||
<div class="antiCard-header__title-wrap">
|
||||
{#if $$slots.header}
|
||||
|
@ -40,5 +40,5 @@
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<EditBox placeholder={linkPlaceholder} bind:value={link} maxWidth={'37.75rem'} focus />
|
||||
<EditBox placeholder={linkPlaceholder} bind:value={link} focus />
|
||||
</Card>
|
||||
|
@ -214,6 +214,7 @@ input.search {
|
||||
.justify-stretch { justify-content: stretch; }
|
||||
.items-baseline { align-items: baseline; }
|
||||
.items-center { align-items: center; }
|
||||
.self-end { align-self: end; }
|
||||
|
||||
.flex-gap-3 { gap: .75rem; }
|
||||
.flex-gap-2 { gap: .5rem; }
|
||||
@ -422,6 +423,7 @@ input.search {
|
||||
.pb-4 { padding-bottom: 1rem; }
|
||||
.pb-6 { padding-bottom: 1.5rem; }
|
||||
.pb-16 { padding-bottom: 4rem; }
|
||||
.px-1 { padding: 0 .25rem; }
|
||||
.px-2 { padding: 0 .5rem; }
|
||||
.px-3 { padding: 0 .75rem; }
|
||||
.px-4 { padding: 0 1rem; }
|
||||
|
@ -20,13 +20,21 @@
|
||||
.antiPanel-application {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: var(--board-bg-color);
|
||||
|
||||
&.vertical {
|
||||
flex-direction: column;
|
||||
min-width: var(--app-panel-width);
|
||||
width: var(--app-panel-width);
|
||||
height: 100%;
|
||||
background-color: var(--board-bg-color);
|
||||
}
|
||||
&.horizonatl {
|
||||
min-height: var(--app-panel-width);
|
||||
height: var(--app-panel-width);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.antiPanel-navigator,
|
||||
.antiPanel-component {
|
||||
@ -49,11 +57,18 @@
|
||||
@media (max-width: 1024px) {
|
||||
.antiPanel-navigator {
|
||||
position: fixed;
|
||||
top: var(--status-bar-height);
|
||||
left: var(--app-panel-width);
|
||||
background-color: var(--body-accent);
|
||||
filter: drop-shadow(2px 0 1px rgba(0, 0, 0, .2));
|
||||
z-index: 450;
|
||||
|
||||
&.portrait {
|
||||
top: var(--status-bar-height);
|
||||
left: 0;
|
||||
}
|
||||
&.landscape {
|
||||
top: var(--status-bar-height);
|
||||
left: var(--app-panel-width);
|
||||
}
|
||||
}
|
||||
}
|
||||
.antiPanel-component:not(.aside) {
|
||||
|
@ -20,24 +20,28 @@
|
||||
height: 100%;
|
||||
|
||||
.ac-header {
|
||||
padding: 0 1.5rem 0 2.25rem;
|
||||
height: 3.5rem;
|
||||
min-height: 3.5rem;
|
||||
padding: 0.5rem 1.5rem 0.5rem 2.25rem;
|
||||
// height: 3.5rem;
|
||||
// min-height: 3.5rem;
|
||||
|
||||
&.short {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
&.full {
|
||||
&.full,
|
||||
&-full {
|
||||
display: grid;
|
||||
grid-template-columns: auto;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: min-content;
|
||||
grid-auto-columns: max-content;
|
||||
gap: .75rem;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
&.withSettings { padding-right: .75rem; }
|
||||
&.mini {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
&.mirror {
|
||||
justify-content: space-between;
|
||||
@ -51,6 +55,10 @@
|
||||
&.divide {
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
.secondRow {
|
||||
align-self: flex-end;
|
||||
margin-top: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.ac-header__wrap-description,
|
||||
|
@ -136,7 +136,14 @@
|
||||
height: max-content;
|
||||
max-width: 60rem;
|
||||
max-height: calc(100vh - 2rem);
|
||||
|
||||
}
|
||||
&.mobile {
|
||||
width: 90vw;
|
||||
max-width: 90vw;
|
||||
max-height: 90vh;
|
||||
}
|
||||
&.dialog,
|
||||
&.mobile {
|
||||
.antiCard-header {
|
||||
padding: .75rem .75rem .375rem;
|
||||
|
||||
|
@ -66,18 +66,25 @@
|
||||
|
||||
.popupPanel-title {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
justify-content: stretch;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.row {
|
||||
padding: .5rem .75rem;
|
||||
width: 100%;
|
||||
height: 3rem;
|
||||
max-height: 3rem;
|
||||
|
||||
&-top { margin: .5rem .75rem .125rem; }
|
||||
&-bottom { margin: .5rem .75rem .5rem 1.25rem; }
|
||||
}
|
||||
&__bordered {
|
||||
min-width: 0;
|
||||
min-height: 3rem;
|
||||
background-color: var(--board-card-bg-color);
|
||||
border: 1px solid var(--divider-color);
|
||||
border-bottom: none;
|
||||
border-radius: .5rem .5rem 0 0;
|
||||
|
||||
}
|
||||
&__content {
|
||||
flex-grow: 1;
|
||||
margin: 0 .75rem;
|
||||
@ -96,7 +103,6 @@
|
||||
.popupPanel-body {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: stretch;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
@ -105,7 +111,13 @@
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 0 0 .5rem .5rem;
|
||||
|
||||
&__main, &__aside {
|
||||
&.main {
|
||||
justify-content: stretch;
|
||||
}
|
||||
&.mobile {
|
||||
justify-content: center;
|
||||
}
|
||||
&__main, &__mobile, &__aside {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
@ -119,14 +131,33 @@
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
|
||||
&-header {
|
||||
&-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: calc(100% - 7.5rem);
|
||||
max-width: 860px;
|
||||
}
|
||||
}
|
||||
|
||||
.popupPanel-body__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&.main {
|
||||
margin: 0 auto;
|
||||
padding: .75rem 1.25rem;
|
||||
width: calc(100% - 5rem);
|
||||
min-width: 0;
|
||||
max-width: 900px;
|
||||
}
|
||||
&.mobile {
|
||||
flex-shrink: 0;
|
||||
padding: .5rem .75rem .75rem;
|
||||
width: 100%;
|
||||
min-width: 700px;
|
||||
}
|
||||
|
||||
&.bottom-divider { border-bottom: 1px solid var(--divider-color); }
|
||||
&.top-divider { border-top: 1px solid var(--divider-color); }
|
||||
@ -140,15 +171,9 @@
|
||||
}
|
||||
.header-row + .header-row { margin-top: .625rem; }
|
||||
}
|
||||
&-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: calc(100% - 7.5rem);
|
||||
max-width: 860px;
|
||||
}
|
||||
.popupPanel-body__mobile-content {
|
||||
padding: 0 .75rem 1rem;
|
||||
min-width: 700px;
|
||||
}
|
||||
|
||||
&__aside {
|
||||
|
@ -21,6 +21,7 @@
|
||||
import type { AnySvelteComponent, EditStyle } from '../types'
|
||||
import Icon from './Icon.svelte'
|
||||
import Label from './Label.svelte'
|
||||
import { resizeObserver } from '../resize'
|
||||
|
||||
export let label: IntlString | undefined = undefined
|
||||
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
||||
@ -39,8 +40,11 @@
|
||||
let input: HTMLInputElement
|
||||
let style: string
|
||||
let phTraslate: string = ''
|
||||
let parentWidth: number | undefined
|
||||
|
||||
$: style = maxWidth ? `max-width: ${maxWidth};` : ''
|
||||
$: style = `max-width: ${
|
||||
maxWidth || (parentWidth ? (icon ? `calc(${parentWidth}px - 1.25rem)` : `${parentWidth}px`) : 'max-content')
|
||||
};`
|
||||
$: translate(placeholder, placeholderParam ?? {}).then((res) => {
|
||||
phTraslate = res
|
||||
})
|
||||
@ -105,6 +109,9 @@
|
||||
on:click={() => {
|
||||
input.focus()
|
||||
}}
|
||||
use:resizeObserver={(element) => {
|
||||
parentWidth = element.parentElement?.getBoundingClientRect().width
|
||||
}}
|
||||
>
|
||||
<!-- {focusIndex} -->
|
||||
<div class="hidden-text {kind}" bind:this={text} />
|
||||
|
@ -54,7 +54,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
afterUpdate(() => dispatch('changeContent', true))
|
||||
afterUpdate(() => dispatch('changeContent'))
|
||||
</script>
|
||||
|
||||
{#if count}
|
||||
|
@ -67,7 +67,7 @@
|
||||
}
|
||||
|
||||
afterUpdate(() => {
|
||||
dispatch('changeContent', true)
|
||||
dispatch('changeContent')
|
||||
})
|
||||
onMount(() => {
|
||||
if (btns[0]) {
|
||||
@ -113,7 +113,7 @@
|
||||
<div
|
||||
class="antiPopup"
|
||||
use:resizeObserver={() => {
|
||||
dispatch('changeContent', true)
|
||||
dispatch('changeContent')
|
||||
}}
|
||||
on:keydown={keyDown}
|
||||
>
|
||||
|
@ -20,6 +20,8 @@
|
||||
import IconDetails from './icons/Details.svelte'
|
||||
import IconScale from './icons/Scale.svelte'
|
||||
import IconScaleFull from './icons/ScaleFull.svelte'
|
||||
import Scroller from './Scroller.svelte'
|
||||
import { deviceOptionsStore as deviceInfo } from '../../'
|
||||
|
||||
export let innerWidth: number = 0
|
||||
export let panelWidth: number = 0
|
||||
@ -31,8 +33,9 @@
|
||||
|
||||
let asideFloat: boolean = false
|
||||
let asideShown: boolean = false
|
||||
let docWidth: number
|
||||
let fullSize: boolean = false
|
||||
let twoRows: boolean = false
|
||||
$: twoRows = $deviceInfo.docWidth <= 480
|
||||
|
||||
const checkPanel = (): void => {
|
||||
if (panelWidth <= 900 && !asideFloat) asideFloat = true
|
||||
@ -53,7 +56,8 @@
|
||||
checkPanel()
|
||||
}}
|
||||
>
|
||||
<div class="popupPanel-title">
|
||||
<div class="popupPanel-title__bordered {twoRows ? 'flex-col flex-no-shrink' : 'flex-row-center'}">
|
||||
<div class="popupPanel-title {twoRows ? 'row-top' : 'row'}">
|
||||
<Button
|
||||
icon={IconClose}
|
||||
kind={'transparent'}
|
||||
@ -62,7 +66,10 @@
|
||||
dispatch('close')
|
||||
}}
|
||||
/>
|
||||
<div class="popupPanel-title__content"><slot name="title" /></div>
|
||||
{#if $$slots.navigator}<slot name="navigator" />{/if}
|
||||
<div class="popupPanel-title__content">
|
||||
{#if !twoRows}<slot name="title" />{/if}
|
||||
</div>
|
||||
<div class="buttons-group xsmall-gap">
|
||||
<slot name="utils" />
|
||||
{#if isFullSize || (asideFloat && $$slots.aside && isAside)}<div class="buttons-divider" />{/if}
|
||||
@ -79,11 +86,10 @@
|
||||
{/if}
|
||||
{#if isFullSize}
|
||||
<Button
|
||||
icon={fullSize || docWidth <= 900 ? IconScale : IconScaleFull}
|
||||
icon={fullSize ? IconScale : IconScaleFull}
|
||||
kind={'transparent'}
|
||||
size={'medium'}
|
||||
selected={fullSize}
|
||||
disabled={docWidth <= 900}
|
||||
on:click={() => {
|
||||
fullSize = !fullSize
|
||||
dispatch('fullsize')
|
||||
@ -92,7 +98,28 @@
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="popupPanel-body" class:asideShown>
|
||||
{#if twoRows}
|
||||
<div class="popupPanel-title row-bottom"><slot name="title" /></div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="popupPanel-body {$deviceInfo.isMobile ? 'mobile' : 'main'}" class:asideShown>
|
||||
{#if $deviceInfo.isMobile}
|
||||
<Scroller horizontal padding={'.5rem .75rem'}>
|
||||
<div
|
||||
class="popupPanel-body__mobile"
|
||||
use:resizeObserver={(element) => {
|
||||
innerWidth = element.clientWidth
|
||||
}}
|
||||
>
|
||||
{#if $$slots.header && isHeader}
|
||||
<div class="popupPanel-body__header mobile bottom-divider">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
{/if}
|
||||
<slot />
|
||||
</div>
|
||||
</Scroller>
|
||||
{:else}
|
||||
<div
|
||||
class="popupPanel-body__main"
|
||||
use:resizeObserver={(element) => {
|
||||
@ -100,12 +127,13 @@
|
||||
}}
|
||||
>
|
||||
{#if $$slots.header && isHeader}
|
||||
<div class="popupPanel-body__main-header bottom-divider">
|
||||
<div class="popupPanel-body__header main bottom-divider">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
{/if}
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $$slots.aside && isAside}
|
||||
<div class="popupPanel-body__aside" class:float={asideFloat} class:shown={asideShown}>
|
||||
<slot name="aside" />
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { afterUpdate, onMount } from 'svelte'
|
||||
import { fitPopupElement } from '../popups'
|
||||
import type { AnyComponent, AnySvelteComponent, PopupAlignment, PopupOptions } from '../types'
|
||||
import { deviceOptionsStore as deviceInfo } from '..'
|
||||
|
||||
export let is: AnyComponent | AnySvelteComponent
|
||||
export let props: object
|
||||
@ -30,7 +31,6 @@
|
||||
|
||||
let modalHTML: HTMLElement
|
||||
let componentInstance: any
|
||||
let docWidth: number
|
||||
let docSize: boolean = false
|
||||
let fullSize: boolean = false
|
||||
|
||||
@ -88,13 +88,13 @@
|
||||
}
|
||||
|
||||
onMount(() => fitPopup())
|
||||
$: if (docWidth <= 900 && !docSize) docSize = true
|
||||
$: if (docWidth > 900 && docSize) docSize = false
|
||||
$: if ($deviceInfo.docWidth <= 900 && !docSize) docSize = true
|
||||
$: if ($deviceInfo.docWidth > 900 && docSize) docSize = false
|
||||
|
||||
afterUpdate(() => fitPopup())
|
||||
</script>
|
||||
|
||||
<svelte:window on:resize={fitPopup} on:keydown={handleKeydown} bind:innerWidth={docWidth} />
|
||||
<svelte:window on:resize={fitPopup} on:keydown={handleKeydown} />
|
||||
|
||||
<div
|
||||
class="popup"
|
||||
@ -145,7 +145,7 @@
|
||||
position: fixed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
// justify-content: center;
|
||||
max-height: calc(100vh - 32px);
|
||||
background-color: transparent;
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
import { themeStore as themeOptions } from '@hcengineering/theme'
|
||||
import type { FadeOptions } from '../types'
|
||||
import { defaultSP } from '../types'
|
||||
import { closeTooltip, tooltipstore } from '../tooltips'
|
||||
|
||||
export let padding: string | undefined = undefined
|
||||
export let autoscroll: boolean = false
|
||||
@ -25,6 +26,7 @@
|
||||
export let fade: FadeOptions = defaultSP
|
||||
export let invertScroll: boolean = false
|
||||
export let horizontal: boolean = false
|
||||
export let contentDirection: 'vertical' | 'horizontal' = 'vertical'
|
||||
|
||||
let mask: 'top' | 'bottom' | 'both' | 'none' = 'none'
|
||||
let maskH: 'left' | 'right' | 'both' | 'none' = 'none'
|
||||
@ -235,11 +237,15 @@
|
||||
class="scroll relative verticalFade"
|
||||
class:overflowXauto={horizontal}
|
||||
class:overflowXhidden={!horizontal}
|
||||
on:scroll={() => {
|
||||
if ($tooltipstore.label !== undefined) closeTooltip()
|
||||
}}
|
||||
>
|
||||
<div
|
||||
bind:this={divBox}
|
||||
class="box"
|
||||
style:padding
|
||||
style:flex-direction={contentDirection === 'vertical' ? 'column' : 'row'}
|
||||
use:resizeObserver={(element) => {
|
||||
boxHeight = element.clientHeight
|
||||
boxWidth = element.clientWidth
|
||||
@ -295,14 +301,26 @@
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
&.normal .track,
|
||||
&.normal .bar {
|
||||
&.normal {
|
||||
.track,
|
||||
.bar {
|
||||
right: 2px;
|
||||
}
|
||||
&.invert .track,
|
||||
&.invert .bar {
|
||||
.track-horizontal,
|
||||
.bar-horizontal {
|
||||
bottom: 2px;
|
||||
}
|
||||
}
|
||||
&.invert {
|
||||
.track,
|
||||
.bar {
|
||||
left: 2px;
|
||||
}
|
||||
.track-horizontal,
|
||||
.bar-horizontal {
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.horizontalBox {
|
||||
min-width: 0;
|
||||
|
@ -86,7 +86,7 @@
|
||||
|
||||
$: huge = size === 'medium' || size === 'large'
|
||||
|
||||
afterUpdate(() => dispatch('changeContent', true))
|
||||
afterUpdate(() => dispatch('changeContent'))
|
||||
</script>
|
||||
|
||||
<FocusHandler {manager} />
|
||||
@ -96,7 +96,7 @@
|
||||
class:full-width={width === 'full'}
|
||||
class:max-width-40={width === 'large'}
|
||||
use:resizeObserver={() => {
|
||||
dispatch('changeContent', true)
|
||||
dispatch('changeContent')
|
||||
}}
|
||||
on:keydown={onKeydown}
|
||||
>
|
||||
@ -119,7 +119,7 @@
|
||||
bind:this={list}
|
||||
count={filteredObjects.length}
|
||||
bind:selection
|
||||
on:changeContent={() => dispatch('changeContent', true)}
|
||||
on:changeContent={() => dispatch('changeContent')}
|
||||
>
|
||||
<svelte:fragment slot="item" let:item={itemId}>
|
||||
{@const item = filteredObjects[itemId]}
|
||||
|
@ -17,6 +17,7 @@
|
||||
import FontSizeSelector from './FontSizeSelector.svelte'
|
||||
import LangSelector from './LangSelector.svelte'
|
||||
import uiPlugin from '../../plugin'
|
||||
import { deviceOptionsStore as deviceInfo } from '../../'
|
||||
|
||||
let application: AnyComponent | undefined
|
||||
|
||||
@ -52,13 +53,34 @@
|
||||
addEventListener(PlatformEvent, async (_event, _status) => {
|
||||
status = _status
|
||||
})
|
||||
|
||||
let docWidth: number = window.innerWidth
|
||||
let docHeight: number = window.innerHeight
|
||||
let maxLenght: number
|
||||
$: maxLenght = docWidth >= docHeight ? docWidth : docHeight
|
||||
let isPortrait: boolean
|
||||
$: isPortrait = docWidth <= docHeight
|
||||
let isMobile: boolean
|
||||
let alwaysMobile: boolean = false
|
||||
$: isMobile =
|
||||
alwaysMobile ?? /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
||||
|
||||
$: $deviceInfo.docWidth = docWidth
|
||||
$: $deviceInfo.docHeight = docHeight
|
||||
$: $deviceInfo.isPortrait = isPortrait
|
||||
$: $deviceInfo.isMobile = isMobile
|
||||
</script>
|
||||
|
||||
<svelte:window bind:innerWidth={docWidth} bind:innerHeight={docHeight} />
|
||||
|
||||
<Theme>
|
||||
<div id="ui-root">
|
||||
<div class="status-bar">
|
||||
<div class="flex-row-center h-full content-color">
|
||||
<div class="status-info">
|
||||
<div
|
||||
class="status-info"
|
||||
style:margin-left={(isPortrait && docWidth <= 480) || (!isPortrait && docHeight <= 480) ? '1.5rem' : '0'}
|
||||
>
|
||||
<StatusComponent {status} />
|
||||
</div>
|
||||
<div class="flex-row-reverse">
|
||||
@ -74,7 +96,12 @@
|
||||
<div class="flex-center widget cursor-pointer mr-3">
|
||||
<FontSizeSelector />
|
||||
</div>
|
||||
<div class="flex-center widget mr-3">
|
||||
<div
|
||||
class="flex-center widget mr-3"
|
||||
class:on={isMobile}
|
||||
class:always={alwaysMobile}
|
||||
on:click={() => (alwaysMobile = !alwaysMobile)}
|
||||
>
|
||||
<WiFi size={'small'} />
|
||||
</div>
|
||||
</div>
|
||||
@ -106,7 +133,7 @@
|
||||
.status-bar {
|
||||
min-height: var(--status-bar-height);
|
||||
height: var(--status-bar-height);
|
||||
min-width: 600px;
|
||||
// min-width: 600px;
|
||||
font-size: 12px;
|
||||
line-height: 150%;
|
||||
background-color: var(--divider-color);
|
||||
@ -116,7 +143,7 @@
|
||||
text-align: center;
|
||||
}
|
||||
.clock {
|
||||
margin: 0 40px 0 24px;
|
||||
margin: 0 1rem 0 24px;
|
||||
font-weight: 500;
|
||||
user-select: none;
|
||||
}
|
||||
@ -124,14 +151,22 @@
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
font-size: 14px;
|
||||
color: var(--theme-content-color);
|
||||
color: var(--content-color);
|
||||
|
||||
&.on {
|
||||
color: var(--caption-color);
|
||||
|
||||
&.always {
|
||||
color: var(--won-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.app {
|
||||
height: calc(100vh - var(--status-bar-height));
|
||||
min-width: 600px;
|
||||
min-height: 480px;
|
||||
// min-width: 600px;
|
||||
// min-height: 480px;
|
||||
|
||||
.error {
|
||||
margin-top: 45vh;
|
||||
|
@ -15,9 +15,10 @@
|
||||
|
||||
import { addLocation, addStringsLoader } from '@hcengineering/platform'
|
||||
import { SvelteComponent } from 'svelte'
|
||||
import { readable } from 'svelte/store'
|
||||
import { readable, writable } from 'svelte/store'
|
||||
import Root from './components/internal/Root.svelte'
|
||||
import { uiId, uis } from './plugin'
|
||||
import type { DeviceOptions } from './types'
|
||||
|
||||
export type {
|
||||
AnyComponent,
|
||||
@ -33,7 +34,8 @@ export type {
|
||||
ButtonKind,
|
||||
ButtonSize,
|
||||
IconSize,
|
||||
TabItem
|
||||
TabItem,
|
||||
DeviceOptions
|
||||
} from './types'
|
||||
// export { applicationShortcutKey } from './utils'
|
||||
export { getCurrentLocation, locationToUrl, navigate, location } from './location'
|
||||
@ -174,4 +176,11 @@ addStringsLoader(uiId, async (lang: string) => {
|
||||
|
||||
addLocation(uiId, async () => ({ default: async () => ({}) }))
|
||||
|
||||
export const deviceOptionsStore = writable<DeviceOptions>({
|
||||
docWidth: 0,
|
||||
docHeight: 0,
|
||||
isPortrait: false,
|
||||
isMobile: false
|
||||
})
|
||||
|
||||
export default uis
|
||||
|
@ -253,6 +253,12 @@ export function fitPopupElement (
|
||||
} else if (element === 'account') {
|
||||
newProps.bottom = '2.75rem'
|
||||
newProps.left = '5rem'
|
||||
} else if (element === 'account-portrait') {
|
||||
newProps.bottom = 'calc(var(--app-panel-width) + .75rem)'
|
||||
newProps.right = '.5rem'
|
||||
} else if (element === 'account-mobile') {
|
||||
newProps.bottom = '.5rem'
|
||||
newProps.left = 'calc(var(--app-panel-width) + .5rem)'
|
||||
} else if (element === 'full' && contentPanel === undefined) {
|
||||
newProps.top = '0'
|
||||
newProps.bottom = '0'
|
||||
|
@ -125,7 +125,16 @@ export interface PopupPositionElement {
|
||||
kind?: 'submenu'
|
||||
}
|
||||
|
||||
export type PopupPosAlignment = 'right' | 'top' | 'float' | 'account' | 'full' | 'content' | 'middle'
|
||||
export type PopupPosAlignment =
|
||||
| 'right'
|
||||
| 'top'
|
||||
| 'float'
|
||||
| 'account'
|
||||
| 'account-portrait'
|
||||
| 'account-mobile'
|
||||
| 'full'
|
||||
| 'content'
|
||||
| 'middle'
|
||||
|
||||
export function isPopupPosAlignment (x: any): x is PopupPosAlignment {
|
||||
return (
|
||||
@ -214,3 +223,10 @@ export interface FadeOptions {
|
||||
export const defaultSP: FadeOptions = { multipler: { top: 0, bottom: 0 } }
|
||||
export const tableSP: FadeOptions = { offset: { top: true }, multipler: { top: 2.5, bottom: 0 } }
|
||||
export const issueSP: FadeOptions = { offset: { top: true }, multipler: { top: 3, bottom: 0 } }
|
||||
|
||||
export interface DeviceOptions {
|
||||
docWidth: number
|
||||
docHeight: number
|
||||
isPortrait: boolean
|
||||
isMobile: boolean
|
||||
}
|
||||
|
@ -60,7 +60,6 @@
|
||||
icon={IconFolder}
|
||||
bind:value={name}
|
||||
placeholder={board.string.Board}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<!-- <ToggleWithLabel label={board.string.MakePrivate} description={board.string.MakePrivateDescription} /> -->
|
||||
|
@ -93,7 +93,6 @@
|
||||
bind:value={title}
|
||||
icon={board.icon.Card}
|
||||
placeholder={board.string.CardPlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
</Grid>
|
||||
|
@ -139,15 +139,8 @@
|
||||
}}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<div class="flex-row-stretch">
|
||||
<div class="fs-title text-xl">
|
||||
<EditBox bind:value={object.title} maxWidth="39rem" focus on:change={() => change('title', object?.title)} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-row-stretch">
|
||||
<div class="flex-grow mr-4">
|
||||
<div class="flex-row-stretch">
|
||||
<div class="background-bg-accent border-bg-accent border-radius-3 p-2 mt-2 w-full">
|
||||
<EditBox bind:value={object.title} kind={'large-style'} focus on:change={() => change('title', object?.title)} />
|
||||
<div class="background-bg-accent border-bg-accent border-radius-3 p-4 mt-4 w-full">
|
||||
<StyledTextBox
|
||||
alwaysEdit={true}
|
||||
showButtons={false}
|
||||
@ -156,7 +149,6 @@
|
||||
on:value={(evt) => change('description', evt.detail)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<Attachments objectId={_id} {_class} space={object.space} attachments={object.attachments ?? 0} />
|
||||
</div>
|
||||
@ -169,8 +161,6 @@
|
||||
<CardChecklist value={checklist} />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<svelte:fragment slot="custom-attributes" let:direction>
|
||||
{#if direction === 'column'}
|
||||
<DocAttributeBar {object} {mixins} {ignoreKeys} {allowedCollections} />
|
||||
|
@ -109,7 +109,6 @@
|
||||
<div class="fs-title text-lg">
|
||||
<EditBox
|
||||
bind:value={object.title}
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
on:change={() => updateCard(client, object, 'title', object?.title)}
|
||||
/>
|
||||
@ -158,7 +157,6 @@
|
||||
<div class="fs-title text-lg">
|
||||
<EditBox
|
||||
bind:value={object.title}
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
on:change={() => updateCard(client, object, 'title', object?.title)}
|
||||
/>
|
||||
|
@ -118,7 +118,7 @@
|
||||
<div class="flex-col flex-gap-1">
|
||||
<Label label={board.string.Title} />
|
||||
<div class="p-2 mt-1 mb-1 border-bg-accent border-radius-1">
|
||||
<EditBox bind:value={name} maxWidth="100%" focus={true} />
|
||||
<EditBox bind:value={name} focus={true} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<EditBox bind:value={title} placeholder={calendar.string.Title} maxWidth={'37.5rem'} kind={'large-style'} focus />
|
||||
<EditBox bind:value={title} placeholder={calendar.string.Title} kind={'large-style'} focus />
|
||||
<svelte:fragment slot="pool">
|
||||
<DateRangePresenter bind:value withTime editable labelNull={ui.string.SelectDate} />
|
||||
<DateRangePresenter bind:value={dueDate} labelNull={calendar.string.DueTo} withTime editable />
|
||||
|
@ -70,7 +70,7 @@
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<EditBox bind:value={title} placeholder={calendar.string.Title} maxWidth={'37.5rem'} kind={'large-style'} focus />
|
||||
<EditBox bind:value={title} placeholder={calendar.string.Title} kind={'large-style'} focus />
|
||||
<svelte:fragment slot="pool">
|
||||
<!-- <TimeShiftPicker title={calendar.string.Date} bind:value direction="after" /> -->
|
||||
<DateRangePresenter bind:value withTime={true} editable={true} labelNull={ui.string.SelectDate} />
|
||||
|
@ -32,6 +32,7 @@
|
||||
import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
|
||||
import { FilterButton, ViewletSettingButton } from '@hcengineering/view-resources'
|
||||
import calendar from '../plugin'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
export let _class: Ref<Class<Event>> = calendar.class.Event
|
||||
export let space: Ref<Space> | undefined = undefined
|
||||
@ -98,10 +99,14 @@
|
||||
tooltip: views.$lookup?.descriptor?.label
|
||||
}
|
||||
})
|
||||
|
||||
let twoRows: boolean
|
||||
$: twoRows = $deviceInfo.docWidth <= 680
|
||||
</script>
|
||||
|
||||
<div class="ac-header full withSettings">
|
||||
<div class="ac-header__wrap-title">
|
||||
<div class="ac-header withSettings" class:full={!twoRows} class:mini={twoRows}>
|
||||
<div class:ac-header-full={!twoRows} class:flex-between={twoRows}>
|
||||
<div class="ac-header__wrap-title mr-3">
|
||||
<div class="ac-header__icon"><Icon icon={viewIcon} size={'small'} /></div>
|
||||
<span class="ac-header__title"><Label label={viewLabel} /></span>
|
||||
<div class="ml-4"><FilterButton {_class} /></div>
|
||||
@ -113,6 +118,8 @@
|
||||
updateResultQuery(search)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="ac-header-full" class:secondRow={twoRows}>
|
||||
<Button icon={IconAdd} label={createLabel} kind={'primary'} size={'small'} on:click={showCreateDialog} />
|
||||
|
||||
{#if viewlets.length > 1}
|
||||
@ -129,6 +136,7 @@
|
||||
{/if}
|
||||
<ViewletSettingButton viewlet={selectedViewlet} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if selectedViewlet?.$lookup?.descriptor?.component}
|
||||
{#if loading}
|
||||
|
@ -65,7 +65,6 @@
|
||||
icon={IconFolder}
|
||||
bind:value={name}
|
||||
placeholder={chunter.string.ChannelNamePlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
</Card>
|
||||
|
@ -62,7 +62,6 @@
|
||||
icon={IconFolder}
|
||||
bind:value={name}
|
||||
placeholder={chunter.string.ChannelNamePlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<ToggleWithLabel
|
||||
|
@ -59,7 +59,6 @@
|
||||
label={chunter.string.Topic}
|
||||
bind:value={channel.topic}
|
||||
placeholder={chunter.string.Topic}
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
on:change={onTopicChange}
|
||||
/>
|
||||
@ -67,7 +66,6 @@
|
||||
label={chunter.string.ChannelDescription}
|
||||
bind:value={channel.description}
|
||||
placeholder={chunter.string.ChannelDescription}
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
on:change={onDescriptionChange}
|
||||
/>
|
||||
|
@ -21,6 +21,7 @@
|
||||
import { ActionContext, FilterButton, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources'
|
||||
import contact from '../plugin'
|
||||
import CreateContact from './CreateContact.svelte'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
let search = ''
|
||||
let resultQuery: DocumentQuery<Doc> = {}
|
||||
@ -61,6 +62,9 @@
|
||||
function showCreateDialog (ev: Event) {
|
||||
showPopup(CreateContact, { space: contact.space.Contacts, targetElement: ev.target }, ev.target as HTMLElement)
|
||||
}
|
||||
|
||||
let twoRows: boolean
|
||||
$: twoRows = $deviceInfo.docWidth <= 680
|
||||
</script>
|
||||
|
||||
<ActionContext
|
||||
@ -69,8 +73,9 @@
|
||||
}}
|
||||
/>
|
||||
<div class="antiPanel-component">
|
||||
<div class="ac-header full withSettings">
|
||||
<div class="ac-header__wrap-title">
|
||||
<div class="ac-header withSettings" class:full={!twoRows} class:mini={twoRows}>
|
||||
<div class:ac-header-full={!twoRows} class:flex-between={twoRows}>
|
||||
<div class="ac-header__wrap-title mr-3">
|
||||
<div class="ac-header__icon"><Icon icon={contact.icon.Person} size={'small'} /></div>
|
||||
<span class="ac-header__title"><Label label={contact.string.Contacts} /></span>
|
||||
<div class="ml-4"><FilterButton _class={contact.class.Contact} /></div>
|
||||
@ -82,6 +87,8 @@
|
||||
updateResultQuery(search)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="ac-header-full" class:secondRow={twoRows}>
|
||||
<Button
|
||||
icon={IconAdd}
|
||||
label={contact.string.ContactCreateLabel}
|
||||
@ -91,6 +98,7 @@
|
||||
/>
|
||||
<ViewletSettingButton {viewlet} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if viewlet}
|
||||
{#if loading}
|
||||
|
@ -31,8 +31,8 @@
|
||||
})
|
||||
|
||||
afterUpdate(() => {
|
||||
dispatch('changeContent', true)
|
||||
dispatch('changeContent')
|
||||
})
|
||||
</script>
|
||||
|
||||
<Menu {actions} on:changeContent={() => dispatch('changeContent', true)} />
|
||||
<Menu {actions} on:changeContent={() => dispatch('changeContent')} />
|
||||
|
@ -119,7 +119,6 @@
|
||||
placeholder={contact.string.PersonFirstNamePlaceholder}
|
||||
bind:value={firstName}
|
||||
kind={'large-style'}
|
||||
maxWidth={'32rem'}
|
||||
focus
|
||||
focusIndex={1}
|
||||
/>
|
||||
@ -127,17 +126,10 @@
|
||||
placeholder={contact.string.PersonLastNamePlaceholder}
|
||||
bind:value={lastName}
|
||||
kind={'large-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={2}
|
||||
/>
|
||||
<div class="mt-1">
|
||||
<EditBox
|
||||
placeholder={contact.string.Email}
|
||||
bind:value={email}
|
||||
kind={'small-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={3}
|
||||
/>
|
||||
<EditBox placeholder={contact.string.Email} bind:value={email} kind={'small-style'} focusIndex={3} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
|
@ -84,7 +84,6 @@
|
||||
<EditBox
|
||||
placeholder={contact.string.OrganizationNamePlaceholder}
|
||||
bind:value={object.name}
|
||||
maxWidth={'37.5rem'}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
focusIndex={1}
|
||||
|
@ -56,7 +56,6 @@
|
||||
icon={IconFolder}
|
||||
bind:value={name}
|
||||
placeholder={contact.string.OrganizationsNamePlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<ToggleWithLabel label={contact.string.MakePrivate} description={contact.string.MakePrivateDescription} />
|
||||
|
@ -109,7 +109,6 @@
|
||||
placeholder={contact.string.PersonFirstNamePlaceholder}
|
||||
bind:value={firstName}
|
||||
kind={'large-style'}
|
||||
maxWidth={'32rem'}
|
||||
focus
|
||||
focusIndex={1}
|
||||
/>
|
||||
@ -117,7 +116,6 @@
|
||||
placeholder={contact.string.PersonLastNamePlaceholder}
|
||||
bind:value={lastName}
|
||||
kind={'large-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={2}
|
||||
/>
|
||||
<div class="mt-1">
|
||||
@ -125,7 +123,6 @@
|
||||
placeholder={contact.string.PersonLocationPlaceholder}
|
||||
bind:value={object.city}
|
||||
kind={'small-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={3}
|
||||
/>
|
||||
</div>
|
||||
|
@ -56,7 +56,6 @@
|
||||
icon={IconFolder}
|
||||
bind:value={name}
|
||||
placeholder={contact.string.PersonsNamePlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<ToggleWithLabel label={contact.string.MakePrivate} description={contact.string.MakePrivateDescription} />
|
||||
|
@ -64,7 +64,6 @@
|
||||
<div class="name">
|
||||
<EditBox
|
||||
placeholder={contact.string.PersonFirstNamePlaceholder}
|
||||
maxWidth="20rem"
|
||||
bind:value={object.name}
|
||||
on:change={nameChange}
|
||||
focus
|
||||
|
@ -118,7 +118,6 @@
|
||||
{#if editable}
|
||||
<EditBox
|
||||
placeholder={contact.string.PersonFirstNamePlaceholder}
|
||||
maxWidth="20rem"
|
||||
bind:value={firstName}
|
||||
on:change={firstNameChange}
|
||||
focusIndex={1}
|
||||
@ -131,7 +130,6 @@
|
||||
{#if editable}
|
||||
<EditBox
|
||||
placeholder={contact.string.PersonLastNamePlaceholder}
|
||||
maxWidth="20rem"
|
||||
bind:value={lastName}
|
||||
on:change={lastNameChange}
|
||||
focusIndex={2}
|
||||
|
@ -43,7 +43,7 @@
|
||||
}}
|
||||
>
|
||||
<Grid column={1} rowGap={1}>
|
||||
<EditBox bind:value={statusName} maxWidth={'16rem'} />
|
||||
<EditBox bind:value={statusName} />
|
||||
<div><Label label={contact.string.StatusDueDate} /></div>
|
||||
|
||||
<EmployeeStatusDueDatePresenter {statusDueDate} on:change={handleDueDateChanged} />
|
||||
|
@ -59,12 +59,7 @@
|
||||
<div class="popup-block">
|
||||
<span><Label label={contact.string.SocialLinks} /></span>
|
||||
{#each providers as provider, i}
|
||||
<EditBox
|
||||
label={provider.label}
|
||||
placeholder={provider.placeholder}
|
||||
bind:value={newValues[i].value}
|
||||
maxWidth={'14.5rem'}
|
||||
/>
|
||||
<EditBox label={provider.label} placeholder={provider.placeholder} bind:value={newValues[i].value} />
|
||||
{/each}
|
||||
</div>
|
||||
</ScrollBox>
|
||||
|
@ -181,20 +181,10 @@
|
||||
on:drop|preventDefault|stopPropagation={fileDrop}
|
||||
>
|
||||
<div class="mb-2">
|
||||
<EditBox
|
||||
label={plugin.string.Subject}
|
||||
bind:value={obj.subject}
|
||||
placeholder={plugin.string.SubjectPlaceholder}
|
||||
maxWidth={'min-content'}
|
||||
/>
|
||||
<EditBox label={plugin.string.Subject} bind:value={obj.subject} placeholder={plugin.string.SubjectPlaceholder} />
|
||||
</div>
|
||||
<div>
|
||||
<EditBox
|
||||
label={plugin.string.Copy}
|
||||
bind:value={copy}
|
||||
placeholder={plugin.string.CopyPlaceholder}
|
||||
maxWidth={'min-content'}
|
||||
/>
|
||||
<EditBox label={plugin.string.Copy} bind:value={copy} placeholder={plugin.string.CopyPlaceholder} />
|
||||
</div>
|
||||
{#if attachments.length}
|
||||
<div class="flex-row-center list mt-2 scroll-divider-color">
|
||||
|
@ -61,15 +61,16 @@
|
||||
<div class="mr-3">
|
||||
<Button focusIndex={1} icon={hr.icon.Department} size={'medium'} kind={'link-bordered'} disabled />
|
||||
</div>
|
||||
<div class="clear-mins flex-grow">
|
||||
<EditBox
|
||||
focusIndex={2}
|
||||
bind:value={name}
|
||||
placeholder={hr.string.DepartmentPlaceholder}
|
||||
maxWidth={'37.5rem'}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<svelte:fragment slot="header">
|
||||
<SpaceSelector _class={hr.class.Department} label={hr.string.ParentDepartmentLabel} bind:space />
|
||||
</svelte:fragment>
|
||||
|
@ -101,13 +101,7 @@
|
||||
</div>
|
||||
<div class="flex-grow flex-col">
|
||||
<div class="name">
|
||||
<EditBox
|
||||
placeholder={core.string.Name}
|
||||
maxWidth="20rem"
|
||||
bind:value={object.name}
|
||||
on:change={nameChange}
|
||||
focusIndex={1}
|
||||
/>
|
||||
<EditBox placeholder={core.string.Name} bind:value={object.name} on:change={nameChange} focusIndex={1} />
|
||||
</div>
|
||||
<div class="separator" />
|
||||
<div class="flex-row-center">
|
||||
|
@ -21,6 +21,7 @@
|
||||
import hr from '../plugin'
|
||||
import CreateDepartment from './CreateDepartment.svelte'
|
||||
import DepartmentCard from './DepartmentCard.svelte'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
let search = ''
|
||||
let resultQuery: DocumentQuery<Department> = {}
|
||||
@ -63,10 +64,14 @@
|
||||
spaceMembers.query(hr.mixin.Staff, {}, (res) => {
|
||||
allEmployees = res
|
||||
})
|
||||
|
||||
let twoRows: boolean
|
||||
$: twoRows = $deviceInfo.docWidth <= 680
|
||||
</script>
|
||||
|
||||
<div class="ac-header full divide">
|
||||
<div class="ac-header__wrap-title">
|
||||
<div class="ac-header withSettings divide" class:full={!twoRows} class:mini={twoRows}>
|
||||
<div class:ac-header-full={!twoRows} class:flex-between={twoRows}>
|
||||
<div class="ac-header__wrap-title mr-3">
|
||||
<div class="ac-header__icon"><Icon icon={hr.icon.Structure} size={'small'} /></div>
|
||||
<span class="ac-header__title"><Label label={hr.string.Structure} /></span>
|
||||
</div>
|
||||
@ -77,6 +82,8 @@
|
||||
updateResultQuery(search)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="ac-header-full" class:secondRow={twoRows}>
|
||||
<Button
|
||||
label={hr.string.CreateDepartmentLabel}
|
||||
icon={IconAdd}
|
||||
@ -85,6 +92,7 @@
|
||||
on:click={showCreateDialog}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Scroller>
|
||||
{#if head}
|
||||
|
@ -20,6 +20,7 @@
|
||||
import inventory from '../plugin'
|
||||
import CreateCategory from './CreateCategory.svelte'
|
||||
import HierarchyView from './HierarchyView.svelte'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
let search = ''
|
||||
let resultQuery: DocumentQuery<Category> = {}
|
||||
@ -31,10 +32,14 @@
|
||||
function showCreateDialog (ev: MouseEvent) {
|
||||
showPopup(CreateCategory, { space: inventory.space.Category }, eventToHTMLElement(ev))
|
||||
}
|
||||
|
||||
let twoRows: boolean
|
||||
$: twoRows = $deviceInfo.docWidth <= 680
|
||||
</script>
|
||||
|
||||
<div class="ac-header full">
|
||||
<div class="ac-header__wrap-title">
|
||||
<div class="ac-header withSettings" class:full={!twoRows} class:mini={twoRows}>
|
||||
<div class:ac-header-full={!twoRows} class:flex-between={twoRows}>
|
||||
<div class="ac-header__wrap-title mr-3">
|
||||
<div class="ac-header__icon"><Icon icon={inventory.icon.Categories} size={'small'} /></div>
|
||||
<span class="ac-header__title"><Label label={inventory.string.Categories} /></span>
|
||||
</div>
|
||||
@ -45,6 +50,8 @@
|
||||
updateResultQuery(search)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="ac-header-full" class:secondRow={twoRows}>
|
||||
<Button
|
||||
label={inventory.string.CategoryCreateLabel}
|
||||
icon={IconAdd}
|
||||
@ -53,6 +60,7 @@
|
||||
on:click={showCreateDialog}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Scroller>
|
||||
<HierarchyView _class={inventory.class.Category} config={['', 'modifiedOn']} options={{}} query={resultQuery} />
|
||||
|
@ -70,7 +70,6 @@
|
||||
icon={inventory.icon.Categories}
|
||||
bind:value={name}
|
||||
placeholder={inventory.string.Category}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
</Grid>
|
||||
|
@ -82,7 +82,6 @@
|
||||
icon={inventory.icon.Products}
|
||||
bind:value={doc.name}
|
||||
placeholder={inventory.string.Product}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<DropdownLabels
|
||||
|
@ -65,13 +65,7 @@
|
||||
}}
|
||||
>
|
||||
<Grid column={1} rowGap={1.75}>
|
||||
<EditBox
|
||||
label={inventory.string.Variant}
|
||||
bind:value={doc.name}
|
||||
placeholder={inventory.string.Variant}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<EditBox label={inventory.string.SKU} bind:value={doc.sku} placeholder={inventory.string.SKU} maxWidth={'16rem'} />
|
||||
<EditBox label={inventory.string.Variant} bind:value={doc.name} placeholder={inventory.string.Variant} focus />
|
||||
<EditBox label={inventory.string.SKU} bind:value={doc.sku} placeholder={inventory.string.SKU} />
|
||||
</Grid>
|
||||
</Card>
|
||||
|
@ -196,7 +196,6 @@
|
||||
placeholder={contact.string.PersonFirstNamePlaceholder}
|
||||
bind:value={firstName}
|
||||
kind={'large-style'}
|
||||
maxWidth={'32rem'}
|
||||
focus
|
||||
focusIndex={1}
|
||||
/>
|
||||
@ -204,7 +203,6 @@
|
||||
placeholder={contact.string.PersonLastNamePlaceholder}
|
||||
bind:value={lastName}
|
||||
kind={'large-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={2}
|
||||
/>
|
||||
<div class="mt-1">
|
||||
@ -212,7 +210,6 @@
|
||||
placeholder={contact.string.PersonLocationPlaceholder}
|
||||
bind:value={object.city}
|
||||
kind={'small-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={3}
|
||||
/>
|
||||
</div>
|
||||
@ -220,7 +217,6 @@
|
||||
placeholder={lead.string.IssueDescriptionPlaceholder}
|
||||
bind:value={object.description}
|
||||
kind={'small-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={4}
|
||||
/>
|
||||
</div>
|
||||
@ -242,7 +238,6 @@
|
||||
<EditBox
|
||||
placeholder={contact.string.OrganizationNamePlaceholder}
|
||||
bind:value={object.name}
|
||||
maxWidth={'37.5rem'}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
focusIndex={1}
|
||||
|
@ -67,7 +67,6 @@
|
||||
icon={IconFolder}
|
||||
bind:value={name}
|
||||
placeholder={lead.string.FunnelName}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<ToggleWithLabel label={lead.string.MakePrivate} description={lead.string.MakePrivateDescription} />
|
||||
|
@ -142,7 +142,6 @@
|
||||
bind:value={title}
|
||||
icon={lead.icon.Lead}
|
||||
placeholder={lead.string.LeadPlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<svelte:fragment slot="pool">
|
||||
|
@ -85,7 +85,6 @@
|
||||
<EditBox
|
||||
bind:value={object.name}
|
||||
placeholder={lead.string.FunnelPlaceholder}
|
||||
maxWidth={'39rem'}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
focusable
|
||||
@ -96,7 +95,6 @@
|
||||
<EditBox
|
||||
bind:value={object.description}
|
||||
placeholder={lead.string.Description}
|
||||
maxWidth={'39rem'}
|
||||
focusable
|
||||
on:blur={() => {
|
||||
if (rawDesc !== object.description) onChange('description', object.description)
|
||||
|
@ -48,7 +48,6 @@
|
||||
bind:value={rawTitle}
|
||||
placeholder={lead.string.LeadPlaceholder}
|
||||
kind={'large-style'}
|
||||
maxWidth={'20rem'}
|
||||
focusable
|
||||
on:blur={() => {
|
||||
if (rawTitle !== object.title) change('title', rawTitle)
|
||||
|
@ -38,6 +38,7 @@
|
||||
import CandidateCard from './CandidateCard.svelte'
|
||||
import VacancyCard from './VacancyCard.svelte'
|
||||
import VacancyOrgPresenter from './VacancyOrgPresenter.svelte'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
export let space: Ref<SpaceWithStates>
|
||||
export let candidate: Ref<Candidate>
|
||||
@ -246,6 +247,8 @@
|
||||
} else {
|
||||
candidateQuery.unsubscribe()
|
||||
}
|
||||
let verticalContent: boolean = false
|
||||
$: verticalContent = $deviceInfo.isMobile && $deviceInfo.isPortrait
|
||||
</script>
|
||||
|
||||
<FocusHandler {manager} />
|
||||
@ -265,7 +268,7 @@
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<StatusControl slot="error" {status} />
|
||||
<div class="candidate-vacancy">
|
||||
<div class:candidate-vacancy={!verticalContent} class:flex-col={verticalContent}>
|
||||
<div class="flex flex-stretch">
|
||||
<UserBox
|
||||
id={'vacancy.talant.selector'}
|
||||
@ -288,7 +291,7 @@
|
||||
</UserBox>
|
||||
</div>
|
||||
|
||||
<div class="flex-center">
|
||||
<div class="flex-center" class:rotate={verticalContent}>
|
||||
<ExpandRightDouble />
|
||||
</div>
|
||||
<div class="flex-grow">
|
||||
@ -359,6 +362,9 @@
|
||||
grid-template-columns: 3fr 1fr 3fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
.rotate {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.color {
|
||||
margin-right: 0.375rem;
|
||||
width: 0.875rem;
|
||||
|
@ -435,7 +435,6 @@
|
||||
placeholder={recruit.string.PersonFirstNamePlaceholder}
|
||||
bind:value={firstName}
|
||||
kind={'large-style'}
|
||||
maxWidth={'32rem'}
|
||||
focus
|
||||
focusIndex={1}
|
||||
/>
|
||||
@ -443,25 +442,12 @@
|
||||
placeholder={recruit.string.PersonLastNamePlaceholder}
|
||||
bind:value={lastName}
|
||||
kind={'large-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={2}
|
||||
/>
|
||||
<div class="mt-1">
|
||||
<EditBox
|
||||
placeholder={recruit.string.Title}
|
||||
bind:value={object.title}
|
||||
kind={'small-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={3}
|
||||
/>
|
||||
<EditBox placeholder={recruit.string.Title} bind:value={object.title} kind={'small-style'} focusIndex={3} />
|
||||
</div>
|
||||
<EditBox
|
||||
placeholder={recruit.string.Location}
|
||||
bind:value={object.city}
|
||||
kind={'small-style'}
|
||||
maxWidth={'32rem'}
|
||||
focusIndex={4}
|
||||
/>
|
||||
<EditBox placeholder={recruit.string.Location} bind:value={object.city} kind={'small-style'} focusIndex={4} />
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<EditableAvatar
|
||||
|
@ -73,15 +73,16 @@
|
||||
<div class="mr-3">
|
||||
<Button focusIndex={1} icon={Vacancy} size={'medium'} kind={'link-bordered'} disabled />
|
||||
</div>
|
||||
<div class="clear-mins flex-grow">
|
||||
<EditBox
|
||||
focusIndex={2}
|
||||
bind:value={name}
|
||||
placeholder={recruit.string.VacancyPlaceholder}
|
||||
maxWidth={'37.5rem'}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<svelte:fragment slot="pool">
|
||||
<UserBox
|
||||
focusIndex={3}
|
||||
|
@ -16,6 +16,7 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Scroller } from '@hcengineering/ui'
|
||||
import type { Candidate, Applicant, Vacancy } from '@hcengineering/recruit'
|
||||
import CandidateCard from './CandidateCard.svelte'
|
||||
import VacancyCard from './VacancyCard.svelte'
|
||||
@ -51,6 +52,7 @@
|
||||
</script>
|
||||
|
||||
{#if object !== undefined && candidate !== undefined}
|
||||
<Scroller horizontal>
|
||||
<div class="flex-between">
|
||||
<div class="card"><CandidateCard {candidate} on:click /></div>
|
||||
<div class="arrows"><ExpandRightDouble /></div>
|
||||
@ -59,6 +61,7 @@
|
||||
<div class="mt-6">
|
||||
<Reviews objectId={candidate._id} reviews={candidate.reviews ?? 0} label={recruit.string.TalentReviews} />
|
||||
</div>
|
||||
</Scroller>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -94,7 +94,6 @@
|
||||
<EditBox
|
||||
bind:value={object.name}
|
||||
placeholder={recruit.string.VacancyPlaceholder}
|
||||
maxWidth={'39rem'}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
focusable
|
||||
@ -114,7 +113,6 @@
|
||||
<EditBox
|
||||
bind:value={object.description}
|
||||
placeholder={recruit.string.VacancyDescription}
|
||||
maxWidth={'39rem'}
|
||||
focusable
|
||||
on:blur={() => {
|
||||
if (rawDesc !== object.description) onChange('description', object.description)
|
||||
|
@ -21,6 +21,7 @@
|
||||
import { FilterButton, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources'
|
||||
import recruit from '../plugin'
|
||||
import CreateVacancy from './CreateVacancy.svelte'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
let search: string = ''
|
||||
let resultQuery: DocumentQuery<Doc> = {}
|
||||
@ -129,10 +130,14 @@
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let twoRows: boolean
|
||||
$: twoRows = $deviceInfo.docWidth <= 680
|
||||
</script>
|
||||
|
||||
<div class="ac-header full">
|
||||
<div class="ac-header__wrap-title">
|
||||
<div class="ac-header withSettings" class:full={!twoRows} class:mini={twoRows}>
|
||||
<div class:ac-header-full={!twoRows} class:flex-between={twoRows}>
|
||||
<div class="ac-header__wrap-title mr-3">
|
||||
<div class="ac-header__icon"><Icon icon={recruit.icon.Vacancy} size={'small'} /></div>
|
||||
<span class="ac-header__title"><Label label={recruit.string.Vacancies} /></span>
|
||||
<div class="ml-4"><FilterButton _class={recruit.class.Vacancy} /></div>
|
||||
@ -143,6 +148,8 @@
|
||||
search = e.detail
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="ac-header-full" class:secondRow={twoRows}>
|
||||
<Button
|
||||
icon={IconAdd}
|
||||
label={recruit.string.VacancyCreateLabel}
|
||||
@ -152,6 +159,8 @@
|
||||
/>
|
||||
<ViewletSettingButton viewlet={descr} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if descr}
|
||||
{#if loading}
|
||||
<Loading />
|
||||
|
@ -94,7 +94,6 @@
|
||||
label={recruit.string.OpinionValue}
|
||||
placeholder={recruit.string.OpinionValuePlaceholder}
|
||||
focus
|
||||
maxWidth={'10rem'}
|
||||
/>
|
||||
<div class="mt-1 mb-1">
|
||||
<Label label={recruit.string.Description} />:
|
||||
|
@ -148,8 +148,8 @@
|
||||
}}
|
||||
>
|
||||
<StatusControl slot="error" {status} />
|
||||
<EditBox placeholder={recruit.string.Title} bind:value={title} maxWidth={'37.5rem'} kind={'large-style'} focus />
|
||||
<EditBox placeholder={recruit.string.Location} bind:value={location} maxWidth={'37.5rem'} kind={'small-style'} />
|
||||
<EditBox placeholder={recruit.string.Title} bind:value={title} kind={'large-style'} focus />
|
||||
<EditBox placeholder={recruit.string.Location} bind:value={location} kind={'small-style'} />
|
||||
<StyledTextBox
|
||||
emphasized
|
||||
showButtons={false}
|
||||
|
@ -73,7 +73,6 @@
|
||||
bind:value
|
||||
icon={recruit.icon.Application}
|
||||
placeholder={recruit.string.OpinionValue}
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
/>
|
||||
<div class="mt-1 mb-1">
|
||||
|
@ -61,7 +61,6 @@
|
||||
<EditBox
|
||||
bind:value={rawTitle}
|
||||
kind={'large-style'}
|
||||
maxWidth={'20rem'}
|
||||
focusable
|
||||
on:blur={() => {
|
||||
if (rawTitle !== object.title) client.update(object, { title: rawTitle })
|
||||
@ -99,7 +98,6 @@
|
||||
bind:value={object.verdict}
|
||||
placeholder={recruit.string.Verdict}
|
||||
kind={'large-style'}
|
||||
maxWidth={'39rem'}
|
||||
focusable
|
||||
on:change={() => client.update(object, { verdict: object.verdict })}
|
||||
/>
|
||||
|
@ -100,7 +100,7 @@
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<div class="mb-2"><EditBox bind:value={name} placeholder={core.string.Name} maxWidth="13rem" /></div>
|
||||
<div class="mb-2"><EditBox bind:value={name} placeholder={core.string.Name} /></div>
|
||||
<div class="flex-col mb-2">
|
||||
<div class="flex-row-center flex-grow">
|
||||
<Label label={setting.string.Type} />
|
||||
|
@ -61,5 +61,5 @@
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
<div class="mb-2"><EditBox focus bind:value={name} placeholder={core.string.Name} maxWidth="13rem" /></div>
|
||||
<div class="mb-2"><EditBox focus bind:value={name} placeholder={core.string.Name} /></div>
|
||||
</Card>
|
||||
|
@ -95,7 +95,7 @@
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<div class="mb-2"><EditBox bind:value={name} placeholder={core.string.Name} maxWidth="13rem" /></div>
|
||||
<div class="mb-2"><EditBox bind:value={name} placeholder={core.string.Name} /></div>
|
||||
<div class="flex-col mb-2">
|
||||
<div class="flex-row-center flex-grow">
|
||||
<Label label={setting.string.Type} />
|
||||
|
@ -74,7 +74,7 @@
|
||||
}}
|
||||
>
|
||||
<div class="mb-2">
|
||||
<EditBox bind:value={name} placeholder={setting.string.NewClassName} maxWidth="23rem" />
|
||||
<EditBox bind:value={name} placeholder={setting.string.NewClassName} />
|
||||
</div>
|
||||
<Label label={setting.string.OldNames} />
|
||||
<div class="flex-col">
|
||||
|
@ -182,10 +182,10 @@
|
||||
>
|
||||
<div on:keydown={onKeydown}>
|
||||
<div class="mb-2">
|
||||
<EditBox bind:value={name} placeholder={core.string.Name} maxWidth="13rem" />
|
||||
<EditBox bind:value={name} placeholder={core.string.Name} />
|
||||
</div>
|
||||
<div class="flex-between mb-4">
|
||||
<EditBox placeholder={presentation.string.Search} kind="large-style" bind:value={newValue} maxWidth="13rem" />
|
||||
<EditBox placeholder={presentation.string.Search} kind="large-style" bind:value={newValue} />
|
||||
<div class="flex gap-2">
|
||||
<ActionIcon icon={IconAdd} label={presentation.string.Add} action={add} size={'small'} />
|
||||
<ActionIcon
|
||||
|
@ -73,7 +73,7 @@
|
||||
selected = value
|
||||
}}
|
||||
>
|
||||
<EditBox maxWidth="15rem" bind:value={value.name} on:change={() => update(value)} />
|
||||
<EditBox bind:value={value.name} on:change={() => update(value)} />
|
||||
<div
|
||||
class="hover-trans"
|
||||
on:click|stopPropagation={(ev) => {
|
||||
|
@ -125,7 +125,6 @@
|
||||
on:keydown={handleKeydown}
|
||||
kind="large-style"
|
||||
bind:value={newValue}
|
||||
maxWidth="18rem"
|
||||
/>
|
||||
<div class="flex gap-2">
|
||||
<ActionIcon icon={IconAdd} label={setting.string.Add} action={add} size={'small'} />
|
||||
|
@ -71,7 +71,6 @@
|
||||
format="password"
|
||||
placeholder={setting.string.EnterCurrentPassword}
|
||||
label={setting.string.CurrentPassword}
|
||||
maxWidth="20rem"
|
||||
bind:value={oldPassword}
|
||||
/>
|
||||
</div>
|
||||
@ -80,7 +79,6 @@
|
||||
format="password"
|
||||
placeholder={setting.string.EnterNewPassword}
|
||||
label={setting.string.NewPassword}
|
||||
maxWidth="20rem"
|
||||
bind:value={password}
|
||||
/>
|
||||
</div>
|
||||
@ -89,7 +87,6 @@
|
||||
format="password"
|
||||
placeholder={setting.string.RepeatNewPassword}
|
||||
label={setting.string.NewPassword}
|
||||
maxWidth="20rem"
|
||||
bind:value={password2}
|
||||
/>
|
||||
</div>
|
||||
|
@ -99,35 +99,30 @@
|
||||
</div>
|
||||
<div class="ac-body p-10">
|
||||
{#if employee}
|
||||
<div class="flex flex-grow">
|
||||
<div class="flex flex-grow w-full">
|
||||
<div class="mr-8">
|
||||
<EditableAvatar avatar={employee.avatar} size={'x-large'} on:done={onAvatarDone} on:remove={removeAvatar} />
|
||||
</div>
|
||||
<div class="flex-grow flex-col">
|
||||
<div class="flex-col">
|
||||
<div class="name">
|
||||
<EditBox
|
||||
placeholder={contactRes.string.PersonFirstNamePlaceholder}
|
||||
maxWidth="20rem"
|
||||
bind:value={firstName}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
focusIndex={1}
|
||||
on:change={() => {
|
||||
changeName(firstName, lastName)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="name">
|
||||
<EditBox
|
||||
placeholder={contactRes.string.PersonLastNamePlaceholder}
|
||||
maxWidth="20rem"
|
||||
bind:value={lastName}
|
||||
kind={'large-style'}
|
||||
focusIndex={2}
|
||||
on:change={() => {
|
||||
changeName(firstName, lastName)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="location">
|
||||
<AttributeEditor
|
||||
maxWidth="20rem"
|
||||
@ -137,7 +132,6 @@
|
||||
key="city"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="separator" />
|
||||
<ChannelsEditor attachedTo={employee._id} attachedClass={employee._class} focusIndex={10} allowOpen={false} />
|
||||
</div>
|
||||
|
@ -117,22 +117,16 @@
|
||||
</svelte:fragment>
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex-col mt-0-5">
|
||||
<div class="flex-col mt-0-5 w-full">
|
||||
<EditBox
|
||||
bind:value={title}
|
||||
placeholder={tags.string.TagName}
|
||||
placeholderParam={{ word: keyTitle }}
|
||||
maxWidth={'35rem'}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
/>
|
||||
<div class="mt-2">
|
||||
<EditBox
|
||||
bind:value={description}
|
||||
placeholder={tags.string.TagDescriptionPlaceholder}
|
||||
maxWidth={'35rem'}
|
||||
kind={'small-style'}
|
||||
/>
|
||||
<EditBox bind:value={description} placeholder={tags.string.TagDescriptionPlaceholder} kind={'small-style'} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -113,16 +113,11 @@
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<EditBox
|
||||
placeholder={tags.string.TagName}
|
||||
placeholderParam={{ word: keyTitle }}
|
||||
maxWidth="15rem"
|
||||
bind:value={data.title}
|
||||
/>
|
||||
<EditBox placeholder={tags.string.TagName} placeholderParam={{ word: keyTitle }} bind:value={data.title} />
|
||||
</div>
|
||||
|
||||
<div class="fs-title mt-4">
|
||||
<EditBox placeholder={tags.string.TagDescriptionPlaceholder} maxWidth="15rem" bind:value={data.description} />
|
||||
<EditBox placeholder={tags.string.TagDescriptionPlaceholder} bind:value={data.description} />
|
||||
</div>
|
||||
|
||||
<div class="text-sm mt-4">
|
||||
|
@ -22,6 +22,7 @@
|
||||
import tags from '../plugin'
|
||||
import CategoryBar from './CategoryBar.svelte'
|
||||
import CreateTagElement from './CreateTagElement.svelte'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
export let title: IntlString = tags.string.Tags
|
||||
export let icon: Asset | AnySvelteComponent = tags.icon.Tags
|
||||
@ -84,10 +85,14 @@
|
||||
const countSorting = (a: Doc, b: Doc) =>
|
||||
(tagElements?.get(b._id as Ref<TagElement>)?.count ?? 0) -
|
||||
(tagElements?.get(a._id as Ref<TagElement>)?.count ?? 0) ?? 0
|
||||
|
||||
let twoRows: boolean
|
||||
$: twoRows = $deviceInfo.docWidth <= 680
|
||||
</script>
|
||||
|
||||
<div class="ac-header full">
|
||||
<div class="ac-header__wrap-title">
|
||||
<div class="ac-header withSettings" class:full={!twoRows} class:mini={twoRows}>
|
||||
<div class:ac-header-full={!twoRows} class:flex-between={twoRows}>
|
||||
<div class="ac-header__wrap-title mr-3">
|
||||
<div class="ac-header__icon"><Icon {icon} size={'small'} /></div>
|
||||
<span class="ac-header__title"><Label label={title} /></span>
|
||||
</div>
|
||||
@ -98,8 +103,11 @@
|
||||
updateResultQuery(search, category)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="ac-header-full" class:secondRow={twoRows}>
|
||||
<Button icon={IconAdd} label={сreateItemLabel} kind={'primary'} size={'small'} on:click={showCreateDialog} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CategoryBar
|
||||
{targetClass}
|
||||
|
@ -67,7 +67,6 @@
|
||||
icon={IconFolder}
|
||||
bind:value={name}
|
||||
placeholder={plugin.string.ProjectNamePlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<ToggleWithLabel label={plugin.string.MakePrivate} description={plugin.string.MakePrivateDescription} />
|
||||
|
@ -52,7 +52,6 @@
|
||||
bind:value={object.name}
|
||||
icon={task.icon.Task}
|
||||
placeholder={plugin.string.TaskNamePlaceholder}
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
on:change={() => change('name', object.name)}
|
||||
/>
|
||||
|
@ -80,7 +80,6 @@
|
||||
bind:value={name}
|
||||
icon={task.icon.Task}
|
||||
placeholder={plugin.string.TodoDescriptionPlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<DatePicker title={plugin.string.TodoDueDate} bind:value={dueTo} />
|
||||
|
@ -77,7 +77,6 @@
|
||||
bind:value={name}
|
||||
icon={task.icon.Task}
|
||||
placeholder={plugin.string.TodoDescriptionPlaceholder}
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<DatePicker title={plugin.string.TodoDueDate} bind:value={dueTo} />
|
||||
|
@ -140,7 +140,6 @@
|
||||
<p><Label label={telegram.string.PasswordDescr} /></p>
|
||||
<EditBox
|
||||
label={telegram.string.Password}
|
||||
maxWidth="10rem"
|
||||
format="password"
|
||||
placeholder={telegram.string.Password}
|
||||
bind:value={password}
|
||||
@ -150,12 +149,7 @@
|
||||
<PinPad length={5} bind:value={code} bind:error />
|
||||
{:else}
|
||||
<p><Label label={telegram.string.PhoneDescr} /></p>
|
||||
<EditBox
|
||||
label={telegram.string.Phone}
|
||||
maxWidth="10rem"
|
||||
placeholder={telegram.string.PhonePlaceholder}
|
||||
bind:value={phone}
|
||||
/>
|
||||
<EditBox label={telegram.string.Phone} placeholder={telegram.string.PhonePlaceholder} bind:value={phone} />
|
||||
{/if}
|
||||
<div class="footer">
|
||||
<Button {label} kind={'primary'} {disabled} on:click={click} />
|
||||
|
@ -153,7 +153,6 @@
|
||||
<p><Label label={telegram.string.PasswordDescr} /></p>
|
||||
<EditBox
|
||||
label={telegram.string.Password}
|
||||
maxWidth="10rem"
|
||||
format="password"
|
||||
placeholder={telegram.string.Password}
|
||||
bind:value={password}
|
||||
@ -164,12 +163,7 @@
|
||||
{:else}
|
||||
<p><Label label={telegram.string.PhoneDescr} /></p>
|
||||
{#await getCurrent() then value}
|
||||
<EditBox
|
||||
label={telegram.string.Phone}
|
||||
maxWidth="10rem"
|
||||
placeholder={telegram.string.PhonePlaceholder}
|
||||
bind:value={phone}
|
||||
/>
|
||||
<EditBox label={telegram.string.Phone} placeholder={telegram.string.PhonePlaceholder} bind:value={phone} />
|
||||
{/await}
|
||||
{/if}
|
||||
<div class="footer">
|
||||
|
@ -115,11 +115,7 @@
|
||||
</span>
|
||||
<div class="text-lg caption-color">
|
||||
{#if mode !== Mode.View}
|
||||
<EditBox
|
||||
bind:value={newTemplate.title}
|
||||
maxWidth={'12rem'}
|
||||
placeholder={templatesPlugin.string.TemplatePlaceholder}
|
||||
/>
|
||||
<EditBox bind:value={newTemplate.title} placeholder={templatesPlugin.string.TemplatePlaceholder} />
|
||||
{:else}
|
||||
{newTemplate.title}
|
||||
{/if}
|
||||
|
@ -319,13 +319,7 @@
|
||||
{#if parentIssue}
|
||||
<ParentIssue issue={parentIssue} on:close={clearParentIssue} />
|
||||
{/if}
|
||||
<EditBox
|
||||
bind:value={object.title}
|
||||
placeholder={tracker.string.IssueTitlePlaceholder}
|
||||
maxWidth={'37.5rem'}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
/>
|
||||
<EditBox bind:value={object.title} placeholder={tracker.string.IssueTitlePlaceholder} kind={'large-style'} focus />
|
||||
<AttachmentStyledBox
|
||||
bind:this={descriptionBox}
|
||||
{objectId}
|
||||
|
@ -123,9 +123,9 @@
|
||||
...(hasRelation ? removeRelationAction : [])
|
||||
]
|
||||
|
||||
afterUpdate(() => dispatch('changeContent', true))
|
||||
afterUpdate(() => dispatch('changeContent'))
|
||||
</script>
|
||||
|
||||
{#if actions}
|
||||
<Menu {actions} on:changeContent={() => dispatch('changeContent', true)} />
|
||||
<Menu {actions} on:changeContent={() => dispatch('changeContent')} />
|
||||
{/if}
|
||||
|
@ -4,6 +4,7 @@
|
||||
import { FilterButton, setActiveViewletId } from '@hcengineering/view-resources'
|
||||
import tracker from '../../plugin'
|
||||
import { WithLookup } from '@hcengineering/core'
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
export let viewlet: WithLookup<Viewlet> | undefined
|
||||
export let viewlets: WithLookup<Viewlet>[] = []
|
||||
@ -18,10 +19,14 @@
|
||||
tooltip: views.$lookup?.descriptor?.label
|
||||
}
|
||||
})
|
||||
|
||||
let twoRows: boolean
|
||||
$: twoRows = $deviceInfo.docWidth <= 680
|
||||
</script>
|
||||
|
||||
<div class="ac-header full">
|
||||
<div class="ac-header__wrap-title">
|
||||
<div class="ac-header withSettings" class:full={!twoRows} class:mini={twoRows}>
|
||||
<div class:ac-header-full={!twoRows} class:flex-between={twoRows}>
|
||||
<div class="ac-header__wrap-title mr-3">
|
||||
{#if showLabelSelector}
|
||||
<slot name="label_selector" />
|
||||
{:else}
|
||||
@ -31,6 +36,8 @@
|
||||
<div class="ml-4"><FilterButton _class={tracker.class.Issue} /></div>
|
||||
</div>
|
||||
<SearchEdit bind:value={search} on:change={() => {}} />
|
||||
</div>
|
||||
<div class="ac-header-full" class:secondRow={twoRows}>
|
||||
{#if viewlets.length > 1}
|
||||
<TabList
|
||||
items={viewslist}
|
||||
@ -49,3 +56,4 @@
|
||||
{/if}
|
||||
<slot name="extra" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -173,7 +173,6 @@
|
||||
<EditBox
|
||||
bind:value={newIssue.title}
|
||||
bind:focusInput={focusIssueTitle}
|
||||
maxWidth="33rem"
|
||||
placeholder={tracker.string.IssueTitlePlaceholder}
|
||||
focus
|
||||
/>
|
||||
|
@ -221,12 +221,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<EditBox
|
||||
bind:value={title}
|
||||
maxWidth="53.75rem"
|
||||
placeholder={tracker.string.IssueTitlePlaceholder}
|
||||
kind="large-style"
|
||||
/>
|
||||
<EditBox bind:value={title} placeholder={tracker.string.IssueTitlePlaceholder} kind="large-style" />
|
||||
<div class="flex-between mt-6">
|
||||
{#key description}
|
||||
<div class="flex-grow">
|
||||
|
@ -181,7 +181,6 @@
|
||||
<EditBox
|
||||
bind:value={newIssue.title}
|
||||
bind:focusInput={focusIssueTitle}
|
||||
maxWidth="33rem"
|
||||
placeholder={tracker.string.IssueTitlePlaceholder}
|
||||
focus
|
||||
/>
|
||||
|
@ -40,7 +40,6 @@
|
||||
export let value: string | number | undefined
|
||||
export let format: 'text' | 'password' | 'number'
|
||||
export let kind: EditStyle = 'search-style'
|
||||
export let maxWidth: string = '10rem'
|
||||
export let object: Issue
|
||||
|
||||
let _value = value
|
||||
@ -76,7 +75,6 @@
|
||||
bind:value={_value}
|
||||
{format}
|
||||
{kind}
|
||||
{maxWidth}
|
||||
placeholder={tracker.string.Estimation}
|
||||
focus
|
||||
on:keypress={_onkeypress}
|
||||
|
@ -28,7 +28,6 @@
|
||||
|
||||
export let value: TimeSpendReport | undefined
|
||||
export let placeholder: IntlString = tracker.string.TimeSpendReportValue
|
||||
export let maxWidth: string = '10rem'
|
||||
|
||||
export function canClose (): boolean {
|
||||
return true
|
||||
@ -79,7 +78,7 @@
|
||||
okLabel={value === undefined ? presentation.string.Create : presentation.string.Save}
|
||||
>
|
||||
<div class="flex-row-center gap-2">
|
||||
<EditBox focus bind:value={data.value} {placeholder} format={'number'} kind={'editbox'} {maxWidth} />
|
||||
<EditBox focus bind:value={data.value} {placeholder} format={'number'} kind={'editbox'} />
|
||||
<UserBox
|
||||
_class={contact.class.Employee}
|
||||
label={contact.string.Employee}
|
||||
@ -88,10 +87,5 @@
|
||||
/>
|
||||
<DatePresenter kind={'link'} bind:value={data.date} editable />
|
||||
</div>
|
||||
<EditBox
|
||||
bind:value={data.description}
|
||||
placeholder={tracker.string.TimeSpendReportDescription}
|
||||
kind={'editbox'}
|
||||
{maxWidth}
|
||||
/>
|
||||
<EditBox bind:value={data.description} placeholder={tracker.string.TimeSpendReportDescription} kind={'editbox'} />
|
||||
</Card>
|
||||
|
@ -46,7 +46,7 @@
|
||||
<svelte:fragment slot="aside">
|
||||
<div class="flex-row p-4 w-60 left-divider">
|
||||
<div class="fs-title text-xl">
|
||||
<EditBox bind:value={project.label} maxWidth="39rem" on:change={() => change('label', project.label)} />
|
||||
<EditBox bind:value={project.label} on:change={() => change('label', project.label)} />
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<StyledTextBox
|
||||
|
@ -64,19 +64,12 @@
|
||||
<SpaceSelector _class={tracker.class.Team} label={tracker.string.Team} bind:space />
|
||||
</svelte:fragment>
|
||||
<div class="label">
|
||||
<EditBox
|
||||
bind:value={object.label}
|
||||
placeholder={tracker.string.ProjectNamePlaceholder}
|
||||
maxWidth="37.5rem"
|
||||
kind="large-style"
|
||||
focus
|
||||
/>
|
||||
<EditBox bind:value={object.label} placeholder={tracker.string.ProjectNamePlaceholder} kind="large-style" focus />
|
||||
</div>
|
||||
<div class="description">
|
||||
<EditBox
|
||||
bind:value={object.description}
|
||||
placeholder={tracker.string.ProjectDescriptionPlaceholder}
|
||||
maxWidth="37.5rem"
|
||||
kind="editbox"
|
||||
/>
|
||||
</div>
|
||||
|
@ -77,7 +77,7 @@
|
||||
<svelte:fragment slot="aside">
|
||||
<div class="flex-grow p-4 w-60 left-divider">
|
||||
<div class="fs-title text-xl">
|
||||
<EditBox bind:value={sprint.label} maxWidth="39rem" on:change={() => change('label', sprint.label)} />
|
||||
<EditBox bind:value={sprint.label} on:change={() => change('label', sprint.label)} />
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<StyledTextBox
|
||||
|
@ -61,19 +61,12 @@
|
||||
<SpaceSelector _class={tracker.class.Team} label={tracker.string.Team} bind:space />
|
||||
</svelte:fragment>
|
||||
<div class="label">
|
||||
<EditBox
|
||||
bind:value={object.label}
|
||||
placeholder={tracker.string.ProjectNamePlaceholder}
|
||||
maxWidth="37.5rem"
|
||||
kind="large-style"
|
||||
focus
|
||||
/>
|
||||
<EditBox bind:value={object.label} placeholder={tracker.string.ProjectNamePlaceholder} kind="large-style" focus />
|
||||
</div>
|
||||
<div class="description">
|
||||
<EditBox
|
||||
bind:value={object.description}
|
||||
placeholder={tracker.string.ProjectDescriptionPlaceholder}
|
||||
maxWidth="37.5rem"
|
||||
kind="editbox"
|
||||
/>
|
||||
</div>
|
||||
|
@ -23,7 +23,6 @@
|
||||
export let format: 'text' | 'password' | 'number'
|
||||
export let placeholder: IntlString
|
||||
export let kind: EditStyle = 'search-style'
|
||||
export let maxWidth: string = '10rem'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@ -34,6 +33,6 @@
|
||||
|
||||
<div class="selectPopup">
|
||||
<div class="header no-border">
|
||||
<EditBox bind:value {placeholder} {format} {kind} {maxWidth} focus on:keypress={_onkeypress} />
|
||||
<EditBox bind:value {placeholder} {format} {kind} focus on:keypress={_onkeypress} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -337,7 +337,7 @@
|
||||
|
||||
{#each fieldEditors as collection}
|
||||
{#if collection.editor}
|
||||
<div class="mt-6">
|
||||
<div class="mt-6 clear-mins">
|
||||
<Component
|
||||
is={collection.editor}
|
||||
props={{
|
||||
|
@ -61,5 +61,5 @@
|
||||
</script>
|
||||
|
||||
{#if loaded}
|
||||
<Menu {actions} on:close on:changeContent={() => dispatch('changeContent', true)} />
|
||||
<Menu {actions} on:close on:changeContent={() => dispatch('changeContent')} />
|
||||
{/if}
|
||||
|
@ -22,7 +22,6 @@
|
||||
export let placeholder: IntlString
|
||||
export let value: number
|
||||
export let focus: boolean
|
||||
export let maxWidth: string = '10rem'
|
||||
export let onChange: (value: number) => void
|
||||
export let kind: 'no-border' | 'link' = 'no-border'
|
||||
export let readonly = false
|
||||
@ -62,7 +61,7 @@
|
||||
<span class="dark-color"><Label label={placeholder} /></span>
|
||||
{/if}
|
||||
{:else}
|
||||
<EditBox {placeholder} {maxWidth} bind:value format={'number'} {focus} on:change={_onchange} />
|
||||
<EditBox {placeholder} bind:value format={'number'} {focus} on:change={_onchange} />
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -22,7 +22,6 @@
|
||||
export let placeholder: IntlString
|
||||
export let value: string
|
||||
export let focus: boolean
|
||||
export let maxWidth: string = '10rem'
|
||||
export let onChange: (value: string) => void
|
||||
export let kind: 'no-border' | 'link' = 'no-border'
|
||||
export let readonly = false
|
||||
@ -62,7 +61,7 @@
|
||||
<span class="dark-color"><Label label={placeholder} /></span>
|
||||
{/if}
|
||||
{:else}
|
||||
<EditBox {placeholder} {maxWidth} bind:value {focus} on:change={_onchange} />
|
||||
<EditBox {placeholder} bind:value {focus} on:change={_onchange} />
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user