From c6ff5f19ec877f46e72e2364159422bf6a58f61b Mon Sep 17 00:00:00 2001
From: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
Date: Wed, 1 Jun 2022 09:25:13 +0600
Subject: [PATCH] Vacancy configure (#1962)
Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
---
changelog.md | 4 +
models/contact/src/index.ts | 2 +-
models/recruit/src/index.ts | 24 ++-
.../src/components/Contacts.svelte | 18 +--
.../src/components/Products.svelte | 27 +---
.../src/components/Customers.svelte | 16 +-
.../src/components/ApplicationsView.svelte | 18 +--
.../src/components/Candidates.svelte | 18 +--
.../src/components/Vacancies.svelte | 138 ++++++++++++------
.../src/components/VacancyPresenter.svelte | 49 +++++--
.../src/components/Table.svelte | 2 +-
.../src/components/ViewletSetting.svelte | 35 +++--
.../components/ViewletSettingButton.svelte | 34 +++++
plugins/view-resources/src/index.ts | 43 +++---
plugins/view-resources/src/utils.ts | 41 ++++--
plugins/view/src/index.ts | 1 -
.../src/components/SpaceHeader.svelte | 18 +--
17 files changed, 282 insertions(+), 206 deletions(-)
create mode 100644 plugins/view-resources/src/components/ViewletSettingButton.svelte
diff --git a/changelog.md b/changelog.md
index 93b9cb4516..06b84ffc39 100644
--- a/changelog.md
+++ b/changelog.md
@@ -10,6 +10,10 @@ Platform:
- Fix skills/labels selection and show real usage counter
- Fix skills/labels activity
+HR:
+
+- Allow to configure vacancy table
+
## 0.6.22
Platform:
diff --git a/models/contact/src/index.ts b/models/contact/src/index.ts
index 9f6e4fd9bd..d787a45bcb 100644
--- a/models/contact/src/index.ts
+++ b/models/contact/src/index.ts
@@ -201,7 +201,7 @@ export function createModel (builder: Builder): void {
editor: contact.component.PersonEditor
})
- builder.mixin(contact.class.Channel, core.class.Class, view.mixin.AttributePresenter, {
+ builder.mixin(contact.class.Channel, core.class.Class, view.mixin.CollectionPresenter, {
presenter: contact.component.ChannelsPresenter
})
diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts
index 36b6bec3d5..1147546a5f 100644
--- a/models/recruit/src/index.ts
+++ b/models/recruit/src/index.ts
@@ -134,10 +134,6 @@ export function createModel (builder: Builder): void {
}
})
- builder.mixin(core.class.Space, core.class.Class, view.mixin.AttributePresenter, {
- presenter: recruit.component.VacancyItemPresenter
- })
-
builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.CollectionEditor, {
editor: recruit.component.Applications
})
@@ -269,6 +265,26 @@ export function createModel (builder: Builder): void {
hiddenKeys: ['name']
})
+ builder.createDoc(view.class.Viewlet, core.space.Model, {
+ attachTo: recruit.class.Vacancy,
+ descriptor: view.viewlet.Table,
+ config: [
+ '',
+ {
+ key: '@applications',
+ label: recruit.string.Applications
+ },
+ '$lookup.company',
+ 'location',
+ 'description',
+ {
+ key: '@applications.modifiedOn',
+ label: core.string.Modified
+ }
+ ],
+ hiddenKeys: ['name', 'space', 'modifiedOn']
+ })
+
builder.createDoc(view.class.Viewlet, core.space.Model, {
attachTo: recruit.class.Applicant,
descriptor: task.viewlet.StatusTable,
diff --git a/plugins/contact-resources/src/components/Contacts.svelte b/plugins/contact-resources/src/components/Contacts.svelte
index a46467ea3a..5dcefcb13b 100644
--- a/plugins/contact-resources/src/components/Contacts.svelte
+++ b/plugins/contact-resources/src/components/Contacts.svelte
@@ -16,10 +16,10 @@
-
+{#if descr}
+ {#if loading}
+
+ {:else}
+
+ {/if}
+{/if}
diff --git a/plugins/recruit-resources/src/components/VacancyPresenter.svelte b/plugins/recruit-resources/src/components/VacancyPresenter.svelte
index 5a93298b8b..0e94f709af 100644
--- a/plugins/recruit-resources/src/components/VacancyPresenter.svelte
+++ b/plugins/recruit-resources/src/components/VacancyPresenter.svelte
@@ -15,23 +15,54 @@
-->
{#if value}
-
+
{/if}
diff --git a/plugins/view-resources/src/components/Table.svelte b/plugins/view-resources/src/components/Table.svelte
index 04915c80d7..94afe292c0 100644
--- a/plugins/view-resources/src/components/Table.svelte
+++ b/plugins/view-resources/src/components/Table.svelte
@@ -43,7 +43,7 @@
const client = getClient()
const hierarchy = client.getHierarchy()
- $: lookup = buildConfigLookup(hierarchy, _class, config)
+ $: lookup = options?.lookup ?? buildConfigLookup(hierarchy, _class, config)
let sortKey = 'modifiedOn'
let sortOrder = SortingOrder.Descending
diff --git a/plugins/view-resources/src/components/ViewletSetting.svelte b/plugins/view-resources/src/components/ViewletSetting.svelte
index bec223ac82..1754460e1c 100644
--- a/plugins/view-resources/src/components/ViewletSetting.svelte
+++ b/plugins/view-resources/src/components/ViewletSetting.svelte
@@ -102,27 +102,26 @@
const allAttributes = hierarchy.getAllAttributes(viewlet.attachTo)
for (const [, attribute] of allAttributes) {
+ if (attribute.hidden === true || attribute.label === undefined) continue
+ if (viewlet.hiddenKeys?.includes(attribute.name)) continue
+ if (hierarchy.isDerived(attribute.type._class, core.class.Collection)) continue
const value = getValue(attribute.name, attribute.type)
if (result.findIndex((p) => p.value === value) !== -1) continue
- if (hierarchy.isDerived(attribute.type._class, core.class.Collection)) continue
- if (viewlet.hiddenKeys?.includes(value)) continue
- if (attribute.hidden !== true && attribute.label !== undefined) {
- const typeClassId = getAttributePresenterClass(attribute)
- const typeClass = hierarchy.getClass(typeClassId)
- let presenter = hierarchy.as(typeClass, view.mixin.AttributePresenter).presenter
- let parent = typeClass.extends
- while (presenter === undefined && parent !== undefined) {
- const pclazz = hierarchy.getClass(parent)
- presenter = hierarchy.as(pclazz, view.mixin.AttributePresenter).presenter
- parent = pclazz.extends
- }
- if (presenter === undefined) continue
- result.push({
- value,
- label: attribute.label,
- enabled: false
- })
+ const typeClassId = getAttributePresenterClass(attribute)
+ const typeClass = hierarchy.getClass(typeClassId)
+ let presenter = hierarchy.as(typeClass, view.mixin.AttributePresenter).presenter
+ let parent = typeClass.extends
+ while (presenter === undefined && parent !== undefined) {
+ const pclazz = hierarchy.getClass(parent)
+ presenter = hierarchy.as(pclazz, view.mixin.AttributePresenter).presenter
+ parent = pclazz.extends
}
+ if (presenter === undefined) continue
+ result.push({
+ value,
+ label: attribute.label,
+ enabled: false
+ })
}
return preference === undefined ? result : setStatus(result, preference)
diff --git a/plugins/view-resources/src/components/ViewletSettingButton.svelte b/plugins/view-resources/src/components/ViewletSettingButton.svelte
new file mode 100644
index 0000000000..43b13139f9
--- /dev/null
+++ b/plugins/view-resources/src/components/ViewletSettingButton.svelte
@@ -0,0 +1,34 @@
+
+
+
+{#if viewlet}
+
+
+{/if}
diff --git a/plugins/view-resources/src/index.ts b/plugins/view-resources/src/index.ts
index 0352c81fc0..5829fea1b3 100644
--- a/plugins/view-resources/src/index.ts
+++ b/plugins/view-resources/src/index.ts
@@ -16,40 +16,40 @@
import { Resources } from '@anticrm/platform'
import { getEventPopupPositionElement, PopupAlignment } from '@anticrm/ui'
import { actionImpl } from './actionImpl'
+import ActionsPopup from './components/ActionsPopup.svelte'
import BooleanEditor from './components/BooleanEditor.svelte'
import BooleanPresenter from './components/BooleanPresenter.svelte'
+import BooleanTruePresenter from './components/BooleanTruePresenter.svelte'
+import ClassAttributeBar from './components/ClassAttributeBar.svelte'
+import ClassPresenter from './components/ClassPresenter.svelte'
import ColorsPopup from './components/ColorsPopup.svelte'
import DateEditor from './components/DateEditor.svelte'
import DatePresenter from './components/DatePresenter.svelte'
-import SpacePresenter from './components/SpacePresenter.svelte'
-import StringEditor from './components/StringEditor.svelte'
-import StringPresenter from './components/StringPresenter.svelte'
+import DocAttributeBar from './components/DocAttributeBar.svelte'
+import EditBoxPopup from './components/EditBoxPopup.svelte'
import EditDoc from './components/EditDoc.svelte'
+import EnumEditor from './components/EnumEditor.svelte'
+import FilterBar from './components/filter/FilterBar.svelte'
+import ObjectFilter from './components/filter/ObjectFilter.svelte'
+import TimestampFilter from './components/filter/TimestampFilter.svelte'
+import ValueFilter from './components/filter/ValueFilter.svelte'
import HTMLPresenter from './components/HTMLPresenter.svelte'
import IntlStringPresenter from './components/IntlStringPresenter.svelte'
+import GithubPresenter from './components/linkPresenters/GithubPresenter.svelte'
+import YoutubePresenter from './components/linkPresenters/YoutubePresenter.svelte'
import Menu from './components/Menu.svelte'
import NumberEditor from './components/NumberEditor.svelte'
import NumberPresenter from './components/NumberPresenter.svelte'
import ObjectPresenter from './components/ObjectPresenter.svelte'
import RolePresenter from './components/RolePresenter.svelte'
+import SpacePresenter from './components/SpacePresenter.svelte'
+import StringEditor from './components/StringEditor.svelte'
+import StringPresenter from './components/StringPresenter.svelte'
import Table from './components/Table.svelte'
+import TableBrowser from './components/TableBrowser.svelte'
import TimestampPresenter from './components/TimestampPresenter.svelte'
import UpDownNavigator from './components/UpDownNavigator.svelte'
-import GithubPresenter from './components/linkPresenters/GithubPresenter.svelte'
-import YoutubePresenter from './components/linkPresenters/YoutubePresenter.svelte'
-import ActionsPopup from './components/ActionsPopup.svelte'
-import DocAttributeBar from './components/DocAttributeBar.svelte'
-import ViewletSetting from './components/ViewletSetting.svelte'
-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'
-import FilterBar from './components/filter/FilterBar.svelte'
-import EditBoxPopup from './components/EditBoxPopup.svelte'
-import BooleanTruePresenter from './components/BooleanTruePresenter.svelte'
-import EnumEditor from './components/EnumEditor.svelte'
-import ClassAttributeBar from './components/ClassAttributeBar.svelte'
+import ViewletSettingButton from './components/ViewletSettingButton.svelte'
function PositionElementAlignment (e?: Event): PopupAlignment | undefined {
return getEventPopupPositionElement(e)
@@ -58,10 +58,10 @@ function PositionElementAlignment (e?: Event): PopupAlignment | undefined {
export { getActions, invokeAction } from './actions'
export { default as ActionContext } from './components/ActionContext.svelte'
export { default as ActionHandler } from './components/ActionHandler.svelte'
+export { default as FilterButton } from './components/filter/FilterButton.svelte'
+export { default as LinkPresenter } from './components/LinkPresenter.svelte'
export { default as ContextMenu } from './components/Menu.svelte'
export { default as TableBrowser } from './components/TableBrowser.svelte'
-export { default as LinkPresenter } from './components/LinkPresenter.svelte'
-export { default as FilterButton } from './components/filter/FilterButton.svelte'
export * from './context'
export * from './selection'
export { buildModel, getCollectionCounter, getObjectPresenter, LoadingProps } from './utils'
@@ -75,7 +75,7 @@ export {
Menu,
SpacePresenter,
UpDownNavigator,
- ViewletSetting,
+ ViewletSettingButton,
FilterBar,
ClassAttributeBar
}
@@ -88,7 +88,6 @@ export default async (): Promise => ({
ValueFilter,
TimestampFilter,
TableBrowser,
- ViewletSetting,
SpacePresenter,
StringEditor,
StringPresenter,
diff --git a/plugins/view-resources/src/utils.ts b/plugins/view-resources/src/utils.ts
index d2545f7ca8..92d03420ba 100644
--- a/plugins/view-resources/src/utils.ts
+++ b/plugins/view-resources/src/utils.ts
@@ -48,16 +48,20 @@ export interface LoadingProps {
export async function getObjectPresenter (
client: Client,
_class: Ref>,
- preserveKey: BuildModelKey
+ preserveKey: BuildModelKey,
+ isCollectionAttr: boolean = false
): Promise {
- const clazz = client.getHierarchy().getClass(_class)
- const presenterMixin = client.getHierarchy().as(clazz, view.mixin.AttributePresenter)
+ const hierarchy = client.getHierarchy()
+ const mixin = isCollectionAttr ? view.mixin.CollectionPresenter : view.mixin.AttributePresenter
+ const clazz = hierarchy.getClass(_class)
+ let mixinClazz = hierarchy.getClass(_class)
+ let presenterMixin = hierarchy.as(clazz, mixin)
+ while (presenterMixin.presenter === undefined && mixinClazz.extends !== undefined) {
+ presenterMixin = hierarchy.as(mixinClazz, mixin)
+ mixinClazz = hierarchy.getClass(mixinClazz.extends)
+ }
if (presenterMixin.presenter === undefined) {
- if (clazz.extends !== undefined) {
- return await getObjectPresenter(client, clazz.extends, preserveKey)
- } else {
- throw new Error('object presenter not found for ' + JSON.stringify(preserveKey))
- }
+ throw new Error('object presenter not found for ' + JSON.stringify(preserveKey))
}
const presenter = await getResource(presenterMixin.presenter)
const key = preserveKey.sortingKey ?? preserveKey.key
@@ -132,7 +136,8 @@ export async function getPresenter (
_class: Ref>,
key: BuildModelKey,
preserveKey: BuildModelKey,
- lookup?: Lookup
+ lookup?: Lookup,
+ isCollectionAttr: boolean = false
): Promise {
if (key.presenter !== undefined) {
const { presenter, label, sortingKey } = key
@@ -146,7 +151,7 @@ export async function getPresenter (
}
}
if (key.key.length === 0) {
- return await getObjectPresenter(client, _class, preserveKey)
+ return await getObjectPresenter(client, _class, preserveKey, isCollectionAttr)
} else {
if (key.key.startsWith('$lookup')) {
if (lookup === undefined) {
@@ -262,7 +267,7 @@ async function getLookupPresenter (
const lookupClass = getLookupClass(key.key, lookup, _class)
const lookupProperty = getLookupProperty(key.key)
const lookupKey = { ...key, key: lookupProperty[0] }
- const model = await getPresenter(client, lookupClass[0], lookupKey, preserveKey)
+ const model = await getPresenter(client, lookupClass[0], lookupKey, preserveKey, undefined, lookupClass[2])
model.label = getLookupLabel(client, lookupClass[1], lookupClass[0], lookupKey, lookupProperty[1])
return model
}
@@ -292,7 +297,7 @@ export function getLookupClass (
key: string,
lookup: Lookup,
parent: Ref>
-): [Ref>, Ref>] {
+): [Ref>, Ref>, boolean] {
const _class = getLookup(key, lookup, parent)
if (_class === undefined) {
throw new Error('lookup class does not provided for ' + key)
@@ -313,7 +318,7 @@ function getLookup (
key: string,
lookup: Lookup,
parent: Ref>
-): [Ref>, Ref>] | undefined {
+): [Ref>, Ref>, boolean] | undefined {
const parts = key.split('$lookup.').filter((p) => p.length > 0)
const currentKey = parts[0].split('.').filter((p) => p.length > 0)[0]
const current = (lookup as any)[currentKey]
@@ -325,13 +330,17 @@ function getLookup (
return getLookup(nestedKey, current[1], current[0])
}
if (Array.isArray(current)) {
- return [current[0], parent]
+ return [current[0], parent, false]
}
if (current === undefined && lookup._id !== undefined) {
const reverse = (lookup._id as any)[currentKey]
- return reverse !== undefined ? [reverse, parent] : undefined
+ return reverse !== undefined
+ ? Array.isArray(reverse)
+ ? [reverse[0], parent, true]
+ : [reverse, parent, true]
+ : undefined
}
- return current !== undefined ? [current, parent] : undefined
+ return current !== undefined ? [current, parent, false] : undefined
}
export function getBooleanLabel (value: boolean | undefined): IntlString {
diff --git a/plugins/view/src/index.ts b/plugins/view/src/index.ts
index 627ea4edce..186d9b2721 100644
--- a/plugins/view/src/index.ts
+++ b/plugins/view/src/index.ts
@@ -391,7 +391,6 @@ const view = plugin(viewId, {
component: {
ObjectPresenter: '' as AnyComponent,
EditDoc: '' as AnyComponent,
- ViewletSetting: '' as AnyComponent,
SpacePresenter: '' as AnyComponent,
BooleanTruePresenter: '' as AnyComponent
},
diff --git a/plugins/workbench-resources/src/components/SpaceHeader.svelte b/plugins/workbench-resources/src/components/SpaceHeader.svelte
index 29b672637f..1a05f351c1 100644
--- a/plugins/workbench-resources/src/components/SpaceHeader.svelte
+++ b/plugins/workbench-resources/src/components/SpaceHeader.svelte
@@ -17,14 +17,14 @@
import core, { WithLookup } from '@anticrm/core'
import { IntlString } from '@anticrm/platform'
import presentation, { createQuery, getClient } from '@anticrm/presentation'
- import { AnyComponent, showPanel, Button, Icon, SearchEdit, showPopup, Tooltip, IconAdd } from '@anticrm/ui'
+ import { AnyComponent, Button, Icon, IconAdd, SearchEdit, showPanel, showPopup, Tooltip } from '@anticrm/ui'
+ import type { Filter } from '@anticrm/view'
import view, { Viewlet } from '@anticrm/view'
- import { ViewletSetting } from '@anticrm/view-resources'
+ import { ViewletSettingButton } from '@anticrm/view-resources'
import { createEventDispatcher } from 'svelte'
import plugin from '../plugin'
import { classIcon } from '../utils'
import Header from './Header.svelte'
- import type { Filter } from '@anticrm/view'
export let spaceId: Ref | undefined
export let createItemDialog: AnyComponent | undefined
@@ -115,16 +115,6 @@
{#if createItemDialog}