Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2023-08-07 20:17:31 +06:00 committed by GitHub
parent 85d040010c
commit 07cc690d23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 346 additions and 306 deletions

View File

@ -16,10 +16,9 @@
import { Event } from '@hcengineering/calendar'
import { Class, DocumentQuery, Ref, Space, WithLookup } from '@hcengineering/core'
import { Asset, IntlString } from '@hcengineering/platform'
import { createQuery } from '@hcengineering/presentation'
import { AnyComponent, Button, Component, Label, Loading, showPopup, TabList, IconAdd } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
import { getViewOptions, setActiveViewletId, viewOptionStore } from '@hcengineering/view-resources'
import { AnyComponent, Button, Component, IconAdd, Label, Loading, showPopup } from '@hcengineering/ui'
import { Viewlet, ViewletPreference } from '@hcengineering/view'
import { ViewletSelector, getViewOptions, viewOptionStore } from '@hcengineering/view-resources'
import calendar from '../plugin'
// import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
@ -33,23 +32,10 @@
export let createComponent: AnyComponent | undefined = calendar.component.CreateEvent
export let createLabel: IntlString | undefined = calendar.string.CreateEvent
const viewletQuery = createQuery()
const search = ''
let resultQuery: DocumentQuery<Event> = {}
let viewlets: WithLookup<Viewlet>[] = []
viewletQuery.query(
view.class.Viewlet,
{ attachTo: _class },
(res) => {
viewlets = res
if (viewlet === undefined || res.findIndex((p) => p._id === viewlet?._id) === -1) {
viewlet = res[0]
setActiveViewletId(viewlet._id)
}
},
{ lookup: { descriptor: view.class.ViewletDescriptor } }
)
function updateResultQuery (search: string): void {
resultQuery = search === '' ? { ...query } : { ...query, $search: search }
@ -66,30 +52,9 @@
let viewlet: WithLookup<Viewlet> | undefined
const preferenceQuery = createQuery()
let preference: ViewletPreference | undefined
let loading = true
$: viewlet &&
preferenceQuery.query(
view.class.ViewletPreference,
{
attachedTo: viewlet._id
},
(res) => {
preference = res[0]
loading = false
},
{ limit: 1 }
)
$: viewslist = viewlets.map((views) => {
return {
id: views._id,
icon: views.$lookup?.descriptor?.icon,
tooltip: views.$lookup?.descriptor?.label
}
})
$: viewOptions = getViewOptions(viewlet, $viewOptionStore)
</script>
@ -99,16 +64,7 @@
</div>
<div class="ac-header-full medium-gap mb-1">
{#if viewlets.length > 1}
<TabList
items={viewslist}
multiselect={false}
selected={viewlet?._id}
on:select={(result) => {
if (result.detail !== undefined) viewlet = viewlets.find((vl) => vl._id === result.detail.id)
}}
/>
{/if}
<ViewletSelector bind:viewlet bind:loading bind:preference bind:viewlets viewletQuery={{ attachTo: _class }} />
<Button icon={IconAdd} label={createLabel} kind={'accented'} on:click={showCreateDialog} />
</div>
</div>

View File

@ -18,7 +18,13 @@
import { ActionContext } from '@hcengineering/presentation'
import { Button, Label, Loading, SearchEdit, showPopup } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference, ViewOptions } from '@hcengineering/view'
import { FilterBar, FilterButton, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources'
import {
FilterBar,
FilterButton,
TableBrowser,
ViewletSelector,
ViewletSettingButton
} from '@hcengineering/view-resources'
import contact from '../plugin'
import CreateContact from './CreateContact.svelte'
// import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
@ -68,16 +74,17 @@
<FilterButton _class={contact.class.Contact} />
</div>
<div class="ac-header-full medium-gap">
<ViewletSettingButton
bind:viewOptions
<ViewletSelector
hidden
bind:viewlet
bind:preference
bind:loading
viewletQuery={{
attachTo: contact.class.Contact,
descriptor: view.viewlet.Table
}}
bind:viewlet
bind:preference
bind:loading
/>
<ViewletSettingButton bind:viewOptions bind:viewlet />
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
</div>
</div>

View File

@ -18,7 +18,7 @@
import { createQuery, getClient } from '@hcengineering/presentation'
import { Button, Icon, IconAdd, Label, showPopup } from '@hcengineering/ui'
import { Viewlet, ViewletPreference } from '@hcengineering/view'
import { Table, ViewletSettingButton } from '@hcengineering/view-resources'
import { Table, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
import contact from '../plugin'
import UsersPopup from './UsersPopup.svelte'
import IconMembersOutline from './icons/MembersOutline.svelte'
@ -75,13 +75,14 @@
<Label label={contact.string.Members} />
</span>
<div class="buttons-group xsmall-gap">
<ViewletSettingButton
viewletQuery={{ _id: contact.viewlet.TableMember }}
kind={'ghost'}
<ViewletSelector
hidden
bind:viewlet
bind:preference
bind:loading
viewletQuery={{ _id: contact.viewlet.TableMember }}
/>
<ViewletSettingButton kind={'ghost'} bind:viewlet />
<Button id={contact.string.AddMember} icon={IconAdd} kind={'ghost'} on:click={createApp} />
</div>
</div>

View File

@ -20,7 +20,7 @@
import { ActionContext } from '@hcengineering/presentation'
import { Label, Loading, SearchEdit } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
import { FilterButton, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources'
import { FilterButton, TableBrowser, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
import document from '../plugin'
export let query: DocumentQuery<Document> = {}
@ -57,15 +57,17 @@
<FilterButton _class={document.class.Document} />
</div>
<div class="ac-header-full medium-gap">
<ViewletSettingButton
<ViewletSelector
hidden
bind:viewlet
bind:preference
bind:loading
viewletQuery={{
attachTo: document.class.Document,
descriptor: view.viewlet.Table
}}
bind:viewlet
bind:preference
bind:loading
/>
<ViewletSettingButton bind:viewlet />
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
</div>
</div>

View File

@ -20,7 +20,7 @@
import { createQuery, getClient } from '@hcengineering/presentation'
import { Button, IconAdd, Label, Scroller, eventToHTMLElement, showPopup } from '@hcengineering/ui'
import { Viewlet, ViewletPreference } from '@hcengineering/view'
import { Table, ViewletSettingButton } from '@hcengineering/view-resources'
import { Table, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
import hr from '../plugin'
import { addMember } from '../utils'
@ -73,13 +73,14 @@
<Label label={hr.string.Members} />
</span>
<div class="flex-row-center gap-2 reverse">
<ViewletSettingButton
viewletQuery={{ _id: hr.viewlet.TableMember }}
kind={'ghost'}
<ViewletSelector
hidden
bind:viewlet
bind:preference
bind:loading
viewletQuery={{ _id: hr.viewlet.TableMember }}
/>
<ViewletSettingButton kind={'ghost'} bind:viewlet />
<Button id={hr.string.AddEmployee} icon={IconAdd} kind={'ghost'} on:click={add} />
</div>
</div>

View File

@ -20,7 +20,7 @@
import { getEmbeddedLabel } from '@hcengineering/platform'
import { Button, Label, Loading, showPopup, tableToCSV } from '@hcengineering/ui'
import { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view'
import { TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources'
import { TableBrowser, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
import hr from '../../plugin'
import {
EmployeeReports,
@ -367,7 +367,14 @@
<div class="clear-mins" />
<div class="ac-header-full small-gap">
<Button label={getEmbeddedLabel('Export')} on:click={(evt) => exportTable(evt)} />
<ViewletSettingButton viewletQuery={{ _id: hr.viewlet.StaffStats }} bind:viewlet bind:preference bind:loading />
<ViewletSelector
hidden
bind:viewlet
bind:preference
bind:loading
viewletQuery={{ _id: hr.viewlet.StaffStats }}
/>
<ViewletSettingButton bind:viewlet />
</div>
</div>
{#if viewlet}

View File

@ -21,7 +21,13 @@
import task from '@hcengineering/task'
import { IModeSelector, Label, Loading, ModeSelector, resolvedLocationStore, SearchEdit } from '@hcengineering/ui'
import { Viewlet, ViewletPreference, ViewOptions } from '@hcengineering/view'
import { FilterBar, FilterButton, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources'
import {
FilterBar,
FilterButton,
TableBrowser,
ViewletSelector,
ViewletSettingButton
} from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import lead from '../plugin'
@ -102,16 +108,17 @@
<div class="buttons-divider" />
<FilterButton {_class} />
</div>
<ViewletSettingButton
bind:viewOptions
<ViewletSelector
hidden
bind:viewlet
bind:preference
bind:loading
viewletQuery={{
attachTo: _class,
descriptor: task.viewlet.StatusTable
}}
bind:viewlet
bind:preference
bind:loading
/>
<ViewletSettingButton bind:viewOptions bind:viewlet />
</div>
<FilterBar {_class} query={searchQuery} {viewOptions} on:change={(e) => (resultQuery = e.detail)} />

View File

@ -16,7 +16,7 @@
import type { Doc, Ref } from '@hcengineering/core'
import { Button, Icon, IconAdd, Label, Scroller, showPopup } from '@hcengineering/ui'
import { Viewlet, ViewletPreference } from '@hcengineering/view'
import { Table, ViewletSettingButton } from '@hcengineering/view-resources'
import { Table, ViewletsSettingButton } from '@hcengineering/view-resources'
import recruit from '../plugin'
import CreateApplication from './CreateApplication.svelte'
import IconApplication from './icons/Application.svelte'
@ -44,7 +44,7 @@
<Label label={recruit.string.Applications} />
</span>
<div class="flex-row-center gap-2 reverse">
<ViewletSettingButton
<ViewletsSettingButton
viewletQuery={{ _id: recruit.viewlet.VacancyApplicationsEmbeddeed }}
kind={'ghost'}
bind:viewlet

View File

@ -19,7 +19,13 @@
import { Applicant, Vacancy } from '@hcengineering/recruit'
import { Button, IconAdd, Label, Loading, SearchEdit, showPopup } from '@hcengineering/ui'
import view, { BuildModelKey, Viewlet, ViewletPreference, ViewOptions } from '@hcengineering/view'
import { FilterBar, FilterButton, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources'
import {
FilterBar,
FilterButton,
TableBrowser,
ViewletSelector,
ViewletSettingButton
} from '@hcengineering/view-resources'
import recruit from '../plugin'
import CreateOrganization from './CreateOrganization.svelte'
import VacancyListApplicationsPopup from './organizations/VacancyListApplicationsPopup.svelte'
@ -205,16 +211,17 @@
<FilterButton _class={recruit.mixin.VacancyList} />
</div>
<div class="ac-header-full medium-gap">
<ViewletSettingButton
bind:viewOptions
<ViewletSelector
hidden
viewletQuery={{
attachTo: recruit.mixin.VacancyList,
descriptor: view.viewlet.Table
}}
bind:viewlet
bind:preference
bind:loading
bind:viewlet
/>
<ViewletSettingButton bind:viewOptions bind:viewlet />
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
</div>
</div>

View File

@ -18,7 +18,13 @@
import { Vacancy } from '@hcengineering/recruit'
import { Button, IconAdd, Label, Loading, SearchEdit, showPopup, tableToCSV } from '@hcengineering/ui'
import view, { BuildModelKey, ViewOptions, Viewlet, ViewletPreference } from '@hcengineering/view'
import { FilterBar, FilterButton, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources'
import {
FilterBar,
FilterButton,
TableBrowser,
ViewletSelector,
ViewletSettingButton
} from '@hcengineering/view-resources'
import recruit from '../plugin'
import CreateVacancy from './CreateVacancy.svelte'
@ -149,16 +155,17 @@
<FilterButton _class={recruit.class.Vacancy} />
</div>
<div class="ac-header-full medium-gap">
<ViewletSettingButton
bind:viewOptions
<ViewletSelector
hidden
viewletQuery={{
attachTo: recruit.class.Vacancy,
descriptor: view.viewlet.Table
}}
bind:viewlet
bind:preference
bind:loading
bind:viewlet
/>
<ViewletSettingButton bind:viewOptions bind:viewlet />
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
</div>
</div>

View File

@ -18,7 +18,7 @@
import { recruitId, Vacancy } from '@hcengineering/recruit'
import { Button, Icon, IconAdd, Label, Loading, resizeObserver, Scroller, showPopup } from '@hcengineering/ui'
import { Viewlet, ViewletPreference } from '@hcengineering/view'
import { NavLink, Table, ViewletSettingButton } from '@hcengineering/view-resources'
import { NavLink, Table, ViewletsSettingButton } from '@hcengineering/view-resources'
import recruit from '../plugin'
import CreateApplication from './CreateApplication.svelte'
import IconApplication from './icons/Application.svelte'
@ -53,7 +53,7 @@
</NavLink>
</span>
<div class="flex-row-center gap-2 reverse">
<ViewletSettingButton
<ViewletsSettingButton
viewletQuery={{ _id: recruit.viewlet.VacancyApplicationsShort }}
kind={'ghost'}
bind:viewlet

View File

@ -29,7 +29,13 @@
SearchEdit
} from '@hcengineering/ui'
import { Viewlet, ViewletPreference, ViewOptions } from '@hcengineering/view'
import { FilterBar, FilterButton, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources'
import {
FilterBar,
FilterButton,
TableBrowser,
ViewletSelector,
ViewletSettingButton
} from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import task from '../plugin'
@ -152,13 +158,14 @@
<div class="buttons-divider" />
<FilterButton {_class} />
</div>
<ViewletSettingButton
bind:viewOptions
viewletQuery={{ attachTo: _class, descriptor: task.viewlet.StatusTable }}
<ViewletSelector
hidden
bind:viewlet
bind:preference
bind:loading
viewletQuery={{ attachTo: _class, descriptor: task.viewlet.StatusTable }}
/>
<ViewletSettingButton bind:viewOptions bind:viewlet />
</div>
<FilterBar {_class} query={searchQuery} {viewOptions} on:change={(e) => (resultQuery = e.detail)} />

View File

@ -16,14 +16,14 @@
import { DocumentQuery, WithLookup } from '@hcengineering/core'
import { IntlString } from '@hcengineering/platform'
import { Component } from '@hcengineering/tracker'
import { Button, IconAdd, Label, SearchEdit, TabList, resolvedLocationStore, showPopup } from '@hcengineering/ui'
import { Button, IconAdd, Label, SearchEdit, resolvedLocationStore, showPopup } from '@hcengineering/ui'
import { ViewOptions, Viewlet } from '@hcengineering/view'
import {
FilterBar,
FilterButton,
ViewletSelector,
ViewletSettingButton,
makeViewletKey,
updateActiveViewlet
makeViewletKey
} from '@hcengineering/view-resources'
import { onDestroy } from 'svelte'
import tracker from '../../plugin'
@ -86,15 +86,7 @@
</div>
<div class="ac-header-full medium-gap mb-1">
{#if viewlets && viewlets.length > 1}
<TabList
items={views}
selected={viewlet?._id}
kind="normal"
on:select={({ detail }) =>
(viewlet = viewlets && detail?.id ? updateActiveViewlet(viewlets, detail.id) : viewlet)}
/>
{/if}
<ViewletSelector bind:viewlet bind:viewlets viewletQuery={{ attachTo: tracker.class.Component }} />
<Button icon={IconAdd} label={tracker.string.Component} kind="accented" on:click={showCreateDialog} />
</div>
</div>
@ -106,12 +98,7 @@
<FilterButton _class={tracker.class.Component} {space} />
</div>
<div class="ac-header-full medium-gap">
<ViewletSettingButton
bind:viewOptions
viewletQuery={{ attachTo: tracker.class.Component }}
bind:viewlet
bind:viewlets
/>
<ViewletSettingButton bind:viewOptions bind:viewlet />
<!-- <ActionIcon icon={IconMoreH} size="small" /> -->
</div>
</div>

View File

@ -16,7 +16,7 @@
export let modeSelectorProps: IModeSelector | undefined = undefined
let viewlet: WithLookup<Viewlet> | undefined = undefined
let viewlets: WithLookup<Viewlet>[] | undefined = undefined
const viewlets: WithLookup<Viewlet>[] | undefined = undefined
let viewOptions: ViewOptions | undefined
let search = ''
@ -51,6 +51,7 @@
bind:viewlet
bind:search
showLabelSelector={$$slots.label_selector}
viewletQuery={{ attachTo: tracker.class.Issue, variant: { $ne: 'subissue' } }}
{viewlets}
{label}
{space}
@ -60,12 +61,7 @@
<slot name="label_selector" />
</svelte:fragment>
<svelte:fragment slot="extra">
<ViewletSettingButton
bind:viewOptions
viewletQuery={{ attachTo: tracker.class.Issue, variant: { $ne: 'subissue' } }}
bind:viewlet
bind:viewlets
/>
<ViewletSettingButton bind:viewOptions bind:viewlet />
{#if asideFloat && $$slots.aside}
<div class="buttons-divider" />
<Button

View File

@ -29,7 +29,7 @@
showPopup
} from '@hcengineering/ui'
import view, { ViewOptions, Viewlet, ViewletPreference } from '@hcengineering/view'
import { ViewletSettingButton, createFilter, setFilters } from '@hcengineering/view-resources'
import { ViewletsSettingButton, createFilter, setFilters } from '@hcengineering/view-resources'
import { afterUpdate } from 'svelte'
import tracker from '../../../plugin'
import CreateIssue from '../../CreateIssue.svelte'
@ -147,7 +147,7 @@
{/if}
<div class="flex-row-center gap-2">
{#if hasSubIssues}
<ViewletSettingButton
<ViewletsSettingButton
bind:viewOptions
viewletQuery={{ _id: tracker.viewlet.SubIssues }}
kind={'ghost'}

View File

@ -5,7 +5,7 @@
import { Issue, trackerId } from '@hcengineering/tracker'
import { Button, Component, Icon, IconAdd, Label, showPopup } from '@hcengineering/ui'
import { ViewOptions, Viewlet } from '@hcengineering/view'
import { ViewletSettingButton, getAdditionalHeader } from '@hcengineering/view-resources'
import { ViewletsSettingButton, getAdditionalHeader } from '@hcengineering/view-resources'
import viewplg from '@hcengineering/view-resources/src/plugin'
import { fade } from 'svelte/transition'
import tracker from '../../../plugin'
@ -56,7 +56,7 @@
<span class="flex-grow" />
{/if}
<div class="flex-row-center gap-2">
<ViewletSettingButton
<ViewletsSettingButton
bind:viewOptions
viewletQuery={{ _id: tracker.viewlet.SubIssues }}
kind={'ghost'}

View File

@ -18,7 +18,7 @@
import { Milestone } from '@hcengineering/tracker'
import { Button, IconAdd, Label, SearchEdit, TabItem, TabList, showPopup } from '@hcengineering/ui'
import { ViewOptions, Viewlet } from '@hcengineering/view'
import { FilterBar, FilterButton, ViewletSettingButton } from '@hcengineering/view-resources'
import { FilterBar, FilterButton, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
import tracker from '../../plugin'
import { MilestoneViewMode, getIncludedMilestoneStatuses, milestoneTitleMap } from '../../utils'
import MilestoneContent from './MilestoneContent.svelte'
@ -99,7 +99,8 @@
<FilterButton _class={tracker.class.Milestone} {space} />
</div>
<div class="ac-header-full medium-gap">
<ViewletSettingButton bind:viewOptions viewletQuery={{ attachTo: tracker.class.Milestone }} bind:viewlet />
<ViewletSelector viewletQuery={{ attachTo: tracker.class.Milestone }} bind:viewlet />
<ViewletSettingButton bind:viewOptions bind:viewlet />
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
</div>
</div>

View File

@ -80,12 +80,7 @@
/>
<div class="buttons-divider" />
{/if}
<ViewletSettingButton
bind:viewOptions
viewletQuery={{ attachTo: tracker.class.IssueTemplate }}
bind:viewlet
bind:viewlets
/>
<ViewletSettingButton bind:viewOptions bind:viewlet />
</svelte:fragment>
</SpaceHeader>
<slot name="afterHeader" />

View File

@ -1,27 +1,19 @@
<script lang="ts">
import { Class, Doc, Ref, Space } from '@hcengineering/core'
import { TabList, SearchEdit, IModeSelector, ModeSelector } from '@hcengineering/ui'
import { Class, Doc, DocumentQuery, Ref, Space, WithLookup } from '@hcengineering/core'
import { IModeSelector, ModeSelector, SearchEdit } from '@hcengineering/ui'
import { Viewlet } from '@hcengineering/view'
import { WithLookup } from '@hcengineering/core'
import { setActiveViewletId } from '../utils'
import ViewletSelector from './ViewletSelector.svelte'
import FilterButton from './filter/FilterButton.svelte'
export let space: Ref<Space> | undefined = undefined
export let _class: Ref<Class<Doc>>
export let viewlet: WithLookup<Viewlet> | undefined
export let viewletQuery: DocumentQuery<Viewlet> | undefined = undefined
export let viewlets: WithLookup<Viewlet>[] = []
export let label: string
export let search: string
export let showLabelSelector = false
export let modeSelectorProps: IModeSelector | undefined = undefined
$: viewslist = viewlets.map((views) => {
return {
id: views._id,
icon: views.$lookup?.descriptor?.icon,
tooltip: views.$lookup?.descriptor?.label
}
})
</script>
<div
@ -42,24 +34,7 @@
{/if}
</div>
<div class="mb-1 clear-mins">
{#if viewlets.length > 1}
<TabList
items={viewslist}
multiselect={false}
selected={viewlet?._id}
onlyIcons
on:select={(result) => {
if (result.detail !== undefined) {
if (viewlet?._id === result.detail.id) return
viewlet = viewlets.find((vl) => vl._id === result.detail.id)
if (viewlet) {
setActiveViewletId(viewlet._id)
}
}
}}
/>
{/if}
<ViewletSelector bind:viewlet bind:viewlets viewletQuery={viewletQuery ?? { attachTo: _class }} />
<slot name="header-tools" />
</div>
</div>

View File

@ -0,0 +1,104 @@
<script lang="ts">
import { createEventDispatcher, onDestroy } from 'svelte'
import { activeViewlet, makeViewletKey, setActiveViewletId } from '../utils'
import { TabList, resolvedLocationStore } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
import { DocumentQuery, Ref, WithLookup } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
export let viewlet: WithLookup<Viewlet> | undefined
export let viewlets: WithLookup<Viewlet>[] = []
export let viewletQuery: DocumentQuery<Viewlet>
export let preference: ViewletPreference | undefined = undefined
export let loading = true
export let hidden = false
const query = createQuery()
$: query.query(
view.class.Viewlet,
viewletQuery,
(res) => {
viewlets = res
dispatch('viewlets', viewlets)
},
{
lookup: {
descriptor: view.class.ViewletDescriptor
}
}
)
let key = makeViewletKey()
onDestroy(
resolvedLocationStore.subscribe((loc) => {
key = makeViewletKey(loc)
})
)
$: getActiveViewlet(viewlets, $activeViewlet, key)
const dispatch = createEventDispatcher()
function getActiveViewlet (
viewlets: WithLookup<Viewlet>[],
activeViewlet: Record<string, Ref<Viewlet> | null>,
key: string
) {
if (viewlets.length === 0) return
const newViewlet = viewlets.find((viewlet) => viewlet?._id === activeViewlet[key]) ?? viewlets[0]
if (viewlet?._id !== newViewlet?._id) {
viewlet = newViewlet
setActiveViewletId(newViewlet._id)
dispatch('viewlet', viewlet)
}
}
$: viewslist = viewlets.map((views) => {
return {
id: views._id,
icon: views.$lookup?.descriptor?.icon,
tooltip: views.$lookup?.descriptor?.label
}
})
const preferenceQuery = createQuery()
$: if (viewlet != null) {
preferenceQuery.query(
view.class.ViewletPreference,
{
attachedTo: viewlet._id
},
(res) => {
preference = res[0]
loading = false
dispatch('loading', loading)
dispatch('preference', preference)
},
{ limit: 1 }
)
} else {
preferenceQuery.unsubscribe()
}
</script>
{#if viewlets.length > 1 && !hidden}
<TabList
items={viewslist}
multiselect={false}
selected={viewlet?._id}
on:select={(result) => {
if (result.detail !== undefined) {
if (viewlet?._id === result.detail.id) {
return
}
viewlet = viewlets.find((vl) => vl._id === result.detail.id)
if (viewlet) {
setActiveViewletId(viewlet._id)
}
}
}}
/>
{/if}

View File

@ -13,28 +13,16 @@
// limitations under the License.
-->
<script lang="ts">
import { DocumentQuery, Ref, WithLookup } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import { Button, ButtonKind, resolvedLocationStore, showPopup } from '@hcengineering/ui'
import { ViewOptions, Viewlet, ViewletPreference } from '@hcengineering/view'
import { createEventDispatcher, onDestroy } from 'svelte'
import { Button, ButtonKind, showPopup } from '@hcengineering/ui'
import { ViewOptions, Viewlet } from '@hcengineering/view'
import view from '../plugin'
import { activeViewlet, makeViewletKey, setActiveViewletId } from '../utils'
import { getViewOptions, viewOptionStore } from '../viewOptions'
import ViewOptionsButton from './ViewOptionsButton.svelte'
import ViewletSetting from './ViewletSetting.svelte'
export let viewletQuery: DocumentQuery<Viewlet> = {}
export let kind: ButtonKind = 'regular'
export let viewOptions: ViewOptions | undefined = undefined
export let loading = true
export let viewlet: Viewlet | undefined = undefined
export let viewlets: WithLookup<Viewlet>[] = []
export let preference: ViewletPreference | undefined = undefined
const dispatch = createEventDispatcher()
let btn: HTMLButtonElement
@ -43,67 +31,6 @@
}
$: viewOptions = getViewOptions(viewlet, $viewOptionStore)
const query = createQuery()
$: query.query(
view.class.Viewlet,
viewletQuery,
(res) => {
viewlets = res
dispatch('viewlets', viewlets)
},
{
lookup: {
descriptor: view.class.ViewletDescriptor
}
}
)
let key = makeViewletKey()
onDestroy(
resolvedLocationStore.subscribe((loc) => {
key = makeViewletKey(loc)
})
)
$: getActiveViewlet(viewlets, $activeViewlet, key)
function getActiveViewlet (
viewlets: WithLookup<Viewlet>[],
activeViewlet: Record<string, Ref<Viewlet> | null>,
key: string
) {
if (viewlets.length === 0) return
const newViewlet = viewlets.find((viewlet) => viewlet?._id === activeViewlet[key]) ?? viewlets[0]
if (viewlet?._id !== newViewlet?._id) {
preference = undefined
viewlet = newViewlet
setActiveViewletId(newViewlet._id)
dispatch('viewlet', viewlet)
}
}
const preferenceQuery = createQuery()
$: if (viewlet != null) {
preferenceQuery.query(
view.class.ViewletPreference,
{
attachedTo: viewlet._id
},
(res) => {
preference = res[0]
loading = false
dispatch('loading', loading)
dispatch('preference', preference)
},
{ limit: 1 }
)
} else {
preferenceQuery.unsubscribe()
}
</script>
{#if viewlet}

View File

@ -0,0 +1,97 @@
<!--
// 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 { DocumentQuery, WithLookup } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import { Button, ButtonKind, showPopup } from '@hcengineering/ui'
import { ViewOptions, Viewlet, ViewletPreference } from '@hcengineering/view'
import { createEventDispatcher } from 'svelte'
import view from '../plugin'
import { getViewOptions, viewOptionStore } from '../viewOptions'
import ViewOptionsButton from './ViewOptionsButton.svelte'
import ViewletSetting from './ViewletSetting.svelte'
export let viewletQuery: DocumentQuery<Viewlet> = {}
export let kind: ButtonKind = 'regular'
export let viewOptions: ViewOptions | undefined = undefined
export let viewlet: Viewlet | undefined = undefined
export let viewlets: WithLookup<Viewlet>[] = []
export let preference: ViewletPreference | undefined = undefined
export let loading = true
const dispatch = createEventDispatcher()
let btn: HTMLButtonElement
function clickHandler (event: MouseEvent) {
showPopup(ViewletSetting, { viewlet }, btn)
}
$: viewOptions = getViewOptions(viewlet, $viewOptionStore)
const query = createQuery()
$: query.query(
view.class.Viewlet,
viewletQuery,
(res) => {
viewlets = res
viewlet = viewlets[0]
dispatch('viewlets', viewlets)
},
{
lookup: {
descriptor: view.class.ViewletDescriptor
}
}
)
const preferenceQuery = createQuery()
$: if (viewlet != null) {
preferenceQuery.query(
view.class.ViewletPreference,
{
attachedTo: viewlet._id
},
(res) => {
preference = res[0]
loading = false
},
{ limit: 1 }
)
} else {
preferenceQuery.unsubscribe()
}
</script>
{#if viewlet}
<div class="flex-row-center gap-2 reverse">
{#if viewOptions}
<ViewOptionsButton {viewlet} {kind} {viewOptions} />
{/if}
<Button
icon={view.icon.Configure}
label={view.string.Show}
{kind}
shrink={1}
adaptiveShrink={'sm'}
showTooltip={{ label: view.string.CustomizeView, direction: 'bottom' }}
bind:input={btn}
on:click={clickHandler}
/>
</div>
{/if}

View File

@ -131,6 +131,9 @@ export { default as TableBrowser } from './components/TableBrowser.svelte'
export { default as ValueSelector } from './components/ValueSelector.svelte'
export { default as FilterRemovedNotification } from './components/filter/FilterRemovedNotification.svelte'
export { default as ParentsNavigator } from './components/ParentsNavigator.svelte'
export { default as ViewletSelector } from './components/ViewletSelector.svelte'
export { default as ViewletsSettingButton } from './components/ViewletsSettingButton.svelte'
export * from './filter'
export * from './selection'
export * from './utils'

View File

@ -99,6 +99,14 @@ export function migrateViewOpttions (): void {
if (!Array.isArray(res.groupBy)) {
res.groupBy = [res.groupBy]
}
let ind = res.groupBy.findIndex((p) => p === 'state')
while (ind !== -1) {
res.groupBy[ind] = 'status'
ind = res.groupBy.findIndex((p) => p === 'state')
}
if (res.orderBy[0] === 'state') {
res.orderBy[0] = 'status'
}
localStorage.setItem(key, JSON.stringify(res))
}
}

View File

@ -17,9 +17,9 @@
import core, { WithLookup } from '@hcengineering/core'
import { IntlString } from '@hcengineering/platform'
import presentation, { createQuery } from '@hcengineering/presentation'
import { AnyComponent, Button, IconAdd, SearchEdit, TabList, showPopup } from '@hcengineering/ui'
import { AnyComponent, Button, IconAdd, SearchEdit, showPopup } from '@hcengineering/ui'
import { ViewOptions, Viewlet } from '@hcengineering/view'
import { FilterButton, ViewletSettingButton, setActiveViewletId } from '@hcengineering/view-resources'
import { FilterButton, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import Header from './Header.svelte'
@ -52,14 +52,6 @@
dispatch('search', '')
}
$: viewslist = viewlets.map((views) => {
return {
id: views._id,
icon: views.$lookup?.descriptor?.icon,
tooltip: views.$lookup?.descriptor?.label
}
})
// $: twoRows = $deviceInfo.twoRows
</script>
@ -68,19 +60,7 @@
<Header {space} {_class} />
<div class="ac-header-full medium-gap mb-1">
{#if viewlets.length > 1}
<TabList
items={viewslist}
multiselect={false}
selected={viewlet?._id}
on:select={(result) => {
if (result.detail !== undefined) {
viewlet = viewlets.find((vl) => vl._id === result.detail.id)
if (viewlet) setActiveViewletId(viewlet._id)
}
}}
/>
{/if}
<ViewletSelector {viewletQuery} bind:viewlet bind:viewlets />
{#if createItemDialog}
<Button icon={IconAdd} label={createItemLabel} kind={'accented'} on:click={(ev) => showCreateDialog(ev)} />
{/if}
@ -94,7 +74,7 @@
<FilterButton {_class} />
</div>
<div class="ac-header-full medium-gap">
<ViewletSettingButton bind:viewOptions {viewletQuery} bind:viewlet bind:viewlets />
<ViewletSettingButton bind:viewOptions bind:viewlet />
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
</div>
</div>

View File

@ -15,19 +15,10 @@
<script lang="ts">
import { Class, Doc, DocumentQuery, Ref, Space, WithLookup } from '@hcengineering/core'
import { Asset, IntlString } from '@hcengineering/platform'
import {
AnyComponent,
Button,
Component,
IconAdd,
Label,
Loading,
SearchEdit,
TabList,
showPopup
} from '@hcengineering/ui'
import { AnyComponent, Button, Component, IconAdd, Label, Loading, SearchEdit, showPopup } from '@hcengineering/ui'
import { ViewOptions, Viewlet, ViewletDescriptor, ViewletPreference } from '@hcengineering/view'
import { FilterBar, FilterButton, ViewletSettingButton, setActiveViewletId } from '@hcengineering/view-resources'
import { FilterBar, FilterButton, ViewletSettingButton } from '@hcengineering/view-resources'
import ViewletSelector from '@hcengineering/view-resources/src/components/ViewletSelector.svelte'
export let _class: Ref<Class<Doc>>
export let space: Ref<Space> | undefined = undefined
@ -55,14 +46,6 @@
if (createComponent === undefined) return
showPopup(createComponent, createComponentProps, 'top')
}
$: viewslist = viewlets.map((views) => {
return {
id: views._id,
icon: views.$lookup?.descriptor?.icon,
tooltip: views.$lookup?.descriptor?.label
}
})
</script>
<div class="ac-header full divide caption-height">
@ -71,24 +54,16 @@
</div>
<div class="ac-header-full medium-gap mb-1">
{#if viewlets.length > 1}
<TabList
items={viewslist}
multiselect={false}
selected={viewlet?._id}
on:select={(result) => {
if (result.detail !== undefined) {
if (viewlet?._id === result.detail.id) {
return
}
viewlet = viewlets.find((vl) => vl._id === result.detail.id)
if (viewlet) {
setActiveViewletId(viewlet._id)
}
}
}}
/>
{/if}
<ViewletSelector
bind:viewlet
bind:preference
bind:viewlets
viewletQuery={{
attachTo: _class,
variant: { $exists: false },
...(descriptors !== undefined ? { descriptor: { $in: descriptors } } : {})
}}
/>
{#if createLabel && createComponent}
<Button
icon={IconAdd}
@ -108,17 +83,7 @@
<FilterButton {_class} />
</div>
<div class="ac-header-full medium-gap">
<ViewletSettingButton
bind:viewOptions
viewletQuery={{
attachTo: _class,
variant: { $exists: false },
...(descriptors !== undefined ? { descriptor: { $in: descriptors } } : {})
}}
bind:viewlets
bind:viewlet
bind:preference
/>
<ViewletSettingButton bind:viewOptions bind:viewlet />
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
</div>
</div>