mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 02:51:54 +03:00
UBERF-4205: updated Panel header layout, custom aside (#3974)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
d5a7280f15
commit
4c3ba1fbc4
@ -296,7 +296,7 @@ export function createModel (builder: Builder): void {
|
||||
builder,
|
||||
{
|
||||
action: view.actionImpl.ShowPanel,
|
||||
actionProps: {},
|
||||
actionProps: { element: 'content' },
|
||||
label: view.string.Open,
|
||||
icon: view.icon.Open,
|
||||
keyBinding: ['e'],
|
||||
@ -353,7 +353,7 @@ export function createModel (builder: Builder): void {
|
||||
builder,
|
||||
{
|
||||
action: view.actionImpl.ShowPanel,
|
||||
actionProps: {},
|
||||
actionProps: { element: 'content' },
|
||||
label: view.string.Open,
|
||||
icon: view.icon.Open,
|
||||
keyBinding: ['e'],
|
||||
|
@ -14,25 +14,15 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { afterUpdate } from 'svelte'
|
||||
import { afterUpdate, createEventDispatcher } from 'svelte'
|
||||
import { Writable, writable } from 'svelte/store'
|
||||
|
||||
import activity from '@hcengineering/activity'
|
||||
import calendar from '@hcengineering/calendar'
|
||||
import { Doc } from '@hcengineering/core'
|
||||
import { Asset } from '@hcengineering/platform'
|
||||
import {
|
||||
AnySvelteComponent,
|
||||
Component,
|
||||
deviceOptionsStore as deviceInfo,
|
||||
Icon,
|
||||
Panel,
|
||||
Scroller
|
||||
} from '@hcengineering/ui'
|
||||
import { Component, deviceOptionsStore as deviceInfo, Panel, Scroller } from '@hcengineering/ui'
|
||||
import type { ButtonItem } from '@hcengineering/ui'
|
||||
|
||||
export let title: string | undefined = undefined
|
||||
export let subtitle: string | undefined = undefined
|
||||
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
||||
export let withoutActivity: boolean = false
|
||||
export let withoutInput: boolean = false
|
||||
export let withoutTitle: boolean = false
|
||||
@ -44,21 +34,30 @@
|
||||
export let isAside: boolean = true
|
||||
export let isUtils: boolean = true
|
||||
export let isCustomAttr: boolean = true
|
||||
export let isReminder: boolean = true
|
||||
export let floatAside = false
|
||||
export let allowBack = true
|
||||
export let allowClose = true
|
||||
export let floatAside: boolean = false
|
||||
export let allowClose: boolean = true
|
||||
export let useMaxWidth: boolean | undefined = undefined
|
||||
export let isFullSize = false
|
||||
export let embedded = false
|
||||
export let isFullSize: boolean = false
|
||||
export let contentClasses: string | undefined = undefined
|
||||
export let content: HTMLElement | undefined | null = undefined
|
||||
export let withoutContentScroll: boolean = false
|
||||
export let customAside: ButtonItem[] | undefined = undefined
|
||||
export let selectedAside: string | false = customAside ? customAside[0].id : false
|
||||
|
||||
export function getAside (): string | false {
|
||||
return selectedAside
|
||||
}
|
||||
export function setAside (id: string | boolean): void {
|
||||
panel.setAside(id)
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let lastHref: string
|
||||
let timer: any
|
||||
let lastScrollHeight: number = -1
|
||||
let count: number = 0
|
||||
let panel: Panel
|
||||
|
||||
const waitCount = 10
|
||||
const PanelScrollTop: Writable<Record<string, number>> = writable<Record<string, number>>({})
|
||||
@ -93,6 +92,7 @@
|
||||
</script>
|
||||
|
||||
<Panel
|
||||
bind:this={panel}
|
||||
bind:isAside
|
||||
{isHeader}
|
||||
bind:panelWidth
|
||||
@ -100,53 +100,33 @@
|
||||
bind:withoutTitle
|
||||
on:open
|
||||
on:close
|
||||
{allowBack}
|
||||
{allowClose}
|
||||
{floatAside}
|
||||
{embedded}
|
||||
bind:useMaxWidth
|
||||
{isFullSize}
|
||||
{customAside}
|
||||
bind:selectedAside
|
||||
on:select={(result) => {
|
||||
selectedAside = result.detail
|
||||
dispatch('select', result.detail)
|
||||
}}
|
||||
>
|
||||
<svelte:fragment slot="navigator">
|
||||
{#if $$slots.navigator}
|
||||
<div class="flex-row-center flex-gap-1-5 mx-2">
|
||||
<slot name="navigator" />
|
||||
</div>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="title">
|
||||
{#if !withoutTitle}
|
||||
<div class="popupPanel-title__content-container antiTitle">
|
||||
{#if $$slots.title}
|
||||
<slot name="title" />
|
||||
{:else}
|
||||
<div class="icon-wrapper">
|
||||
{#if icon}<div class="wrapped-icon"><Icon {icon} size={'medium'} /></div>{/if}
|
||||
<div class="title-wrapper">
|
||||
{#if title}<span class="wrapped-title">{title}</span>{/if}
|
||||
{#if subtitle || $$slots.subtitle}
|
||||
<span class="wrapped-subtitle">
|
||||
{#if subtitle}
|
||||
{subtitle}
|
||||
{/if}
|
||||
<slot name="subtitle" />
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if $$slots.title}
|
||||
<slot name="title" />
|
||||
{:else if title}
|
||||
<div class="title not-active">{title}</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="utils">
|
||||
<svelte:fragment slot="pre-utils">
|
||||
<slot name="pre-utils" />
|
||||
{#if isReminder}
|
||||
<Component is={calendar.component.DocReminder} props={{ value: object, title, focusIndex: 9000 }} />
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="utils">
|
||||
{#if isUtils && $$slots.utils}
|
||||
<div class="buttons-divider" />
|
||||
<!-- <div class="buttons-divider" /> -->
|
||||
<slot name="utils" />
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
@ -202,7 +182,7 @@
|
||||
{#key object._id}
|
||||
<Component
|
||||
is={activity.component.Activity}
|
||||
props={{ object, showCommenInput: !withoutInput, shouldScroll: embedded, focusIndex: 1000 }}
|
||||
props={{ object, showCommenInput: !withoutInput, shouldScroll: true, focusIndex: 1000 }}
|
||||
/>
|
||||
{/key}
|
||||
{/if}
|
||||
@ -221,7 +201,7 @@
|
||||
props={{
|
||||
object,
|
||||
showCommenInput: !withoutInput,
|
||||
shouldScroll: embedded,
|
||||
shouldScroll: true,
|
||||
focusIndex: 1000,
|
||||
boundary: content
|
||||
}}
|
||||
@ -247,7 +227,7 @@
|
||||
props={{
|
||||
object,
|
||||
showCommenInput: !withoutInput,
|
||||
shouldScroll: embedded,
|
||||
shouldScroll: true,
|
||||
focusIndex: 1000,
|
||||
boundary: content
|
||||
}}
|
||||
|
@ -13,55 +13,52 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Component, ScrollerBar, getPlatformColor, themeStore } from '@hcengineering/ui'
|
||||
import { Component, SelectPopup, showPopup } from '@hcengineering/ui'
|
||||
import type { MouseTargetEvent } from '@hcengineering/ui'
|
||||
import { NavLink } from '../..'
|
||||
import BreadcrumbsElement from './BreadcrumbsElement.svelte'
|
||||
import { BreadcrumbsModel } from './types'
|
||||
import { hasComponent } from './utils'
|
||||
|
||||
export let models: readonly BreadcrumbsModel[]
|
||||
export let gap: 'none' | 'small' | 'big' = 'small'
|
||||
|
||||
let scroller: HTMLElement
|
||||
$: trimmed = models.length > 3
|
||||
$: narrowModel = trimmed ? [models[0], models[models.length - 1]] : models
|
||||
|
||||
function getPosition (position: number): 'start' | 'end' | 'middle' {
|
||||
if (position === 0) {
|
||||
return 'start'
|
||||
}
|
||||
|
||||
if (position === models.length - 1) {
|
||||
return 'end'
|
||||
}
|
||||
|
||||
return 'middle'
|
||||
const handleMenuOpened = (event: MouseTargetEvent) => {
|
||||
event.preventDefault()
|
||||
const items = models.slice(1, -1).map((m, i) => {
|
||||
if (hasComponent(m)) {
|
||||
const { component, props } = m
|
||||
return { id: i, component, props }
|
||||
} else {
|
||||
const { title } = m
|
||||
return { id: i, text: title }
|
||||
}
|
||||
})
|
||||
showPopup(SelectPopup, { value: items }, event.currentTarget)
|
||||
}
|
||||
</script>
|
||||
|
||||
<ScrollerBar {gap} bind:scroller>
|
||||
{#each models as model, i}
|
||||
{@const { color } = model}
|
||||
{#if hasComponent(model)}
|
||||
{@const { component, props } = model}
|
||||
<BreadcrumbsElement
|
||||
position={getPosition(i)}
|
||||
color={color !== undefined ? getPlatformColor(color, $themeStore.dark) : 'var(--accent-bg-color)'}
|
||||
>
|
||||
{#if typeof component === 'string'}
|
||||
<Component is={component} {props} />
|
||||
{:else}
|
||||
<svelte:component this={component} {...props} />
|
||||
{/if}
|
||||
</BreadcrumbsElement>
|
||||
{:else}
|
||||
{@const { title, href, onClick } = model}
|
||||
<NavLink {href} noUnderline {onClick}>
|
||||
<BreadcrumbsElement
|
||||
label={title}
|
||||
{title}
|
||||
position={getPosition(i)}
|
||||
color={color !== undefined ? getPlatformColor(color, $themeStore.dark) : 'var(--accent-bg-color)'}
|
||||
/>
|
||||
</NavLink>
|
||||
{/if}
|
||||
{/each}
|
||||
</ScrollerBar>
|
||||
{#each narrowModel as model, i}
|
||||
{#if hasComponent(model)}
|
||||
{@const { component, props } = model}
|
||||
<div class="title">
|
||||
{#if typeof component === 'string'}
|
||||
<Component is={component} {props} />
|
||||
{:else}
|
||||
<svelte:component this={component} {...props} />
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
{@const { title, href, onClick } = model}
|
||||
<NavLink {href} noUnderline {onClick}>
|
||||
<div class="title">{title}</div>
|
||||
</NavLink>
|
||||
{/if}
|
||||
<div class="title disabled">/</div>
|
||||
{#if trimmed && i === 0}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="title" on:click={handleMenuOpened}>...</div>
|
||||
<div class="title disabled">/</div>
|
||||
{/if}
|
||||
{/each}
|
||||
|
@ -102,6 +102,13 @@
|
||||
--theme-button-disabled: transparent;
|
||||
--theme-button-border: rgba(255, 255, 255, .09);
|
||||
|
||||
--theme-breadcrumb-default: rgba(255, 255, 255, 0);
|
||||
--theme-breadcrumb-hovered: rgba(255, 255, 255, .08);
|
||||
--theme-breadcrumb-pressed: rgba(255, 255, 255, .1);
|
||||
--theme-button-icon-default: rgba(255, 255, 255, 0);
|
||||
--theme-button-icon-hovered: rgba(255, 255, 255, .06);
|
||||
--theme-button-icon-pressed: rgba(255, 255, 255, .1);
|
||||
|
||||
--theme-button-contrast-color: #000;
|
||||
--theme-button-contrast-enabled: rgba(255, 255, 255, .8);
|
||||
--theme-button-contrast-hovered: #fff;
|
||||
@ -320,6 +327,13 @@
|
||||
--theme-button-disabled: rgba(0, 0, 0, .08);
|
||||
--theme-button-border: rgba(0, 0, 0, .09);
|
||||
|
||||
--theme-breadcrumb-default: rgba(0, 0, 0, 0);
|
||||
--theme-breadcrumb-hovered: rgba(0, 0, 0, .08);
|
||||
--theme-breadcrumb-pressed: rgba(0, 0, 0, .1);
|
||||
--theme-button-icon-default: rgba(0, 0, 0, 0);
|
||||
--theme-button-icon-hovered: rgba(0, 0, 0, .06);
|
||||
--theme-button-icon-pressed: rgba(0, 0, 0, .1);
|
||||
|
||||
--theme-button-contrast-color: #fff;
|
||||
--theme-button-contrast-enabled: rgba(0, 0, 0, .8);
|
||||
--theme-button-contrast-hovered: #000;
|
||||
|
@ -483,6 +483,7 @@ input.search {
|
||||
.ml-12 { margin-left: 3rem; }
|
||||
.ml-22 { margin-left: 5.5rem; }
|
||||
.ml-auto { margin-left: auto; }
|
||||
.mr-0-5 { margin-right: .125rem; }
|
||||
.mr-1 { margin-right: .25rem; }
|
||||
.mr-1-5 { margin-right: .375rem; }
|
||||
.mr-2 { margin-right: .5rem; }
|
||||
|
@ -343,4 +343,16 @@
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
&:focus { z-index: 1; }
|
||||
&.icon {
|
||||
background-color: var(--theme-button-icon-default);
|
||||
|
||||
.btn-icon { color: var(--theme-dark-color); }
|
||||
|
||||
&:hover, &:focus, &.selected { background-color: var(--theme-button-icon-hovered); }
|
||||
&:active { background-color: var(--theme-button-icon-pressed); }
|
||||
&:hover, &:focus, &.selected, &:active {
|
||||
.btn-icon { color: var(--theme-caption-color); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@
|
||||
::-webkit-scrollbar:horizontal {
|
||||
height: 6px;
|
||||
}
|
||||
::-webkit-scrollbar-track, .panel-container .scroll .scroll::-webkit-scrollbar-track {
|
||||
::-webkit-scrollbar-track, .panel-instance .scroll .scroll::-webkit-scrollbar-track {
|
||||
margin: 6px;
|
||||
// background-color: var(--scrollbar-bar-color);
|
||||
}
|
||||
|
@ -77,54 +77,49 @@
|
||||
.popupPanel {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
&.rowContent {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
&:not(.rowContent) { flex-direction: column; }
|
||||
&.embedded { width: 100%; }
|
||||
&:not(.embedded) { border-radius: .5rem; }
|
||||
|
||||
.popupPanel-title {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
justify-content: stretch;
|
||||
align-items: center;
|
||||
padding: 0 1rem 0 1.25rem;
|
||||
min-width: 0;
|
||||
min-height: 3.25rem;
|
||||
background-color: var(--theme-comp-header-color);
|
||||
border-bottom: 1px solid var(--theme-divider-color);
|
||||
|
||||
&.row {
|
||||
padding: .5rem .75rem;
|
||||
width: 100%;
|
||||
|
||||
&-top { margin: .5rem .75rem .125rem; }
|
||||
&-bottom { margin: .5rem .75rem .5rem 1.25rem; }
|
||||
}
|
||||
&__bordered {
|
||||
min-width: 0;
|
||||
min-height: 3.25rem;
|
||||
background-color: var(--theme-comp-header-color);
|
||||
&:not(.embedded) {
|
||||
border: 1px solid var(--theme-divider-color);
|
||||
border-bottom: none;
|
||||
border-radius: .5rem .5rem 0 0;
|
||||
}
|
||||
&.embedded {
|
||||
border-bottom: 1px solid var(--theme-divider-color);
|
||||
}
|
||||
}
|
||||
&__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
margin: 0 .75rem;
|
||||
margin-right: .75rem;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
&-container {
|
||||
display: flex;
|
||||
justify-content: stretch;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
.title {
|
||||
padding: .125rem .375rem;
|
||||
font-size: .8125rem;
|
||||
color: var(--theme-content-color);
|
||||
background-color: var(--theme-breadcrumb-default);
|
||||
border-radius: .25rem;
|
||||
|
||||
&:not(:last-child) { margin-right: .125rem; }
|
||||
&:not(.disabled, .not-active) {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover, &:focus { background-color: var(--theme-breadcrumb-hovered); }
|
||||
&:active { background-color: var(--theme-breadcrumb-pressed); }
|
||||
&:hover, &:focus, &:active { color: var(--theme-caption-color); }
|
||||
}
|
||||
&.disabled { color: var(--theme-dark-color); }
|
||||
&.not-active { color: var(--theme-caption-color); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,13 +133,8 @@
|
||||
height: 100%;
|
||||
background-color: var(--theme-panel-color);
|
||||
border: 1px solid var(--theme-divider-color);
|
||||
&:not(.embedded) {
|
||||
border-radius: 0 0 .5rem .5rem;
|
||||
}
|
||||
&.embedded {
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
}
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
|
||||
&.main {
|
||||
justify-content: stretch;
|
||||
|
48
packages/ui/src/components/ButtonGroup.svelte
Normal file
48
packages/ui/src/components/ButtonGroup.svelte
Normal file
@ -0,0 +1,48 @@
|
||||
<!--
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import type { ButtonItem } from '..'
|
||||
import Button from './Button.svelte'
|
||||
|
||||
export let items: ButtonItem[]
|
||||
export let selected: string | false = false
|
||||
export let allowDeselected: boolean = true
|
||||
export let mode: 'filled-icon' | 'highlighted' | 'selected' = 'selected'
|
||||
export let props: any = {}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const select = (value: string | false): void => {
|
||||
selected = value
|
||||
dispatch('select', value)
|
||||
}
|
||||
</script>
|
||||
|
||||
{#each items as item}
|
||||
{@const isSelect = selected === item.id}
|
||||
<Button
|
||||
{...item}
|
||||
id={`btnGID-${item.id}`}
|
||||
iconProps={mode === 'filled-icon' && isSelect ? { filled: true } : {}}
|
||||
selected={mode === 'selected' ? isSelect : false}
|
||||
highlight={mode === 'highlighted' ? isSelect : false}
|
||||
{...props}
|
||||
on:click={() => {
|
||||
if (!isSelect) select(item.id)
|
||||
else if (allowDeselected) select(false)
|
||||
}}
|
||||
/>
|
||||
{/each}
|
@ -16,14 +16,14 @@
|
||||
import { afterUpdate, createEventDispatcher, onMount } from 'svelte'
|
||||
import {
|
||||
deviceOptionsStore as deviceInfo,
|
||||
checkAdaptiveMatching,
|
||||
IconBack,
|
||||
Separator,
|
||||
defineSeparators,
|
||||
resizeObserver,
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Scroller,
|
||||
panelSeparators
|
||||
panelSeparators,
|
||||
ButtonItem
|
||||
} from '../../'
|
||||
import IconClose from './icons/Close.svelte'
|
||||
import IconDetails from './icons/Details.svelte'
|
||||
@ -38,21 +38,35 @@
|
||||
export let isAside: boolean = true
|
||||
export let isFullSize: boolean = false
|
||||
export let withoutTitle: boolean = false
|
||||
export let floatAside = false
|
||||
export let allowBack = true
|
||||
export let allowClose = true
|
||||
export let floatAside: boolean = false
|
||||
export let allowClose: boolean = true
|
||||
export let useMaxWidth: boolean | undefined = undefined
|
||||
export let embedded = false
|
||||
export let customAside: ButtonItem[] | undefined = undefined
|
||||
export let selectedAside: string | false = customAside ? customAside[0].id : false
|
||||
|
||||
export function getAside (): string | false {
|
||||
return selectedAside
|
||||
}
|
||||
export function setAside (id: string | boolean): void {
|
||||
if (typeof id === 'string' && customAside) {
|
||||
const i = customAside.findIndex((as) => as.id === id)
|
||||
if (i === -1) return
|
||||
handleSelectAside({ detail: id } as CustomEvent<any>)
|
||||
} else {
|
||||
asideShown = id as boolean
|
||||
hideAside = !asideShown
|
||||
if (id === false) selectedAside = false
|
||||
}
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let asideFloat: boolean = false
|
||||
let asideShown: boolean = true
|
||||
let hideAside: boolean = false
|
||||
let fullSize: boolean = false
|
||||
|
||||
$: devSize = $deviceInfo.size
|
||||
$: twoRows = checkAdaptiveMatching(devSize, 'xs')
|
||||
$: moveUtils = checkAdaptiveMatching(devSize, 'sm')
|
||||
let oldAside: string | false = selectedAside
|
||||
$: if (typeof selectedAside === 'string' && oldAside !== selectedAside) oldAside = selectedAside
|
||||
|
||||
let oldWidth = ''
|
||||
let hideTimer: any | undefined
|
||||
@ -69,13 +83,13 @@
|
||||
asideFloat = true
|
||||
if (asideShown) {
|
||||
asideShown = false
|
||||
if (customAside) handleSelectAside({ detail: false } as CustomEvent<any>, false)
|
||||
}
|
||||
} else if (panelWidth > 900) {
|
||||
if (asideFloat) {
|
||||
asideFloat = false
|
||||
}
|
||||
if (!asideShown) {
|
||||
if (asideFloat) asideFloat = false
|
||||
if (!asideShown && !hideAside) {
|
||||
asideShown = true
|
||||
if (customAside) handleSelectAside({ detail: oldAside } as CustomEvent<any>, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,100 +105,94 @@
|
||||
onMount(() => dispatch('open'))
|
||||
|
||||
defineSeparators('panel-aside', panelSeparators)
|
||||
|
||||
const handleAside = (): void => {
|
||||
asideShown = !asideShown
|
||||
hideAside = !asideShown
|
||||
}
|
||||
const handleSelectAside = (result: CustomEvent<any>, sw: boolean = true): void => {
|
||||
selectedAside = result.detail
|
||||
if (sw) {
|
||||
asideShown = selectedAside !== false
|
||||
hideAside = !asideShown
|
||||
}
|
||||
dispatch('select', result.detail)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="popupPanel panel"
|
||||
class:embedded
|
||||
use:resizeObserver={(element) => {
|
||||
panelWidth = element.clientWidth
|
||||
checkPanel()
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="popupPanel-title__bordered {twoRows && !withoutTitle ? 'flex-col flex-no-shrink' : 'flex-row-center'}"
|
||||
class:embedded
|
||||
>
|
||||
<div class="popupPanel-title {twoRows && !withoutTitle ? 'row-top' : 'row'}">
|
||||
{#if allowBack}
|
||||
<div class="popupPanel-title">
|
||||
<div class="popupPanel-title__content">
|
||||
{#if !withoutTitle}<slot name="title" />{/if}
|
||||
</div>
|
||||
<slot name="pre-utils" />
|
||||
<div class="flex-row-center ml-3">
|
||||
<slot name="utils" />
|
||||
{#if $$slots.aside && isAside}
|
||||
{#if customAside}
|
||||
<ButtonGroup
|
||||
items={customAside}
|
||||
props={{ kind: 'icon', iconProps: { size: 'medium' } }}
|
||||
bind:selected={selectedAside}
|
||||
on:select={handleSelectAside}
|
||||
/>
|
||||
{:else}
|
||||
<Button
|
||||
focusIndex={10008}
|
||||
icon={IconDetails}
|
||||
iconProps={{ size: 'medium', filled: asideShown }}
|
||||
kind={'icon'}
|
||||
selected={asideShown}
|
||||
on:click={handleAside}
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if useMaxWidth !== undefined}
|
||||
<Button
|
||||
focusIndex={10000}
|
||||
icon={IconBack}
|
||||
kind={'ghost'}
|
||||
size={'medium'}
|
||||
focusIndex={10009}
|
||||
icon={useMaxWidth ? IconMaxWidth : IconMinWidth}
|
||||
iconProps={{ size: 'medium' }}
|
||||
kind={'icon'}
|
||||
selected={useMaxWidth}
|
||||
on:click={() => {
|
||||
history.back()
|
||||
useMaxWidth = !useMaxWidth
|
||||
dispatch('maxWidth', useMaxWidth)
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{#if isFullSize}
|
||||
<Button
|
||||
focusIndex={100010}
|
||||
icon={fullSize ? IconScale : IconScaleFull}
|
||||
iconProps={{ size: 'medium' }}
|
||||
kind={'icon'}
|
||||
selected={fullSize}
|
||||
on:click={() => {
|
||||
fullSize = !fullSize
|
||||
dispatch('fullsize')
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{#if allowClose}
|
||||
<div class="antiHSpacer" />
|
||||
<Button
|
||||
focusIndex={10001}
|
||||
icon={IconClose}
|
||||
kind={'ghost'}
|
||||
size={'medium'}
|
||||
iconProps={{ size: 'medium' }}
|
||||
kind={'icon'}
|
||||
on:click={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{#if $$slots.navigator}<slot name="navigator" />{/if}
|
||||
<div class="popupPanel-title__content">
|
||||
{#if !twoRows && !withoutTitle}<slot name="title" />{/if}
|
||||
</div>
|
||||
<div class="buttons-group xsmall-gap">
|
||||
{#if !moveUtils}
|
||||
<slot name="utils" />
|
||||
{/if}
|
||||
{#if isFullSize || useMaxWidth !== undefined || ($$slots.aside && isAside)}
|
||||
<div class="buttons-divider" />
|
||||
{/if}
|
||||
{#if $$slots.aside && isAside}
|
||||
<Button
|
||||
focusIndex={10008}
|
||||
icon={IconDetails}
|
||||
kind={'ghost'}
|
||||
size={'medium'}
|
||||
selected={asideShown}
|
||||
on:click={() => {
|
||||
asideShown = !asideShown
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{#if useMaxWidth !== undefined}
|
||||
<Button
|
||||
focusIndex={10009}
|
||||
icon={useMaxWidth ? IconMaxWidth : IconMinWidth}
|
||||
kind={'ghost'}
|
||||
size={'medium'}
|
||||
selected={useMaxWidth}
|
||||
on:click={() => {
|
||||
useMaxWidth = !useMaxWidth
|
||||
dispatch('maxWidth', useMaxWidth)
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{#if isFullSize}
|
||||
<Button
|
||||
focusIndex={100010}
|
||||
icon={fullSize ? IconScale : IconScaleFull}
|
||||
kind={'ghost'}
|
||||
size={'medium'}
|
||||
selected={fullSize}
|
||||
on:click={() => {
|
||||
fullSize = !fullSize
|
||||
dispatch('fullsize')
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if twoRows && !withoutTitle}
|
||||
<div class="popupPanel-title row-bottom"><slot name="title" /></div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="popupPanel-body {$deviceInfo.isMobile ? 'mobile' : 'main'}" class:asideShown class:embedded>
|
||||
<div class="popupPanel-body {$deviceInfo.isMobile ? 'mobile' : 'main'}" class:asideShown>
|
||||
{#if $deviceInfo.isMobile}
|
||||
<Scroller horizontal padding={'.5rem .75rem'}>
|
||||
<div
|
||||
@ -223,11 +231,6 @@
|
||||
<div class="popupPanel-body__aside" class:float={asideFloat} class:shown={asideShown}>
|
||||
<Separator name={'panel-aside'} float={asideFloat ? 'aside' : true} index={0} />
|
||||
<div class="antiPanel-wrap__content">
|
||||
{#if moveUtils}
|
||||
<div class="buttons-group justify-end xsmall-gap" style:margin={'.5rem 2rem 0'}>
|
||||
<slot name="utils" />
|
||||
</div>
|
||||
{/if}
|
||||
<slot name="aside" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -143,7 +143,6 @@
|
||||
<slot name="panel-header" />
|
||||
<div
|
||||
class="panel-instance"
|
||||
class:bg={false}
|
||||
bind:this={modalHTML}
|
||||
style:top={options?.props?.top}
|
||||
style:bottom={options?.props?.bottom}
|
||||
@ -156,20 +155,18 @@
|
||||
style:min-width={options?.props?.minWidth}
|
||||
style:transform={options?.props?.transform}
|
||||
>
|
||||
<div class="panel-container" class:padding={props.element === 'content'}>
|
||||
<svelte:component
|
||||
this={component}
|
||||
bind:this={componentInstance}
|
||||
_id={props._id}
|
||||
_class={props._class}
|
||||
rightSection={props.rightSection}
|
||||
position={props.element}
|
||||
bind:popupOptions={options}
|
||||
on:open={_open}
|
||||
on:close={_close}
|
||||
on:update={_update}
|
||||
/>
|
||||
</div>
|
||||
<svelte:component
|
||||
this={component}
|
||||
bind:this={componentInstance}
|
||||
_id={props._id}
|
||||
_class={props._class}
|
||||
rightSection={props.rightSection}
|
||||
position={props.element}
|
||||
bind:popupOptions={options}
|
||||
on:open={_open}
|
||||
on:close={_close}
|
||||
on:update={_update}
|
||||
/>
|
||||
</div>
|
||||
{#if props.element !== 'content'}
|
||||
<div
|
||||
@ -188,19 +185,6 @@
|
||||
z-index: 401;
|
||||
position: fixed;
|
||||
background-color: transparent;
|
||||
|
||||
&.bg {
|
||||
background-color: var(--theme-back-color);
|
||||
}
|
||||
.panel-container {
|
||||
padding: 0.5rem;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
&.padding {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
|
@ -437,8 +437,12 @@
|
||||
|
||||
const checkSibling = (start: boolean = false): void => {
|
||||
if (separator === null) return
|
||||
if (prevElement === null || start) prevElement = separator.previousElementSibling as HTMLElement
|
||||
if (nextElement === null || start) nextElement = separator.nextElementSibling as HTMLElement
|
||||
if ((prevElement === null || start) && separator) {
|
||||
prevElement = separator.previousElementSibling as HTMLElement
|
||||
}
|
||||
if ((nextElement === null || start) && separator) {
|
||||
nextElement = separator.nextElementSibling as HTMLElement
|
||||
}
|
||||
if (separators && prevElement && separators[index].float !== undefined) {
|
||||
prevElement.setAttribute('data-float', separators[index].float ?? '')
|
||||
}
|
||||
@ -447,7 +451,7 @@
|
||||
}
|
||||
}
|
||||
const checkParent = (): void => {
|
||||
if (parentElement === null) parentElement = separator.parentElement as HTMLElement
|
||||
if (parentElement === null && separator) parentElement = separator.parentElement as HTMLElement
|
||||
if (parentElement && typeof float === 'string') parentElement.setAttribute('data-float', float)
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
export let fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M3.14645 3.14645C2.95118 3.34171 2.95118 3.65829 3.14645 3.85355L7.29289 8L3.14645 12.1464C2.95118 12.3417 2.95118 12.6583 3.14645 12.8536C3.34171 13.0488 3.65829 13.0488 3.85355 12.8536L8 8.70711L12.1464 12.8536C12.3417 13.0488 12.6583 13.0488 12.8536 12.8536C13.0488 12.6583 13.0488 12.3417 12.8536 12.1464L8.70711 8L12.8536 3.85355C13.0488 3.65829 13.0488 3.34171 12.8536 3.14645C12.6583 2.95118 12.3417 2.95118 12.1464 3.14645L8 7.29289L3.85355 3.14645C3.65829 2.95118 3.34171 2.95118 3.14645 3.14645Z"
|
||||
d="M6.29289 6.29338C5.90237 6.68391 5.90237 7.31707 6.29289 7.70759L14.5858 16.0005L6.29289 24.2934C5.90237 24.6839 5.90237 25.3171 6.29289 25.7076C6.68342 26.0981 7.31658 26.0981 7.70711 25.7076L16 17.4147L24.2929 25.7076C24.6834 26.0981 25.3166 26.0981 25.7071 25.7076C26.0976 25.3171 26.0976 24.6839 25.7071 24.2934L17.4142 16.0005L25.7071 7.70759C26.0976 7.31707 26.0976 6.68391 25.7071 6.29338C25.3166 5.90286 24.6834 5.90286 24.2929 6.29338L16 14.5863L7.70711 6.29338C7.31658 5.90286 6.68342 5.90286 6.29289 6.29338Z"
|
||||
/>
|
||||
</svg>
|
||||
|
@ -15,14 +15,22 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
export let size: 'x-small' | 'small' | 'medium' | 'large'
|
||||
export let filled: boolean = false
|
||||
const fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 4.25 2 C 2.45508 2 1 3.45508 1 5.25 V 10.7499 C 1 12.5449 2.45508 13.9999 4.25 13.9999 H 11.75 C 13.5449 13.9999 15 12.5449 15 10.7499 V 5.25 C 15 3.45508 13.5449 2 11.75 2 H 4.25 Z M 2.5 10.4999 C 2.5 11.6045 3.39543 12.4999 4.5 12.4999 H 11.75 C 12.7165 12.4999 13.5 11.7164 13.5 10.7499 V 5.25 C 13.5 4.28351 12.7165 3.5 11.75 3.5 H 4.5 C 3.39543 3.5 2.5 4.39543 2.5 5.5 V 10.4999 Z"
|
||||
/>
|
||||
<rect x="9" y="3" width="1.5" height="10" />
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
{#if filled}
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M2 8.00049C2 5.79135 3.79086 4.00049 6 4.00049H26C28.2091 4.00049 30 5.79135 30 8.00049V24.0005C30 26.2096 28.2091 28.0005 26 28.0005H6C3.79086 28.0005 2 26.2096 2 24.0005V8.00049ZM20 6.00049H6C4.89543 6.00049 4 6.89592 4 8.00049V24.0005C4 25.1051 4.89543 26.0005 6 26.0005H20V6.00049Z"
|
||||
/>
|
||||
{:else}
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M2 8.00049C2 5.79135 3.79086 4.00049 6 4.00049H26C28.2091 4.00049 30 5.79135 30 8.00049V24.0005C30 26.2096 28.2091 28.0005 26 28.0005H6C3.79086 28.0005 2 26.2096 2 24.0005V8.00049ZM20 6.00049H6C4.89543 6.00049 4 6.89592 4 8.00049V24.0005C4 25.1051 4.89543 26.0005 6 26.0005H20V6.00049ZM22 26.0002V6.00049H26C27.1046 6.00049 28 6.89592 28 8.00049V24.0002C28 25.1048 27.1046 26.0002 26 26.0002H22Z"
|
||||
/>
|
||||
{/if}
|
||||
</svg>
|
||||
|
@ -18,10 +18,10 @@
|
||||
const fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M1 5.25C1 3.45508 2.45508 2 4.25 2H11.75C13.5449 2 15 3.45508 15 5.25V10.7499C15 12.5449 13.5449 13.9999 11.75 13.9999H4.25C2.45508 13.9999 1 12.5449 1 10.7499V5.25ZM4.5 12.4999C3.39543 12.4999 2.5 11.6045 2.5 10.4999V5.5C2.5 4.39543 3.39543 3.5 4.5 3.5H9V12.4999H4.5Z"
|
||||
d="M2 8.00049C2 5.79135 3.79086 4.00049 6 4.00049H26C28.2091 4.00049 30 5.79135 30 8.00049V24.0005C30 26.2096 28.2091 28.0005 26 28.0005H6C3.79086 28.0005 2 26.2096 2 24.0005V8.00049ZM20 6.00049H6C4.89543 6.00049 4 6.89592 4 8.00049V24.0005C4 25.1051 4.89543 26.0005 6 26.0005H20V6.00049Z"
|
||||
/>
|
||||
</svg>
|
||||
|
@ -19,14 +19,20 @@
|
||||
const fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12.3,7.8H3.7c-0.8,0-1.5-0.7-1.5-1.5V3.7c0-0.8,0.7-1.5,1.5-1.5h8.7c0.8,0,1.5,0.7,1.5,1.5v2.7C13.8,7.2,13.2,7.8,12.3,7.8z M3.7,3.2c-0.3,0-0.5,0.2-0.5,0.5v2.7c0,0.3,0.2,0.5,0.5,0.5h8.7c0.3,0,0.5-0.2,0.5-0.5V3.7c0-0.3-0.2-0.5-0.5-0.5H3.7z"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M25.0544 4.00001H6.94561C6.52154 3.99992 6.10941 3.99984 5.76949 4.04554C5.38629 4.09706 4.94902 4.22259 4.5858 4.5858C4.22259 4.94902 4.09706 5.38629 4.04554 5.76949C3.99984 6.10941 3.99992 6.52155 4.00001 6.94562V11.0544C3.99992 11.4785 3.99984 11.8906 4.04554 12.2305C4.09706 12.6137 4.22259 13.051 4.5858 13.4142C4.94902 13.7774 5.38629 13.903 5.76949 13.9545C6.1094 14.0002 6.52152 14.0001 6.94558 14H25.0544C25.4785 14.0001 25.8906 14.0002 26.2305 13.9545C26.6137 13.903 27.051 13.7774 27.4142 13.4142C27.7774 13.051 27.903 12.6137 27.9545 12.2305C28.0002 11.8906 28.0001 11.4785 28 11.0544V6.94561C28.0001 6.52154 28.0002 6.10941 27.9545 5.76949C27.903 5.38629 27.7774 4.94902 27.4142 4.5858C27.051 4.22259 26.6137 4.09706 26.2305 4.04554C25.8906 3.99984 25.4785 3.99992 25.0544 4.00001ZM25.9713 6.02871L25.9723 6.03599C25.9979 6.22618 26 6.50034 26 7.00001V11C26 11.4997 25.9979 11.7738 25.9723 11.964L25.9713 11.9713L25.964 11.9723C25.7738 11.9979 25.4997 12 25 12H7.00001C6.50034 12 6.22618 11.9979 6.03599 11.9723L6.02871 11.9713L6.02771 11.964C6.00214 11.7738 6.00001 11.4997 6.00001 11V7.00001C6.00001 6.50034 6.00214 6.22618 6.02771 6.03599L6.02871 6.02871L6.03599 6.02771C6.22618 6.00214 6.50034 6.00001 7.00001 6.00001H25C25.4997 6.00001 25.7738 6.00214 25.964 6.02771L25.9713 6.02871Z"
|
||||
/>
|
||||
<path
|
||||
d="M4.7,13.8c-1,0-1.6,0-2.1-0.4s-0.4-1-0.4-2.1s0-1.6,0.4-2.1s1-0.4,2.1-0.4h2.5v2.5c0,1,0,1.6-0.4,2.1S5.7,13.8,4.7,13.8z M4.7,9.8c-0.7,0-1.2,0-1.4,0.1s-0.1,0.6-0.1,1.4s0,1.2,0.1,1.4s0.6,0.1,1.4,0.1s1.2,0,1.4-0.1s0.1-0.6,0.1-1.4V9.8H4.7z"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M6.94563 18.0001L14 18.0001L14.0001 25.0545C14.0001 25.4786 14.0002 25.8907 13.9545 26.2306C13.903 26.6138 13.7775 27.0511 13.4143 27.4143C13.051 27.7775 12.6138 27.903 12.2306 27.9545C11.8907 28.0002 11.4786 28.0002 11.0545 28.0001H6.94563C6.52159 28.0002 6.10942 28.0002 5.76952 27.9545C5.38632 27.903 4.94904 27.7775 4.58583 27.4143C4.22261 27.0511 4.09709 26.6138 4.04557 26.2306C3.99987 25.8907 3.99995 25.4786 4.00003 25.0545V20.9457C3.99995 20.5216 3.99987 20.1095 4.04557 19.7696C4.09709 19.3864 4.22261 18.9491 4.58583 18.5859C4.94904 18.2226 5.38632 18.0971 5.76952 18.0456C6.10943 17.9999 6.52157 18 6.94563 18.0001ZM6.02874 20.0288L6.02774 20.0361C6.00217 20.2262 6.00004 20.5004 6.00004 21.0001V25.0001C6.00004 25.4998 6.00217 25.7739 6.02774 25.9641L6.02874 25.9714L6.03602 25.9724C6.22621 25.998 6.50037 26.0001 7.00004 26.0001H11C11.4997 26.0001 11.7739 25.998 11.9641 25.9724L11.9713 25.9714L11.9723 25.9641C11.9979 25.7739 12 25.4998 12 25.0001V20.0001H7.00004C6.50037 20.0001 6.22621 20.0022 6.03602 20.0278L6.02874 20.0288Z"
|
||||
/>
|
||||
<path
|
||||
d="M11.3,13.8c-1,0-1.6,0-2.1-0.4s-0.4-1-0.4-2.1V8.8h2.5c1,0,1.6,0,2.1,0.4s0.4,1,0.4,2.1s0,1.6-0.4,2.1S12.4,13.8,11.3,13.8z M9.8,9.8v1.5c0,0.7,0,1.2,0.1,1.4s0.6,0.1,1.4,0.1s1.2,0,1.4-0.1s0.1-0.6,0.1-1.4s0-1.2-0.1-1.4s-0.6-0.1-1.4-0.1H9.8z"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M27.4143 18.5859C27.051 18.2226 26.6138 18.0971 26.2306 18.0456C25.8906 17.9999 25.4785 18 25.0545 18.0001L18 18.0001L18 25.0545C18 25.4786 17.9999 25.8907 18.0456 26.2306C18.0971 26.6138 18.2226 27.0511 18.5858 27.4143C18.949 27.7775 19.3863 27.903 19.7695 27.9545C20.1094 28.0002 20.5215 28.0002 20.9456 28.0001H25.0545C25.4785 28.0002 25.8907 28.0002 26.2306 27.9545C26.6138 27.903 27.051 27.7775 27.4143 27.4143C27.7775 27.0511 27.903 26.6138 27.9545 26.2306C28.0002 25.8907 28.0001 25.4786 28 25.0545V20.9457C28.0001 20.5216 28.0002 20.1095 27.9545 19.7696C27.903 19.3864 27.7775 18.9491 27.4143 18.5859ZM25 20.0001C25.4997 20.0001 25.7739 20.0022 25.9641 20.0278L25.9713 20.0288L25.9723 20.0361C25.9979 20.2262 26 20.5004 26 21.0001V25.0001C26 25.4998 25.9979 25.7739 25.9723 25.9641L25.9713 25.9714L25.9641 25.9724C25.7739 25.998 25.4997 26.0001 25 26.0001H21C20.5004 26.0001 20.2262 25.998 20.036 25.9724L20.0287 25.9714L20.0277 25.9641C20.0022 25.7739 20 25.4998 20 25.0001V20.0001H25Z"
|
||||
/>
|
||||
</svg>
|
||||
|
@ -33,7 +33,7 @@
|
||||
})
|
||||
}}
|
||||
>
|
||||
<span>{getTimeZoneName()}</span>
|
||||
{#if getTimeZoneName() !== ''}<span>{getTimeZoneName()}</span> {/if}
|
||||
<span>{hours}</span>
|
||||
<span style:visibility={delimiter ? 'visible' : 'hidden'}>:</span>
|
||||
<span>{minutes}</span>
|
||||
|
@ -84,10 +84,12 @@
|
||||
{#each selectedTZ as selected, i}
|
||||
<div class="statusPopup-option">
|
||||
<ClockFace bind:timeZone={selected} size={clockSize} />
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<span class="label overflow-label" style:max-width={clockSize} on:click={(ev) => changeTimeZone(ev, i)}>
|
||||
{selected === '' ? '--' : convertTimeZone(selected).short}
|
||||
</span>
|
||||
{#if selected !== ''}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<span class="label overflow-label" style:max-width={clockSize} on:click={(ev) => changeTimeZone(ev, i)}>
|
||||
{convertTimeZone(selected).short}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
@ -33,6 +33,7 @@ export type {
|
||||
PopupPositionElement,
|
||||
ButtonKind,
|
||||
ButtonSize,
|
||||
ButtonItem,
|
||||
IconSize,
|
||||
TabItem,
|
||||
DeviceOptions,
|
||||
@ -40,7 +41,8 @@ export type {
|
||||
SeparatedItem,
|
||||
DefSeparators,
|
||||
SeparatedElement,
|
||||
TimeZone
|
||||
TimeZone,
|
||||
MouseTargetEvent
|
||||
} from './types'
|
||||
|
||||
export { themeStore } from '@hcengineering/theme'
|
||||
@ -50,6 +52,7 @@ export { getCurrentLocation, locationToUrl, navigate, location, setLocationStora
|
||||
export { default as EditBox } from './components/EditBox.svelte'
|
||||
export { default as Label } from './components/Label.svelte'
|
||||
export { default as Button } from './components/Button.svelte'
|
||||
export { default as ButtonGroup } from './components/ButtonGroup.svelte'
|
||||
export { default as Status } from './components/Status.svelte'
|
||||
export { default as Component } from './components/Component.svelte'
|
||||
export { default as Icon } from './components/Icon.svelte'
|
||||
|
@ -141,6 +141,7 @@ export type ButtonKind =
|
||||
| 'negative'
|
||||
| 'regular'
|
||||
| 'ghost'
|
||||
| 'icon'
|
||||
| 'no-border'
|
||||
| 'link'
|
||||
| 'link-bordered'
|
||||
@ -170,6 +171,16 @@ export type EditStyle =
|
||||
| 'ghost'
|
||||
| 'default-large'
|
||||
| 'ghost-large'
|
||||
|
||||
export interface ButtonItem {
|
||||
id: string
|
||||
icon?: Asset | AnySvelteComponent | ComponentType
|
||||
label?: IntlString
|
||||
labelParams?: Record<string, any>
|
||||
disabled?: boolean
|
||||
showTooltip?: LabelAndProps
|
||||
}
|
||||
|
||||
export interface PopupPositionElement {
|
||||
getBoundingClientRect: () => DOMRect
|
||||
position?: {
|
||||
@ -241,6 +252,7 @@ export interface IconProps {
|
||||
icon?: number
|
||||
size?: IconSize
|
||||
fill?: string
|
||||
filled?: boolean
|
||||
}
|
||||
|
||||
export function getIconSize2x (size: IconSize): IconSize {
|
||||
@ -484,3 +496,8 @@ export interface TimeZone {
|
||||
short: string
|
||||
offset?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type MouseTargetEvent = MouseEvent & { currentTarget: EventTarget & HTMLElement }
|
||||
|
@ -32,13 +32,7 @@
|
||||
Label,
|
||||
showPopup
|
||||
} from '@hcengineering/ui'
|
||||
import {
|
||||
ContextMenu,
|
||||
DocAttributeBar,
|
||||
invokeAction,
|
||||
ParentsNavigator,
|
||||
UpDownNavigator
|
||||
} from '@hcengineering/view-resources'
|
||||
import { ContextMenu, DocAttributeBar, invokeAction, ParentsNavigator } from '@hcengineering/view-resources'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import board from '../plugin'
|
||||
import { getCardActions } from '../utils/CardActionUtils'
|
||||
@ -112,18 +106,12 @@
|
||||
|
||||
{#if object !== undefined}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<Panel
|
||||
icon={board.icon.Card}
|
||||
title={object?.title}
|
||||
{object}
|
||||
isHeader
|
||||
isAside={true}
|
||||
isSub={false}
|
||||
on:close={() => dispatch('close')}
|
||||
>
|
||||
<svelte:fragment slot="navigator">
|
||||
<UpDownNavigator element={object} />
|
||||
<Panel {object} isHeader isAside={true} isSub={false} on:close={() => dispatch('close')}>
|
||||
<svelte:fragment slot="title">
|
||||
<ParentsNavigator element={object} />
|
||||
{#if object?.title}
|
||||
<div class="title not-active">{object?.title}</div>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="header">
|
||||
<div class="flex fs-title flex-gap-1">
|
||||
|
@ -20,7 +20,7 @@
|
||||
export let _id: Ref<Space>
|
||||
</script>
|
||||
|
||||
<div class="antiPanel-component">
|
||||
<div class="antiComponent">
|
||||
<SpaceHeader spaceId={_id} withSearch={false} />
|
||||
<ChannelView space={_id} />
|
||||
</div>
|
||||
|
@ -21,7 +21,6 @@
|
||||
import { Class, Doc, Ref, getCurrentAccount } from '@hcengineering/core'
|
||||
|
||||
export let _id: Ref<Comment> | undefined
|
||||
export let embedded: boolean = true
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
@ -91,5 +90,5 @@
|
||||
{#if loading}
|
||||
<Loading />
|
||||
{:else if component && attachedDocId && attachedDocClass}
|
||||
<Component is={component} props={{ _id: attachedDocId, _class: attachedDocClass, embedded }} on:close />
|
||||
<Component is={component} props={{ _id: attachedDocId, _class: attachedDocClass }} on:close />
|
||||
{/if}
|
||||
|
@ -18,13 +18,12 @@
|
||||
import type { Class, Ref } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { SpaceMembers } from '@hcengineering/contact-resources'
|
||||
import { Icon, Label, Panel, Scroller } from '@hcengineering/ui'
|
||||
import { Label, Panel, Scroller } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
import chunter from '../plugin'
|
||||
import EditChannelDescriptionTab from './EditChannelDescriptionTab.svelte'
|
||||
import EditChannelSettingsTab from './EditChannelSettingsTab.svelte'
|
||||
import Lock from './icons/Lock.svelte'
|
||||
|
||||
export let _id: Ref<ChunterSpace>
|
||||
export let _class: Ref<Class<ChunterSpace>>
|
||||
@ -54,20 +53,12 @@
|
||||
<svelte:fragment slot="title">
|
||||
{#if clazz && channel}
|
||||
{#if _class === chunter.class.DirectMessage}
|
||||
<span class="fs-title"><Label label={clazz.label} /></span>
|
||||
<span class="title"><Label label={clazz.label} /></span>
|
||||
{:else}
|
||||
<div class="antiTitle icon-wrapper">
|
||||
<div class="wrapped-icon">
|
||||
{#if clazz.icon}<Icon icon={channel.private ? Lock : clazz.icon} size={'medium'} />{/if}
|
||||
</div>
|
||||
<div class="title-wrapper">
|
||||
<span class="wrapped-title">
|
||||
<span class="trans-title content-color"><Label label={clazz.label} />›</span>
|
||||
{channel.name}
|
||||
</span>
|
||||
<span class="wrapped-subtitle">{channel.description}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="title">
|
||||
<span class="trans-title content-color"><Label label={clazz.label} />›</span>
|
||||
{channel.name}
|
||||
</span>
|
||||
{/if}
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
export let _id: Ref<Channel>
|
||||
export let _class: Ref<Class<Channel>>
|
||||
export let embedded = false
|
||||
|
||||
const client = getClient()
|
||||
|
||||
@ -43,9 +42,6 @@
|
||||
|
||||
{#await getPresenter(channel) then presenter}
|
||||
{#if presenter}
|
||||
<Component
|
||||
is={presenter}
|
||||
props={{ embedded, _id: channel?.attachedTo, _class: channel?.attachedToClass, channel }}
|
||||
/>
|
||||
<Component is={presenter} props={{ _id: channel?.attachedTo, _class: channel?.attachedToClass, channel }} />
|
||||
{/if}
|
||||
{/await}
|
||||
|
@ -27,7 +27,6 @@
|
||||
Button,
|
||||
EditBox,
|
||||
eventToHTMLElement,
|
||||
Icon,
|
||||
IconAttachment,
|
||||
Label,
|
||||
Panel,
|
||||
@ -236,12 +235,7 @@
|
||||
}}
|
||||
>
|
||||
<svelte:fragment slot="title">
|
||||
<div class="antiTitle icon-wrapper">
|
||||
<div class="wrapped-icon"><Icon icon={contact.icon.Email} size={'medium'} /></div>
|
||||
<div class="title-wrapper">
|
||||
<span class="wrapped-title">Email</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title not-active">Email</div>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="utils">
|
||||
|
@ -17,16 +17,7 @@
|
||||
import { DocumentQuery, Ref, WithLookup } from '@hcengineering/core'
|
||||
import type { Department, Staff } from '@hcengineering/hr'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import {
|
||||
Button,
|
||||
deviceOptionsStore as deviceInfo,
|
||||
eventToHTMLElement,
|
||||
Label,
|
||||
Scroller,
|
||||
SearchEdit,
|
||||
showPopup,
|
||||
IconAdd
|
||||
} from '@hcengineering/ui'
|
||||
import { Button, eventToHTMLElement, Label, Scroller, SearchEdit, showPopup, IconAdd } from '@hcengineering/ui'
|
||||
import hr from '../plugin'
|
||||
import CreateDepartment from './CreateDepartment.svelte'
|
||||
import DepartmentCard from './DepartmentCard.svelte'
|
||||
@ -75,8 +66,6 @@
|
||||
spaceMembers.query(hr.mixin.Staff, {}, (res) => {
|
||||
allEmployees = res
|
||||
})
|
||||
|
||||
$: twoRows = $deviceInfo.twoRows
|
||||
</script>
|
||||
|
||||
<div class="ac-header full divide caption-height">
|
||||
|
@ -38,7 +38,6 @@
|
||||
const client = getClient()
|
||||
|
||||
const query = createQuery()
|
||||
const clazz = client.getHierarchy().getClass(lead.class.Funnel)
|
||||
|
||||
function updateObject (_id: Ref<Funnel>): void {
|
||||
query.query(lead.class.Funnel, { _id }, (result) => {
|
||||
@ -58,8 +57,6 @@
|
||||
{#if object}
|
||||
<Panel
|
||||
title={object.name}
|
||||
subtitle={object.description}
|
||||
icon={clazz.icon}
|
||||
isHeader={false}
|
||||
isAside={true}
|
||||
{object}
|
||||
|
@ -187,7 +187,7 @@
|
||||
}}
|
||||
/>
|
||||
{:else if component && _id && _class}
|
||||
<Component is={component} props={{ _id, _class, embedded: true }} on:close={() => select(undefined)} />
|
||||
<Component is={component} props={{ _id, _class }} on:close={() => select(undefined)} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -23,14 +23,22 @@
|
||||
import { Vacancy } from '@hcengineering/recruit'
|
||||
import tracker from '@hcengineering/tracker'
|
||||
import view from '@hcengineering/view'
|
||||
import { Button, Component, EditBox, IconMixin, IconMoreH, Label, LinkWrapper, showPopup } from '@hcengineering/ui'
|
||||
import { ContextMenu, DocAttributeBar } from '@hcengineering/view-resources'
|
||||
import {
|
||||
Button,
|
||||
Component,
|
||||
EditBox,
|
||||
IconMixin,
|
||||
IconMoreH,
|
||||
Label,
|
||||
showPopup,
|
||||
deviceOptionsStore as deviceInfo
|
||||
} from '@hcengineering/ui'
|
||||
import { ContextMenu, DocAttributeBar, DocNavLink } from '@hcengineering/view-resources'
|
||||
import { createEventDispatcher, onDestroy } from 'svelte'
|
||||
import recruit from '../plugin'
|
||||
import VacancyApplications from './VacancyApplications.svelte'
|
||||
|
||||
export let _id: Ref<Vacancy>
|
||||
export let embedded = false
|
||||
|
||||
let object: Required<Vacancy>
|
||||
let rawName: string = ''
|
||||
@ -50,7 +58,7 @@
|
||||
const client = getClient()
|
||||
|
||||
const query = createQuery()
|
||||
const clazz = client.getHierarchy().getClass(recruit.class.Vacancy)
|
||||
// const clazz = client.getHierarchy().getClass(recruit.class.Vacancy)
|
||||
|
||||
function updateObject (_id: Ref<Vacancy>): void {
|
||||
if (lastId !== _id) {
|
||||
@ -125,26 +133,19 @@
|
||||
|
||||
{#if object}
|
||||
<Panel
|
||||
icon={clazz.icon}
|
||||
title={object.name}
|
||||
isHeader={false}
|
||||
isSub={false}
|
||||
isAside={true}
|
||||
{embedded}
|
||||
{object}
|
||||
on:open
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<svelte:fragment slot="subtitle">
|
||||
{#if object.description}
|
||||
<div class="flex">
|
||||
<span class="overflow-label" title={object.description}>
|
||||
<LinkWrapper text={object.description} />
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
<svelte:fragment slot="title">
|
||||
<DocNavLink noUnderline {object}>
|
||||
<div class="title">{object.name}</div>
|
||||
</DocNavLink>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="attributes" let:direction={dir}>
|
||||
@ -159,7 +160,7 @@
|
||||
placeholder={recruit.string.VacancyPlaceholder}
|
||||
kind={'large-style'}
|
||||
focusable
|
||||
autoFocus={!embedded}
|
||||
autoFocus={!$deviceInfo.isMobile}
|
||||
on:blur={save}
|
||||
/>
|
||||
</span>
|
||||
@ -170,10 +171,11 @@
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="utils">
|
||||
<Button icon={IconMoreH} kind={'ghost'} size={'medium'} on:click={showMenu} />
|
||||
<Button icon={IconMoreH} iconProps={{ size: 'medium' }} kind={'icon'} on:click={showMenu} />
|
||||
<Button
|
||||
icon={IconMixin}
|
||||
kind={'ghost'}
|
||||
kind={'icon'}
|
||||
iconProps={{ size: 'medium' }}
|
||||
selected={showAllMixins}
|
||||
on:click={() => {
|
||||
showAllMixins = !showAllMixins
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
export let _id: Ref<Integration>
|
||||
export let _class: Ref<Class<Integration>>
|
||||
export let embedded = false
|
||||
|
||||
let integration: Integration | undefined = undefined
|
||||
const query = createQuery()
|
||||
@ -54,16 +53,7 @@
|
||||
</script>
|
||||
|
||||
{#if integration}
|
||||
<Panel
|
||||
icon={setting.icon.Integrations}
|
||||
{title}
|
||||
object={integration}
|
||||
{embedded}
|
||||
isHeader={false}
|
||||
isAside={false}
|
||||
withoutActivity
|
||||
withoutInput
|
||||
>
|
||||
<Panel {title} object={integration} isHeader={false} isAside={false} withoutActivity withoutInput>
|
||||
<div class="max-w-80 min-w-80">
|
||||
{#if type}
|
||||
<PluginCard {integration} integrationType={type} />
|
||||
|
@ -24,10 +24,11 @@
|
||||
import { activeProjects } from '../../utils'
|
||||
|
||||
export let value: WithLookup<Issue>
|
||||
export let disabled = false
|
||||
export let disabled: boolean = false
|
||||
export let onClick: (() => void) | undefined = undefined
|
||||
export let shouldShowAvatar: boolean = false
|
||||
export let noUnderline = disabled
|
||||
export let noUnderline: boolean = disabled
|
||||
export let noSelect: boolean = false
|
||||
export let inline = false
|
||||
export let kind: 'list' | undefined = undefined
|
||||
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
||||
@ -64,7 +65,7 @@
|
||||
<Icon icon={icon ?? tracker.icon.Issues} size={'small'} />
|
||||
</div>
|
||||
{/if}
|
||||
<span class="overflow-label select-text" title={value?.title}>
|
||||
<span class="overflow-label" class:select-text={!noSelect} title={value?.title}>
|
||||
{title}
|
||||
<slot name="details" />
|
||||
</span>
|
||||
|
@ -24,7 +24,8 @@
|
||||
|
||||
<Button
|
||||
{icon}
|
||||
kind={'ghost'}
|
||||
iconProps={{ size: 'medium' }}
|
||||
kind={'icon'}
|
||||
showTooltip={{ label: title, direction: 'bottom' }}
|
||||
on:click={() => copyTextToClipboard(text)}
|
||||
/>
|
||||
|
@ -40,9 +40,10 @@
|
||||
createFocusManager,
|
||||
getCurrentResolvedLocation,
|
||||
navigate,
|
||||
showPopup
|
||||
showPopup,
|
||||
deviceOptionsStore as deviceInfo
|
||||
} from '@hcengineering/ui'
|
||||
import { ContextMenu, DocNavLink, ParentsNavigator, UpDownNavigator } from '@hcengineering/view-resources'
|
||||
import { ContextMenu, DocNavLink, ParentsNavigator } from '@hcengineering/view-resources'
|
||||
import view from '@hcengineering/view'
|
||||
import { createEventDispatcher, onDestroy } from 'svelte'
|
||||
import { generateIssueShortLink, getIssueId } from '../../../issues'
|
||||
@ -55,7 +56,6 @@
|
||||
|
||||
export let _id: Ref<Issue>
|
||||
export let _class: Ref<Class<Issue>>
|
||||
export let embedded = false
|
||||
|
||||
let lastId: Ref<Doc> = _id
|
||||
const queryClient = createQuery()
|
||||
@ -165,14 +165,12 @@
|
||||
let content: HTMLElement
|
||||
</script>
|
||||
|
||||
{#if !embedded}
|
||||
<FocusHandler {manager} isEnabled={isContextEnabled} />
|
||||
<ActionContext
|
||||
context={{
|
||||
mode: 'editor'
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
<FocusHandler {manager} isEnabled={isContextEnabled} />
|
||||
<ActionContext
|
||||
context={{
|
||||
mode: 'editor'
|
||||
}}
|
||||
/>
|
||||
|
||||
{#if issue !== undefined}
|
||||
<Panel
|
||||
@ -181,26 +179,19 @@
|
||||
isAside={true}
|
||||
isSub={false}
|
||||
withoutActivity={false}
|
||||
withoutTitle
|
||||
bind:content
|
||||
{embedded}
|
||||
bind:innerWidth
|
||||
on:open
|
||||
on:close={() => dispatch('close')}
|
||||
on:select
|
||||
>
|
||||
<svelte:fragment slot="navigator">
|
||||
{#if !embedded}
|
||||
<UpDownNavigator element={issue} />
|
||||
<ParentsNavigator element={issue} />
|
||||
<svelte:fragment slot="title">
|
||||
<ParentsNavigator element={issue} />
|
||||
{#if issueId}
|
||||
<DocNavLink noUnderline object={issue}>
|
||||
<div class="title">{issueId}</div>
|
||||
</DocNavLink>
|
||||
{/if}
|
||||
|
||||
<span class="ml-4 fs-title select-text-i overflow-label">
|
||||
{#if embedded}
|
||||
<DocNavLink object={issue}>
|
||||
{#if issueId}{issueId}{/if}
|
||||
</DocNavLink>
|
||||
{:else if issueId}{issueId}{/if}
|
||||
</span>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="pre-utils">
|
||||
<ComponentExtensions
|
||||
@ -212,6 +203,39 @@
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="utils">
|
||||
<Button icon={IconMoreH} iconProps={{ size: 'medium' }} kind={'icon'} on:click={showMenu} />
|
||||
{#if issueId}
|
||||
<CopyToClipboard issueUrl={generateIssueShortLink(issueId)} />
|
||||
{/if}
|
||||
<Button
|
||||
icon={setting.icon.Setting}
|
||||
kind={'icon'}
|
||||
iconProps={{ size: 'medium' }}
|
||||
showTooltip={{ label: setting.string.ClassSetting }}
|
||||
on:click={(ev) => {
|
||||
ev.stopPropagation()
|
||||
const loc = getCurrentResolvedLocation()
|
||||
loc.path[2] = settingId
|
||||
loc.path[3] = 'setting'
|
||||
loc.path[4] = 'classes'
|
||||
loc.path.length = 5
|
||||
loc.query = { _class }
|
||||
loc.fragment = undefined
|
||||
navigate(loc)
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
icon={IconMixin}
|
||||
iconProps={{ size: 'medium' }}
|
||||
kind={'icon'}
|
||||
selected={showAllMixins}
|
||||
on:click={() => {
|
||||
showAllMixins = !showAllMixins
|
||||
}}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
|
||||
{#if parentIssue}
|
||||
<div class="mb-6">
|
||||
{#if currentProject}
|
||||
@ -227,7 +251,7 @@
|
||||
placeholder={tracker.string.IssueTitlePlaceholder}
|
||||
kind="large-style"
|
||||
on:blur={save}
|
||||
autoFocus={!embedded}
|
||||
autoFocus={!$deviceInfo.isMobile}
|
||||
/>
|
||||
<div class="w-full mt-6">
|
||||
<AttachmentStyleBoxEditor
|
||||
@ -260,36 +284,6 @@
|
||||
<span slot="actions-label" class="select-text">
|
||||
{#if issueId}{issueId}{/if}
|
||||
</span>
|
||||
<svelte:fragment slot="utils">
|
||||
<Button icon={IconMoreH} kind={'ghost'} size={'medium'} on:click={showMenu} />
|
||||
{#if issueId}
|
||||
<CopyToClipboard issueUrl={generateIssueShortLink(issueId)} {issueId} />
|
||||
{/if}
|
||||
<Button
|
||||
icon={setting.icon.Setting}
|
||||
kind={'ghost'}
|
||||
showTooltip={{ label: setting.string.ClassSetting }}
|
||||
on:click={(ev) => {
|
||||
ev.stopPropagation()
|
||||
const loc = getCurrentResolvedLocation()
|
||||
loc.path[2] = settingId
|
||||
loc.path[3] = 'setting'
|
||||
loc.path[4] = 'classes'
|
||||
loc.path.length = 5
|
||||
loc.query = { _class }
|
||||
loc.fragment = undefined
|
||||
navigate(loc)
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
kind={'ghost'}
|
||||
icon={IconMixin}
|
||||
selected={showAllMixins}
|
||||
on:click={() => {
|
||||
showAllMixins = !showAllMixins
|
||||
}}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="custom-attributes">
|
||||
{#if issue && currentProject}
|
||||
|
@ -22,17 +22,8 @@
|
||||
import setting, { settingId } from '@hcengineering/setting'
|
||||
import tags from '@hcengineering/tags'
|
||||
import { IssueTemplate, IssueTemplateChild, Project } from '@hcengineering/tracker'
|
||||
import {
|
||||
Button,
|
||||
EditBox,
|
||||
Icon,
|
||||
IconMoreH,
|
||||
Label,
|
||||
getCurrentResolvedLocation,
|
||||
navigate,
|
||||
showPopup
|
||||
} from '@hcengineering/ui'
|
||||
import { ContextMenu, ParentsNavigator, UpDownNavigator } from '@hcengineering/view-resources'
|
||||
import { Button, EditBox, IconMoreH, Label, getCurrentResolvedLocation, navigate, showPopup } from '@hcengineering/ui'
|
||||
import { ContextMenu } from '@hcengineering/view-resources'
|
||||
import view from '@hcengineering/view'
|
||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
||||
import tracker from '../../plugin'
|
||||
@ -42,7 +33,6 @@
|
||||
|
||||
export let _id: Ref<IssueTemplate>
|
||||
export let _class: Ref<Class<IssueTemplate>>
|
||||
export let embedded = false
|
||||
|
||||
let lastId: Ref<Doc> = _id
|
||||
const query = createQuery()
|
||||
@ -52,7 +42,6 @@
|
||||
let template: WithLookup<IssueTemplate> | undefined
|
||||
let currentProject: Project | undefined
|
||||
let title = ''
|
||||
let description = ''
|
||||
let innerWidth: number
|
||||
|
||||
let descriptionBox: AttachmentStyleBoxEditor
|
||||
@ -80,7 +69,6 @@
|
||||
async (result) => {
|
||||
;[template] = result
|
||||
title = template.title
|
||||
description = template.description
|
||||
currentProject = template.$lookup?.space
|
||||
},
|
||||
{ lookup: { space: tracker.class.Project, labels: tags.class.TagElement } }
|
||||
@ -149,30 +137,16 @@
|
||||
|
||||
{#if template !== undefined}
|
||||
<Panel
|
||||
title={template.title}
|
||||
object={template}
|
||||
isHeader={false}
|
||||
isAside={true}
|
||||
isSub={false}
|
||||
withoutActivity={false}
|
||||
{embedded}
|
||||
bind:innerWidth
|
||||
on:open
|
||||
on:close={() => dispatch('close')}
|
||||
>
|
||||
<svelte:fragment slot="navigator">
|
||||
{#if !embedded}
|
||||
<UpDownNavigator element={template} />
|
||||
<ParentsNavigator element={template} />
|
||||
{/if}
|
||||
|
||||
<div class="ml-2">
|
||||
<Icon icon={tracker.icon.IssueTemplates} size={'small'} />
|
||||
</div>
|
||||
<span class="fs-title flex-row-center">
|
||||
{template.title}
|
||||
</span>
|
||||
</svelte:fragment>
|
||||
|
||||
<EditBox bind:value={title} placeholder={tracker.string.IssueTitlePlaceholder} kind="large-style" on:blur={save} />
|
||||
<div class="w-full mt-6">
|
||||
<AttachmentStyleBoxEditor
|
||||
@ -207,10 +181,11 @@
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="utils">
|
||||
<Button icon={IconMoreH} kind={'ghost'} size={'medium'} on:click={showMenu} />
|
||||
<Button icon={IconMoreH} iconProps={{ size: 'medium' }} kind={'icon'} on:click={showMenu} />
|
||||
<Button
|
||||
icon={setting.icon.Setting}
|
||||
kind={'ghost'}
|
||||
iconProps={{ size: 'medium' }}
|
||||
kind={'icon'}
|
||||
showTooltip={{ label: setting.string.ClassSetting }}
|
||||
on:click={(ev) => {
|
||||
ev.stopPropagation()
|
||||
|
@ -63,9 +63,9 @@
|
||||
<path d="M5 11C4.72386 11 4.5 11.2239 4.5 11.5C4.5 11.7761 4.72386 12 5 12H8C8.27614 12 8.5 11.7761 8.5 11.5C8.5 11.2239 8.27614 11 8 11H5Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.5 1C10.1531 1 10.7087 1.4174 10.9146 2H11.5C12.6046 2 13.5 2.89543 13.5 4V13C13.5 14.1046 12.6046 15 11.5 15H4.5C3.39543 15 2.5 14.1046 2.5 13V4C2.5 2.89543 3.39543 2 4.5 2H5.08535C5.29127 1.4174 5.84689 1 6.5 1H9.5ZM6 2.5C6 2.22386 6.22386 2 6.5 2H9.5C9.77614 2 10 2.22386 10 2.5C10 2.77614 9.77614 3 9.5 3H6.5C6.22386 3 6 2.77614 6 2.5ZM9.5 4C10.1531 4 10.7087 3.5826 10.9146 3H11.5C12.0523 3 12.5 3.44772 12.5 4V13C12.5 13.5523 12.0523 14 11.5 14H4.5C3.94772 14 3.5 13.5523 3.5 13V4C3.5 3.44772 3.94772 3 4.5 3H5.08535C5.29127 3.5826 5.84689 4 6.5 4H9.5Z" />
|
||||
</symbol>
|
||||
<symbol id="copyLink" viewBox="0 0 16 16">
|
||||
<path d="M14.6,3.4c-0.3-0.3-0.6-0.5-1-0.7c-0.4-0.2-0.8-0.2-1.2-0.2c-0.4,0-0.8,0.1-1.2,0.2c-0.2,0.1-0.4,0.2-0.6,0.3c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0c0.1,0,0.2-0.1,0.3-0.1c0.2-0.1,0.5-0.2,0.8-0.2c0.3,0,0.5,0.1,0.8,0.2s0.5,0.2,0.7,0.4c0.2,0.2,0.3,0.4,0.4,0.7c0.1,0.2,0.2,0.5,0.2,0.8c0,0.3-0.1,0.5-0.2,0.8c-0.1,0.2-0.2,0.5-0.4,0.7l-4,4c-0.4,0.4-0.9,0.6-1.4,0.6c-0.5,0-1-0.2-1.4-0.6C6.7,10.6,6.5,10,6.5,9.5c0-0.5,0.2-1,0.6-1.4l0.4-0.4c0.2-0.2,0.2-0.5,0-0.7C7.2,6.8,6.9,6.8,6.7,7L6.4,7.4C6.1,7.7,5.9,8,5.7,8.4C5.6,8.7,5.5,9.1,5.5,9.5c0,0.4,0.1,0.8,0.2,1.2c0.2,0.4,0.4,0.7,0.7,1c0.6,0.6,1.3,0.9,2.1,0.9c0.4,0,0.8-0.1,1.2-0.2c0.4-0.2,0.7-0.4,1-0.7l4-4c0.6-0.6,0.9-1.3,0.9-2.1C15.5,4.7,15.2,3.9,14.6,3.4z" />
|
||||
<path d="M2.1,12.4c-0.2-0.2-0.3-0.4-0.4-0.6c-0.1-0.2-0.2-0.5-0.2-0.8c0-0.3,0.1-0.5,0.2-0.8C1.8,10,1.9,9.8,2.1,9.6l4-4c0.2-0.2,0.4-0.3,0.6-0.4C7,5,7.2,5,7.5,5C7.8,5,8,5,8.3,5.1c0.2,0.1,0.5,0.2,0.6,0.4C9.1,5.8,9.3,6,9.4,6.2C9.5,6.5,9.5,6.7,9.5,7c0,0.3,0,0.5-0.1,0.8C9.2,8,9.1,8.2,8.9,8.4L8.2,9.1C8,9.3,8,9.7,8.2,9.9c0.2,0.2,0.5,0.2,0.7,0l0.7-0.7c0.6-0.6,0.9-1.3,0.9-2.1c0-0.8-0.3-1.6-0.9-2.1C9.1,4.3,8.3,4,7.5,4C6.7,4,5.9,4.3,5.4,4.9l-4,4c-0.3,0.3-0.5,0.6-0.7,1c-0.2,0.4-0.2,0.8-0.2,1.2c0,0.4,0.1,0.8,0.2,1.2c0.2,0.4,0.4,0.7,0.7,1C1.9,13.7,2.7,14,3.5,14c0.6,0,1.2-0.2,1.8-0.6c0.2-0.2,0.2-0.5,0-0.7c-0.2-0.2-0.5-0.2-0.7,0c-0.1,0-0.2,0.1-0.3,0.1C4,12.9,3.8,13,3.5,13c-0.3,0-0.5-0.1-0.8-0.2S2.3,12.6,2.1,12.4z" />
|
||||
<symbol id="copyLink" viewBox="0 0 32 32">
|
||||
<path d="M29.25 6.75997C28.6926 6.20061 28.0302 5.75679 27.3009 5.45396C26.5716 5.15112 25.7897 4.99524 25 4.99524C24.2103 4.99524 23.4284 5.15112 22.6991 5.45396C22.278 5.62881 21.8792 5.85065 21.5101 6.1146C21.0614 6.43545 21.0693 7.07931 21.4594 7.46935C21.8499 7.85988 22.4827 7.84994 22.9575 7.5679C23.1218 7.47029 23.2933 7.38434 23.4707 7.31086C23.9571 7.10938 24.4785 7.00567 25.005 7.00567C25.5315 7.00567 26.0528 7.10938 26.5393 7.31086C27.0257 7.51235 27.4677 7.80767 27.84 8.17997C28.2123 8.55227 28.5076 8.99425 28.7091 9.48068C28.9106 9.96711 29.0143 10.4885 29.0143 11.015C29.0143 11.5415 28.9106 12.0628 28.7091 12.5493C28.5076 13.0357 28.2123 13.4777 27.84 13.85L19.84 21.85C19.0894 22.6019 18.0709 23.0248 17.0085 23.0257C15.9461 23.0267 14.9269 22.6055 14.175 21.855C13.4231 21.1044 13.0001 20.0859 12.9992 19.0235C12.9983 17.9611 13.4194 16.9419 14.17 16.19L14.8803 15.4746C15.2675 15.0846 15.2659 14.4537 14.8787 14.0637C14.4886 13.6709 13.8519 13.6681 13.4604 14.0596L12.75 14.77C12.1906 15.3274 11.7468 15.9897 11.444 16.7191C11.1411 17.4484 10.9852 18.2303 10.9852 19.02C10.9852 19.8097 11.1411 20.5916 11.444 21.3209C11.7468 22.0502 12.1906 22.7125 12.75 23.27C13.8815 24.387 15.41 25.0092 17 25C17.7927 25.0032 18.5782 24.8494 19.3111 24.5473C20.044 24.2452 20.7098 23.8009 21.27 23.24L29.27 15.24C30.3909 14.1123 31.0184 12.5858 31.0147 10.9958C31.0109 9.40582 30.3762 7.88232 29.25 6.75997Z" />
|
||||
<path d="M4.18997 24.82C3.81656 24.4483 3.52026 24.0065 3.31807 23.52C3.11589 23.0335 3.01181 22.5118 3.01181 21.985C3.01181 21.4581 3.11589 20.9365 3.31807 20.4499C3.52026 19.9634 3.81656 19.5216 4.18997 19.15L12.19 11.15C12.5616 10.7766 13.0034 10.4803 13.4899 10.2781C13.9765 10.0759 14.4981 9.97181 15.025 9.97181C15.5518 9.97181 16.0735 10.0759 16.56 10.2781C17.0465 10.4803 17.4883 10.7766 17.86 11.15C18.231 11.5246 18.5231 11.9698 18.7189 12.4594C18.9147 12.9489 19.0103 13.4728 19 14C19.003 14.5288 18.9012 15.0529 18.7004 15.5421C18.4995 16.0313 18.2037 16.4758 17.83 16.85L16.4072 18.2929C16.0213 18.6842 16.0289 19.3189 16.4175 19.7075C16.808 20.098 17.4466 20.1034 17.8371 19.7129L19.25 18.3C20.3785 17.1715 21.0124 15.6409 21.0124 14.045C21.0124 12.449 20.3785 10.9185 19.25 9.78997C18.1215 8.66147 16.5909 8.02749 14.995 8.02749C13.399 8.02749 11.8685 8.66147 10.74 9.78997L2.73997 17.79C2.17911 18.3476 1.73401 19.0106 1.43029 19.7408C1.12657 20.471 0.970215 21.2541 0.970215 22.045C0.970215 22.8358 1.12657 23.6189 1.43029 24.3492C1.73401 25.0794 2.17911 25.7424 2.73997 26.3C3.87879 27.4084 5.41087 28.0198 6.99997 28C8.26594 28.0012 9.49169 27.6069 10.5118 26.885C10.964 26.5651 10.961 25.921 10.5693 25.5293C10.1781 25.1381 9.54699 25.1518 9.0717 25.4348C8.90786 25.5324 8.73689 25.6184 8.56 25.6919C8.07349 25.8941 7.55182 25.9981 7.02497 25.9981C6.49812 25.9981 5.97645 25.8941 5.48994 25.6919C5.00342 25.4897 4.56164 25.1934 4.18997 24.82Z" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="arrow-right" viewBox="0 0 16 16">
|
||||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 26 KiB |
@ -15,10 +15,10 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { Contact, getName } from '@hcengineering/contact'
|
||||
import core, { Class, ClassifierKind, Doc, Mixin, Obj, Ref } from '@hcengineering/core'
|
||||
import core, { Class, ClassifierKind, Doc, Mixin, Ref } from '@hcengineering/core'
|
||||
import notification from '@hcengineering/notification'
|
||||
import { Panel } from '@hcengineering/panel'
|
||||
import { Asset, getResource, translate } from '@hcengineering/platform'
|
||||
import { getResource, translate } from '@hcengineering/platform'
|
||||
import {
|
||||
AttributeCategory,
|
||||
AttributeCategoryOrder,
|
||||
@ -33,14 +33,12 @@
|
||||
import { AnyComponent, Button, Component, IconMixin, IconMoreH, showPopup, themeStore } from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import { createEventDispatcher, onDestroy } from 'svelte'
|
||||
import { ContextMenu, ParentsNavigator } from '..'
|
||||
import { ContextMenu, ParentsNavigator, DocNavLink } from '..'
|
||||
import { categorizeFields, getCollectionCounter, getFiltredKeys } from '../utils'
|
||||
import DocAttributeBar from './DocAttributeBar.svelte'
|
||||
import UpDownNavigator from './UpDownNavigator.svelte'
|
||||
|
||||
export let _id: Ref<Doc>
|
||||
export let _class: Ref<Class<Doc>>
|
||||
export let embedded = false
|
||||
|
||||
let realObjectClass: Ref<Class<Doc>> = _class
|
||||
let lastId: Ref<Doc> = _id
|
||||
@ -203,21 +201,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function getIcon (_class: Ref<Class<Obj>> | undefined): Asset | undefined {
|
||||
if (_class === undefined) return undefined
|
||||
let clazz = hierarchy.getClass(_class)
|
||||
if (clazz.icon !== undefined) return clazz.icon
|
||||
while (clazz.extends !== undefined) {
|
||||
clazz = hierarchy.getClass(clazz.extends)
|
||||
if (clazz.icon != null) {
|
||||
return clazz.icon
|
||||
}
|
||||
}
|
||||
// throw new Error(`Icon not found for ${_class}`)
|
||||
}
|
||||
|
||||
$: icon = getIcon(realObjectClass)
|
||||
|
||||
let title: string = ''
|
||||
let rawTitle: string = ''
|
||||
|
||||
@ -282,20 +265,15 @@
|
||||
let content: HTMLElement
|
||||
</script>
|
||||
|
||||
{#if !embedded}
|
||||
<ActionContext
|
||||
context={{
|
||||
mode: 'editor'
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
<ActionContext
|
||||
context={{
|
||||
mode: 'editor'
|
||||
}}
|
||||
/>
|
||||
|
||||
{#if object !== undefined && finalTitle !== undefined}
|
||||
<Panel
|
||||
{icon}
|
||||
title={finalTitle}
|
||||
{object}
|
||||
{embedded}
|
||||
isHeader={mainEditor?.pinned ?? false}
|
||||
isAside={true}
|
||||
bind:content
|
||||
@ -309,18 +287,19 @@
|
||||
withoutActivity={!activityOptions.enabled}
|
||||
withoutInput={!activityOptions.showInput}
|
||||
>
|
||||
<svelte:fragment slot="navigator">
|
||||
{#if !embedded}
|
||||
<UpDownNavigator element={object} />
|
||||
<ParentsNavigator element={object} />
|
||||
{/if}
|
||||
<svelte:fragment slot="title">
|
||||
<ParentsNavigator element={object} />
|
||||
<DocNavLink noUnderline {object}>
|
||||
<div class="title">{finalTitle}</div>
|
||||
</DocNavLink>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="utils">
|
||||
<Button icon={IconMoreH} kind={'ghost'} size={'medium'} on:click={showMenu} />
|
||||
<Button icon={IconMoreH} iconProps={{ size: 'medium' }} kind={'icon'} on:click={showMenu} />
|
||||
<Button
|
||||
icon={IconMixin}
|
||||
kind={'ghost'}
|
||||
iconProps={{ size: 'medium' }}
|
||||
kind={'icon'}
|
||||
selected={showAllMixins}
|
||||
on:click={() => {
|
||||
showAllMixins = !showAllMixins
|
||||
@ -333,7 +312,7 @@
|
||||
{#if headerEditor !== undefined}
|
||||
<Component
|
||||
is={headerEditor}
|
||||
props={{ object, keys, mixins, ignoreKeys, vertical: dir === 'column', allowedCollections, embedded }}
|
||||
props={{ object, keys, mixins, ignoreKeys, vertical: dir === 'column', allowedCollections }}
|
||||
on:update={updateKeys}
|
||||
/>
|
||||
{:else if dir === 'column'}
|
||||
|
@ -58,7 +58,13 @@
|
||||
if (attributeModel) {
|
||||
const breadcrumbsModel: BreadcrumbsModel = {
|
||||
component: attributeModel.presenter,
|
||||
props: { shouldShowAvatar: false, ...(attributeModel.props ?? {}), value: parent }
|
||||
props: {
|
||||
shouldShowAvatar: false,
|
||||
noUnderline: true,
|
||||
noSelect: true,
|
||||
...(attributeModel.props ?? {}),
|
||||
value: parent
|
||||
}
|
||||
}
|
||||
|
||||
models.push(breadcrumbsModel)
|
||||
@ -71,6 +77,6 @@
|
||||
|
||||
{#await getBreadcrumbsModels(element) then models}
|
||||
{#if models.length > 0}
|
||||
<Breadcrumbs {models} gap="none" />
|
||||
<Breadcrumbs {models} />
|
||||
{/if}
|
||||
{/await}
|
||||
|
@ -97,7 +97,7 @@
|
||||
Mem: {data.statistics.memoryUsed} / {data.statistics.memoryTotal} CPU: {data.statistics.cpuUsage}
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="navigator">
|
||||
<svelte:fragment slot="title">
|
||||
<span class="p-3"> Server manager </span>
|
||||
<TabList
|
||||
items={tabs}
|
||||
|
@ -17,7 +17,7 @@
|
||||
import type { Class, Ref, Space } from '@hcengineering/core'
|
||||
import core from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { EditBox, Icon, Label, Scroller, Panel, Component } from '@hcengineering/ui'
|
||||
import { EditBox, Label, Scroller, Panel, Component } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import workbench from '../../plugin'
|
||||
import contact from '@hcengineering/contact'
|
||||
@ -62,12 +62,7 @@
|
||||
>
|
||||
<svelte:fragment slot="title">
|
||||
{#if clazz}
|
||||
<div class="antiTitle icon-wrapper">
|
||||
<div class="wrapped-icon">
|
||||
{#if clazz.icon}<Icon icon={clazz.icon} size={'medium'} />{/if}
|
||||
</div>
|
||||
<span class="wrapped-title"><Label label={clazz.label} /></span>
|
||||
</div>
|
||||
<div class="title not-active"><Label label={clazz.label} /></div>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
|
@ -9,7 +9,7 @@ export class ApplicationsDetailsPage extends CommonRecruitingPage {
|
||||
constructor (page: Page) {
|
||||
super(page)
|
||||
this.page = page
|
||||
this.textApplicationId = page.locator('div.popupPanel-title div.title-wrapper > span')
|
||||
this.textApplicationId = page.locator('div.popupPanel-title a.noUnderline > div.title')
|
||||
this.buttonState = page
|
||||
.locator('div[class*="collapsed-container"]')
|
||||
.nth(0)
|
||||
|
@ -22,7 +22,7 @@ export class CommonRecruitingPage extends CalendarPage {
|
||||
this.inputAddAttachment = page.locator('div.antiSection #file')
|
||||
this.textAttachmentName = page.locator('div.name a')
|
||||
this.buttonCreateFirstReview = page.locator('span:has-text("Create review")')
|
||||
this.buttonMoreActions = page.locator('div.popupPanel-title div.buttons-group > button:nth-of-type(2)')
|
||||
this.buttonMoreActions = page.locator('.popupPanel-title > .flex-row-center > button >> nth=0')
|
||||
this.buttonDelete = page.locator('button[class*="menuItem"] span', { hasText: 'Delete' })
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user