Fix HR issues. (#2418)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2022-12-05 23:27:49 +07:00 committed by GitHub
parent 2ed837ac59
commit e16f1921d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 169 additions and 51 deletions

2
.vscode/launch.json vendored
View File

@ -27,7 +27,7 @@
"ts-node/register" "ts-node/register"
], ],
"sourceMaps": true, "sourceMaps": true,
"cwd": "${workspaceRoot}/server/server", "cwd": "${workspaceRoot}/pods/server",
"protocol": "inspector" "protocol": "inspector"
}, },
{ {

View File

@ -266,9 +266,9 @@ export function devTool (
program program
.command('backup-restore <dirName> <workspace> [date]') .command('backup-restore <dirName> <workspace> [date]')
.description('dump workspace transactions and minio resources') .description('dump workspace transactions and minio resources')
.action(async (dirName, workspace, date, cmd) => { .action(async (dirName: string, workspace: string, date, cmd) => {
const storage = await createFileBackupStorage(dirName) const storage = await createFileBackupStorage(dirName)
return await restore(transactorUrl, workspace, storage, parseInt(date ?? '-1')) return await restore(transactorUrl, getWorkspaceId(workspace, productId), storage, parseInt(date ?? '-1'))
}) })
program program

View File

@ -113,7 +113,7 @@ export class TChannel extends TAttachedDoc implements Channel {
@Model(contact.class.Person, contact.class.Contact) @Model(contact.class.Person, contact.class.Contact)
@UX(contact.string.Person, contact.icon.Person, undefined, 'name') @UX(contact.string.Person, contact.icon.Person, undefined, 'name')
export class TPerson extends TContact implements Person { export class TPerson extends TContact implements Person {
@Prop(TypeDate(), contact.string.Birthday) @Prop(TypeDate(false, false), contact.string.Birthday)
birthday?: Timestamp birthday?: Timestamp
} }

View File

@ -305,6 +305,9 @@ export function createModel (builder: Builder): void {
builder.mixin(core.class.Class, core.class.Class, view.mixin.IgnoreActions, { builder.mixin(core.class.Class, core.class.Class, view.mixin.IgnoreActions, {
actions: [view.action.Delete] actions: [view.action.Delete]
}) })
builder.mixin(core.class.Attribute, core.class.Class, view.mixin.IgnoreActions, {
actions: [view.action.Delete]
})
createAction(builder, { createAction(builder, {
action: view.actionImpl.ShowPopup, action: view.actionImpl.ShowPopup,
@ -341,6 +344,46 @@ export function createModel (builder: Builder): void {
) )
// builder.mixin(core.class.Space, core.class.Class, setting.mixin.Editable, {}) // builder.mixin(core.class.Space, core.class.Class, setting.mixin.Editable, {})
createAction(builder, {
action: view.actionImpl.UpdateDocument,
actionProps: {
key: 'hidden',
value: true
},
query: {
hidden: { $in: [false, undefined, null] }
},
label: setting.string.HideAttribute,
input: 'any',
icon: view.icon.Setting,
category: setting.category.Settings,
target: core.class.Attribute,
context: {
mode: ['context', 'browser'],
group: 'edit'
}
})
createAction(builder, {
action: view.actionImpl.UpdateDocument,
actionProps: {
key: 'hidden',
value: false
},
query: {
hidden: true
},
label: setting.string.ShowAttribute,
input: 'any',
icon: view.icon.Setting,
category: setting.category.Settings,
target: core.class.Attribute,
context: {
mode: ['context', 'browser'],
group: 'edit'
}
})
} }
export { settingOperation } from './migration' export { settingOperation } from './migration'

View File

@ -51,6 +51,7 @@
export let allowDeselect = false export let allowDeselect = false
export let component: AnySvelteComponent | undefined = undefined export let component: AnySvelteComponent | undefined = undefined
export let componentProps: any | undefined = undefined export let componentProps: any | undefined = undefined
export let autoSelect = true
let selected: Space | undefined let selected: Space | undefined
@ -61,10 +62,10 @@
async function updateSelected (value: Ref<Space> | undefined) { async function updateSelected (value: Ref<Space> | undefined) {
selected = value !== undefined ? await client.findOne(_class, { ...(spaceQuery ?? {}), _id: value }) : undefined selected = value !== undefined ? await client.findOne(_class, { ...(spaceQuery ?? {}), _id: value }) : undefined
if (selected === undefined) { if (selected === undefined && autoSelect) {
selected = await client.findOne(_class, { ...(spaceQuery ?? {}) }) selected = await client.findOne(_class, { ...(spaceQuery ?? {}) })
if (selected !== undefined) { if (selected !== undefined) {
value = selected._id value = selected._id ?? undefined
dispatch('change', value) dispatch('change', value)
dispatch('space', selected) dispatch('space', selected)
} }
@ -89,8 +90,8 @@
}, },
!$$slots.content ? eventToHTMLElement(ev) : getEventPositionElement(ev), !$$slots.content ? eventToHTMLElement(ev) : getEventPositionElement(ev),
(result) => { (result) => {
if (result) { if (result !== undefined) {
value = result._id value = result?._id ?? undefined
dispatch('change', value) dispatch('change', value)
mgr?.setFocusPos(focusIndex) mgr?.setFocusPos(focusIndex)
} }
@ -100,6 +101,7 @@
</script> </script>
{#if $$slots.content} {#if $$slots.content}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div id="space.selector" class="w-full h-full flex-streatch" on:click={showSpacesPopup}> <div id="space.selector" class="w-full h-full flex-streatch" on:click={showSpacesPopup}>
<slot name="content" /> <slot name="content" />
</div> </div>
@ -116,7 +118,7 @@
showTooltip={{ label, direction: labelDirection }} showTooltip={{ label, direction: labelDirection }}
on:click={showSpacesPopup} on:click={showSpacesPopup}
> >
<span slot="content" class="overflow-label disabled text-sm"> <span slot="content" class="overflow-label disabled text-sm" class:dark-color={value == null}>
{#if selected}{selected.name}{:else}<Label {label} />{/if} {#if selected}{selected.name}{:else}<Label {label} />{/if}
</span> </span>
</Button> </Button>

View File

@ -32,6 +32,7 @@
export let focus = true export let focus = true
export let component: AnySvelteComponent | undefined = undefined export let component: AnySvelteComponent | undefined = undefined
export let componentProps: any | undefined = undefined export let componentProps: any | undefined = undefined
export let autoSelect = true
export let create: ObjectCreate | undefined = undefined export let create: ObjectCreate | undefined = undefined
</script> </script>
@ -51,6 +52,7 @@
{width} {width}
{component} {component}
{componentProps} {componentProps}
{autoSelect}
bind:value={space} bind:value={space}
on:change={(evt) => { on:change={(evt) => {
space = evt.detail space = evt.detail

View File

@ -118,6 +118,7 @@
$: hideIcon = size === 'x-large' || (size === 'large' && kind !== 'link') $: hideIcon = size === 'x-large' || (size === 'large' && kind !== 'link')
</script> </script>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div {id} bind:this={container} class="min-w-0" class:w-full={width === '100%'} class:h-full={$$slots.content}> <div {id} bind:this={container} class="min-w-0" class:w-full={width === '100%'} class:h-full={$$slots.content}>
{#if $$slots.content} {#if $$slots.content}
<div <div
@ -129,7 +130,12 @@
</div> </div>
{:else} {:else}
<Button {focusIndex} width={width ?? 'min-content'} {size} {kind} {justify} {showTooltip} on:click={_click}> <Button {focusIndex} width={width ?? 'min-content'} {size} {kind} {justify} {showTooltip} on:click={_click}>
<span slot="content" class="overflow-label flex-grow" class:flex-between={showNavigate && selected}> <span
slot="content"
class="overflow-label flex-grow"
class:flex-between={showNavigate && selected}
class:dark-color={value == null}
>
<div <div
class="disabled" class="disabled"
style:width={showNavigate && selected style:width={showNavigate && selected

View File

@ -36,6 +36,7 @@
export let labelDirection: TooltipAlignment | undefined = undefined export let labelDirection: TooltipAlignment | undefined = undefined
export let focusIndex = -1 export let focusIndex = -1
export let autoSelect: boolean = true export let autoSelect: boolean = true
export let useFlexGrow = false
let container: HTMLElement let container: HTMLElement
let opened: boolean = false let opened: boolean = false
@ -52,7 +53,7 @@
const mgr = getFocusManager() const mgr = getFocusManager()
</script> </script>
<div bind:this={container} class="min-w-0"> <div bind:this={container} class="min-w-0" class:flex-grow={useFlexGrow}>
<Button <Button
{focusIndex} {focusIndex}
{icon} {icon}
@ -75,7 +76,7 @@
} }
}} }}
> >
<span slot="content" class="overflow-label disabled"> <span slot="content" class="overflow-label disabled" class:dark-color={selectedItem === undefined}>
{#if selectedItem}{selectedItem.label}{:else}<Label label={label ?? ui.string.NotSelected} />{/if} {#if selectedItem}{selectedItem.label}{:else}<Label label={label ?? ui.string.NotSelected} />{/if}
</span> </span>
</Button> </Button>

View File

@ -272,6 +272,7 @@
adaptValue() adaptValue()
</script> </script>
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<button <button
bind:this={datePresenter} bind:this={datePresenter}
class="datetime-button {kind}" class="datetime-button {kind}"
@ -292,7 +293,7 @@
> >
{#if edits[0].value > -1} {#if edits[0].value > -1}
{edits[0].value.toString().padStart(2, '0')} {edits[0].value.toString().padStart(2, '0')}
{:else}ДД{/if} {:else}DD{/if}
</span> </span>
<span class="separator">.</span> <span class="separator">.</span>
<span <span
@ -305,7 +306,7 @@
> >
{#if edits[1].value > -1} {#if edits[1].value > -1}
{edits[1].value.toString().padStart(2, '0')} {edits[1].value.toString().padStart(2, '0')}
{:else}ММ{/if} {:else}MM{/if}
</span> </span>
<span class="separator">.</span> <span class="separator">.</span>
<span <span
@ -318,7 +319,7 @@
> >
{#if edits[2].value > -1} {#if edits[2].value > -1}
{edits[2].value.toString().padStart(4, '0')} {edits[2].value.toString().padStart(4, '0')}
{:else}ГГГГ{/if} {:else}YYYY{/if}
</span> </span>
{#if withTime} {#if withTime}
<div class="time-divider" /> <div class="time-divider" />
@ -332,7 +333,7 @@
> >
{#if edits[3].value > -1} {#if edits[3].value > -1}
{edits[3].value.toString().padStart(2, '0')} {edits[3].value.toString().padStart(2, '0')}
{:else}ЧЧ{/if} {:else}HH{/if}
</span> </span>
<span class="separator">:</span> <span class="separator">:</span>
<span <span
@ -345,10 +346,11 @@
> >
{#if edits[4].value > -1} {#if edits[4].value > -1}
{edits[4].value.toString().padStart(2, '0')} {edits[4].value.toString().padStart(2, '0')}
{:else}ММ{/if} {:else}MM{/if}
</span> </span>
{/if} {/if}
{#if value} {#if value}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div <div
bind:this={closeBtn} bind:this={closeBtn}
class="close-btn" class="close-btn"
@ -388,7 +390,9 @@
{/if} {/if}
{/if} {/if}
{:else} {:else}
<Label label={labelNull} /> <div class="dark-color">
<Label label={labelNull} />
</div>
{/if} {/if}
{/if} {/if}
</button> </button>
@ -502,8 +506,8 @@
padding: 0 0.875rem; padding: 0 0.875rem;
width: 100%; width: 100%;
height: 2rem; height: 2rem;
color: var(--caption-color);
&:hover { &:hover {
color: var(--caption-color);
background-color: var(--body-color); background-color: var(--body-color);
border-color: var(--divider-color); border-color: var(--divider-color);
.btn-icon { .btn-icon {

View File

@ -37,6 +37,7 @@
{justify} {justify}
allowDeselect allowDeselect
{width} {width}
autoSelect={false}
focus={false} focus={false}
bind:space={value} bind:space={value}
on:change={(e) => onChange(e.detail)} on:change={(e) => onChange(e.detail)}

View File

@ -62,6 +62,10 @@
"ImportEnumCopy": "Copy enum values from clipboard", "ImportEnumCopy": "Copy enum values from clipboard",
"CreateMixin": "Create Mixin", "CreateMixin": "Create Mixin",
"OldNames": "Old values", "OldNames": "Old values",
"NewClassName": "Type new class name or select from previous values..." "NewClassName": "Type new class name or select from previous values...",
"ShowAttribute": "Show attribute",
"HideAttribute": "Hide attribute",
"Visibility": "Visibility",
"Hidden": "Hidden"
} }
} }

View File

@ -62,6 +62,11 @@
"ImportEnumCopy": "Загрузить значения справочника из буфера обмена", "ImportEnumCopy": "Загрузить значения справочника из буфера обмена",
"CreateMixin": "Создать Миксин", "CreateMixin": "Создать Миксин",
"OldNames": "Предыдушие значения", "OldNames": "Предыдушие значения",
"NewClassName": "Введите новое имя класса или выберете прошлое значение..." "NewClassName": "Введите новое имя класса или выберете прошлое значение...",
"ShowAttribute": "Hide",
"HideAttribute": "Show",
"Visibility": "Видимость",
"Hidden": "Спрятанный"
} }
} }

View File

@ -26,7 +26,7 @@
RefTo, RefTo,
Type Type
} from '@hcengineering/core' } from '@hcengineering/core'
import { IntlString } from '@hcengineering/platform' import { getResource, IntlString } from '@hcengineering/platform'
import presentation, { createQuery, getClient, MessageBox } from '@hcengineering/presentation' import presentation, { createQuery, getClient, MessageBox } from '@hcengineering/presentation'
import { import {
Action, Action,
@ -44,10 +44,12 @@
showPopup showPopup
} from '@hcengineering/ui' } from '@hcengineering/ui'
import view from '@hcengineering/view' import view from '@hcengineering/view'
import { getContextActions } from '@hcengineering/view-resources/src/actions'
import settings from '../plugin' import settings from '../plugin'
import CreateAttribute from './CreateAttribute.svelte' import CreateAttribute from './CreateAttribute.svelte'
import EditAttribute from './EditAttribute.svelte' import EditAttribute from './EditAttribute.svelte'
import EditClassLabel from './EditClassLabel.svelte' import EditClassLabel from './EditClassLabel.svelte'
export let _class: Ref<Class<Doc>> export let _class: Ref<Class<Doc>>
const client = getClient() const client = getClient()
@ -65,10 +67,16 @@
function getCustomAttributes (_class: Ref<Class<Doc>>): AnyAttribute[] { function getCustomAttributes (_class: Ref<Class<Doc>>): AnyAttribute[] {
const cl = hierarchy.getClass(_class) const cl = hierarchy.getClass(_class)
const attributes = Array.from(hierarchy.getAllAttributes(_class, cl.extends).values()) const attributes = Array.from(hierarchy.getAllAttributes(_class, cl.extends).values())
const filtred = attributes.filter((p) => !p.hidden) // const filtred = attributes.filter((p) => !p.hidden)
return filtred return attributes
} }
const attrQuery = createQuery()
$: attrQuery.query(core.class.Attribute, { attributeOf: _class }, () => {
attributes = getCustomAttributes(_class)
})
function update () { function update () {
attributes = getCustomAttributes(_class) attributes = getCustomAttributes(_class)
} }
@ -108,15 +116,28 @@
action: async () => { action: async () => {
editAttribute(attribute, exist) editAttribute(attribute, exist)
} }
}, }
{ ]
if (attribute.isCustom) {
actions.push({
label: presentation.string.Remove, label: presentation.string.Remove,
icon: IconDelete, icon: IconDelete,
action: async () => { action: async () => {
removeAttribute(attribute, exist) removeAttribute(attribute, exist)
} }
} })
] }
const extra = await getContextActions(client, attribute, { mode: 'context' })
actions.push(
...extra.map((it) => ({
label: it.label,
icon: it.icon,
action: async (_: any, evt: Event) => {
const r = await getResource(it.action)
r(attribute, evt, it.actionProps)
}
}))
)
showPopup(Menu, { actions }, getEventPositionElement(ev), () => {}) showPopup(Menu, { actions }, getEventPositionElement(ev), () => {})
} }
@ -179,6 +200,11 @@
<Label label={settings.string.Type} /> <Label label={settings.string.Type} />
</div> </div>
</th> </th>
<th>
<div class="antiTable-cells">
<Label label={settings.string.Visibility} />
</div>
</th>
<th> <th>
<div class="antiTable-cells"> <div class="antiTable-cells">
<Label label={settings.string.Custom} /> <Label label={settings.string.Custom} />
@ -192,23 +218,17 @@
<tr <tr
class="antiTable-body__row" class="antiTable-body__row"
on:contextmenu={(ev) => { on:contextmenu={(ev) => {
if (attr.isCustom) { ev.preventDefault()
ev.preventDefault() showMenu(ev, attr)
showMenu(ev, attr)
}
}} }}
> >
<!-- <td class='select-text'>
{attr.name}
</td> -->
<td> <td>
<div class="antiTable-cells__firstCell"> <div class="antiTable-cells__firstCell">
<Label label={attr.label} /> <Label label={attr.label} />
{#if attr.isCustom} <!-- svelte-ignore a11y-click-events-have-key-events -->
<div id="context-menu" class="antiTable-cells__firstCell-menuRow" on:click={(ev) => showMenu(ev, attr)}> <div id="context-menu" class="antiTable-cells__firstCell-menuRow" on:click={(ev) => showMenu(ev, attr)}>
<IconMoreV size={'small'} /> <IconMoreV size={'small'} />
</div> </div>
{/if}
</div> </div>
</td> </td>
<td class="select-text"> <td class="select-text">
@ -224,6 +244,11 @@
{/await} {/await}
{/if} {/if}
</td> </td>
<td>
{#if attr.hidden}
<Label label={settings.string.Hidden} />
{/if}
</td>
<td> <td>
<Component is={view.component.BooleanTruePresenter} props={{ value: attr.isCustom ?? false }} /> <Component is={view.component.BooleanTruePresenter} props={{ value: attr.isCustom ?? false }} />
</td> </td>

View File

@ -52,6 +52,7 @@
{#each classes as cl} {#each classes as cl}
{@const clazz = hierarchy.getClass(cl)} {@const clazz = hierarchy.getClass(cl)}
{@const desc = getDescendants(cl)} {@const desc = getDescendants(cl)}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div <div
class="ac-column__list-item" class="ac-column__list-item"
class:ac-column__list-selected={cl === _class} class:ac-column__list-selected={cl === _class}

View File

@ -66,6 +66,7 @@
</div> </div>
<div class="overflow-y-auto"> <div class="overflow-y-auto">
{#each enums as value} {#each enums as value}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div <div
class="ac-column__list-item" class="ac-column__list-item"
class:selected={selected === value} class:selected={selected === value}

View File

@ -41,6 +41,7 @@
</div> </div>
<div class="flex-col overflow-y-auto"> <div class="flex-col overflow-y-auto">
{#each folders as f (f._id)} {#each folders as f (f._id)}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="flex-between item" class:selected={f._id === folder?._id} on:click={() => select(f)}> <div class="flex-between item" class:selected={f._id === folder?._id} on:click={() => select(f)}>
<div class="icon flex-no-shrink mr-4"> <div class="icon flex-no-shrink mr-4">
<Component is={f.icon} /> <Component is={f.icon} />

View File

@ -112,6 +112,7 @@
</div> </div>
<div id="templates" class="flex-col overflow-y-auto"> <div id="templates" class="flex-col overflow-y-auto">
{#each templates as t (t._id)} {#each templates as t (t._id)}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="ac-column__list-item" class:selected={t._id === template?._id} on:click={() => select(t)}> <div class="ac-column__list-item" class:selected={t._id === template?._id} on:click={() => select(t)}>
<AttributeEditor maxWidth={'15rem'} _class={task.class.KanbanTemplate} object={t} key="title" /> <AttributeEditor maxWidth={'15rem'} _class={task.class.KanbanTemplate} object={t} key="title" />
{#if templates.length > 1} {#if templates.length > 1}

View File

@ -56,6 +56,10 @@ export default mergeIds(settingId, setting, {
ImportEnumCopy: '' as IntlString, ImportEnumCopy: '' as IntlString,
CreateMixin: '' as IntlString, CreateMixin: '' as IntlString,
OldNames: '' as IntlString, OldNames: '' as IntlString,
NewClassName: '' as IntlString NewClassName: '' as IntlString,
HideAttribute: '' as IntlString,
ShowAttribute: '' as IntlString,
Visibility: '' as IntlString,
Hidden: '' as IntlString
} }
}) })

View File

@ -50,9 +50,8 @@
}} }}
> >
<div class="color" style:background-color={getPlatformColor(value.color ?? 0)} /> <div class="color" style:background-color={getPlatformColor(value.color ?? 0)} />
<span class="overflow-label ml-1-5 caption-color" <span class="overflow-label ml-1-5 caption-color">
>{value.title}- {value.title}
<Icon icon={tagIcon} size={'small'} />
</span> </span>
{#if isEditable} {#if isEditable}
<button class="btn-close" on:click|stopPropagation={() => dispatch('remove', value.tag)}> <button class="btn-close" on:click|stopPropagation={() => dispatch('remove', value.tag)}>

View File

@ -15,7 +15,7 @@
<script lang="ts"> <script lang="ts">
import core, { Class, Doc, Ref } from '@hcengineering/core' import core, { Class, Doc, Ref } from '@hcengineering/core'
import { IntlString } from '@hcengineering/platform' import { IntlString } from '@hcengineering/platform'
import { AttributesBar, getClient, KeyedAttribute } from '@hcengineering/presentation' import { AttributesBar, getAttribute, getClient, KeyedAttribute } from '@hcengineering/presentation'
import setting, { settingId } from '@hcengineering/setting' import setting, { settingId } from '@hcengineering/setting'
import { Button, getCurrentLocation, Label, navigate } from '@hcengineering/ui' import { Button, getCurrentLocation, Label, navigate } from '@hcengineering/ui'
import { getFiltredKeys, isCollectionAttr } from '../utils' import { getFiltredKeys, isCollectionAttr } from '../utils'
@ -27,7 +27,6 @@
export let allowedCollections: string[] = [] export let allowedCollections: string[] = []
export let readonly = false export let readonly = false
export let showLabel: IntlString | undefined = undefined export let showLabel: IntlString | undefined = undefined
export let defaultCollapsed = false
export let draft = false export let draft = false
export let showHeader: boolean = true export let showHeader: boolean = true
@ -35,7 +34,6 @@
const hierarchy = client.getHierarchy() const hierarchy = client.getHierarchy()
let keys: KeyedAttribute[] = [] let keys: KeyedAttribute[] = []
let collapsed: boolean = defaultCollapsed
function updateKeys (_class: Ref<Class<Doc>>, ignoreKeys: string[], to: Ref<Class<Doc>> | undefined): void { function updateKeys (_class: Ref<Class<Doc>>, ignoreKeys: string[], to: Ref<Class<Doc>> | undefined): void {
const filtredKeys = getFiltredKeys(hierarchy, _class, ignoreKeys, to) const filtredKeys = getFiltredKeys(hierarchy, _class, ignoreKeys, to)
@ -44,7 +42,15 @@
$: updateKeys(_class, ignoreKeys, to) $: updateKeys(_class, ignoreKeys, to)
$: nonEmpty = keys.find((it) => getAttribute(client, object, it) != null)
$: label = showLabel ?? hierarchy.getClass(_class).label $: label = showLabel ?? hierarchy.getClass(_class).label
function getCollapsed (_class: Ref<Class<Doc>>, nonEmpty?: KeyedAttribute): boolean {
return nonEmpty === undefined
}
$: collapsed = getCollapsed(_class, nonEmpty)
</script> </script>
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->

View File

@ -31,6 +31,8 @@
{#each mixins as mixin} {#each mixins as mixin}
{@const to = !hierarchy.hasMixin(mixin, setting.mixin.UserMixin) ? object._class : mixin.extends} {@const to = !hierarchy.hasMixin(mixin, setting.mixin.UserMixin) ? object._class : mixin.extends}
{#if !hierarchy.hasMixin(mixin, setting.mixin.Editable) || hierarchy.as(mixin, setting.mixin.Editable).value} {#if !hierarchy.hasMixin(mixin, setting.mixin.Editable) || hierarchy.as(mixin, setting.mixin.Editable).value}
<ClassAttributeBar _class={mixin._id} {object} {ignoreKeys} {to} {allowedCollections} on:update /> {#key mixin._id}
<ClassAttributeBar _class={mixin._id} {object} {ignoreKeys} {to} {allowedCollections} on:update />
{/key}
{/if} {/if}
{/each} {/each}

View File

@ -88,11 +88,15 @@
function getMixins (parentClass: Ref<Class<Doc>>, object: Doc, showAllMixins: boolean): void { function getMixins (parentClass: Ref<Class<Doc>>, object: Doc, showAllMixins: boolean): void {
if (object === undefined || parentClass === undefined) return if (object === undefined || parentClass === undefined) return
const descendants = hierarchy.getDescendants(parentClass).map((p) => hierarchy.getClass(p)) const descendants = hierarchy.getDescendants(parentClass).map((p) => hierarchy.getClass(p))
mixins = descendants.filter( mixins = descendants.filter(
(m) => (m) =>
m.kind === ClassifierKind.MIXIN && m.kind === ClassifierKind.MIXIN &&
!ignoreMixins.has(m._id) && !ignoreMixins.has(m._id) &&
(hierarchy.hasMixin(object, m._id) || showAllMixins) (hierarchy.hasMixin(object, m._id) ||
(showAllMixins &&
// hierarchy.isDerived(hierarchy.getBaseClass(m._id), realObjectClass)
hierarchy.isDerived(realObjectClass, hierarchy.getBaseClass(m._id))))
) )
} }

View File

@ -46,6 +46,11 @@
bind:selected={value} bind:selected={value}
{items} {items}
{label} {label}
useFlexGrow={true}
justify={'left'}
size={'large'}
kind={'link'}
width={'100%'}
autoSelect={false} autoSelect={false}
on:selected={(e) => { on:selected={(e) => {
onChange(e.detail) onChange(e.detail)

View File

@ -33,6 +33,7 @@
} }
</script> </script>
<!-- svelte-ignore a11y-click-events-have-key-events -->
{#if kind === 'link'} {#if kind === 'link'}
<div <div
class="link-container" class="link-container"
@ -74,9 +75,9 @@
border: 1px solid transparent; border: 1px solid transparent;
border-radius: 0.25rem; border-radius: 0.25rem;
cursor: pointer; cursor: pointer;
color: var(--caption-color);
&:hover { &:hover {
color: var(--caption-color);
background-color: var(--body-color); background-color: var(--body-color);
border-color: var(--divider-color); border-color: var(--divider-color);
} }

View File

@ -176,7 +176,7 @@ class ElasticDataAdapter implements DbAdapter {
) )
const operations = part.flatMap((doc) => [ const operations = part.flatMap((doc) => [
{ index: { _index: this.workspaceId, _id: doc._id } }, { index: { _index: toWorkspaceString(this.workspaceId), _id: doc._id } },
(doc as FullTextData).data (doc as FullTextData).data
]) ])