mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 11:01:54 +03:00
Filters improve (#2572)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
67e86538bb
commit
f7e220d0f2
@ -35,6 +35,7 @@ import { DOMAIN_MODEL, IndexKind } from '@hcengineering/core'
|
||||
import {
|
||||
Builder,
|
||||
Collection,
|
||||
Hidden,
|
||||
Index,
|
||||
Model,
|
||||
Prop,
|
||||
@ -76,6 +77,7 @@ export class TChannelProvider extends TDoc implements ChannelProvider {
|
||||
export class TContact extends TDoc implements Contact {
|
||||
@Prop(TypeString(), contact.string.Name)
|
||||
@Index(IndexKind.FullText)
|
||||
@Hidden()
|
||||
name!: string
|
||||
|
||||
avatar?: string | null
|
||||
|
@ -70,17 +70,21 @@ import core from './component'
|
||||
export class TObj implements Obj {
|
||||
@Prop(TypeRef(core.class.Class), core.string.ClassLabel)
|
||||
@Index(IndexKind.Indexed)
|
||||
@Hidden()
|
||||
_class!: Ref<Class<this>>
|
||||
}
|
||||
|
||||
@Model(core.class.Doc, core.class.Obj)
|
||||
@UX(core.string.Object)
|
||||
export class TDoc extends TObj implements Doc {
|
||||
@Prop(TypeRef(core.class.Doc), core.string.Id)
|
||||
@Hidden()
|
||||
// @Index(IndexKind.Indexed) // - automatically indexed by default.
|
||||
_id!: Ref<this>
|
||||
|
||||
@Prop(TypeRef(core.class.Space), core.string.Space)
|
||||
@Index(IndexKind.Indexed)
|
||||
@Hidden()
|
||||
space!: Ref<Space>
|
||||
|
||||
@Prop(TypeTimestamp(), core.string.Modified)
|
||||
@ -94,10 +98,12 @@ export class TDoc extends TObj implements Doc {
|
||||
export class TAttachedDoc extends TDoc implements AttachedDoc {
|
||||
@Prop(TypeRef(core.class.Doc), core.string.AttachedTo)
|
||||
@Index(IndexKind.Indexed)
|
||||
@Hidden()
|
||||
attachedTo!: Ref<Doc>
|
||||
|
||||
@Prop(TypeRef(core.class.Class), core.string.AttachedToClass)
|
||||
@Index(IndexKind.Indexed)
|
||||
@Hidden()
|
||||
attachedToClass!: Ref<Class<Doc>>
|
||||
|
||||
@Prop(TypeString(), core.string.Collection)
|
||||
|
@ -16,7 +16,6 @@
|
||||
import type { Employee, Organization } from '@hcengineering/contact'
|
||||
import { Doc, FindOptions, IndexKind, Lookup, Ref, Timestamp } from '@hcengineering/core'
|
||||
import {
|
||||
ArrOf,
|
||||
Builder,
|
||||
Collection,
|
||||
Index,
|
||||
@ -125,7 +124,7 @@ export class TCandidate extends TPerson implements Candidate {
|
||||
@Mixin(recruit.mixin.VacancyList, contact.class.Organization)
|
||||
@UX(recruit.string.VacancyList, recruit.icon.RecruitApplication, undefined, 'name')
|
||||
export class TVacancyList extends TOrganization implements VacancyList {
|
||||
@Prop(ArrOf(TypeRef(recruit.class.Vacancy)), recruit.string.Vacancies)
|
||||
@Prop(Collection(recruit.class.Vacancy), recruit.string.Vacancies)
|
||||
vacancies!: number
|
||||
}
|
||||
|
||||
@ -192,7 +191,7 @@ export function createModel (builder: Builder): void {
|
||||
editor: recruit.component.Applications
|
||||
})
|
||||
|
||||
builder.mixin(recruit.class.Vacancy, core.class.Class, view.mixin.ArrayEditor, {
|
||||
builder.mixin(recruit.class.Vacancy, core.class.Class, view.mixin.CollectionEditor, {
|
||||
editor: recruit.component.VacancyList
|
||||
})
|
||||
|
||||
|
@ -121,6 +121,7 @@ export class TTask extends TAttachedDoc implements Task {
|
||||
|
||||
@Prop(TypeString(), task.string.TaskNumber)
|
||||
@Index(IndexKind.FullText)
|
||||
@Hidden()
|
||||
number!: number
|
||||
|
||||
// @Prop(TypeRef(contact.class.Employee), task.string.TaskAssignee)
|
||||
|
@ -512,7 +512,7 @@ export function createModel (builder: Builder): void {
|
||||
)
|
||||
|
||||
builder.mixin(core.class.Space, core.class.Class, view.mixin.AttributePresenter, {
|
||||
presenter: view.component.SpacePresenter
|
||||
presenter: view.component.SpaceRefPresenter
|
||||
})
|
||||
|
||||
// Selection stuff
|
||||
|
@ -64,7 +64,8 @@ export default mergeIds(viewId, view, {
|
||||
MarkupEditor: '' as AnyComponent,
|
||||
MarkupEditorPopup: '' as AnyComponent,
|
||||
ListView: '' as AnyComponent,
|
||||
IndexedDocumentPreview: '' as AnyComponent
|
||||
IndexedDocumentPreview: '' as AnyComponent,
|
||||
SpaceRefPresenter: '' as AnyComponent
|
||||
},
|
||||
string: {
|
||||
Table: '' as IntlString,
|
||||
|
@ -150,6 +150,7 @@ export default plugin(coreId, {
|
||||
Name: '' as IntlString,
|
||||
Enum: '' as IntlString,
|
||||
Description: '' as IntlString,
|
||||
Hyperlink: '' as IntlString
|
||||
Hyperlink: '' as IntlString,
|
||||
Object: '' as IntlString
|
||||
}
|
||||
})
|
||||
|
@ -394,6 +394,34 @@ export class Hierarchy {
|
||||
return result
|
||||
}
|
||||
|
||||
getOwnAttributes (clazz: Ref<Classifier>): Map<string, AnyAttribute> {
|
||||
const result = new Map<string, AnyAttribute>()
|
||||
|
||||
const attributes = this.attributes.get(clazz)
|
||||
if (attributes !== undefined) {
|
||||
for (const [name, attr] of attributes) {
|
||||
result.set(name, attr)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
getParentClass (_class: Ref<Class<Obj>>): Ref<Class<Obj>> {
|
||||
const baseDomain = this.getDomain(_class)
|
||||
const ancestors = this.getAncestors(_class)
|
||||
let result: Ref<Class<Obj>> = _class
|
||||
for (const ancestor of ancestors) {
|
||||
try {
|
||||
const domain = this.getClass(ancestor).domain
|
||||
if (domain === baseDomain) {
|
||||
result = ancestor
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
getAttribute (classifier: Ref<Classifier>, name: string): AnyAttribute {
|
||||
const attr = this.findAttribute(classifier, name)
|
||||
if (attr === undefined) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
"Array": "Array",
|
||||
"Enum": "Enum",
|
||||
"Members": "Members",
|
||||
"Hyperlink": "URL"
|
||||
"Hyperlink": "URL",
|
||||
"Object": "Object"
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
"Array": "Массив",
|
||||
"Enum": "Справочник",
|
||||
"Members": "Участники",
|
||||
"Hyperlink": "URL"
|
||||
"Hyperlink": "URL",
|
||||
"Object": "Объект"
|
||||
}
|
||||
}
|
||||
|
@ -148,18 +148,9 @@
|
||||
transition-duration: 0.15s;
|
||||
|
||||
.btn-icon {
|
||||
color: var(--content-color);
|
||||
transition: color 0.15s;
|
||||
pointer-events: none;
|
||||
}
|
||||
&:hover {
|
||||
color: var(--accent-color);
|
||||
transition-duration: 0;
|
||||
|
||||
.btn-icon {
|
||||
color: var(--caption-color);
|
||||
}
|
||||
}
|
||||
&.disabled {
|
||||
color: rgb(var(--caption-color) / 40%);
|
||||
|
||||
@ -167,6 +158,14 @@
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
color: var(--caption-color);
|
||||
transition-duration: 0;
|
||||
|
||||
.btn-icon {
|
||||
color: var(--caption-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.jf-left {
|
||||
justify-content: flex-start;
|
||||
|
@ -20,6 +20,7 @@
|
||||
import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
|
||||
import {
|
||||
ActionContext,
|
||||
FilterBar,
|
||||
FilterButton,
|
||||
getViewOptions,
|
||||
setActiveViewletId,
|
||||
@ -31,10 +32,11 @@
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
let search = ''
|
||||
let resultQuery: DocumentQuery<Doc> = {}
|
||||
let searchQuery: DocumentQuery<Doc> = {}
|
||||
let resultQuery: DocumentQuery<Doc> = searchQuery
|
||||
|
||||
function updateResultQuery (search: string): void {
|
||||
resultQuery = search === '' ? {} : { $search: search }
|
||||
searchQuery = search === '' ? {} : { $search: search }
|
||||
}
|
||||
|
||||
let viewlet: Viewlet | undefined
|
||||
@ -109,6 +111,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FilterBar
|
||||
_class={contact.class.Contact}
|
||||
{viewOptions}
|
||||
query={searchQuery}
|
||||
on:change={(e) => (resultQuery = e.detail)}
|
||||
/>
|
||||
|
||||
{#if viewlet}
|
||||
{#if loading}
|
||||
<Loading />
|
||||
|
@ -19,6 +19,7 @@
|
||||
import { Button, Icon, IconAdd, Label, Loading, SearchEdit, showPopup } from '@hcengineering/ui'
|
||||
import view, { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view'
|
||||
import {
|
||||
FilterBar,
|
||||
FilterButton,
|
||||
getViewOptions,
|
||||
setActiveViewletId,
|
||||
@ -30,9 +31,10 @@
|
||||
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||
|
||||
let search: string = ''
|
||||
let searchQuery: DocumentQuery<Doc> = {}
|
||||
let resultQuery: DocumentQuery<Doc> = {}
|
||||
|
||||
$: resultQuery = search === '' ? {} : { $search: search }
|
||||
$: searchQuery = search === '' ? {} : { $search: search }
|
||||
|
||||
type ApplicationInfo = { count: number; modifiedOn: number }
|
||||
let applications: Map<Ref<Vacancy>, ApplicationInfo> = new Map<Ref<Vacancy>, ApplicationInfo>()
|
||||
@ -169,6 +171,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FilterBar
|
||||
_class={recruit.class.Vacancy}
|
||||
{viewOptions}
|
||||
query={searchQuery}
|
||||
on:change={(e) => (resultQuery = e.detail)}
|
||||
/>
|
||||
|
||||
{#if descr}
|
||||
{#if loading}
|
||||
<Loading />
|
||||
|
@ -123,8 +123,8 @@
|
||||
}
|
||||
}
|
||||
const filtredKeys = Array.from(keysMap.values())
|
||||
|
||||
const { attributes, collections } = categorizeFields(hierarchy, filtredKeys, collectionArrays, allowedCollections)
|
||||
|
||||
keys = attributes.map((it) => it.key)
|
||||
|
||||
const editors: { key: KeyedAttribute; editor: AnyComponent; category: AttributeCategory }[] = []
|
||||
@ -171,7 +171,7 @@
|
||||
$: getEditorOrDefault(realObjectClass, showAllMixins, _id)
|
||||
|
||||
function getEditorOrDefault (_class: Ref<Class<Doc>>, showAllMixins: boolean, _id: Ref<Doc>): void {
|
||||
parentClass = getParentClass(_class)
|
||||
parentClass = hierarchy.getParentClass(_class)
|
||||
mainEditor = getEditor(_class)
|
||||
updateKeys(showAllMixins)
|
||||
}
|
||||
@ -210,21 +210,6 @@
|
||||
|
||||
$: icon = getIcon(realObjectClass)
|
||||
|
||||
function getParentClass (_class: Ref<Class<Doc>>): Ref<Class<Doc>> {
|
||||
const baseDomain = hierarchy.getDomain(_class)
|
||||
const ancestors = hierarchy.getAncestors(_class)
|
||||
let result: Ref<Class<Doc>> = _class
|
||||
for (const ancestor of ancestors) {
|
||||
try {
|
||||
const domain = hierarchy.getClass(ancestor).domain
|
||||
if (domain === baseDomain) {
|
||||
result = ancestor
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let title: string = ''
|
||||
|
||||
$: if (object !== undefined) {
|
||||
|
@ -34,7 +34,7 @@
|
||||
_id: type.of
|
||||
},
|
||||
(res) => {
|
||||
items = res[0].enumValues.map((p) => {
|
||||
items = res[0]?.enumValues?.map((p) => {
|
||||
return { id: p, label: p }
|
||||
})
|
||||
},
|
||||
|
@ -0,0 +1,22 @@
|
||||
<!--
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import core, { Ref, Space } from '@hcengineering/core'
|
||||
import { ObjectPresenter } from '..'
|
||||
|
||||
export let value: Ref<Space>
|
||||
</script>
|
||||
|
||||
<ObjectPresenter objectId={value} _class={core.class.Space} />
|
@ -14,10 +14,17 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import core, { AnyAttribute, ArrOf, Class, Doc, Ref, Type } from '@hcengineering/core'
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import { Asset, IntlString } from '@hcengineering/platform'
|
||||
import preferencePlugin from '@hcengineering/preference'
|
||||
import presentation, { Card, createQuery, getAttributePresenterClass, getClient } from '@hcengineering/presentation'
|
||||
import { Button, getPlatformColorForText, ToggleButton } from '@hcengineering/ui'
|
||||
import {
|
||||
Button,
|
||||
getEventPositionElement,
|
||||
getPlatformColorForText,
|
||||
SelectPopup,
|
||||
showPopup,
|
||||
ToggleButton
|
||||
} from '@hcengineering/ui'
|
||||
import { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
@ -55,14 +62,16 @@
|
||||
label: IntlString
|
||||
value: string | BuildModelKey
|
||||
_class: Ref<Class<Doc>>
|
||||
icon: Asset | undefined
|
||||
}
|
||||
|
||||
function getObjectConfig (_class: Ref<Class<Doc>>, param: string): AttributeConfig {
|
||||
const clazz = client.getHierarchy().getClass(_class)
|
||||
const clazz = hierarchy.getClass(_class)
|
||||
return {
|
||||
value: param,
|
||||
label: clazz.label,
|
||||
enabled: true,
|
||||
icon: clazz.icon,
|
||||
_class
|
||||
}
|
||||
}
|
||||
@ -70,6 +79,7 @@
|
||||
function getBaseConfig (viewlet: Viewlet): AttributeConfig[] {
|
||||
const lookup = buildConfigLookup(hierarchy, viewlet.attachTo, viewlet.config, viewlet.options?.lookup)
|
||||
const result: AttributeConfig[] = []
|
||||
const clazz = hierarchy.getClass(viewlet.attachTo)
|
||||
for (const param of viewlet.config) {
|
||||
if (typeof param === 'string') {
|
||||
if (param.length === 0) {
|
||||
@ -79,7 +89,8 @@
|
||||
value: param,
|
||||
enabled: true,
|
||||
label: getKeyLabel(client, viewlet.attachTo, param, lookup),
|
||||
_class: viewlet.attachTo
|
||||
_class: viewlet.attachTo,
|
||||
icon: clazz.icon
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@ -87,7 +98,8 @@
|
||||
value: param,
|
||||
label: param.label as IntlString,
|
||||
enabled: true,
|
||||
_class: viewlet.attachTo
|
||||
_class: viewlet.attachTo,
|
||||
icon: clazz.icon
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -126,13 +138,15 @@
|
||||
parent = pclazz.extends
|
||||
}
|
||||
if (presenter === undefined) return
|
||||
const clazz = hierarchy.getClass(attribute.attributeOf)
|
||||
|
||||
if (useMixinProxy) {
|
||||
const newValue = {
|
||||
value: attribute.attributeOf + '.' + attribute.name,
|
||||
label: attribute.label,
|
||||
enabled: false,
|
||||
_class: attribute.attributeOf
|
||||
_class: attribute.attributeOf,
|
||||
icon: clazz.icon
|
||||
}
|
||||
if (!isExist(result, newValue)) {
|
||||
result.push(newValue)
|
||||
@ -142,7 +156,8 @@
|
||||
value,
|
||||
label: attribute.label,
|
||||
enabled: false,
|
||||
_class: attribute.attributeOf
|
||||
_class: attribute.attributeOf,
|
||||
icon: clazz.icon
|
||||
}
|
||||
if (!isExist(result, newValue)) {
|
||||
result.push(newValue)
|
||||
@ -169,11 +184,21 @@
|
||||
}
|
||||
|
||||
hierarchy.getDescendants(viewlet.attachTo).forEach((it) => {
|
||||
const ancestor = hierarchy.getAncestors(it)[1]
|
||||
hierarchy.getAllAttributes(it, ancestor).forEach((attr) => {
|
||||
if (attr.isCustom === true) {
|
||||
processAttribute(attr, result, true)
|
||||
}
|
||||
hierarchy.getOwnAttributes(it).forEach((attr) => {
|
||||
processAttribute(attr, result, true)
|
||||
})
|
||||
})
|
||||
|
||||
const ancestors = new Set(hierarchy.getAncestors(viewlet.attachTo))
|
||||
const parent = hierarchy.getParentClass(viewlet.attachTo)
|
||||
const parentMixins = hierarchy
|
||||
.getDescendants(parent)
|
||||
.map((p) => hierarchy.getClass(p))
|
||||
.filter((p) => hierarchy.isMixin(p._id) && p.extends && ancestors.has(p.extends))
|
||||
|
||||
parentMixins.forEach((it) => {
|
||||
hierarchy.getOwnAttributes(it._id).forEach((attr) => {
|
||||
processAttribute(attr, result, true)
|
||||
})
|
||||
})
|
||||
|
||||
@ -252,6 +277,24 @@
|
||||
const color = getPlatformColorForText(attribute._class)
|
||||
return `border: 1px solid ${color + (attribute.enabled ? 'ff' : 'cc')};`
|
||||
}
|
||||
|
||||
function groupByClasses (attributes: AttributeConfig[]): Map<Ref<Class<Doc>>, AttributeConfig[]> {
|
||||
const res = new Map()
|
||||
for (const attribute of attributes) {
|
||||
if (attribute.enabled) continue
|
||||
const arr = res.get(attribute._class) ?? []
|
||||
arr.push(attribute)
|
||||
res.set(attribute._class, arr)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
$: enabled = attributes.filter((p) => p.enabled)
|
||||
$: classes = groupByClasses(attributes)
|
||||
|
||||
function getClassLabel (_class: Ref<Class<Doc>>): IntlString {
|
||||
return hierarchy.getClass(_class).label
|
||||
}
|
||||
</script>
|
||||
|
||||
<Card
|
||||
@ -264,7 +307,7 @@
|
||||
}}
|
||||
>
|
||||
<div class="flex-row-stretch flex-wrap">
|
||||
{#each attributes as attribute, i}
|
||||
{#each enabled as attribute, i}
|
||||
<div
|
||||
class="m-0-5 border-radius-1 overflow-label"
|
||||
style={getStyle(attribute)}
|
||||
@ -281,7 +324,41 @@
|
||||
selected = undefined
|
||||
}}
|
||||
>
|
||||
<ToggleButton backgroundColor={getColor(attribute)} label={attribute.label} bind:value={attribute.enabled} />
|
||||
<ToggleButton
|
||||
backgroundColor={getColor(attribute)}
|
||||
icon={attribute.icon}
|
||||
label={attribute.label}
|
||||
bind:value={attribute.enabled}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="flex-row-stretch flex-wrap">
|
||||
{#each Array.from(classes.keys()) as _class}
|
||||
<div class="m-0-5">
|
||||
<Button
|
||||
label={getClassLabel(_class)}
|
||||
on:click={(e) => {
|
||||
showPopup(
|
||||
SelectPopup,
|
||||
{
|
||||
value: classes.get(_class)?.map((it) => ({ id: it.value, label: it.label }))
|
||||
},
|
||||
getEventPositionElement(e),
|
||||
(val) => {
|
||||
console.log('val')
|
||||
console.log(val)
|
||||
if (val !== undefined) {
|
||||
const value = classes.get(_class)?.find((it) => it.value === val)
|
||||
if (value) {
|
||||
value.enabled = true
|
||||
attributes = attributes
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
@ -22,11 +22,20 @@
|
||||
Doc,
|
||||
Ref,
|
||||
RefTo,
|
||||
Type,
|
||||
Space
|
||||
Space,
|
||||
Type
|
||||
} from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { closePopup, closeTooltip, Icon, Label, showPopup, Submenu, resizeObserver } from '@hcengineering/ui'
|
||||
import {
|
||||
closePopup,
|
||||
closeTooltip,
|
||||
Icon,
|
||||
Label,
|
||||
resizeObserver,
|
||||
Scroller,
|
||||
showPopup,
|
||||
Submenu
|
||||
} from '@hcengineering/ui'
|
||||
import { Filter, KeyFilter } from '@hcengineering/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { FilterQuery } from '../../filter'
|
||||
@ -86,9 +95,6 @@
|
||||
}
|
||||
|
||||
function buildFilterForAttr (_class: Ref<Class<Doc>>, attribute: AnyAttribute, result: KeyFilter[]): void {
|
||||
if (attribute.isCustom !== true) {
|
||||
return
|
||||
}
|
||||
if (attribute.label === undefined || attribute.hidden) {
|
||||
return
|
||||
}
|
||||
@ -101,6 +107,7 @@
|
||||
result.push(filter)
|
||||
}
|
||||
}
|
||||
|
||||
function buildFilterFor (
|
||||
_class: Ref<Class<Doc>>,
|
||||
allAttributes: Map<string, AnyAttribute>,
|
||||
@ -118,7 +125,7 @@
|
||||
|
||||
const desc = hierarchy.getDescendants(_class)
|
||||
for (const d of desc) {
|
||||
const extra = hierarchy.getAllAttributes(d, _class)
|
||||
const extra = hierarchy.getOwnAttributes(d)
|
||||
for (const [k, v] of extra) {
|
||||
if (!allAttributes.has(k)) {
|
||||
allAttributes.set(k, v)
|
||||
@ -127,6 +134,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
const ancestors = new Set(hierarchy.getAncestors(_class))
|
||||
const parent = hierarchy.getParentClass(_class)
|
||||
const parentMixins = hierarchy
|
||||
.getDescendants(parent)
|
||||
.map((p) => hierarchy.getClass(p))
|
||||
.filter((p) => hierarchy.isMixin(p._id) && p.extends && ancestors.has(p.extends))
|
||||
|
||||
for (const d of parentMixins) {
|
||||
const extra = hierarchy.getOwnAttributes(d._id)
|
||||
for (const [k, v] of extra) {
|
||||
if (!allAttributes.has(k)) {
|
||||
allAttributes.set(k, v)
|
||||
buildFilterForAttr(d._id, v, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@ -207,44 +231,42 @@
|
||||
</script>
|
||||
|
||||
<div class="selectPopup" use:resizeObserver={() => dispatch('changeContent')}>
|
||||
<div class="scroll">
|
||||
<div class="box">
|
||||
{#each getTypes(_class) as type, i}
|
||||
{#if filter === undefined && type.component === view.component.ObjectFilter && hasNested(type)}
|
||||
<Submenu
|
||||
on:keydown={(event) => keyDown(event, i)}
|
||||
on:click={(event) => {
|
||||
click(type)
|
||||
}}
|
||||
icon={type.icon}
|
||||
label={type.label}
|
||||
props={getNestedProps(type)}
|
||||
options={{ component: view.component.FilterTypePopup }}
|
||||
withHover
|
||||
/>
|
||||
{:else}
|
||||
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
||||
<button
|
||||
class="menu-item withIcon"
|
||||
on:keydown={(event) => keyDown(event, i)}
|
||||
on:mouseover={(event) => {
|
||||
event.currentTarget.focus()
|
||||
}}
|
||||
on:click={(event) => {
|
||||
click(type)
|
||||
}}
|
||||
>
|
||||
<div class="icon mr-3">
|
||||
{#if type.icon}
|
||||
<Icon icon={type.icon} size={'small'} />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="pr-1"><Label label={type.label} /></div>
|
||||
</button>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<Scroller>
|
||||
{#each getTypes(_class) as type, i}
|
||||
{#if filter === undefined && type.component === view.component.ObjectFilter && hasNested(type)}
|
||||
<Submenu
|
||||
on:keydown={(event) => keyDown(event, i)}
|
||||
on:click={(event) => {
|
||||
click(type)
|
||||
}}
|
||||
icon={type.icon}
|
||||
label={type.label}
|
||||
props={getNestedProps(type)}
|
||||
options={{ component: view.component.FilterTypePopup }}
|
||||
withHover
|
||||
/>
|
||||
{:else}
|
||||
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
||||
<button
|
||||
class="menu-item withIcon"
|
||||
on:keydown={(event) => keyDown(event, i)}
|
||||
on:mouseover={(event) => {
|
||||
event.currentTarget.focus()
|
||||
}}
|
||||
on:click={(event) => {
|
||||
click(type)
|
||||
}}
|
||||
>
|
||||
<div class="icon mr-3">
|
||||
{#if type.icon}
|
||||
<Icon icon={type.icon} size={'small'} />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="pr-1"><Label label={type.label} /></div>
|
||||
</button>
|
||||
{/if}
|
||||
{/each}
|
||||
</Scroller>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -62,6 +62,7 @@ import TimestampPresenter from './components/TimestampPresenter.svelte'
|
||||
import UpDownNavigator from './components/UpDownNavigator.svelte'
|
||||
import ValueSelector from './components/ValueSelector.svelte'
|
||||
import ViewletSettingButton from './components/ViewletSettingButton.svelte'
|
||||
import SpaceRefPresenter from './components/SpaceRefPresenter.svelte'
|
||||
|
||||
import {
|
||||
afterResult,
|
||||
@ -172,7 +173,8 @@ export default async (): Promise<Resources> => ({
|
||||
HTMLEditor,
|
||||
ListView,
|
||||
GrowPresenter,
|
||||
IndexedDocumentPreview
|
||||
IndexedDocumentPreview,
|
||||
SpaceRefPresenter
|
||||
},
|
||||
popup: {
|
||||
PositionElementAlignment
|
||||
|
Loading…
Reference in New Issue
Block a user