mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-20 07:10:02 +00:00
Vacancy configure (#1962)
Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
This commit is contained in:
parent
a4353b0fc7
commit
c6ff5f19ec
@ -10,6 +10,10 @@ Platform:
|
|||||||
- Fix skills/labels selection and show real usage counter
|
- Fix skills/labels selection and show real usage counter
|
||||||
- Fix skills/labels activity
|
- Fix skills/labels activity
|
||||||
|
|
||||||
|
HR:
|
||||||
|
|
||||||
|
- Allow to configure vacancy table
|
||||||
|
|
||||||
## 0.6.22
|
## 0.6.22
|
||||||
|
|
||||||
Platform:
|
Platform:
|
||||||
|
@ -201,7 +201,7 @@ export function createModel (builder: Builder): void {
|
|||||||
editor: contact.component.PersonEditor
|
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
|
presenter: contact.component.ChannelsPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -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, {
|
builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.CollectionEditor, {
|
||||||
editor: recruit.component.Applications
|
editor: recruit.component.Applications
|
||||||
})
|
})
|
||||||
@ -269,6 +265,26 @@ export function createModel (builder: Builder): void {
|
|||||||
hiddenKeys: ['name']
|
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, {
|
builder.createDoc(view.class.Viewlet, core.space.Model, {
|
||||||
attachTo: recruit.class.Applicant,
|
attachTo: recruit.class.Applicant,
|
||||||
descriptor: task.viewlet.StatusTable,
|
descriptor: task.viewlet.StatusTable,
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Doc, DocumentQuery } from '@anticrm/core'
|
import { Doc, DocumentQuery } from '@anticrm/core'
|
||||||
import { createQuery, getClient } from '@anticrm/presentation'
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
import { Tooltip, Button, Icon, IconAdd, Label, Loading, SearchEdit, showPopup } from '@anticrm/ui'
|
import { Button, Icon, IconAdd, Label, Loading, SearchEdit, showPopup } from '@anticrm/ui'
|
||||||
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
|
||||||
import type { Filter } from '@anticrm/view'
|
import type { Filter } from '@anticrm/view'
|
||||||
import { ActionContext, TableBrowser, ViewletSetting, FilterButton } from '@anticrm/view-resources'
|
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
||||||
|
import { ActionContext, FilterButton, TableBrowser, ViewletSettingButton } from '@anticrm/view-resources'
|
||||||
import contact from '../plugin'
|
import contact from '../plugin'
|
||||||
import CreateContact from './CreateContact.svelte'
|
import CreateContact from './CreateContact.svelte'
|
||||||
|
|
||||||
@ -90,17 +90,7 @@
|
|||||||
kind={'primary'}
|
kind={'primary'}
|
||||||
on:click={(ev) => showCreateDialog(ev)}
|
on:click={(ev) => showCreateDialog(ev)}
|
||||||
/>
|
/>
|
||||||
{#if viewlet}
|
<ViewletSettingButton {viewlet} />
|
||||||
<Tooltip label={view.string.CustomizeView}>
|
|
||||||
<Button
|
|
||||||
icon={view.icon.Setting}
|
|
||||||
kind={'transparent'}
|
|
||||||
on:click={() => {
|
|
||||||
showPopup(ViewletSetting, { viewlet })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if viewlet}
|
{#if viewlet}
|
||||||
|
@ -14,23 +14,22 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
import ui, {
|
import ui, {
|
||||||
Button,
|
Button,
|
||||||
EditWithIcon,
|
EditWithIcon,
|
||||||
|
eventToHTMLElement,
|
||||||
Icon,
|
Icon,
|
||||||
|
IconAdd,
|
||||||
IconSearch,
|
IconSearch,
|
||||||
Label,
|
Label,
|
||||||
showPopup,
|
|
||||||
IconAdd,
|
|
||||||
eventToHTMLElement,
|
|
||||||
Loading,
|
Loading,
|
||||||
Tooltip
|
showPopup
|
||||||
} from '@anticrm/ui'
|
} from '@anticrm/ui'
|
||||||
import CreateProduct from './CreateProduct.svelte'
|
|
||||||
import inventory from '../plugin'
|
|
||||||
import { TableBrowser, ViewletSetting } from '@anticrm/view-resources'
|
|
||||||
import { createQuery, getClient } from '@anticrm/presentation'
|
|
||||||
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
||||||
|
import { TableBrowser, ViewletSettingButton } from '@anticrm/view-resources'
|
||||||
|
import inventory from '../plugin'
|
||||||
|
import CreateProduct from './CreateProduct.svelte'
|
||||||
|
|
||||||
let search = ''
|
let search = ''
|
||||||
$: resultQuery = search === '' ? {} : { $search: search }
|
$: resultQuery = search === '' ? {} : { $search: search }
|
||||||
@ -89,17 +88,7 @@
|
|||||||
kind={'primary'}
|
kind={'primary'}
|
||||||
on:click={(ev) => showCreateDialog(ev)}
|
on:click={(ev) => showCreateDialog(ev)}
|
||||||
/>
|
/>
|
||||||
{#if descr}
|
<ViewletSettingButton viewlet={descr} />
|
||||||
<Tooltip label={view.string.CustomizeView}>
|
|
||||||
<Button
|
|
||||||
icon={view.icon.Setting}
|
|
||||||
kind={'transparent'}
|
|
||||||
on:click={() => {
|
|
||||||
showPopup(ViewletSetting, { viewlet: descr })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if descr}
|
{#if descr}
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Doc, DocumentQuery } from '@anticrm/core'
|
import { Doc, DocumentQuery } from '@anticrm/core'
|
||||||
import { createQuery, getClient } from '@anticrm/presentation'
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
import { Tooltip, Button, Icon, Label, Loading, showPopup, SearchEdit } from '@anticrm/ui'
|
import { Icon, Label, Loading, SearchEdit } from '@anticrm/ui'
|
||||||
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
||||||
import { ViewletSetting, TableBrowser } from '@anticrm/view-resources'
|
import { TableBrowser, ViewletSettingButton } from '@anticrm/view-resources'
|
||||||
import lead from '../plugin'
|
import lead from '../plugin'
|
||||||
|
|
||||||
let search = ''
|
let search = ''
|
||||||
@ -70,17 +70,7 @@
|
|||||||
updateResultQuery(search)
|
updateResultQuery(search)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{#if descr}
|
<ViewletSettingButton viewlet={descr} />
|
||||||
<Tooltip label={view.string.CustomizeView}>
|
|
||||||
<Button
|
|
||||||
icon={view.icon.Setting}
|
|
||||||
kind={'transparent'}
|
|
||||||
on:click={() => {
|
|
||||||
showPopup(ViewletSetting, { viewlet: descr })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if descr}
|
{#if descr}
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
import { createQuery, getClient } from '@anticrm/presentation'
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
import { Applicant } from '@anticrm/recruit'
|
import { Applicant } from '@anticrm/recruit'
|
||||||
import task from '@anticrm/task'
|
import task from '@anticrm/task'
|
||||||
import { Tooltip, Button, Icon, IconAdd, Label, Loading, SearchEdit, showPopup } from '@anticrm/ui'
|
import { Button, Icon, IconAdd, Label, Loading, SearchEdit, showPopup } from '@anticrm/ui'
|
||||||
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
|
||||||
import type { Filter } from '@anticrm/view'
|
import type { Filter } from '@anticrm/view'
|
||||||
import { TableBrowser, ViewletSetting, FilterButton } from '@anticrm/view-resources'
|
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
||||||
|
import { FilterButton, TableBrowser, ViewletSettingButton } from '@anticrm/view-resources'
|
||||||
import recruit from '../plugin'
|
import recruit from '../plugin'
|
||||||
import CreateApplication from './CreateApplication.svelte'
|
import CreateApplication from './CreateApplication.svelte'
|
||||||
|
|
||||||
@ -83,17 +83,7 @@
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button icon={IconAdd} label={recruit.string.ApplicationCreateLabel} kind={'primary'} on:click={showCreateDialog} />
|
<Button icon={IconAdd} label={recruit.string.ApplicationCreateLabel} kind={'primary'} on:click={showCreateDialog} />
|
||||||
{#if descr}
|
<ViewletSettingButton viewlet={descr} />
|
||||||
<Tooltip label={view.string.CustomizeView}>
|
|
||||||
<Button
|
|
||||||
icon={view.icon.Setting}
|
|
||||||
kind={'transparent'}
|
|
||||||
on:click={() => {
|
|
||||||
showPopup(ViewletSetting, { viewlet: descr })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if descr}
|
{#if descr}
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
import contact from '@anticrm/contact'
|
import contact from '@anticrm/contact'
|
||||||
import { Doc, DocumentQuery } from '@anticrm/core'
|
import { Doc, DocumentQuery } from '@anticrm/core'
|
||||||
import { createQuery, getClient } from '@anticrm/presentation'
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
import { Tooltip, showPopup, Icon, Label, Loading, SearchEdit, Button, IconAdd } from '@anticrm/ui'
|
import { Button, Icon, IconAdd, Label, Loading, SearchEdit, showPopup } from '@anticrm/ui'
|
||||||
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
|
||||||
import type { Filter } from '@anticrm/view'
|
import type { Filter } from '@anticrm/view'
|
||||||
import { ActionContext, TableBrowser, ViewletSetting, FilterButton } from '@anticrm/view-resources'
|
import view, { Viewlet, ViewletPreference } from '@anticrm/view'
|
||||||
|
import { ActionContext, FilterButton, TableBrowser, ViewletSettingButton } from '@anticrm/view-resources'
|
||||||
import recruit from '../plugin'
|
import recruit from '../plugin'
|
||||||
import CreateCandidate from './CreateCandidate.svelte'
|
import CreateCandidate from './CreateCandidate.svelte'
|
||||||
|
|
||||||
@ -83,17 +83,7 @@
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button icon={IconAdd} label={recruit.string.CandidateCreateLabel} kind={'primary'} on:click={showCreateDialog} />
|
<Button icon={IconAdd} label={recruit.string.CandidateCreateLabel} kind={'primary'} on:click={showCreateDialog} />
|
||||||
{#if descr}
|
<ViewletSettingButton viewlet={descr} />
|
||||||
<Tooltip label={view.string.CustomizeView}>
|
|
||||||
<Button
|
|
||||||
icon={view.icon.Setting}
|
|
||||||
kind={'transparent'}
|
|
||||||
on:click={() => {
|
|
||||||
showPopup(ViewletSetting, { viewlet: descr })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ActionContext
|
<ActionContext
|
||||||
|
@ -14,20 +14,14 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import core, { Doc, DocumentQuery, Ref } from '@anticrm/core'
|
import core, { Doc, DocumentQuery, Ref } from '@anticrm/core'
|
||||||
import { createQuery } from '@anticrm/presentation'
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
import { Vacancy } from '@anticrm/recruit'
|
import { Vacancy } from '@anticrm/recruit'
|
||||||
import { Button, getCurrentLocation, Icon, IconAdd, Label, navigate, SearchEdit, showPopup } from '@anticrm/ui'
|
import { Button, Icon, IconAdd, Label, Loading, SearchEdit, showPopup } from '@anticrm/ui'
|
||||||
import { TableBrowser } from '@anticrm/view-resources'
|
import view, { BuildModelKey, Filter, Viewlet, ViewletPreference } from '@anticrm/view'
|
||||||
|
import { FilterButton, TableBrowser, ViewletSettingButton } from '@anticrm/view-resources'
|
||||||
import recruit from '../plugin'
|
import recruit from '../plugin'
|
||||||
import CreateVacancy from './CreateVacancy.svelte'
|
import CreateVacancy from './CreateVacancy.svelte'
|
||||||
|
|
||||||
function action (vacancy: Ref<Vacancy>): void {
|
|
||||||
const loc = getCurrentLocation()
|
|
||||||
loc.path[2] = vacancy
|
|
||||||
loc.path.length = 3
|
|
||||||
navigate(loc)
|
|
||||||
}
|
|
||||||
|
|
||||||
let search: string = ''
|
let search: string = ''
|
||||||
let resultQuery: DocumentQuery<Doc> = {}
|
let resultQuery: DocumentQuery<Doc> = {}
|
||||||
|
|
||||||
@ -69,42 +63,21 @@
|
|||||||
const modifiedSorting = (a: Doc, b: Doc) =>
|
const modifiedSorting = (a: Doc, b: Doc) =>
|
||||||
(applications?.get(b._id as Ref<Vacancy>)?.modifiedOn ?? 0) -
|
(applications?.get(b._id as Ref<Vacancy>)?.modifiedOn ?? 0) -
|
||||||
(applications?.get(a._id as Ref<Vacancy>)?.modifiedOn ?? 0) ?? 0
|
(applications?.get(a._id as Ref<Vacancy>)?.modifiedOn ?? 0) ?? 0
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="ac-header full">
|
const replacedKeys: Map<string, BuildModelKey> = new Map<string, BuildModelKey>([
|
||||||
<div class="ac-header__wrap-title">
|
[
|
||||||
<div class="ac-header__icon"><Icon icon={recruit.icon.Vacancy} size={'small'} /></div>
|
'@applications',
|
||||||
<span class="ac-header__title"><Label label={recruit.string.Vacancies} /></span>
|
|
||||||
</div>
|
|
||||||
<SearchEdit
|
|
||||||
bind:value={search}
|
|
||||||
on:change={(e) => {
|
|
||||||
search = e.detail
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Button icon={IconAdd} label={recruit.string.VacancyCreateLabel} kind={'primary'} on:click={showCreateDialog} />
|
|
||||||
</div>
|
|
||||||
<TableBrowser
|
|
||||||
_class={recruit.class.Vacancy}
|
|
||||||
config={[
|
|
||||||
{
|
{
|
||||||
key: '',
|
key: '@applications',
|
||||||
presenter: recruit.component.VacancyItemPresenter,
|
|
||||||
label: recruit.string.Vacancy,
|
|
||||||
sortingKey: 'name',
|
|
||||||
props: { action }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '',
|
|
||||||
presenter: recruit.component.VacancyCountPresenter,
|
presenter: recruit.component.VacancyCountPresenter,
|
||||||
label: recruit.string.Applications,
|
label: recruit.string.Applications,
|
||||||
props: { applications },
|
props: { applications },
|
||||||
sortingKey: '@applications',
|
sortingKey: '@applications',
|
||||||
sortingFunction: applicationSorting
|
sortingFunction: applicationSorting
|
||||||
},
|
}
|
||||||
'$lookup.company',
|
],
|
||||||
'location',
|
[
|
||||||
'description',
|
'@applications.modifiedOn',
|
||||||
{
|
{
|
||||||
key: '',
|
key: '',
|
||||||
presenter: recruit.component.VacancyModifiedPresenter,
|
presenter: recruit.component.VacancyModifiedPresenter,
|
||||||
@ -113,10 +86,83 @@
|
|||||||
sortingKey: 'modifiedOn',
|
sortingKey: 'modifiedOn',
|
||||||
sortingFunction: modifiedSorting
|
sortingFunction: modifiedSorting
|
||||||
}
|
}
|
||||||
]}
|
]
|
||||||
|
])
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
let filters: Filter[] = []
|
||||||
|
|
||||||
|
let descr: Viewlet | undefined
|
||||||
|
let loading = true
|
||||||
|
|
||||||
|
const preferenceQuery = createQuery()
|
||||||
|
let preference: ViewletPreference | undefined
|
||||||
|
|
||||||
|
client
|
||||||
|
.findOne<Viewlet>(view.class.Viewlet, {
|
||||||
|
attachTo: recruit.class.Vacancy,
|
||||||
|
descriptor: view.viewlet.Table
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
descr = res
|
||||||
|
if (res !== undefined) {
|
||||||
|
preferenceQuery.query(
|
||||||
|
view.class.ViewletPreference,
|
||||||
|
{
|
||||||
|
attachedTo: res._id
|
||||||
|
},
|
||||||
|
(res) => {
|
||||||
|
preference = res[0]
|
||||||
|
loading = false
|
||||||
|
},
|
||||||
|
{ limit: 1 }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function createConfig (descr: Viewlet, preference: ViewletPreference | undefined): (string | BuildModelKey)[] {
|
||||||
|
const base = preference?.config ?? descr.config
|
||||||
|
const result: (string | BuildModelKey)[] = []
|
||||||
|
for (const key of base) {
|
||||||
|
if (typeof key === 'string') {
|
||||||
|
result.push(replacedKeys.get(key) ?? key)
|
||||||
|
} else {
|
||||||
|
result.push(replacedKeys.get(key.key) ?? key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="ac-header full">
|
||||||
|
<div class="ac-header__wrap-title">
|
||||||
|
<div class="ac-header__icon"><Icon icon={recruit.icon.Vacancy} size={'small'} /></div>
|
||||||
|
<span class="ac-header__title"><Label label={recruit.string.Vacancies} /></span>
|
||||||
|
<div class="ml-4"><FilterButton _class={recruit.mixin.Candidate} bind:filters /></div>
|
||||||
|
</div>
|
||||||
|
<SearchEdit
|
||||||
|
bind:value={search}
|
||||||
|
on:change={(e) => {
|
||||||
|
search = e.detail
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button icon={IconAdd} label={recruit.string.VacancyCreateLabel} kind={'primary'} on:click={showCreateDialog} />
|
||||||
|
<ViewletSettingButton viewlet={descr} />
|
||||||
|
</div>
|
||||||
|
{#if descr}
|
||||||
|
{#if loading}
|
||||||
|
<Loading />
|
||||||
|
{:else}
|
||||||
|
<TableBrowser
|
||||||
|
_class={recruit.class.Vacancy}
|
||||||
|
config={createConfig(descr, preference)}
|
||||||
|
options={descr.options}
|
||||||
query={{
|
query={{
|
||||||
...resultQuery,
|
...resultQuery,
|
||||||
archived: false
|
archived: false
|
||||||
}}
|
}}
|
||||||
|
bind:filters
|
||||||
showNotification
|
showNotification
|
||||||
/>
|
/>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
@ -15,23 +15,54 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Vacancy } from '@anticrm/recruit'
|
import type { Vacancy } from '@anticrm/recruit'
|
||||||
import { Icon } from '@anticrm/ui'
|
import {
|
||||||
import { getPanelURI } from '@anticrm/ui/src/panelup'
|
ActionIcon,
|
||||||
|
getCurrentLocation,
|
||||||
|
Icon,
|
||||||
|
IconEdit,
|
||||||
|
Location,
|
||||||
|
locationToUrl,
|
||||||
|
navigate,
|
||||||
|
showPanel
|
||||||
|
} from '@anticrm/ui'
|
||||||
import recruit from '../plugin'
|
import recruit from '../plugin'
|
||||||
|
|
||||||
export let value: Vacancy
|
export let value: Vacancy
|
||||||
export let inline: boolean = false
|
export let inline: boolean = false
|
||||||
|
|
||||||
|
function editVacancy (): void {
|
||||||
|
showPanel(recruit.component.EditVacancy, value._id, value._class, 'content')
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLoc (): Location {
|
||||||
|
const loc = getCurrentLocation()
|
||||||
|
loc.path[2] = value._id
|
||||||
|
loc.path.length = 3
|
||||||
|
return loc
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLink (): string {
|
||||||
|
const loc = getLoc()
|
||||||
|
return document.location.origin + locationToUrl(loc)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<a
|
<div class="flex-presenter" class:inline-presenter={inline}>
|
||||||
class="flex-presenter"
|
|
||||||
class:inline-presenter={inline}
|
|
||||||
href="#{getPanelURI(recruit.component.EditVacancy, value._id, value._class, 'content')}"
|
|
||||||
>
|
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={recruit.icon.Vacancy} size={'small'} />
|
<Icon icon={recruit.icon.Vacancy} size={'small'} />
|
||||||
</div>
|
</div>
|
||||||
|
<a
|
||||||
|
on:click|preventDefault={(e) => {
|
||||||
|
navigate(getLoc())
|
||||||
|
e.preventDefault()
|
||||||
|
}}
|
||||||
|
href={getLink()}
|
||||||
|
>
|
||||||
<span class="label">{value.name}</span>
|
<span class="label">{value.name}</span>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="action">
|
||||||
|
<ActionIcon label={recruit.string.Edit} size={'small'} icon={IconEdit} action={editVacancy} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
|
|
||||||
$: lookup = buildConfigLookup(hierarchy, _class, config)
|
$: lookup = options?.lookup ?? buildConfigLookup(hierarchy, _class, config)
|
||||||
|
|
||||||
let sortKey = 'modifiedOn'
|
let sortKey = 'modifiedOn'
|
||||||
let sortOrder = SortingOrder.Descending
|
let sortOrder = SortingOrder.Descending
|
||||||
|
@ -102,11 +102,11 @@
|
|||||||
|
|
||||||
const allAttributes = hierarchy.getAllAttributes(viewlet.attachTo)
|
const allAttributes = hierarchy.getAllAttributes(viewlet.attachTo)
|
||||||
for (const [, attribute] of allAttributes) {
|
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)
|
const value = getValue(attribute.name, attribute.type)
|
||||||
if (result.findIndex((p) => p.value === value) !== -1) continue
|
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 typeClassId = getAttributePresenterClass(attribute)
|
||||||
const typeClass = hierarchy.getClass(typeClassId)
|
const typeClass = hierarchy.getClass(typeClassId)
|
||||||
let presenter = hierarchy.as(typeClass, view.mixin.AttributePresenter).presenter
|
let presenter = hierarchy.as(typeClass, view.mixin.AttributePresenter).presenter
|
||||||
@ -123,7 +123,6 @@
|
|||||||
enabled: false
|
enabled: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return preference === undefined ? result : setStatus(result, preference)
|
return preference === undefined ? result : setStatus(result, preference)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
<!--
|
||||||
|
// 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 { Button, showPopup, Tooltip } from '@anticrm/ui'
|
||||||
|
import { Viewlet } from '@anticrm/view'
|
||||||
|
import ViewletSetting from './ViewletSetting.svelte'
|
||||||
|
import view from '../plugin'
|
||||||
|
|
||||||
|
export let viewlet: Viewlet | undefined
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if viewlet}
|
||||||
|
<Tooltip label={view.string.CustomizeView}>
|
||||||
|
<Button
|
||||||
|
icon={view.icon.Setting}
|
||||||
|
kind={'transparent'}
|
||||||
|
on:click={() => {
|
||||||
|
showPopup(ViewletSetting, { viewlet })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
@ -16,40 +16,40 @@
|
|||||||
import { Resources } from '@anticrm/platform'
|
import { Resources } from '@anticrm/platform'
|
||||||
import { getEventPopupPositionElement, PopupAlignment } from '@anticrm/ui'
|
import { getEventPopupPositionElement, PopupAlignment } from '@anticrm/ui'
|
||||||
import { actionImpl } from './actionImpl'
|
import { actionImpl } from './actionImpl'
|
||||||
|
import ActionsPopup from './components/ActionsPopup.svelte'
|
||||||
import BooleanEditor from './components/BooleanEditor.svelte'
|
import BooleanEditor from './components/BooleanEditor.svelte'
|
||||||
import BooleanPresenter from './components/BooleanPresenter.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 ColorsPopup from './components/ColorsPopup.svelte'
|
||||||
import DateEditor from './components/DateEditor.svelte'
|
import DateEditor from './components/DateEditor.svelte'
|
||||||
import DatePresenter from './components/DatePresenter.svelte'
|
import DatePresenter from './components/DatePresenter.svelte'
|
||||||
import SpacePresenter from './components/SpacePresenter.svelte'
|
import DocAttributeBar from './components/DocAttributeBar.svelte'
|
||||||
import StringEditor from './components/StringEditor.svelte'
|
import EditBoxPopup from './components/EditBoxPopup.svelte'
|
||||||
import StringPresenter from './components/StringPresenter.svelte'
|
|
||||||
import EditDoc from './components/EditDoc.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 HTMLPresenter from './components/HTMLPresenter.svelte'
|
||||||
import IntlStringPresenter from './components/IntlStringPresenter.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 Menu from './components/Menu.svelte'
|
||||||
import NumberEditor from './components/NumberEditor.svelte'
|
import NumberEditor from './components/NumberEditor.svelte'
|
||||||
import NumberPresenter from './components/NumberPresenter.svelte'
|
import NumberPresenter from './components/NumberPresenter.svelte'
|
||||||
import ObjectPresenter from './components/ObjectPresenter.svelte'
|
import ObjectPresenter from './components/ObjectPresenter.svelte'
|
||||||
import RolePresenter from './components/RolePresenter.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 Table from './components/Table.svelte'
|
||||||
|
import TableBrowser from './components/TableBrowser.svelte'
|
||||||
import TimestampPresenter from './components/TimestampPresenter.svelte'
|
import TimestampPresenter from './components/TimestampPresenter.svelte'
|
||||||
import UpDownNavigator from './components/UpDownNavigator.svelte'
|
import UpDownNavigator from './components/UpDownNavigator.svelte'
|
||||||
import GithubPresenter from './components/linkPresenters/GithubPresenter.svelte'
|
import ViewletSettingButton from './components/ViewletSettingButton.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'
|
|
||||||
|
|
||||||
function PositionElementAlignment (e?: Event): PopupAlignment | undefined {
|
function PositionElementAlignment (e?: Event): PopupAlignment | undefined {
|
||||||
return getEventPopupPositionElement(e)
|
return getEventPopupPositionElement(e)
|
||||||
@ -58,10 +58,10 @@ function PositionElementAlignment (e?: Event): PopupAlignment | undefined {
|
|||||||
export { getActions, invokeAction } from './actions'
|
export { getActions, invokeAction } from './actions'
|
||||||
export { default as ActionContext } from './components/ActionContext.svelte'
|
export { default as ActionContext } from './components/ActionContext.svelte'
|
||||||
export { default as ActionHandler } from './components/ActionHandler.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 ContextMenu } from './components/Menu.svelte'
|
||||||
export { default as TableBrowser } from './components/TableBrowser.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 './context'
|
||||||
export * from './selection'
|
export * from './selection'
|
||||||
export { buildModel, getCollectionCounter, getObjectPresenter, LoadingProps } from './utils'
|
export { buildModel, getCollectionCounter, getObjectPresenter, LoadingProps } from './utils'
|
||||||
@ -75,7 +75,7 @@ export {
|
|||||||
Menu,
|
Menu,
|
||||||
SpacePresenter,
|
SpacePresenter,
|
||||||
UpDownNavigator,
|
UpDownNavigator,
|
||||||
ViewletSetting,
|
ViewletSettingButton,
|
||||||
FilterBar,
|
FilterBar,
|
||||||
ClassAttributeBar
|
ClassAttributeBar
|
||||||
}
|
}
|
||||||
@ -88,7 +88,6 @@ export default async (): Promise<Resources> => ({
|
|||||||
ValueFilter,
|
ValueFilter,
|
||||||
TimestampFilter,
|
TimestampFilter,
|
||||||
TableBrowser,
|
TableBrowser,
|
||||||
ViewletSetting,
|
|
||||||
SpacePresenter,
|
SpacePresenter,
|
||||||
StringEditor,
|
StringEditor,
|
||||||
StringPresenter,
|
StringPresenter,
|
||||||
|
@ -48,16 +48,20 @@ export interface LoadingProps {
|
|||||||
export async function getObjectPresenter (
|
export async function getObjectPresenter (
|
||||||
client: Client,
|
client: Client,
|
||||||
_class: Ref<Class<Obj>>,
|
_class: Ref<Class<Obj>>,
|
||||||
preserveKey: BuildModelKey
|
preserveKey: BuildModelKey,
|
||||||
|
isCollectionAttr: boolean = false
|
||||||
): Promise<AttributeModel> {
|
): Promise<AttributeModel> {
|
||||||
const clazz = client.getHierarchy().getClass(_class)
|
const hierarchy = client.getHierarchy()
|
||||||
const presenterMixin = client.getHierarchy().as(clazz, view.mixin.AttributePresenter)
|
const mixin = isCollectionAttr ? view.mixin.CollectionPresenter : view.mixin.AttributePresenter
|
||||||
if (presenterMixin.presenter === undefined) {
|
const clazz = hierarchy.getClass(_class)
|
||||||
if (clazz.extends !== undefined) {
|
let mixinClazz = hierarchy.getClass(_class)
|
||||||
return await getObjectPresenter(client, clazz.extends, preserveKey)
|
let presenterMixin = hierarchy.as(clazz, mixin)
|
||||||
} else {
|
while (presenterMixin.presenter === undefined && mixinClazz.extends !== undefined) {
|
||||||
throw new Error('object presenter not found for ' + JSON.stringify(preserveKey))
|
presenterMixin = hierarchy.as(mixinClazz, mixin)
|
||||||
|
mixinClazz = hierarchy.getClass(mixinClazz.extends)
|
||||||
}
|
}
|
||||||
|
if (presenterMixin.presenter === undefined) {
|
||||||
|
throw new Error('object presenter not found for ' + JSON.stringify(preserveKey))
|
||||||
}
|
}
|
||||||
const presenter = await getResource(presenterMixin.presenter)
|
const presenter = await getResource(presenterMixin.presenter)
|
||||||
const key = preserveKey.sortingKey ?? preserveKey.key
|
const key = preserveKey.sortingKey ?? preserveKey.key
|
||||||
@ -132,7 +136,8 @@ export async function getPresenter<T extends Doc> (
|
|||||||
_class: Ref<Class<T>>,
|
_class: Ref<Class<T>>,
|
||||||
key: BuildModelKey,
|
key: BuildModelKey,
|
||||||
preserveKey: BuildModelKey,
|
preserveKey: BuildModelKey,
|
||||||
lookup?: Lookup<T>
|
lookup?: Lookup<T>,
|
||||||
|
isCollectionAttr: boolean = false
|
||||||
): Promise<AttributeModel> {
|
): Promise<AttributeModel> {
|
||||||
if (key.presenter !== undefined) {
|
if (key.presenter !== undefined) {
|
||||||
const { presenter, label, sortingKey } = key
|
const { presenter, label, sortingKey } = key
|
||||||
@ -146,7 +151,7 @@ export async function getPresenter<T extends Doc> (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (key.key.length === 0) {
|
if (key.key.length === 0) {
|
||||||
return await getObjectPresenter(client, _class, preserveKey)
|
return await getObjectPresenter(client, _class, preserveKey, isCollectionAttr)
|
||||||
} else {
|
} else {
|
||||||
if (key.key.startsWith('$lookup')) {
|
if (key.key.startsWith('$lookup')) {
|
||||||
if (lookup === undefined) {
|
if (lookup === undefined) {
|
||||||
@ -262,7 +267,7 @@ async function getLookupPresenter<T extends Doc> (
|
|||||||
const lookupClass = getLookupClass(key.key, lookup, _class)
|
const lookupClass = getLookupClass(key.key, lookup, _class)
|
||||||
const lookupProperty = getLookupProperty(key.key)
|
const lookupProperty = getLookupProperty(key.key)
|
||||||
const lookupKey = { ...key, key: lookupProperty[0] }
|
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])
|
model.label = getLookupLabel(client, lookupClass[1], lookupClass[0], lookupKey, lookupProperty[1])
|
||||||
return model
|
return model
|
||||||
}
|
}
|
||||||
@ -292,7 +297,7 @@ export function getLookupClass<T extends Doc> (
|
|||||||
key: string,
|
key: string,
|
||||||
lookup: Lookup<T>,
|
lookup: Lookup<T>,
|
||||||
parent: Ref<Class<T>>
|
parent: Ref<Class<T>>
|
||||||
): [Ref<Class<Doc>>, Ref<Class<Doc>>] {
|
): [Ref<Class<Doc>>, Ref<Class<Doc>>, boolean] {
|
||||||
const _class = getLookup(key, lookup, parent)
|
const _class = getLookup(key, lookup, parent)
|
||||||
if (_class === undefined) {
|
if (_class === undefined) {
|
||||||
throw new Error('lookup class does not provided for ' + key)
|
throw new Error('lookup class does not provided for ' + key)
|
||||||
@ -313,7 +318,7 @@ function getLookup (
|
|||||||
key: string,
|
key: string,
|
||||||
lookup: Lookup<any>,
|
lookup: Lookup<any>,
|
||||||
parent: Ref<Class<Doc>>
|
parent: Ref<Class<Doc>>
|
||||||
): [Ref<Class<Doc>>, Ref<Class<Doc>>] | undefined {
|
): [Ref<Class<Doc>>, Ref<Class<Doc>>, boolean] | undefined {
|
||||||
const parts = key.split('$lookup.').filter((p) => p.length > 0)
|
const parts = key.split('$lookup.').filter((p) => p.length > 0)
|
||||||
const currentKey = parts[0].split('.').filter((p) => p.length > 0)[0]
|
const currentKey = parts[0].split('.').filter((p) => p.length > 0)[0]
|
||||||
const current = (lookup as any)[currentKey]
|
const current = (lookup as any)[currentKey]
|
||||||
@ -325,13 +330,17 @@ function getLookup (
|
|||||||
return getLookup(nestedKey, current[1], current[0])
|
return getLookup(nestedKey, current[1], current[0])
|
||||||
}
|
}
|
||||||
if (Array.isArray(current)) {
|
if (Array.isArray(current)) {
|
||||||
return [current[0], parent]
|
return [current[0], parent, false]
|
||||||
}
|
}
|
||||||
if (current === undefined && lookup._id !== undefined) {
|
if (current === undefined && lookup._id !== undefined) {
|
||||||
const reverse = (lookup._id as any)[currentKey]
|
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 {
|
export function getBooleanLabel (value: boolean | undefined): IntlString {
|
||||||
|
@ -391,7 +391,6 @@ const view = plugin(viewId, {
|
|||||||
component: {
|
component: {
|
||||||
ObjectPresenter: '' as AnyComponent,
|
ObjectPresenter: '' as AnyComponent,
|
||||||
EditDoc: '' as AnyComponent,
|
EditDoc: '' as AnyComponent,
|
||||||
ViewletSetting: '' as AnyComponent,
|
|
||||||
SpacePresenter: '' as AnyComponent,
|
SpacePresenter: '' as AnyComponent,
|
||||||
BooleanTruePresenter: '' as AnyComponent
|
BooleanTruePresenter: '' as AnyComponent
|
||||||
},
|
},
|
||||||
|
@ -17,14 +17,14 @@
|
|||||||
import core, { WithLookup } from '@anticrm/core'
|
import core, { WithLookup } from '@anticrm/core'
|
||||||
import { IntlString } from '@anticrm/platform'
|
import { IntlString } from '@anticrm/platform'
|
||||||
import presentation, { createQuery, getClient } from '@anticrm/presentation'
|
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 view, { Viewlet } from '@anticrm/view'
|
||||||
import { ViewletSetting } from '@anticrm/view-resources'
|
import { ViewletSettingButton } from '@anticrm/view-resources'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import plugin from '../plugin'
|
import plugin from '../plugin'
|
||||||
import { classIcon } from '../utils'
|
import { classIcon } from '../utils'
|
||||||
import Header from './Header.svelte'
|
import Header from './Header.svelte'
|
||||||
import type { Filter } from '@anticrm/view'
|
|
||||||
|
|
||||||
export let spaceId: Ref<Space> | undefined
|
export let spaceId: Ref<Space> | undefined
|
||||||
export let createItemDialog: AnyComponent | undefined
|
export let createItemDialog: AnyComponent | undefined
|
||||||
@ -115,16 +115,6 @@
|
|||||||
{#if createItemDialog}
|
{#if createItemDialog}
|
||||||
<Button icon={IconAdd} label={createItemLabel} kind={'primary'} on:click={(ev) => showCreateDialog(ev)} />
|
<Button icon={IconAdd} label={createItemLabel} kind={'primary'} on:click={(ev) => showCreateDialog(ev)} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if viewlet}
|
<ViewletSettingButton {viewlet} />
|
||||||
<Tooltip label={view.string.CustomizeView}>
|
|
||||||
<Button
|
|
||||||
icon={view.icon.Setting}
|
|
||||||
kind={'transparent'}
|
|
||||||
on:click={() => {
|
|
||||||
showPopup(ViewletSetting, { viewlet })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user