mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
Update Panel layout. (#1591)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
21f0928e71
commit
c4267cc7ae
@ -19,49 +19,108 @@
|
|||||||
import type { Doc } from '@anticrm/core'
|
import type { Doc } from '@anticrm/core'
|
||||||
import notification from '@anticrm/notification'
|
import notification from '@anticrm/notification'
|
||||||
import type { Asset } from '@anticrm/platform'
|
import type { Asset } from '@anticrm/platform'
|
||||||
import { AnyComponent, AnySvelteComponent, Component, Panel } from '@anticrm/ui'
|
import { AnyComponent, AnySvelteComponent, Component, Panel, Icon } from '@anticrm/ui'
|
||||||
|
|
||||||
export let title: string | undefined = undefined
|
export let title: string | undefined = undefined
|
||||||
export let subtitle: string | undefined = undefined
|
export let subtitle: string | undefined = undefined
|
||||||
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
||||||
export let showHeader: boolean = true
|
|
||||||
export let rightSection: AnyComponent | undefined = undefined
|
export let rightSection: AnyComponent | undefined = undefined
|
||||||
export let object: Doc
|
export let object: Doc
|
||||||
export let panelWidth: number = 0
|
export let panelWidth: number = 0
|
||||||
export let innerWidth: number = 0
|
export let innerWidth: number = 0
|
||||||
export let isSubtitle: boolean = false
|
export let isHeader: boolean = true
|
||||||
export let isProperties: boolean = false
|
export let isSub: boolean = true
|
||||||
|
export let isAside: boolean = true
|
||||||
|
export let minimize: boolean = false
|
||||||
|
|
||||||
|
let docWidth: number = 0
|
||||||
|
$: minimize = docWidth < 1280 && docWidth >= 1024
|
||||||
|
$: needHeader = $$slots.header || minimize || isHeader
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<svelte:window bind:innerWidth={docWidth} />
|
||||||
<Panel
|
<Panel
|
||||||
{title}
|
|
||||||
{subtitle}
|
|
||||||
{icon}
|
|
||||||
rightSection={rightSection !== undefined}
|
rightSection={rightSection !== undefined}
|
||||||
{showHeader}
|
bind:isAside
|
||||||
|
isHeader={needHeader}
|
||||||
bind:panelWidth
|
bind:panelWidth
|
||||||
bind:innerWidth
|
bind:innerWidth
|
||||||
isProperties={innerWidth >= 500 || isProperties}
|
|
||||||
isSubtitle={innerWidth < 900 || isSubtitle}
|
|
||||||
on:close
|
on:close
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="subtitle">
|
<svelte:fragment slot="title">
|
||||||
{#if $$slots.subtitle}<slot name="subtitle" />{/if}
|
<div class="popupPanel-title__content-container antiTitle">
|
||||||
|
{#if $$slots.navigator}
|
||||||
|
<div class="buttons-group xsmall-gap mr-4">
|
||||||
|
<slot name="navigator" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#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}<span class="wrapped-subtitle">{subtitle}</span>{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="properties">
|
|
||||||
{#if $$slots.properties}<slot name="properties" />{/if}
|
<svelte:fragment slot="utils">
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="navigate-actions">
|
|
||||||
<slot name="navigate-actions" />
|
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="commands">
|
|
||||||
<div class="buttons-group xsmall-gap">
|
|
||||||
<Component is={calendar.component.DocReminder} props={{ value: object, title }} />
|
<Component is={calendar.component.DocReminder} props={{ value: object, title }} />
|
||||||
<Component is={notification.component.LastViewEditor} props={{ value: object }} />
|
<Component is={notification.component.LastViewEditor} props={{ value: object }} />
|
||||||
</div>
|
{#if $$slots.utils}
|
||||||
<slot name="actions" />
|
<div class="buttons-divider" />
|
||||||
|
<slot name="utils" />
|
||||||
|
{/if}
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<Component is={rightSection ?? activity.component.Activity} props={{ object, integrate: true }}>
|
|
||||||
|
<svelte:fragment slot="header">
|
||||||
|
{#if $$slots.header || ($$slots.actions && minimize)}
|
||||||
|
<div class="header-row between">
|
||||||
|
{#if $$slots.header}<slot name="header" />{/if}
|
||||||
|
<div class="buttons-group xsmall-gap ml-4">
|
||||||
|
<slot name="tools" />
|
||||||
|
{#if $$slots.actions && minimize}
|
||||||
|
<div class="buttons-divider" />
|
||||||
|
<slot name="actions" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if $$slots['custom-attributes']}
|
||||||
|
{#if isSub}<div class="header-row"><slot name="custom-attributes" direction="row" /></div>{/if}
|
||||||
|
{:else}
|
||||||
|
{#if $$slots.attributes && minimize}<div class="header-row"><slot name="attributes" direction="row" /></div>{/if}
|
||||||
|
{/if}
|
||||||
|
</svelte:fragment>
|
||||||
|
|
||||||
|
<svelte:fragment slot="aside">
|
||||||
|
<div style="padding: .75rem 1.5rem">
|
||||||
|
{#if $$slots.actions}
|
||||||
|
<div class="flex-row-center pb-3 bottom-divider">
|
||||||
|
<span class="fs-bold w-24 mr-6"><slot name="actions-label" /></span>
|
||||||
|
<div class="buttons-group xsmall-gap">
|
||||||
|
<slot name="actions" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if $$slots['custom-attributes']}
|
||||||
|
<slot name="custom-attributes" direction="column" />
|
||||||
|
{:else}
|
||||||
|
{#if $$slots.attributes}<slot name="attributes" direction="column" />{/if}
|
||||||
|
{/if}
|
||||||
|
{#if $$slots.aside}<slot name="aside" />{/if}
|
||||||
|
</div>
|
||||||
|
</svelte:fragment>
|
||||||
|
|
||||||
|
{#if rightSection !== undefined}
|
||||||
|
<slot />
|
||||||
|
{:else}
|
||||||
|
<Component is={activity.component.Activity} props={{ object, integrate: true }}>
|
||||||
<slot />
|
<slot />
|
||||||
</Component>
|
</Component>
|
||||||
|
{/if}
|
||||||
</Panel>
|
</Panel>
|
||||||
|
@ -80,6 +80,8 @@
|
|||||||
--popup-bg-hover: #37373c;
|
--popup-bg-hover: #37373c;
|
||||||
--popup-divider: #313236;
|
--popup-divider: #313236;
|
||||||
--popup-shadow: rgb(0 0 0 / 20%) 0px 4px 24px;
|
--popup-shadow: rgb(0 0 0 / 20%) 0px 4px 24px;
|
||||||
|
--popup-panel-shadow: rgb(0 0 0 / 55%) 0px 7px 24px;
|
||||||
|
--popup-aside-shadow: rgb(0 0 0 / 25%) 0px 8px 16px;
|
||||||
--card-shadow: rgb(0 0 0 / 50%) 0px 16px 70px;
|
--card-shadow: rgb(0 0 0 / 50%) 0px 16px 70px;
|
||||||
--card-overlay-color: rgba(28, 29, 31, .5);
|
--card-overlay-color: rgba(28, 29, 31, .5);
|
||||||
--avatar-bg-color: #4f5358;
|
--avatar-bg-color: #4f5358;
|
||||||
@ -220,6 +222,7 @@
|
|||||||
--popup-bg-hover: #f8f9fb;
|
--popup-bg-hover: #f8f9fb;
|
||||||
--popup-divider: #eff1f4;
|
--popup-divider: #eff1f4;
|
||||||
--popup-shadow: rgb(0 0 0 / 20%) 0px 4px 24px; // Dark
|
--popup-shadow: rgb(0 0 0 / 20%) 0px 4px 24px; // Dark
|
||||||
|
--popup-panel-shadow: rgb(0 0 0 / 55%) 0px 7px 24px; // Dark
|
||||||
--card-shadow: rgb(0 0 0 / 50%) 0px 16px 70px;
|
--card-shadow: rgb(0 0 0 / 50%) 0px 16px 70px;
|
||||||
--card-overlay-color: rgba(144, 149, 157, .4);
|
--card-overlay-color: rgba(144, 149, 157, .4);
|
||||||
--avatar-bg-color: #e0e0e0; // HZ
|
--avatar-bg-color: #e0e0e0; // HZ
|
||||||
|
@ -263,6 +263,12 @@ p:last-child { margin-block-end: 0; }
|
|||||||
grid-auto-flow: row;
|
grid-auto-flow: row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.buttons-divider {
|
||||||
|
min-width: 1px;
|
||||||
|
width: 1px;
|
||||||
|
height: 1.5rem;
|
||||||
|
background-color: var(--divider-color);
|
||||||
|
}
|
||||||
|
|
||||||
.gap-1, .gap-1-5, .gap-2 {
|
.gap-1, .gap-1-5, .gap-2 {
|
||||||
& > *:not(:last-child) { margin-right: .25rem; }
|
& > *:not(:last-child) { margin-right: .25rem; }
|
||||||
@ -365,6 +371,7 @@ p:last-child { margin-block-end: 0; }
|
|||||||
.pb-3 { padding-bottom: .75rem; }
|
.pb-3 { padding-bottom: .75rem; }
|
||||||
.pb-4 { padding-bottom: 1rem; }
|
.pb-4 { padding-bottom: 1rem; }
|
||||||
.px-2 { padding: 0 .5rem; }
|
.px-2 { padding: 0 .5rem; }
|
||||||
|
.px-3 { padding: 0 .75rem; }
|
||||||
.px-4 { padding: 0 1rem; }
|
.px-4 { padding: 0 1rem; }
|
||||||
|
|
||||||
.p-1 { padding: .25rem; }
|
.p-1 { padding: .25rem; }
|
||||||
@ -419,6 +426,7 @@ p:last-child { margin-block-end: 0; }
|
|||||||
.h-7 { height: 1.75rem; }
|
.h-7 { height: 1.75rem; }
|
||||||
.h-8 { height: 2rem; }
|
.h-8 { height: 2rem; }
|
||||||
.h-9 { height: 2.25rem; }
|
.h-9 { height: 2.25rem; }
|
||||||
|
.h-14 { height: 3.5rem; }
|
||||||
.h-16 { height: 4rem; }
|
.h-16 { height: 4rem; }
|
||||||
.h-18 { height: 4.5rem; }
|
.h-18 { height: 4.5rem; }
|
||||||
.w-full { width: 100%; }
|
.w-full { width: 100%; }
|
||||||
|
@ -202,3 +202,48 @@
|
|||||||
.antiNav-bottomFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 1px, rgba(0, 0, 0, 1) calc(100% - 2rem), rgba(0, 0, 0, 0) 100%); }
|
.antiNav-bottomFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 1px, rgba(0, 0, 0, 1) calc(100% - 2rem), rgba(0, 0, 0, 0) 100%); }
|
||||||
.antiNav-bothFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 2rem, rgba(0, 0, 0, 1) calc(100% - 2rem), rgba(0, 0, 0, 0) 100%); }
|
.antiNav-bothFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 2rem, rgba(0, 0, 0, 1) calc(100% - 2rem), rgba(0, 0, 0, 0) 100%); }
|
||||||
.antiNav-noneFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 1px, rgba(0, 0, 0, 1) calc(100% - 1px), rgba(0, 0, 0, 0) 100%); }
|
.antiNav-noneFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 1px, rgba(0, 0, 0, 1) calc(100% - 1px), rgba(0, 0, 0, 0) 100%); }
|
||||||
|
|
||||||
|
/* Basic */
|
||||||
|
.antiTitle {
|
||||||
|
.icon-wrapper,
|
||||||
|
.title-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.title-wrapper {
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.icon-wrapper { align-items: center; }
|
||||||
|
|
||||||
|
.wrapped-icon {
|
||||||
|
margin-right: .75rem;
|
||||||
|
color: var(--content-color);
|
||||||
|
}
|
||||||
|
.wrapped-title {
|
||||||
|
min-width: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--caption-color);
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.wrapped-subtitle {
|
||||||
|
min-width: 0;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--dark-color);
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: visible;
|
||||||
|
display: -webkit-box;
|
||||||
|
/* autoprefixer: ignore next */
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
line-clamp: 2;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -55,3 +55,159 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.popupPanel {
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: .5rem;
|
||||||
|
box-shadow: var(--popup-panel-shadow);
|
||||||
|
|
||||||
|
.popupPanel-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: stretch;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: .5rem .75rem;
|
||||||
|
width: 100%;
|
||||||
|
height: 3rem;
|
||||||
|
max-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;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
&-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: stretch;
|
||||||
|
min-width: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popupPanel-body {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: stretch;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--body-color);
|
||||||
|
border: 1px solid var(--divider-color);
|
||||||
|
border-radius: 0 0 .5rem .5rem;
|
||||||
|
|
||||||
|
&__main, &__aside {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__main {
|
||||||
|
flex-grow: 2;
|
||||||
|
flex-basis: 760px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: .75rem 1.25rem;
|
||||||
|
width: calc(100% - 5rem);
|
||||||
|
min-width: 0;
|
||||||
|
max-width: 900px;
|
||||||
|
border-bottom: 1px solid var(--divider-color);
|
||||||
|
|
||||||
|
.header-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
&.between { justify-content: space-between; }
|
||||||
|
}
|
||||||
|
.header-row + .header-row { margin-top: .625rem; }
|
||||||
|
}
|
||||||
|
&-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: calc(100% - 7.5rem);
|
||||||
|
height: 100%;
|
||||||
|
max-width: 860px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__aside {
|
||||||
|
position: relative;
|
||||||
|
width: 25%;
|
||||||
|
min-width: 320px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
top: 1rem;
|
||||||
|
bottom: 1rem;
|
||||||
|
left: 0;
|
||||||
|
width: 0;
|
||||||
|
border-left: 1px solid var(--divider-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.float {
|
||||||
|
position: absolute;
|
||||||
|
flex-shrink: 0;
|
||||||
|
top: 0;
|
||||||
|
left: 100%;
|
||||||
|
width: 320px;
|
||||||
|
height: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
background-color: var(--board-card-bg-color);
|
||||||
|
border-top: 1px solid var(--board-card-bg-color);
|
||||||
|
border-left: 1px solid var(--divider-color);
|
||||||
|
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
|
||||||
|
transition: box-shadow 150ms ease 0s, transform 150ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||||
|
transform: translateX(0);
|
||||||
|
|
||||||
|
&::before { content: none; }
|
||||||
|
&.shown {
|
||||||
|
box-shadow: var(--popup-aside-shadow);
|
||||||
|
transform: translateX(-100%);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
top: 0;
|
||||||
|
left: 100%;
|
||||||
|
width: 360px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--board-card-bg-color);
|
||||||
|
border: 1px solid var(--board-card-bg-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.asideShown {
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
.popupPanel-body__main {
|
||||||
|
border: 1px solid var(--divider-color);
|
||||||
|
border-radius: 0 0 .5rem .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
export let width: string | undefined = undefined
|
export let width: string | undefined = undefined
|
||||||
export let resetIconSize: boolean = false
|
export let resetIconSize: boolean = false
|
||||||
export let highlight: boolean = false
|
export let highlight: boolean = false
|
||||||
|
export let selected: boolean = false
|
||||||
export let focus: boolean = false
|
export let focus: boolean = false
|
||||||
export let click: boolean = false
|
export let click: boolean = false
|
||||||
export let title: string | undefined = undefined
|
export let title: string | undefined = undefined
|
||||||
@ -60,6 +61,7 @@
|
|||||||
class:border-radius-2={shape === 'round'}
|
class:border-radius-2={shape === 'round'}
|
||||||
class:border-radius-4={shape === 'circle'}
|
class:border-radius-4={shape === 'circle'}
|
||||||
class:highlight
|
class:highlight
|
||||||
|
class:selected
|
||||||
disabled={disabled || loading}
|
disabled={disabled || loading}
|
||||||
style={width ? 'width: ' + width : ''}
|
style={width ? 'width: ' + width : ''}
|
||||||
{title}
|
{title}
|
||||||
@ -215,9 +217,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.transparent:hover {
|
&.transparent:hover,
|
||||||
background-color: var(--button-bg-hover);
|
&.transparent.selected { background-color: var(--button-bg-hover); }
|
||||||
}
|
|
||||||
&.link {
|
&.link {
|
||||||
padding: 0 0.875rem;
|
padding: 0 0.875rem;
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -13,152 +13,65 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Asset } from '@anticrm/platform'
|
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import { AnySvelteComponent } from '../types'
|
import { Button, IconClose, IconDetails, Scroller } from '..'
|
||||||
import Button from './Button.svelte'
|
|
||||||
import Icon from './Icon.svelte'
|
|
||||||
import IconClose from './icons/Close.svelte'
|
|
||||||
|
|
||||||
export let title: string | undefined = undefined
|
|
||||||
export let subtitle: string | undefined = undefined
|
|
||||||
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
|
||||||
export let rightSection: boolean = false
|
export let rightSection: boolean = false
|
||||||
export let showHeader: boolean = true
|
|
||||||
export let innerWidth: number = 0
|
export let innerWidth: number = 0
|
||||||
export let panelWidth: number = 0
|
export let panelWidth: number = 0
|
||||||
export let isSubtitle: boolean = true
|
export let isHeader: boolean = true
|
||||||
export let isProperties: boolean = true
|
export let isAside: boolean = true
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
let asideFloat: boolean = false
|
||||||
|
let asideShown: boolean = false
|
||||||
|
let docWidth: number
|
||||||
|
$: if (docWidth < 1024 && !asideFloat) asideFloat = true
|
||||||
|
$: if (docWidth >= 1024 && asideFloat) {
|
||||||
|
asideFloat = false
|
||||||
|
asideShown = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="antiPanel antiComponent" bind:clientWidth={panelWidth}>
|
<svelte:window bind:innerWidth={docWidth} />
|
||||||
<div class="panel-content-container">
|
<div class="popupPanel" bind:clientWidth={panelWidth}>
|
||||||
{#if showHeader}
|
<div class="popupPanel-title">
|
||||||
<div class="ac-header short mirror divide highlight">
|
<Button icon={IconClose} kind={'transparent'} size={'medium'} on:click={() => { dispatch('close') }} />
|
||||||
<div class="buttons-group">
|
<div class="popupPanel-title__content"><slot name="title" /></div>
|
||||||
|
<div class="buttons-group xsmall-gap">
|
||||||
|
<slot name="utils" />
|
||||||
|
{#if asideFloat}
|
||||||
|
{#if $$slots.utils}<div class="buttons-divider" />{/if}
|
||||||
<Button
|
<Button
|
||||||
icon={IconClose}
|
icon={IconDetails}
|
||||||
size={'medium'}
|
|
||||||
kind={'transparent'}
|
kind={'transparent'}
|
||||||
|
size={'medium'}
|
||||||
|
selected={asideShown}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
dispatch('close')
|
asideShown = !asideShown
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{#if $$slots['navigate-actions']}
|
|
||||||
<div class="buttons-group xsmall-gap">
|
|
||||||
<slot name="navigate-actions" />
|
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4 ac-header__wrap-title flex-grow">
|
</div>
|
||||||
{#if icon}
|
<div class="popupPanel-body" class:asideShown>
|
||||||
<div class="ac-header__icon">
|
<div class="popupPanel-body__main" bind:clientWidth={innerWidth}>
|
||||||
<Icon {icon} size={'large'} />
|
{#if $$slots.header && isHeader}
|
||||||
|
<div class="popupPanel-body__main-header">
|
||||||
|
<slot name="header" />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="ac-header__wrap-description">
|
<Scroller>
|
||||||
{#if title}<span class="ac-header__title">{title}</span>{/if}
|
<div class="popupPanel-body__main-content">
|
||||||
{#if subtitle}<span class="ac-header__description">{subtitle}</span>{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="buttons-group xsmall-gap">
|
|
||||||
<slot name="commands" />
|
|
||||||
<slot name="actions" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div class="ac-header short mirror divide highlight">
|
|
||||||
<div class="buttons-group">
|
|
||||||
<Button
|
|
||||||
icon={IconClose}
|
|
||||||
size={'medium'}
|
|
||||||
kind={'transparent'}
|
|
||||||
on:click={() => {
|
|
||||||
dispatch('close')
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{#if $$slots['navigate-actions']}
|
|
||||||
<div class="buttons-group xsmall-gap">
|
|
||||||
<slot name="navigate-actions" />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{#if $$slots['custom-title']}
|
|
||||||
<div class="ml-4 flex-row-center flex-grow">
|
|
||||||
<slot name="custom-title" />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<div class="main-content" class:withProperties={$$slots.properties} bind:clientWidth={innerWidth}>
|
|
||||||
{#if $$slots.subtitle && $$slots.properties && isSubtitle}
|
|
||||||
<div class="flex-col flex-grow clear-mins">
|
|
||||||
<div class="ac-subtitle">
|
|
||||||
<div class="ac-subtitle-content">
|
|
||||||
<slot name="subtitle" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-col flex-grow clear-mins">
|
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
</Scroller>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{#if $$slots.aside && isAside}
|
||||||
<div class="flex-col flex-grow clear-mins">
|
<div class="popupPanel-body__aside" class:float={asideFloat} class:shown={asideShown}>
|
||||||
<slot />
|
<slot name="aside" />
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{#if rightSection}
|
|
||||||
<slot name="rightSection" />
|
|
||||||
{/if}
|
|
||||||
{#if $$slots.properties && isProperties}
|
|
||||||
<div class="properties-container">
|
|
||||||
<slot name="properties" />
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.panel-content-container {
|
|
||||||
display: flex;
|
|
||||||
flex-grow: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.main-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
min-width: 0;
|
|
||||||
min-height: 0;
|
|
||||||
flex-grow: 1;
|
|
||||||
// height: 100%;
|
|
||||||
|
|
||||||
&.withProperties {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
.properties-container {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex-shrink: 0;
|
|
||||||
min-width: 20rem;
|
|
||||||
width: 20rem;
|
|
||||||
border-left: 1px solid var(--divider-color);
|
|
||||||
// background-color: var(--board-card-bg-color);
|
|
||||||
|
|
||||||
// &::before {
|
|
||||||
// position: absolute;
|
|
||||||
// content: '';
|
|
||||||
// top: 1.5rem;
|
|
||||||
// bottom: 1.5rem;
|
|
||||||
// left: 0;
|
|
||||||
// width: 1px;
|
|
||||||
// background-color: var(--divider-color);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
25
packages/ui/src/components/icons/Details.svelte
Normal file
25
packages/ui/src/components/icons/Details.svelte
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||||
|
// Copyright © 2021 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">
|
||||||
|
export let size: 'x-small' | 'small' | 'medium' | 'large'
|
||||||
|
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>
|
@ -119,6 +119,7 @@ export { default as IconNavNext } from './components/icons/NavNext.svelte'
|
|||||||
export { default as IconDPCalendar } from './components/calendar/icons/DPCalendar.svelte'
|
export { default as IconDPCalendar } from './components/calendar/icons/DPCalendar.svelte'
|
||||||
export { default as IconDPCalendarOver } from './components/calendar/icons/DPCalendarOver.svelte'
|
export { default as IconDPCalendarOver } from './components/calendar/icons/DPCalendarOver.svelte'
|
||||||
export { default as IconOptions } from './components/icons/Options.svelte'
|
export { default as IconOptions } from './components/icons/Options.svelte'
|
||||||
|
export { default as IconDetails } from './components/icons/Details.svelte'
|
||||||
|
|
||||||
export { default as PanelInstance } from './components/PanelInstance.svelte'
|
export { default as PanelInstance } from './components/PanelInstance.svelte'
|
||||||
export { default as Panel } from './components/Panel.svelte'
|
export { default as Panel } from './components/Panel.svelte'
|
||||||
|
@ -195,6 +195,13 @@ export function fitPopupElement (modalHTML: HTMLElement, element?: PopupAlignmen
|
|||||||
newProps.left = '50%'
|
newProps.left = '50%'
|
||||||
newProps.transform = 'translateX(-50%)'
|
newProps.transform = 'translateX(-50%)'
|
||||||
show = true
|
show = true
|
||||||
|
} else if (element === 'float') {
|
||||||
|
newProps.top = 'calc(var(--status-bar-height) + .25rem)'
|
||||||
|
newProps.bottom = '.25rem'
|
||||||
|
newProps.width = '40rem'
|
||||||
|
newProps.maxWidth = '40%'
|
||||||
|
newProps.right = '.25rem'
|
||||||
|
show = true
|
||||||
} else if (element === 'account') {
|
} else if (element === 'account') {
|
||||||
newProps.bottom = '2.75rem'
|
newProps.bottom = '2.75rem'
|
||||||
newProps.left = '5rem'
|
newProps.left = '5rem'
|
||||||
|
@ -72,7 +72,7 @@ export interface PopupPositionElement {
|
|||||||
h: HorizontalAlignment
|
h: HorizontalAlignment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export type PopupAlignment = PopupPositionElement | null | 'right' | 'top' | 'account' | 'full' | 'content' | 'middle'
|
export type PopupAlignment = PopupPositionElement | null | 'right' | 'top' | 'float' | 'account' | 'full' | 'content' | 'middle'
|
||||||
export type TooltipAlignment = 'top' | 'bottom' | 'left' | 'right'
|
export type TooltipAlignment = 'top' | 'bottom' | 'left' | 'right'
|
||||||
export type VerticalAlignment = 'top' | 'bottom'
|
export type VerticalAlignment = 'top' | 'bottom'
|
||||||
export type HorizontalAlignment = 'left' | 'right'
|
export type HorizontalAlignment = 'left' | 'right'
|
||||||
|
@ -82,14 +82,13 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<Scroller>
|
<div class="mt-4 pb-4 bottom-highlight-select">
|
||||||
<div class="p-10 bottom-highlight-select">
|
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
<div class="ac-header short mirror-tool mt-2">
|
<div class="flex-row-center h-14 px-3 mt-4 antiTitle">
|
||||||
<div class="ac-header__wrap-title">
|
<div class="icon-wrapper">
|
||||||
<div class="flex-center icon"><IconActivity size={'small'} /></div>
|
<div class="wrapped-icon icon flex-center"><IconActivity size={'small'} /></div>
|
||||||
<span class="ac-header__title"><Label label={activity.string.Activity} /></span>
|
<span class="wrapped-title"><Label label={activity.string.Activity} /></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if showCommenInput}
|
{#if showCommenInput}
|
||||||
@ -106,7 +105,6 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</Scroller>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -120,10 +118,11 @@
|
|||||||
}
|
}
|
||||||
.ref-input {
|
.ref-input {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
padding: 1.5rem 2.5rem;
|
padding: 1.5rem 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
.p-activity {
|
.p-activity {
|
||||||
padding: 1.5rem 2.5rem;
|
padding: 1.5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.grid .msgactivity-container:last-child::after) {
|
:global(.grid .msgactivity-container:last-child::after) {
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
import type { State } from '@anticrm/task'
|
import type { State } from '@anticrm/task'
|
||||||
import task from '@anticrm/task'
|
import task from '@anticrm/task'
|
||||||
import { StyledTextBox } from '@anticrm/text-editor'
|
import { StyledTextBox } from '@anticrm/text-editor'
|
||||||
import { EditBox, Icon, Label } from '@anticrm/ui'
|
import { Button, EditBox, Icon, Label } from '@anticrm/ui'
|
||||||
import { UpDownNavigator } from '@anticrm/view-resources'
|
import { UpDownNavigator } from '@anticrm/view-resources'
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
import board from '../plugin'
|
import board from '../plugin'
|
||||||
@ -72,11 +72,20 @@
|
|||||||
onMount(() => {
|
onMount(() => {
|
||||||
dispatch('open', { ignoreKeys: ['comments', 'number', 'title'] })
|
dispatch('open', { ignoreKeys: ['comments', 'number', 'title'] })
|
||||||
})
|
})
|
||||||
|
let minimize: boolean = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if object !== undefined}
|
{#if object !== undefined}
|
||||||
<Panel icon={board.icon.Card} title={object?.title} {object} on:close={() => dispatch('close')}>
|
<Panel
|
||||||
<svelte:fragment slot="navigate-actions">
|
icon={board.icon.Card}
|
||||||
|
title={object?.title}
|
||||||
|
{object}
|
||||||
|
bind:minimize
|
||||||
|
isHeader={minimize}
|
||||||
|
isAside={!minimize}
|
||||||
|
on:close={() => dispatch('close')}
|
||||||
|
>
|
||||||
|
<svelte:fragment slot="navigator">
|
||||||
<UpDownNavigator element={object}/>
|
<UpDownNavigator element={object}/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
||||||
@ -128,8 +137,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<svelte:fragment slot="properties">
|
<svelte:fragment slot="custom-attributes" let:direction>
|
||||||
<div class="p-4"><CardActions bind:value={object} /></div>
|
{#if direction === 'column'}
|
||||||
|
<CardActions bind:value={object} />
|
||||||
|
{:else}
|
||||||
|
<Button icon={board.icon.Card} label={board.string.Actions} kind={'no-border'} size={'small'} />
|
||||||
|
{/if}
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</Panel>
|
</Panel>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
import type { ButtonKind, ButtonSize } from '@anticrm/ui'
|
import type { ButtonKind, ButtonSize } from '@anticrm/ui'
|
||||||
import ChannelsDropdown from './ChannelsDropdown.svelte'
|
import ChannelsDropdown from './ChannelsDropdown.svelte'
|
||||||
import { showPanel } from '@anticrm/ui'
|
import { showPanel } from '@anticrm/ui'
|
||||||
import view from '@anticrm/view'
|
|
||||||
|
|
||||||
export let value: Channel[] | Channel | null
|
export let value: Channel[] | Channel | null
|
||||||
|
|
||||||
@ -32,7 +31,13 @@
|
|||||||
if (ev.detail.presenter !== undefined && Array.isArray(value)) {
|
if (ev.detail.presenter !== undefined && Array.isArray(value)) {
|
||||||
const channel = value[0]
|
const channel = value[0]
|
||||||
if (channel !== undefined) {
|
if (channel !== undefined) {
|
||||||
showPanel(view.component.EditDoc, channel.attachedTo, channel.attachedToClass, 'content', ev.detail.presenter)
|
showPanel(
|
||||||
|
ev.detail.presenter,
|
||||||
|
channel.attachedTo,
|
||||||
|
channel.attachedToClass,
|
||||||
|
'float',
|
||||||
|
ev.detail.presenter
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
"@anticrm/attachment": "~0.6.1",
|
"@anticrm/attachment": "~0.6.1",
|
||||||
"@anticrm/attachment-resources": "~0.6.0",
|
"@anticrm/attachment-resources": "~0.6.0",
|
||||||
"@anticrm/login": "~0.6.1",
|
"@anticrm/login": "~0.6.1",
|
||||||
"@anticrm/core": "~0.6.16"
|
"@anticrm/core": "~0.6.16",
|
||||||
|
"@anticrm/panel": "~0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,6 +195,7 @@
|
|||||||
border-bottom: 1px solid var(--theme-zone-bg);
|
border-bottom: 1px solid var(--theme-zone-bg);
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
|
flex-shrink: 0;
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
width: 2.25rem;
|
width: 2.25rem;
|
||||||
height: 2.25rem;
|
height: 2.25rem;
|
||||||
@ -206,6 +207,6 @@
|
|||||||
|
|
||||||
.right-content {
|
.right-content {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
padding: 1.5rem 1rem;
|
padding: 1.5rem 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -14,31 +14,49 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Channel, Contact } from '@anticrm/contact'
|
import type { AnyComponent } from '@anticrm/ui'
|
||||||
|
import { Ref, Doc, Class } from '@anticrm/core'
|
||||||
|
import contact, { Channel } from '@anticrm/contact'
|
||||||
import { SharedMessage } from '@anticrm/gmail'
|
import { SharedMessage } from '@anticrm/gmail'
|
||||||
import NewMessage from './NewMessage.svelte'
|
import NewMessage from './NewMessage.svelte'
|
||||||
import FullMessage from './FullMessage.svelte'
|
import FullMessage from './FullMessage.svelte'
|
||||||
import Chats from './Chats.svelte'
|
import Chats from './Chats.svelte'
|
||||||
import { getClient } from '@anticrm/presentation'
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
import { NotificationClientImpl } from '@anticrm/notification-resources'
|
import { NotificationClientImpl } from '@anticrm/notification-resources'
|
||||||
|
import { Panel } from '@anticrm/panel'
|
||||||
|
import { createEventDispatcher } from 'svelte'
|
||||||
|
|
||||||
export let object: Contact
|
export let _id: Ref<Doc>
|
||||||
|
export let _class: Ref<Class<Doc>>
|
||||||
|
export let rightSection: AnyComponent | undefined = undefined
|
||||||
|
|
||||||
|
// export let object: Contact
|
||||||
|
// $: console.log('!!!!!!!!!!!! id: ', _id, ' - class: ', _class)
|
||||||
|
let object: any
|
||||||
let newMessage: boolean = false
|
let newMessage: boolean = false
|
||||||
let currentMessage: SharedMessage | undefined = undefined
|
let currentMessage: SharedMessage | undefined = undefined
|
||||||
let channel: Channel | undefined = undefined
|
let channel: Channel | undefined = undefined
|
||||||
const notificationClient = NotificationClientImpl.getClient()
|
const notificationClient = NotificationClientImpl.getClient()
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
client
|
client
|
||||||
.findOne(contact.class.Channel, {
|
.findOne(contact.class.Channel, {
|
||||||
attachedTo: object._id,
|
attachedTo: _id,
|
||||||
provider: contact.channelProvider.Email
|
provider: contact.channelProvider.Email
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
channel = res
|
channel = res
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const query = createQuery()
|
||||||
|
$: _id &&
|
||||||
|
_class &&
|
||||||
|
query.query(_class, { _id }, (result) => {
|
||||||
|
object = result[0]
|
||||||
|
})
|
||||||
|
|
||||||
function back () {
|
function back () {
|
||||||
if (newMessage) {
|
if (newMessage) {
|
||||||
return (newMessage = false)
|
return (newMessage = false)
|
||||||
@ -54,7 +72,18 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if channel}
|
{#if channel && object}
|
||||||
|
<Panel
|
||||||
|
icon={contact.icon.Email}
|
||||||
|
title={'Email'}
|
||||||
|
{rightSection}
|
||||||
|
{object}
|
||||||
|
isHeader={false}
|
||||||
|
isAside={false}
|
||||||
|
on:close={() => {
|
||||||
|
dispatch('close')
|
||||||
|
}}
|
||||||
|
>
|
||||||
{#if newMessage}
|
{#if newMessage}
|
||||||
<NewMessage {object} {channel} {currentMessage} on:close={back} />
|
<NewMessage {object} {channel} {currentMessage} on:close={back} />
|
||||||
{:else if currentMessage}
|
{:else if currentMessage}
|
||||||
@ -62,4 +91,5 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<Chats {object} {channel} bind:newMessage on:select={selectHandler} />
|
<Chats {object} {channel} bind:newMessage on:select={selectHandler} />
|
||||||
{/if}
|
{/if}
|
||||||
|
</Panel>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
"@anticrm/core": "~0.6.16",
|
"@anticrm/core": "~0.6.16",
|
||||||
"@anticrm/notification-resources": "~0.6.0",
|
"@anticrm/notification-resources": "~0.6.0",
|
||||||
"@anticrm/attachment": "~0.6.1",
|
"@anticrm/attachment": "~0.6.1",
|
||||||
"@anticrm/attachment-resources": "~0.6.0"
|
"@anticrm/attachment-resources": "~0.6.0",
|
||||||
|
"@anticrm/panel": "~0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,12 +16,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import attachment from '@anticrm/attachment'
|
import attachment from '@anticrm/attachment'
|
||||||
import { AttachmentRefInput } from '@anticrm/attachment-resources'
|
import { AttachmentRefInput } from '@anticrm/attachment-resources'
|
||||||
import contact, { Channel, Contact, EmployeeAccount, formatName } from '@anticrm/contact'
|
import { Panel } from '@anticrm/panel'
|
||||||
import { generateId, getCurrentAccount, Ref, SortingOrder, Space } from '@anticrm/core'
|
import { createEventDispatcher } from 'svelte'
|
||||||
|
import contact, { Channel, EmployeeAccount, formatName } from '@anticrm/contact'
|
||||||
|
import { generateId, getCurrentAccount, Ref, SortingOrder, Space, Doc, Class } from '@anticrm/core'
|
||||||
import { NotificationClientImpl } from '@anticrm/notification-resources'
|
import { NotificationClientImpl } from '@anticrm/notification-resources'
|
||||||
import { createQuery, getClient } from '@anticrm/presentation'
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
import setting, { Integration } from '@anticrm/setting'
|
import setting, { Integration } from '@anticrm/setting'
|
||||||
import type { NewTelegramMessage, SharedTelegramMessage, TelegramMessage } from '@anticrm/telegram'
|
import type { NewTelegramMessage, SharedTelegramMessage, TelegramMessage } from '@anticrm/telegram'
|
||||||
|
import type { AnyComponent } from '@anticrm/ui'
|
||||||
import { Button, eventToHTMLElement, IconShare, Tooltip, Scroller, showPopup } from '@anticrm/ui'
|
import { Button, eventToHTMLElement, IconShare, Tooltip, Scroller, showPopup } from '@anticrm/ui'
|
||||||
import telegram from '../plugin'
|
import telegram from '../plugin'
|
||||||
import Connect from './Connect.svelte'
|
import Connect from './Connect.svelte'
|
||||||
@ -29,22 +32,35 @@
|
|||||||
import Messages from './Messages.svelte'
|
import Messages from './Messages.svelte'
|
||||||
import Reconnect from './Reconnect.svelte'
|
import Reconnect from './Reconnect.svelte'
|
||||||
|
|
||||||
export let object: Contact
|
export let _id: Ref<Doc>
|
||||||
|
export let _class: Ref<Class<Doc>>
|
||||||
|
export let rightSection: AnyComponent | undefined = undefined
|
||||||
|
|
||||||
|
let object: any
|
||||||
let channel: Channel | undefined = undefined
|
let channel: Channel | undefined = undefined
|
||||||
let objectId: Ref<NewTelegramMessage> = generateId()
|
let objectId: Ref<NewTelegramMessage> = generateId()
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const notificationClient = NotificationClientImpl.getClient()
|
const notificationClient = NotificationClientImpl.getClient()
|
||||||
|
|
||||||
client
|
client
|
||||||
.findOne(contact.class.Channel, {
|
.findOne(contact.class.Channel, {
|
||||||
attachedTo: object._id,
|
attachedTo: _id,
|
||||||
provider: contact.channelProvider.Telegram
|
provider: contact.channelProvider.Telegram
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
channel = res
|
channel = res
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const query = createQuery()
|
||||||
|
$: _id &&
|
||||||
|
_class &&
|
||||||
|
query.query(_class, { _id }, (result) => {
|
||||||
|
object = result[0]
|
||||||
|
})
|
||||||
|
|
||||||
let messages: TelegramMessage[] = []
|
let messages: TelegramMessage[] = []
|
||||||
let accounts: EmployeeAccount[] = []
|
let accounts: EmployeeAccount[] = []
|
||||||
let integration: Integration | undefined
|
let integration: Integration | undefined
|
||||||
@ -171,14 +187,22 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="telegram-header">
|
{#if object !== undefined}
|
||||||
<div class="ac-header__wrap-title">
|
<Panel
|
||||||
<div class="flex-center icon"><TelegramIcon size={'small'} /></div>
|
icon={TelegramIcon}
|
||||||
<div class="ac-header__wrap-description">
|
title={'Telegram'}
|
||||||
<span class="ac-header__title">Telegram</span>
|
{rightSection}
|
||||||
<span class="ac-header__description">You and {formatName(object.name)}</span>
|
{object}
|
||||||
</div>
|
isHeader={false}
|
||||||
</div>
|
isAside={false}
|
||||||
|
on:close={() => {
|
||||||
|
dispatch('close')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svelte:fragment slot="header">
|
||||||
|
You and {formatName(object.name)}
|
||||||
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot="tools">
|
||||||
<Tooltip label={telegram.string.Share}>
|
<Tooltip label={telegram.string.Share}>
|
||||||
<Button
|
<Button
|
||||||
icon={IconShare}
|
icon={IconShare}
|
||||||
@ -189,7 +213,8 @@
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</svelte:fragment>
|
||||||
|
|
||||||
<div class="telegram-content" class:selectable>
|
<div class="telegram-content" class:selectable>
|
||||||
<Scroller bottomStart autoscroll>
|
<Scroller bottomStart autoscroll>
|
||||||
{#if messages && accounts}
|
{#if messages && accounts}
|
||||||
@ -246,36 +271,17 @@
|
|||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
</Panel>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.telegram-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
margin: 0 2.5rem;
|
|
||||||
padding: 0;
|
|
||||||
height: 4rem;
|
|
||||||
min-height: 4rem;
|
|
||||||
border-bottom: 1px solid var(--divider-color);
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
margin-right: 1rem;
|
|
||||||
width: 2.25rem;
|
|
||||||
height: 2.25rem;
|
|
||||||
color: var(--white-color);
|
|
||||||
background-color: var(--primary-bg-color);
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ref-input {
|
.ref-input {
|
||||||
padding: 0 2.5rem 1.5rem;
|
padding: 0 0 1.5rem;
|
||||||
|
|
||||||
&.selectable {
|
&.selectable {
|
||||||
padding: 1rem 2.5rem;
|
padding: 1rem 0;
|
||||||
color: var(--theme-caption-color);
|
color: var(--theme-caption-color);
|
||||||
background-color: var(--accent-bg-color);
|
border-top: 1px solid var(--divider-color);
|
||||||
border-top: 1px solid var(--theme-card-divider);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,13 +80,16 @@
|
|||||||
onMount(() => {
|
onMount(() => {
|
||||||
dispatch('open', { ignoreKeys: ['comments', 'name', 'description', 'number'] })
|
dispatch('open', { ignoreKeys: ['comments', 'name', 'description', 'number'] })
|
||||||
})
|
})
|
||||||
|
let minimize: boolean = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if issue !== undefined}
|
{#if issue !== undefined}
|
||||||
<Panel
|
<Panel
|
||||||
object={issue}
|
object={issue}
|
||||||
showHeader={false}
|
bind:minimize
|
||||||
isSubtitle={true}
|
isHeader
|
||||||
|
isAside={!minimize}
|
||||||
|
isSub={minimize}
|
||||||
bind:innerWidth
|
bind:innerWidth
|
||||||
on:close={() => {
|
on:close={() => {
|
||||||
dispatch('close')
|
dispatch('close')
|
||||||
@ -106,12 +109,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="navigate-actions">
|
<svelte:fragment slot="navigator">
|
||||||
<Button icon={IconDownOutline} kind={'secondary'} size={'medium'} />
|
<Button icon={IconDownOutline} kind={'secondary'} size={'medium'} />
|
||||||
<Button icon={IconUpOutline} kind={'secondary'} size={'medium'} />
|
<Button icon={IconUpOutline} kind={'secondary'} size={'medium'} />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot="header">
|
||||||
|
<span class="fs-title">{issueLabel}</span>
|
||||||
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot="tools">
|
||||||
|
<Button icon={IconEdit} kind={'transparent'} size={'medium'} />
|
||||||
|
<Button icon={IconMoreH} kind={'transparent'} size={'medium'} />
|
||||||
|
</svelte:fragment>
|
||||||
|
|
||||||
<div class="flex-col flex-grow flex-no-shrink h-full mx-auto content">
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<EditBox
|
<EditBox
|
||||||
label={tracker.string.Title}
|
label={tracker.string.Title}
|
||||||
@ -122,7 +131,7 @@
|
|||||||
on:change={() => change('title', issue?.title)}
|
on:change={() => change('title', issue?.title)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6">
|
<div class="mt-6 mb-6">
|
||||||
<StyledTextBox
|
<StyledTextBox
|
||||||
alwaysEdit
|
alwaysEdit
|
||||||
bind:content={issue.description}
|
bind:content={issue.description}
|
||||||
@ -130,14 +139,9 @@
|
|||||||
on:value={(evt) => change('description', evt.detail)}
|
on:value={(evt) => change('description', evt.detail)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<svelte:fragment slot="properties">
|
<span slot="actions-label">{issueLabel}</span>
|
||||||
{#if issue && currentTeam && issueStatuses}
|
<svelte:fragment slot="actions">
|
||||||
<div class="flex-grow relative min-w-80 right-panel">
|
|
||||||
<div class="ac-header short divide header">
|
|
||||||
<span class="w-24 overflow-label">{issueLabel}</span>
|
|
||||||
<div class="buttons-group">
|
|
||||||
<Button
|
<Button
|
||||||
icon={tracker.icon.Issue}
|
icon={tracker.icon.Issue}
|
||||||
title={tracker.string.CopyIssueUrl}
|
title={tracker.string.CopyIssueUrl}
|
||||||
@ -154,10 +158,11 @@
|
|||||||
kind="transparent"
|
kind="transparent"
|
||||||
on:click={() => issueLabel && copy(issueLabel)}
|
on:click={() => issueLabel && copy(issueLabel)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</svelte:fragment>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content">
|
<svelte:fragment slot="custom-attributes" let:direction>
|
||||||
|
{#if issue && currentTeam && issueStatuses && direction === 'column'}
|
||||||
|
<div class="content mt-4">
|
||||||
<div class="flex-row-center mb-4">
|
<div class="flex-row-center mb-4">
|
||||||
<span class="label w-24">
|
<span class="label w-24">
|
||||||
<Label label={tracker.string.Status} />
|
<Label label={tracker.string.Status} />
|
||||||
@ -183,6 +188,8 @@
|
|||||||
bind:value={issue.assignee}
|
bind:value={issue.assignee}
|
||||||
allowDeselect
|
allowDeselect
|
||||||
titleDeselect={tracker.string.Unassigned}
|
titleDeselect={tracker.string.Unassigned}
|
||||||
|
size="large"
|
||||||
|
kind="link"
|
||||||
on:change={() => change('assignee', issue?.assignee)}
|
on:change={() => change('assignee', issue?.assignee)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -194,9 +201,9 @@
|
|||||||
<Button
|
<Button
|
||||||
label={tracker.string.Labels}
|
label={tracker.string.Labels}
|
||||||
icon={tracker.icon.Labels}
|
icon={tracker.icon.Labels}
|
||||||
width="min-content"
|
width="max-content"
|
||||||
size="small"
|
size="large"
|
||||||
kind="no-border"
|
kind="link"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -206,6 +213,24 @@
|
|||||||
<span class="label w-24">
|
<span class="label w-24">
|
||||||
<Label label={tracker.string.Project} />
|
<Label label={tracker.string.Project} />
|
||||||
</span>
|
</span>
|
||||||
|
<Button
|
||||||
|
label={tracker.string.Project}
|
||||||
|
icon={tracker.icon.Projects}
|
||||||
|
width="fit-content"
|
||||||
|
size="large"
|
||||||
|
kind="link"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="buttons-group small-gap">
|
||||||
|
<Button
|
||||||
|
label={tracker.string.Labels}
|
||||||
|
icon={tracker.icon.Labels}
|
||||||
|
width="min-content"
|
||||||
|
size="small"
|
||||||
|
kind="no-border"
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
label={tracker.string.Project}
|
label={tracker.string.Project}
|
||||||
icon={tracker.icon.Projects}
|
icon={tracker.icon.Projects}
|
||||||
@ -213,8 +238,6 @@
|
|||||||
size="small"
|
size="small"
|
||||||
kind="no-border"
|
kind="no-border"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
@ -222,23 +245,10 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.header {
|
|
||||||
max-width: 56.25rem;
|
|
||||||
width: calc(100% - 5rem);
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-panel {
|
|
||||||
.header {
|
|
||||||
padding: 1rem 0;
|
|
||||||
margin: 0 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 2.5rem 0 0;
|
inset: 2.5rem 0 0;
|
||||||
@ -254,5 +264,4 @@
|
|||||||
border-bottom: 1px solid var(--divider-color);
|
border-bottom: 1px solid var(--divider-color);
|
||||||
margin: 0.75rem 1.5rem 1.25rem 0;
|
margin: 0.75rem 1.5rem 1.25rem 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { ChannelProvider, formatName } from '@anticrm/contact'
|
import contact, { ChannelProvider, formatName } from '@anticrm/contact'
|
||||||
import core, { Class, ClassifierKind, Doc, getCurrentAccount, Hierarchy, Mixin, Obj, Ref, Space } from '@anticrm/core'
|
import core, { Class, ClassifierKind, Doc, getCurrentAccount, Mixin, Obj, Ref, Space } from '@anticrm/core'
|
||||||
import notification from '@anticrm/notification'
|
import notification from '@anticrm/notification'
|
||||||
import { Panel } from '@anticrm/panel'
|
import { Panel } from '@anticrm/panel'
|
||||||
import { Asset, getResource, IntlString, translate } from '@anticrm/platform'
|
import { Asset, getResource, IntlString, translate } from '@anticrm/platform'
|
||||||
@ -27,8 +27,7 @@
|
|||||||
KeyedAttribute
|
KeyedAttribute
|
||||||
} from '@anticrm/presentation'
|
} from '@anticrm/presentation'
|
||||||
import setting, { IntegrationType } from '@anticrm/setting'
|
import setting, { IntegrationType } from '@anticrm/setting'
|
||||||
import { AnyComponent, Button, Component, IconActivity } from '@anticrm/ui'
|
import { AnyComponent, Component } from '@anticrm/ui'
|
||||||
import Tooltip from '@anticrm/ui/src/components/Tooltip.svelte'
|
|
||||||
import view from '@anticrm/view'
|
import view from '@anticrm/view'
|
||||||
import { createEventDispatcher, onDestroy } from 'svelte'
|
import { createEventDispatcher, onDestroy } from 'svelte'
|
||||||
import { getCollectionCounter } from '../utils'
|
import { getCollectionCounter } from '../utils'
|
||||||
@ -38,7 +37,6 @@
|
|||||||
export let _id: Ref<Doc>
|
export let _id: Ref<Doc>
|
||||||
export let _class: Ref<Class<Doc>>
|
export let _class: Ref<Class<Doc>>
|
||||||
export let rightSection: AnyComponent | undefined = undefined
|
export let rightSection: AnyComponent | undefined = undefined
|
||||||
// export let position: PopupAlignment | undefined = undefined
|
|
||||||
|
|
||||||
let lastId: Ref<Doc> = _id
|
let lastId: Ref<Doc> = _id
|
||||||
let lastClass: Ref<Class<Doc>> = _class
|
let lastClass: Ref<Class<Doc>> = _class
|
||||||
@ -49,7 +47,6 @@
|
|||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
const notificationClient = getResource(notification.function.GetNotificationClient).then((res) => res())
|
const notificationClient = getResource(notification.function.GetNotificationClient).then((res) => res())
|
||||||
|
|
||||||
const docKeys: Set<string> = new Set<string>(hierarchy.getAllAttributes(core.class.AttachedDoc).keys())
|
const docKeys: Set<string> = new Set<string>(hierarchy.getAllAttributes(core.class.AttachedDoc).keys())
|
||||||
|
|
||||||
$: read(_id)
|
$: read(_id)
|
||||||
@ -76,18 +73,11 @@
|
|||||||
|
|
||||||
$: if (object !== undefined) objectClass = hierarchy.getClass(object._class)
|
$: if (object !== undefined) objectClass = hierarchy.getClass(object._class)
|
||||||
|
|
||||||
let selectedClass: Ref<Class<Doc>> | undefined
|
|
||||||
let prevSelected = selectedClass
|
|
||||||
|
|
||||||
let keys: KeyedAttribute[] = []
|
let keys: KeyedAttribute[] = []
|
||||||
let collectionEditors: { key: KeyedAttribute; editor: AnyComponent }[] = []
|
let collectionEditors: { key: KeyedAttribute; editor: AnyComponent }[] = []
|
||||||
|
|
||||||
let mixins: Mixin<Doc>[] = []
|
let mixins: Mixin<Doc>[] = []
|
||||||
|
$: if (object) {
|
||||||
$: if (object && prevSelected !== object._class) {
|
|
||||||
prevSelected = object._class
|
|
||||||
selectedClass = Hierarchy.mixinOrClass(object)
|
|
||||||
|
|
||||||
parentClass = getParentClass(object._class)
|
parentClass = getParentClass(object._class)
|
||||||
getMixins()
|
getMixins()
|
||||||
}
|
}
|
||||||
@ -119,7 +109,11 @@
|
|||||||
let ignoreMixins: Set<Ref<Mixin<Doc>>> = new Set<Ref<Mixin<Doc>>>()
|
let ignoreMixins: Set<Ref<Mixin<Doc>>> = new Set<Ref<Mixin<Doc>>>()
|
||||||
|
|
||||||
async function updateKeys (): Promise<void> {
|
async function updateKeys (): Promise<void> {
|
||||||
const filtredKeys = getFiltredKeys(selectedClass ?? object._class, ignoreKeys)
|
let filtredKeys = getFiltredKeys(object._class, ignoreKeys)
|
||||||
|
for (const m of mixins) {
|
||||||
|
const mkeys = getFiltredKeys(m._id, ignoreKeys)
|
||||||
|
filtredKeys = filtredKeys.concat(mkeys).filter((it, idx, arr) => arr.indexOf(it) === idx)
|
||||||
|
}
|
||||||
keys = collectionsFilter(filtredKeys, false)
|
keys = collectionsFilter(filtredKeys, false)
|
||||||
|
|
||||||
const collectionKeys = collectionsFilter(filtredKeys, true)
|
const collectionKeys = collectionsFilter(filtredKeys, true)
|
||||||
@ -151,9 +145,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mainEditor: AnyComponent
|
let mainEditor: AnyComponent
|
||||||
|
$: if (object) getEditorOrDefault(object._class, object._class)
|
||||||
$: if (object) getEditorOrDefault(selectedClass, object._class)
|
|
||||||
|
|
||||||
async function getEditorOrDefault (_class: Ref<Class<Doc>> | undefined, defaultClass: Ref<Class<Doc>>): Promise<void> {
|
async function getEditorOrDefault (_class: Ref<Class<Doc>> | undefined, defaultClass: Ref<Class<Doc>>): Promise<void> {
|
||||||
let editor = _class !== undefined ? await getEditor(_class) : undefined
|
let editor = _class !== undefined ? await getEditor(_class) : undefined
|
||||||
if (editor === undefined) {
|
if (editor === undefined) {
|
||||||
@ -286,6 +278,8 @@
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let minimize: boolean = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ActionContext
|
<ActionContext
|
||||||
@ -300,6 +294,9 @@
|
|||||||
{title}
|
{title}
|
||||||
{rightSection}
|
{rightSection}
|
||||||
{object}
|
{object}
|
||||||
|
bind:minimize
|
||||||
|
isHeader={false}
|
||||||
|
isAside={!minimize}
|
||||||
bind:panelWidth
|
bind:panelWidth
|
||||||
bind:innerWidth
|
bind:innerWidth
|
||||||
on:update={(ev) => _update(ev.detail)}
|
on:update={(ev) => _update(ev.detail)}
|
||||||
@ -307,56 +304,20 @@
|
|||||||
dispatch('close')
|
dispatch('close')
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="navigate-actions">
|
<svelte:fragment slot="navigator">
|
||||||
<UpDownNavigator element={object} />
|
<UpDownNavigator element={object} />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="subtitle">
|
|
||||||
|
<svelte:fragment slot="attributes" let:direction={dir}>
|
||||||
{#if !headerLoading}
|
{#if !headerLoading}
|
||||||
{#if headerEditor !== undefined}
|
{#if headerEditor !== undefined}
|
||||||
<Component is={headerEditor} props={{ object, keys }} />
|
<Component is={headerEditor} props={{ object, keys, vertical: dir === 'column' }} />
|
||||||
{:else}
|
{:else}
|
||||||
<AttributesBar {object} {keys} />
|
<AttributesBar {object} {keys} vertical={dir === 'column'} />
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="properties">
|
|
||||||
{#if !headerLoading}
|
|
||||||
<div class="p-4">
|
|
||||||
{#if headerEditor !== undefined}
|
|
||||||
<Component is={headerEditor} props={{ object, keys, vertical: true }} />
|
|
||||||
{:else}
|
|
||||||
<AttributesBar {object} {keys} vertical />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</svelte:fragment>
|
|
||||||
<svelte:fragment slot="actions">
|
|
||||||
{#if displayedIntegrations && displayedIntegrations.length > 0}
|
|
||||||
<div class="actions-divider" />
|
|
||||||
{#each displayedIntegrations as pr}
|
|
||||||
<Tooltip label={pr.label}>
|
|
||||||
<Button
|
|
||||||
icon={pr.icon}
|
|
||||||
size={'medium'}
|
|
||||||
kind={'transparent'}
|
|
||||||
highlight={rightSection === pr.presenter}
|
|
||||||
on:click={() => {
|
|
||||||
if (rightSection !== pr.presenter) rightSection = pr.presenter
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
{/each}
|
|
||||||
<Button
|
|
||||||
icon={IconActivity}
|
|
||||||
size={'medium'}
|
|
||||||
kind={'transparent'}
|
|
||||||
highlight={!rightSection}
|
|
||||||
on:click={() => {
|
|
||||||
if (rightSection) rightSection = undefined
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</svelte:fragment>
|
|
||||||
<div class="main-editor">
|
<div class="main-editor">
|
||||||
{#if mainEditor}
|
{#if mainEditor}
|
||||||
<Component
|
<Component
|
||||||
@ -376,7 +337,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{#each collectionEditors as collection}
|
{#each collectionEditors as collection}
|
||||||
{#if collection.editor}
|
{#if collection.editor}
|
||||||
<div class="mt-14">
|
<div class="mt-6">
|
||||||
<Component
|
<Component
|
||||||
is={collection.editor}
|
is={collection.editor}
|
||||||
props={{
|
props={{
|
||||||
@ -400,12 +361,4 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-divider {
|
|
||||||
margin: 0 0.25rem;
|
|
||||||
min-width: 1px;
|
|
||||||
width: 1px;
|
|
||||||
height: 1.5rem;
|
|
||||||
background-color: var(--divider-color);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -298,12 +298,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let navFloat: boolean = !(window.innerWidth < 1100)
|
let navFloat: boolean = window.innerWidth < 1024 ? false : true
|
||||||
const windowResize = (): void => {
|
const windowResize = (): void => {
|
||||||
if (window.innerWidth < 1100 && !navFloat) {
|
if (window.innerWidth < 1024 && !navFloat) {
|
||||||
visibileNav = false
|
visibileNav = false
|
||||||
navFloat = true
|
navFloat = true
|
||||||
} else if (window.innerWidth >= 1100 && navFloat) {
|
} else if (window.innerWidth >= 1024 && navFloat) {
|
||||||
navFloat = false
|
navFloat = false
|
||||||
visibileNav = true
|
visibileNav = true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user