Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2022-02-08 21:33:32 +07:00 committed by GitHub
parent f4c5e84db1
commit 738354e9ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 129 additions and 98 deletions

View File

@ -25,20 +25,22 @@
export let is: AnyComponent export let is: AnyComponent
export let props = {} export let props = {}
$: component = getResource(is) $: component = (is != null) ? getResource(is) : Promise.reject(new Error('is not defined'))
</script> </script>
{#await component} {#if is}
<Loading/> {#await component}
{:then Ctor} <Loading/>
<ErrorBoundary> {:then Ctor}
<Ctor {...props} on:change on:close on:open on:click> <ErrorBoundary>
<slot /> <Ctor {...props} on:change on:close on:open on:click>
</Ctor> <slot />
</ErrorBoundary> </Ctor>
{:catch err} </ErrorBoundary>
<pre style='max-height: 140px; overflow: auto;'> {:catch err}
<ErrorPresenter error={err}/> <pre style='max-height: 140px; overflow: auto;'>
</pre> <ErrorPresenter error={err}/>
<!-- <Icon icon={ui.icon.Error} size="32" /> --> </pre>
{/await} <!-- <Icon icon={ui.icon.Error} size="32" /> -->
{/await}
{/if}

View File

@ -16,7 +16,7 @@
<script lang="ts"> <script lang="ts">
import { getResource } from '@anticrm/platform' import { getResource } from '@anticrm/platform'
import { afterUpdate } from 'svelte' import { afterUpdate } from 'svelte'
import { Spinner } from '..' import { AnySvelteComponent, Spinner } from '..'
import { closePanel, PanelProps, panelstore as modal } from '../panelup' import { closePanel, PanelProps, panelstore as modal } from '../panelup'
import { popupstore } from '../popups' import { popupstore } from '../popups'
@ -24,6 +24,8 @@
let componentInstance: any let componentInstance: any
let show: boolean = false let show: boolean = false
let component: AnySvelteComponent
let props: PanelProps | undefined let props: PanelProps | undefined
function _close () { function _close () {
closePanel() closePanel()
@ -31,6 +33,12 @@
$: props = $modal.panel $: props = $modal.panel
$: if (props !== undefined) {
getResource(props.component).then((r) => {
component = r
})
}
function escapeClose () { function escapeClose () {
// Check if there is popup visible, then ignore // Check if there is popup visible, then ignore
if ($popupstore.length > 0) { if ($popupstore.length > 0) {
@ -113,9 +121,9 @@
}} }}
/> />
{#if props} {#if props}
{#await getResource(props.component)} {#if !component}
<Spinner /> <Spinner />
{:then component} {:else}
<div class="popup" bind:this={modalHTML} style={'z-index: 401'}> <div class="popup" bind:this={modalHTML} style={'z-index: 401'}>
<svelte:component <svelte:component
this={component} this={component}
@ -128,7 +136,7 @@
/> />
</div> </div>
<div class="modal-overlay" class:show style={'z-index: 400'} on:click={() => escapeClose()} /> <div class="modal-overlay" class:show style={'z-index: 400'} on:click={() => escapeClose()} />
{/await} {/if}
{/if} {/if}
<style lang="scss"> <style lang="scss">

View File

@ -25,7 +25,7 @@
getClient, getClient,
KeyedAttribute KeyedAttribute
} from '@anticrm/presentation' } from '@anticrm/presentation'
import { AnyComponent, Component, Label } from '@anticrm/ui' import { AnyComponent, Component, Label, Spinner } from '@anticrm/ui'
import view from '@anticrm/view' import view from '@anticrm/view'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { getMixinStyle } from '../utils' import { getMixinStyle } from '../utils'
@ -49,22 +49,20 @@
object = result[0] object = result[0]
}) })
$: if (object) objectClass = hierarchy.getClass(object._class) $: if (object !== undefined) objectClass = hierarchy.getClass(object._class)
let selectedClass: Ref<Class<Doc>> | undefined let selectedClass: Ref<Class<Doc>> | undefined
let prevSelected = selectedClass let prevSelected = selectedClass
let keys: KeyedAttribute[] = [] let keys: KeyedAttribute[] = []
let collectionKeys: KeyedAttribute[] = [] let collectionKeys: KeyedAttribute[] = []
let collectionEditors: AnyComponent[] = []
let mixins: Mixin<Doc>[] = [] let mixins: Mixin<Doc>[] = []
let selectedMixin: Mixin<Doc> | undefined
$: if (object && prevSelected !== object._class) { $: if (object && prevSelected !== object._class) {
prevSelected = object._class prevSelected = object._class
selectedClass = objectClass._id selectedClass = objectClass._id
selectedMixin = undefined
parentClass = getParentClass(object._class) parentClass = getParentClass(object._class)
mixins = getMixins() mixins = getMixins()
} }
@ -128,10 +126,7 @@
$: if (object) getEditorOrDefault(selectedClass, object._class) $: if (object) getEditorOrDefault(selectedClass, object._class)
async function getEditorOrDefault ( async function getEditorOrDefault (_class: Ref<Class<Doc>> | undefined, defaultClass: Ref<Class<Doc>>): Promise<void> {
_class: Ref<Class<Doc>> | undefined,
defaultClass: Ref<Class<Doc>>
): Promise<void> {
console.log('get editor or default') console.log('get editor or default')
let editor = _class !== undefined ? await getEditor(_class) : undefined let editor = _class !== undefined ? await getEditor(_class) : undefined
if (editor === undefined) { if (editor === undefined) {
@ -184,6 +179,14 @@
return result return result
} }
let title: string = ''
$: if (object !== undefined) {
getTitle(object).then((t) => {
title = t
})
}
async function getTitle (object: Doc): Promise<string> { async function getTitle (object: Doc): Promise<string> {
const name = (object as any).name const name = (object as any).name
if (name !== undefined) { if (name !== undefined) {
@ -202,88 +205,106 @@
if (editorMixin.editor != null) return editorMixin.editor if (editorMixin.editor != null) return editorMixin.editor
if (clazz.extends != null) return getHeaderEditor(clazz.extends) if (clazz.extends != null) return getHeaderEditor(clazz.extends)
} }
let headerEditor: AnyComponent | undefined = undefined
let headerLoading = false
$: if (object !== undefined) {
headerLoading = true
getHeaderEditor(object._class).then((r) => {
headerEditor = r
headerLoading = false
})
}
async function updateCollectionEditors (keys: KeyedAttribute[]): Promise<void> {
const editors: AnyComponent[] = []
for (const k of keys) {
editors.push(await getCollectionEditor(k))
}
collectionEditors = editors
}
$: updateCollectionEditors(collectionKeys)
</script> </script>
{#if object !== undefined} {#if object !== undefined && title !== undefined}
{#await getTitle(object) then title} <Panel
<Panel {icon}
{icon} {title}
{title} {rightSection}
{rightSection} {fullSize}
{fullSize} {object}
{object} on:close={() => {
on:close={() => { dispatch('close')
dispatch('close') }}
}} >
> <div class="w-full" slot="subtitle">
<div class="w-full" slot="subtitle"> {#if !headerLoading}
{#await getHeaderEditor(object._class) then is} {#if headerEditor !== undefined}
{#if is} <Component is={headerEditor} props={{ object, keys }} />
<Component {is} props={{ object, keys }} /> {:else}
{:else} <AttributesBar {object} {keys} />
<AttributesBar {object} {keys} />
{/if}
{/await}
</div>
<div class="main-editor">
{#if mainEditor}
<Component
is={mainEditor}
props={{ object }}
on:open={(ev) => {
ignoreKeys = ev.detail.ignoreKeys
updateKeys()
}}
on:click={(ev) => {
fullSize = true
rightSection = ev.detail.presenter
}}
/>
{/if} {/if}
</div> {/if}
{#if mixins.length > 0} </div>
<div class="mixin-container"> <div class="main-editor">
{#if mainEditor}
<Component
is={mainEditor}
props={{ object }}
on:open={(ev) => {
ignoreKeys = ev.detail.ignoreKeys
updateKeys()
}}
on:click={(ev) => {
fullSize = true
rightSection = ev.detail.presenter
}}
/>
{/if}
</div>
{#if mixins.length > 0}
<div class="mixin-container">
<div
class="mixin-selector"
style={getMixinStyle(objectClass._id, selectedClass === objectClass._id)}
on:click={() => {
selectedClass = objectClass._id
}}
>
<Label label={objectClass.label} />
</div>
{#each mixins as mixin}
<div <div
class="mixin-selector" class="mixin-selector"
style={getMixinStyle(objectClass._id, selectedClass === objectClass._id)} style={getMixinStyle(mixin._id, selectedClass === mixin._id)}
on:click={() => { on:click={() => {
selectedClass = objectClass._id selectedClass = mixin._id
selectedMixin = undefined
}} }}
> >
<Label label={objectClass.label} /> <Label label={mixin.label} />
</div> </div>
{#each mixins as mixin} {/each}
<div </div>
class="mixin-selector" {/if}
style={getMixinStyle(mixin._id, selectedClass === mixin._id)} {#if collectionKeys.length !== collectionEditors.length}
on:click={() => { <Spinner />
selectedClass = mixin._id {:else}
selectedMixin = mixin {#each collectionKeys as collection, i}
}}
>
<Label label={mixin.label} />
</div>
{/each}
</div>
{/if}
{#each collectionKeys as collection}
<div class="mt-14"> <div class="mt-14">
{#await getCollectionEditor(collection) then is} <Component
<Component is={collectionEditors[i]}
{is} props={{
props={{ objectId: object._id,
objectId: object._id, _class: object._class,
_class: object._class, space: object.space,
space: object.space, [collection.key]: getCollectionCounter(object, collection)
[collection.key]: getCollectionCounter(object, collection) }}
}} />
/>
{/await}
</div> </div>
{/each} {/each}
</Panel> {/if}
{/await} </Panel>
{/if} {/if}
<style lang="scss"> <style lang="scss">