mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-25 09:50:19 +00:00
Contacts: Type Filter (#1855)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com> Co-authored-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
51d29fbe12
commit
578283d78b
models
contact/src
core/src
lead/src
recruit/src
view/src
packages/core/lang
plugins
view-resources/src
workbench-resources/src/components
@ -68,6 +68,9 @@ export class TContact extends TDoc implements Contact {
|
||||
@Prop(TypeString(), contact.string.Location)
|
||||
@Index(IndexKind.FullText)
|
||||
city!: string
|
||||
|
||||
@Prop(TypeRef(core.class.Class), core.string.ClassLabel)
|
||||
declare _class: Ref<Class<this>>
|
||||
}
|
||||
|
||||
@Model(contact.class.Channel, core.class.AttachedDoc, DOMAIN_CHANNEL)
|
||||
@ -162,7 +165,7 @@ export function createModel (builder: Builder): void {
|
||||
descriptor: view.viewlet.Table,
|
||||
config: [
|
||||
'',
|
||||
{ key: '$lookup._class.label', label: contact.string.TypeLabel },
|
||||
'$lookup._class',
|
||||
'city',
|
||||
'attachments',
|
||||
'modifiedOn',
|
||||
@ -291,7 +294,7 @@ export function createModel (builder: Builder): void {
|
||||
})
|
||||
|
||||
builder.mixin(contact.class.Contact, core.class.Class, view.mixin.ClassFilters, {
|
||||
filters: ['city', 'modifiedOn']
|
||||
filters: ['_class', 'city', 'modifiedOn']
|
||||
})
|
||||
|
||||
builder.createDoc(
|
||||
|
@ -21,6 +21,7 @@ export default mergeIds(coreId, core, {
|
||||
Description: '' as IntlString,
|
||||
Private: '' as IntlString,
|
||||
Archived: '' as IntlString,
|
||||
ClassLabel: '' as IntlString
|
||||
ClassLabel: '' as IntlString,
|
||||
ClassPropertyLabel: '' as IntlString
|
||||
}
|
||||
})
|
||||
|
@ -45,7 +45,7 @@ import core from './component'
|
||||
// C O R E
|
||||
@Model(core.class.Obj, core.class.Obj)
|
||||
export class TObj implements Obj {
|
||||
@Prop(TypeRef(core.class.Class), core.string.Class)
|
||||
@Prop(TypeRef(core.class.Class), core.string.ClassLabel)
|
||||
@Index(IndexKind.Indexed)
|
||||
_class!: Ref<Class<this>>
|
||||
}
|
||||
@ -86,7 +86,7 @@ export class TAttachedDoc extends TDoc implements AttachedDoc {
|
||||
export class TClass extends TDoc implements Class<Obj> {
|
||||
kind!: ClassifierKind
|
||||
|
||||
@Prop(TypeIntlString(), core.string.ClassLabel)
|
||||
@Prop(TypeIntlString(), core.string.ClassPropertyLabel)
|
||||
label!: IntlString
|
||||
|
||||
extends!: Ref<Class<Obj>>
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
// To help typescript locate view plugin properly
|
||||
import type { Employee } from '@anticrm/contact'
|
||||
import { Doc, FindOptions, IndexKind, Ref } from '@anticrm/core'
|
||||
import { Class, Doc, FindOptions, IndexKind, Ref } from '@anticrm/core'
|
||||
import type { Customer, Funnel, Lead } from '@anticrm/lead'
|
||||
import { Builder, Collection, Index, Mixin, Model, Prop, TypeRef, TypeString, UX } from '@anticrm/model'
|
||||
import attachment from '@anticrm/model-attachment'
|
||||
@ -60,6 +60,9 @@ export class TCustomer extends TContact implements Customer {
|
||||
@Prop(TypeString(), core.string.Description)
|
||||
@Index(IndexKind.FullText)
|
||||
description!: string
|
||||
|
||||
@Prop(TypeRef(core.class.Class), core.string.ClassLabel)
|
||||
declare _class: Ref<Class<this>>
|
||||
}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
@ -123,7 +126,7 @@ export function createModel (builder: Builder): void {
|
||||
descriptor: view.viewlet.Table,
|
||||
config: [
|
||||
'',
|
||||
{ key: '$lookup._class.label', label: contact.string.TypeLabel },
|
||||
'$lookup._class',
|
||||
{ key: 'leads', presenter: lead.component.LeadsPresenter, label: lead.string.Leads },
|
||||
'modifiedOn',
|
||||
'$lookup.channels'
|
||||
|
@ -452,11 +452,11 @@ export function createModel (builder: Builder): void {
|
||||
})
|
||||
|
||||
builder.mixin(recruit.mixin.Candidate, core.class.Class, view.mixin.ClassFilters, {
|
||||
filters: ['title', 'source', 'city', 'skills', 'modifiedOn', 'onsite', 'remote']
|
||||
filters: ['_class', 'title', 'source', 'city', 'skills', 'modifiedOn', 'onsite', 'remote']
|
||||
})
|
||||
|
||||
builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.ClassFilters, {
|
||||
filters: ['attachedTo', 'assignee', 'modifiedOn']
|
||||
filters: ['attachedTo', 'assignee', 'state', 'doneState', 'modifiedOn']
|
||||
})
|
||||
|
||||
createReviewModel(builder)
|
||||
|
@ -275,6 +275,7 @@ export function createModel (builder: Builder): void {
|
||||
classPresenter(builder, core.class.TypeTimestamp, view.component.TimestampPresenter)
|
||||
classPresenter(builder, core.class.TypeDate, view.component.DatePresenter, view.component.DateEditor)
|
||||
classPresenter(builder, core.class.Space, view.component.ObjectPresenter)
|
||||
classPresenter(builder, core.class.Class, view.component.ClassPresenter)
|
||||
|
||||
builder.mixin(core.class.TypeString, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: view.component.StringTypeEditor
|
||||
|
@ -82,7 +82,8 @@ export default mergeIds(viewId, view, {
|
||||
BooleanTypeEditor: '' as AnyComponent,
|
||||
NumberTypeEditor: '' as AnyComponent,
|
||||
DateTypeEditor: '' as AnyComponent,
|
||||
RefEditor: '' as AnyComponent
|
||||
RefEditor: '' as AnyComponent,
|
||||
ClassPresenter: '' as AnyComponent
|
||||
},
|
||||
string: {
|
||||
Table: '' as IntlString,
|
||||
|
@ -11,7 +11,8 @@
|
||||
"Description": "Description",
|
||||
"Private": "Private",
|
||||
"Archived": "Archived",
|
||||
"ClassLabel": "Label",
|
||||
"ClassLabel": "Type",
|
||||
"ClassPropertyLabel": "Label",
|
||||
"String": "String",
|
||||
"Markup": "Markup",
|
||||
"Number": "Number",
|
||||
|
@ -12,6 +12,7 @@
|
||||
"Private": "Личный",
|
||||
"Archived": "Архивный",
|
||||
"ClassLabel": "Тип",
|
||||
"ClassPropertyLabel": "Название",
|
||||
"String": "Строка",
|
||||
"Markup": "Разметка",
|
||||
"Number": "Число",
|
||||
|
22
plugins/view-resources/src/components/ClassPresenter.svelte
Normal file
22
plugins/view-resources/src/components/ClassPresenter.svelte
Normal file
@ -0,0 +1,22 @@
|
||||
<!--
|
||||
// Copyright © 2022 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 type { Class, Doc } from '@anticrm/core'
|
||||
import { Label } from '@anticrm/ui'
|
||||
|
||||
export let value: Class<Doc>
|
||||
</script>
|
||||
|
||||
<Label label={value.label} />
|
@ -78,7 +78,11 @@
|
||||
let merged = false
|
||||
for (const key in newValue) {
|
||||
if (newQuery[filter.key.key][key] === undefined) {
|
||||
newQuery[filter.key.key][key] = newValue[key]
|
||||
if (key === '$in' && typeof newQuery[filter.key.key] === 'string') {
|
||||
newQuery[filter.key.key] = { $in: newValue[key].filter((p: any) => p === newQuery[filter.key.key]) }
|
||||
} else {
|
||||
newQuery[filter.key.key][key] = newValue[key]
|
||||
}
|
||||
merged = true
|
||||
continue
|
||||
}
|
||||
|
@ -59,7 +59,8 @@
|
||||
|
||||
let values: (Doc | undefined | null)[] = []
|
||||
let objectsPromise: Promise<FindResult<Doc>> | undefined
|
||||
|
||||
const targetClass = (hierarchy.getAttribute(_class, filter.key.key).type as RefTo<Doc>).to
|
||||
const clazz = hierarchy.getClass(targetClass)
|
||||
const targets = new Map<any, number>()
|
||||
async function getValues (search: string): Promise<void> {
|
||||
if (objectsPromise) {
|
||||
@ -71,8 +72,7 @@
|
||||
const value = getObjectValue(filter.key.key, object) ?? undefined
|
||||
targets.set(value, (targets.get(value) ?? 0) + 1)
|
||||
}
|
||||
const targetClass = (hierarchy.getAttribute(_class, filter.key.key).type as RefTo<Doc>).to
|
||||
const clazz = hierarchy.getClass(targetClass)
|
||||
|
||||
const resultQuery =
|
||||
search !== '' && clazz.sortingKey
|
||||
? {
|
||||
@ -130,17 +130,19 @@
|
||||
</script>
|
||||
|
||||
<div class="selectPopup">
|
||||
<div class="header">
|
||||
<input
|
||||
bind:this={searchInput}
|
||||
type="text"
|
||||
bind:value={search}
|
||||
on:change={() => {
|
||||
getValues(search)
|
||||
}}
|
||||
placeholder={phTraslate}
|
||||
/>
|
||||
</div>
|
||||
{#if clazz.sortingKey}
|
||||
<div class="header">
|
||||
<input
|
||||
bind:this={searchInput}
|
||||
type="text"
|
||||
bind:value={search}
|
||||
on:change={() => {
|
||||
getValues(search)
|
||||
}}
|
||||
placeholder={phTraslate}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="scroll">
|
||||
<div class="box">
|
||||
{#await promise then attribute}
|
||||
|
@ -49,6 +49,7 @@ import TableBrowser from './components/TableBrowser.svelte'
|
||||
import ValueFilter from './components/filter/ValueFilter.svelte'
|
||||
import ObjectFilter from './components/filter/ObjectFilter.svelte'
|
||||
import TimestampFilter from './components/filter/TimestampFilter.svelte'
|
||||
import ClassPresenter from './components/ClassPresenter.svelte'
|
||||
|
||||
export { getActions, invokeAction } from './actions'
|
||||
export { default as ActionContext } from './components/ActionContext.svelte'
|
||||
@ -76,6 +77,7 @@ export {
|
||||
export default async (): Promise<Resources> => ({
|
||||
actionImpl: actionImpl,
|
||||
component: {
|
||||
ClassPresenter,
|
||||
ObjectFilter,
|
||||
ValueFilter,
|
||||
TimestampFilter,
|
||||
|
@ -32,7 +32,7 @@
|
||||
{#if model}
|
||||
<TableBrowser
|
||||
_class={core.class.Space}
|
||||
config={['', '$lookup._class.label', 'modifiedOn']}
|
||||
config={['', '$lookup._class', 'modifiedOn']}
|
||||
showNotification
|
||||
baseMenuClass={core.class.Space}
|
||||
query={{
|
||||
|
Loading…
Reference in New Issue
Block a user