Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2024-04-21 20:48:28 +05:00 committed by GitHub
parent 8dfd0fcf6c
commit 207b8f9f50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 108 additions and 16 deletions

View File

@ -101,9 +101,7 @@ export default mergeIds(viewId, view, {
General: '' as IntlString, General: '' as IntlString,
Navigation: '' as IntlString, Navigation: '' as IntlString,
Editor: '' as IntlString, Editor: '' as IntlString,
MarkdownFormatting: '' as IntlString, MarkdownFormatting: '' as IntlString
Pin: '' as IntlString,
Unpin: '' as IntlString
}, },
function: { function: {
FilterArrayAllResult: '' as FilterFunction, FilterArrayAllResult: '' as FilterFunction,

View File

@ -317,6 +317,11 @@
box-shadow: var(--theme-popup-shadow); box-shadow: var(--theme-popup-shadow);
user-select: none; user-select: none;
&.isDock {
border-radius: 0;
height: 100%;
}
.ap-space { .ap-space {
flex-shrink: 0; flex-shrink: 0;
height: .25rem; height: .25rem;

View File

@ -0,0 +1,52 @@
<!--
// Copyright © 2024 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 { dockStore, unpin } from '../popups'
function _close (result: any): void {
if ($dockStore?.onClose !== undefined) $dockStore.onClose(result)
$dockStore?.close()
}
</script>
{#if $dockStore !== undefined}
<div class="dock">
<svelte:component
this={$dockStore.is}
{...$dockStore.props}
isDock
on:close={(ev) => {
_close(ev?.detail)
}}
on:dock={() => {
if ($dockStore !== undefined) {
unpin()
}
}}
/>
</div>
{/if}
<style lang="scss">
.dock {
display: flex;
flex-shrink: 0;
flex-direction: column;
min-width: 0;
min-height: 0;
background-color: transparent;
transform-origin: center;
}
</style>

View File

@ -24,13 +24,13 @@
instances.forEach((p) => p.fitPopupInstance()) instances.forEach((p) => p.fitPopupInstance())
} }
$: instances.length = $modal.length $: instances.length = $modal.filter((p) => p.dock !== true).length
</script> </script>
{#if $modal.length > 0} {#if $modal.length > 0}
<slot name="popup-header" /> <slot name="popup-header" />
{/if} {/if}
{#each $modal as popup, i (popup.id)} {#each $modal.filter((p) => p.dock !== true) as popup, i (popup.id)}
<PopupInstance <PopupInstance
bind:this={instances[i]} bind:this={instances[i]}
is={popup.is} is={popup.is}

View File

@ -16,7 +16,7 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { deviceOptionsStore as deviceInfo, resizeObserver, testing } from '..' import { deviceOptionsStore as deviceInfo, resizeObserver, testing } from '..'
import { CompAndProps, fitPopupElement } from '../popups' import { CompAndProps, fitPopupElement, pin } from '../popups'
import type { AnySvelteComponent, DeviceOptions, PopupAlignment, PopupOptions, PopupPositionElement } from '../types' import type { AnySvelteComponent, DeviceOptions, PopupAlignment, PopupOptions, PopupPositionElement } from '../types'
export let is: AnySvelteComponent export let is: AnySvelteComponent
@ -314,6 +314,9 @@
fullSize = !fullSize fullSize = !fullSize
fitPopup(modalHTML, element, contentPanel) fitPopup(modalHTML, element, contentPanel)
}} }}
on:dock={() => {
pin(popup.id)
}}
on:changeContent={(ev) => { on:changeContent={(ev) => {
fitPopup(modalHTML, element, contentPanel) fitPopup(modalHTML, element, contentPanel)
if (ev.detail?.notFit !== undefined) notFit = ev.detail.notFit if (ev.detail?.notFit !== undefined) notFit = ev.detail.notFit

View File

@ -250,6 +250,7 @@
} }
.app { .app {
display: flex;
height: calc(100% - var(--status-bar-height)); height: calc(100% - var(--status-bar-height));
.error { .error {

View File

@ -252,6 +252,8 @@ export { default as NumberInput } from './components/NumberInput.svelte'
export { default as Lazy } from './components/Lazy.svelte' export { default as Lazy } from './components/Lazy.svelte'
export { default as TimeZonesPopup } from './components/TimeZonesPopup.svelte' export { default as TimeZonesPopup } from './components/TimeZonesPopup.svelte'
export { default as Dock } from './components/Dock.svelte'
export * from './types' export * from './types'
export * from './location' export * from './location'
export * from './utils' export * from './utils'

View File

@ -1,6 +1,6 @@
import { getResource } from '@hcengineering/platform' import { getResource } from '@hcengineering/platform'
import { type ComponentType } from 'svelte' import { type ComponentType } from 'svelte'
import { writable } from 'svelte/store' import { derived, writable } from 'svelte/store'
import type { import type {
AnyComponent, AnyComponent,
AnySvelteComponent, AnySvelteComponent,
@ -29,6 +29,7 @@ export interface CompAndProps {
fixed?: boolean fixed?: boolean
refId?: string refId?: string
} }
dock?: boolean
} }
export interface PopupResult { export interface PopupResult {
@ -39,6 +40,10 @@ export interface PopupResult {
export const popupstore = writable<CompAndProps[]>([]) export const popupstore = writable<CompAndProps[]>([])
export const dockStore = derived(popupstore, (popups) => {
return popups.find((popup) => popup.dock)
})
export function updatePopup (id: string, props: Partial<CompAndProps>): void { export function updatePopup (id: string, props: Partial<CompAndProps>): void {
popupstore.update((popups) => { popupstore.update((popups) => {
const popupIndex = popups.findIndex((p) => p.id === id) const popupIndex = popups.findIndex((p) => p.id === id)
@ -409,3 +414,17 @@ export function getEventPositionElement (evt: MouseEvent): PopupAlignment | unde
getBoundingClientRect: () => rect getBoundingClientRect: () => rect
} }
} }
export function pin (id: string): void {
popupstore.update((popups) => {
popups.forEach((p) => (p.dock = p.id === id))
return popups
})
}
export function unpin (): void {
popupstore.update((popups) => {
popups.forEach((p) => (p.dock = false))
return popups
})
}

View File

@ -34,7 +34,8 @@
defineSeparators, defineSeparators,
settingsSeparators, settingsSeparators,
Separator, Separator,
NavItem NavItem,
Loading
} from '@hcengineering/ui' } from '@hcengineering/ui'
import notification from '../plugin' import notification from '../plugin'
import NotificationGroupSetting from './NotificationGroupSetting.svelte' import NotificationGroupSetting from './NotificationGroupSetting.svelte'
@ -53,6 +54,8 @@
const query = createQuery() const query = createQuery()
let loading = true
query.query(notification.class.NotificationSetting, {}, (res) => { query.query(notification.class.NotificationSetting, {}, (res) => {
settings = new Map() settings = new Map()
for (const value of res) { for (const value of res) {
@ -61,6 +64,7 @@
settings.set(value.type, arr) settings.set(value.type, arr)
} }
settings = settings settings = settings
loading = false
}) })
let group: Ref<NotificationGroup> | undefined = undefined let group: Ref<NotificationGroup> | undefined = undefined
@ -136,13 +140,17 @@
<div class="hulyComponent-content__column content"> <div class="hulyComponent-content__column content">
<Scroller align={'center'} padding={'var(--spacing-3)'} bottomPadding={'var(--spacing-3)'}> <Scroller align={'center'} padding={'var(--spacing-3)'} bottomPadding={'var(--spacing-3)'}>
<div class="hulyComponent-content"> <div class="hulyComponent-content">
{#if group} {#if loading}
<NotificationGroupSetting {group} {settings} /> <Loading />
{/if} {:else}
{#if currentPreferenceGroup} {#if group}
{#await getResource(currentPreferenceGroup.presenter) then presenter} <NotificationGroupSetting {group} {settings} />
<svelte:component this={presenter} /> {/if}
{/await} {#if currentPreferenceGroup}
{#await getResource(currentPreferenceGroup.presenter) then presenter}
<svelte:component this={presenter} />
{/await}
{/if}
{/if} {/if}
</div> </div>
</Scroller> </Scroller>

View File

@ -197,7 +197,9 @@ const view = plugin(viewId, {
Save: '' as IntlString, Save: '' as IntlString,
PublicView: '' as IntlString, PublicView: '' as IntlString,
Archived: '' as IntlString, Archived: '' as IntlString,
MoreActions: '' as IntlString MoreActions: '' as IntlString,
Pin: '' as IntlString,
Unpin: '' as IntlString
}, },
icon: { icon: {
Table: '' as Asset, Table: '' as Asset,

View File

@ -35,6 +35,7 @@
Button, Button,
CompAndProps, CompAndProps,
Component, Component,
Dock,
IconSettings, IconSettings,
Label, Label,
Location, Location,
@ -852,6 +853,7 @@
</Popup> </Popup>
<ComponentExtensions extension={workbench.extensions.WorkbenchExtensions} /> <ComponentExtensions extension={workbench.extensions.WorkbenchExtensions} />
<BrowserNotificatator /> <BrowserNotificatator />
<Dock />
{/if} {/if}
<style lang="scss"> <style lang="scss">