Save view options (#2528)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2023-01-21 20:16:14 +06:00 committed by GitHub
parent a7da534e06
commit a7cdd8a680
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 159 additions and 91 deletions

View File

@ -30,7 +30,7 @@
TabList TabList
} from '@hcengineering/ui' } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view' import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
import { FilterButton, getViewOptions, ViewletSettingButton } from '@hcengineering/view-resources' import { FilterButton, getViewOptions, setActiveViewletId, ViewletSettingButton } from '@hcengineering/view-resources'
import calendar from '../plugin' import calendar from '../plugin'
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui' import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
@ -56,6 +56,7 @@
viewlets = res viewlets = res
if (selectedViewlet === undefined || res.findIndex((p) => p._id === selectedViewlet?._id) === -1) { if (selectedViewlet === undefined || res.findIndex((p) => p._id === selectedViewlet?._id) === -1) {
selectedViewlet = res[0] selectedViewlet = res[0]
setActiveViewletId(selectedViewlet._id)
} }
}, },
{ lookup: { descriptor: view.class.ViewletDescriptor } } { lookup: { descriptor: view.class.ViewletDescriptor } }

View File

@ -22,6 +22,7 @@
ActionContext, ActionContext,
FilterButton, FilterButton,
getViewOptions, getViewOptions,
setActiveViewletId,
TableBrowser, TableBrowser,
ViewletSettingButton ViewletSettingButton
} from '@hcengineering/view-resources' } from '@hcengineering/view-resources'
@ -51,6 +52,7 @@
.then((res) => { .then((res) => {
viewlet = res viewlet = res
if (res !== undefined) { if (res !== undefined) {
setActiveViewletId(res._id)
preferenceQuery.query( preferenceQuery.query(
view.class.ViewletPreference, view.class.ViewletPreference,
{ {

View File

@ -18,7 +18,7 @@
import { createQuery, getClient, UsersPopup, IconMembersOutline } from '@hcengineering/presentation' import { createQuery, getClient, UsersPopup, IconMembersOutline } from '@hcengineering/presentation'
import { Button, IconAdd, Label, showPopup, Icon } from '@hcengineering/ui' import { Button, IconAdd, Label, showPopup, Icon } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view' import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
import { getViewOptions, Table, ViewletSettingButton } from '@hcengineering/view-resources' import { getViewOptions, setActiveViewletId, Table, ViewletSettingButton } from '@hcengineering/view-resources'
import contact from '../plugin' import contact from '../plugin'
export let objectId: Ref<Doc> export let objectId: Ref<Doc>
@ -76,6 +76,7 @@
.then((res) => { .then((res) => {
descr = res descr = res
if (res !== undefined) { if (res !== undefined) {
setActiveViewletId(res._id)
preferenceQuery.query( preferenceQuery.query(
view.class.ViewletPreference, view.class.ViewletPreference,
{ {

View File

@ -24,6 +24,7 @@
ActionContext, ActionContext,
FilterButton, FilterButton,
getViewOptions, getViewOptions,
setActiveViewletId,
TableBrowser, TableBrowser,
ViewletSettingButton ViewletSettingButton
} from '@hcengineering/view-resources' } from '@hcengineering/view-resources'
@ -53,6 +54,7 @@
.then((res) => { .then((res) => {
viewlet = res viewlet = res
if (res !== undefined) { if (res !== undefined) {
setActiveViewletId(res._id)
preferenceQuery.query( preferenceQuery.query(
view.class.ViewletPreference, view.class.ViewletPreference,
{ {

View File

@ -19,7 +19,7 @@
import { createQuery, getClient, UsersPopup } from '@hcengineering/presentation' import { createQuery, getClient, UsersPopup } from '@hcengineering/presentation'
import { Button, eventToHTMLElement, IconAdd, Label, Scroller, showPopup } from '@hcengineering/ui' import { Button, eventToHTMLElement, IconAdd, Label, Scroller, showPopup } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view' import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
import { getViewOptions, Table, ViewletSettingButton } from '@hcengineering/view-resources' import { getViewOptions, setActiveViewletId, Table, ViewletSettingButton } from '@hcengineering/view-resources'
import hr from '../plugin' import hr from '../plugin'
import { addMember } from '../utils' import { addMember } from '../utils'
@ -77,6 +77,7 @@
.then((res) => { .then((res) => {
descr = res descr = res
if (res !== undefined) { if (res !== undefined) {
setActiveViewletId(res._id)
preferenceQuery.query( preferenceQuery.query(
view.class.ViewletPreference, view.class.ViewletPreference,
{ {

View File

@ -20,7 +20,7 @@
import { createQuery, getClient } from '@hcengineering/presentation' import { createQuery, getClient } from '@hcengineering/presentation'
import { Button, Label, Loading, Scroller, tableSP } from '@hcengineering/ui' import { Button, Label, Loading, Scroller, tableSP } from '@hcengineering/ui'
import view, { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view' import view, { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view'
import { getViewOptions, Table, ViewletSettingButton } from '@hcengineering/view-resources' import { getViewOptions, setActiveViewletId, Table, ViewletSettingButton } from '@hcengineering/view-resources'
import hr from '../../plugin' import hr from '../../plugin'
import { import {
EmployeeReports, EmployeeReports,
@ -182,6 +182,7 @@
.then((res) => { .then((res) => {
descr = res descr = res
if (res !== undefined) { if (res !== undefined) {
setActiveViewletId(res._id)
preferenceQuery.query( preferenceQuery.query(
view.class.ViewletPreference, view.class.ViewletPreference,
{ {

View File

@ -18,7 +18,13 @@
import { Vacancy } from '@hcengineering/recruit' import { Vacancy } from '@hcengineering/recruit'
import { Button, Icon, IconAdd, Label, Loading, SearchEdit, showPopup } from '@hcengineering/ui' import { Button, Icon, IconAdd, Label, Loading, SearchEdit, showPopup } from '@hcengineering/ui'
import view, { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view' import view, { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view'
import { FilterButton, getViewOptions, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources' import {
FilterButton,
getViewOptions,
setActiveViewletId,
TableBrowser,
ViewletSettingButton
} from '@hcengineering/view-resources'
import recruit from '../plugin' import recruit from '../plugin'
import CreateVacancy from './CreateVacancy.svelte' import CreateVacancy from './CreateVacancy.svelte'
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui' import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
@ -104,6 +110,7 @@
.then((res) => { .then((res) => {
descr = res descr = res
if (res !== undefined) { if (res !== undefined) {
setActiveViewletId(res._id)
preferenceQuery.query( preferenceQuery.query(
view.class.ViewletPreference, view.class.ViewletPreference,
{ {

View File

@ -50,6 +50,7 @@
if (result.detail !== undefined) { if (result.detail !== undefined) {
if (viewlet?._id === result.detail.id) return if (viewlet?._id === result.detail.id) return
viewlet = viewlets.find((vl) => vl._id === result.detail.id) viewlet = viewlets.find((vl) => vl._id === result.detail.id)
console.log('set viewlet by issue headed')
if (viewlet) setActiveViewletId(viewlet._id) if (viewlet) setActiveViewletId(viewlet._id)
} }
}} }}

View File

@ -5,7 +5,7 @@
import { Issue, IssueStatus, Team } from '@hcengineering/tracker' import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
import { Button, IconDetails, IconDetailsFilled } from '@hcengineering/ui' import { Button, IconDetails, IconDetailsFilled } from '@hcengineering/ui'
import view, { Viewlet } from '@hcengineering/view' import view, { Viewlet } from '@hcengineering/view'
import { FilterBar, getActiveViewletId, getViewOptions } from '@hcengineering/view-resources' import { FilterBar, getActiveViewletId, getViewOptions, setActiveViewletId } from '@hcengineering/view-resources'
import ViewletSettingButton from '@hcengineering/view-resources/src/components/ViewletSettingButton.svelte' import ViewletSettingButton from '@hcengineering/view-resources/src/components/ViewletSettingButton.svelte'
import tracker from '../../plugin' import tracker from '../../plugin'
import IssuesContent from './IssuesContent.svelte' import IssuesContent from './IssuesContent.svelte'
@ -45,6 +45,7 @@
) )
const _id = getActiveViewletId() const _id = getActiveViewletId()
viewlet = viewlets.find((viewlet) => viewlet._id === _id) || viewlets[0] viewlet = viewlets.find((viewlet) => viewlet._id === _id) || viewlets[0]
setActiveViewletId(viewlet._id)
} }
$: if (!label && title) { $: if (!label && title) {
translate(title, {}).then((res) => { translate(title, {}).then((res) => {
@ -118,7 +119,7 @@
</svelte:fragment> </svelte:fragment>
</IssuesHeader> </IssuesHeader>
<slot name="afterHeader" /> <slot name="afterHeader" />
<FilterBar _class={tracker.class.Issue} query={searchQuery} on:change={(e) => (resultQuery = e.detail)} /> <FilterBar _class={tracker.class.Issue} query={searchQuery} {viewOptions} on:change={(e) => (resultQuery = e.detail)} />
<div class="flex w-full h-full clear-mins"> <div class="flex w-full h-full clear-mins">
{#if viewlet && _teams && issueStatuses} {#if viewlet && _teams && issueStatuses}
<IssuesContent {viewlet} query={resultQuery} {space} teams={_teams} {issueStatuses} {viewOptions} /> <IssuesContent {viewlet} query={resultQuery} {space} teams={_teams} {issueStatuses} {viewOptions} />

View File

@ -5,7 +5,7 @@
import { IssueTemplate } from '@hcengineering/tracker' import { IssueTemplate } from '@hcengineering/tracker'
import { Button, IconAdd, IconDetails, IconDetailsFilled, showPopup } from '@hcengineering/ui' import { Button, IconAdd, IconDetails, IconDetailsFilled, showPopup } from '@hcengineering/ui'
import view, { Viewlet } from '@hcengineering/view' import view, { Viewlet } from '@hcengineering/view'
import { FilterBar, getActiveViewletId, getViewOptions } from '@hcengineering/view-resources' import { FilterBar, getActiveViewletId, getViewOptions, setActiveViewletId } from '@hcengineering/view-resources'
import ViewletSettingButton from '@hcengineering/view-resources/src/components/ViewletSettingButton.svelte' import ViewletSettingButton from '@hcengineering/view-resources/src/components/ViewletSettingButton.svelte'
import tracker from '../../plugin' import tracker from '../../plugin'
import IssuesHeader from '../issues/IssuesHeader.svelte' import IssuesHeader from '../issues/IssuesHeader.svelte'
@ -47,6 +47,7 @@
) )
const _id = getActiveViewletId() const _id = getActiveViewletId()
viewlet = viewlets.find((viewlet) => viewlet._id === _id) || viewlets[0] viewlet = viewlets.find((viewlet) => viewlet._id === _id) || viewlets[0]
setActiveViewletId(viewlet._id)
} }
$: if (!label && title) { $: if (!label && title) {
translate(title, {}).then((res) => { translate(title, {}).then((res) => {
@ -105,7 +106,12 @@
</svelte:fragment> </svelte:fragment>
</IssuesHeader> </IssuesHeader>
<slot name="afterHeader" /> <slot name="afterHeader" />
<FilterBar _class={tracker.class.IssueTemplate} query={searchQuery} on:change={(e) => (resultQuery = e.detail)} /> <FilterBar
_class={tracker.class.IssueTemplate}
{viewOptions}
query={searchQuery}
on:change={(e) => (resultQuery = e.detail)}
/>
<div class="flex w-full h-full clear-mins"> <div class="flex w-full h-full clear-mins">
{#if viewlet && viewOptions} {#if viewlet && viewOptions}
<IssueTemplatesContent {viewOptions} {viewlet} query={resultQuery} /> <IssueTemplatesContent {viewOptions} {viewlet} query={resultQuery} />

View File

@ -17,7 +17,7 @@
import { getResource } from '@hcengineering/platform' import { getResource } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation' import { getClient } from '@hcengineering/presentation'
import { Button, eventToHTMLElement, getCurrentLocation, IconAdd, locationToUrl, showPopup } from '@hcengineering/ui' import { Button, eventToHTMLElement, getCurrentLocation, IconAdd, locationToUrl, showPopup } from '@hcengineering/ui'
import { Filter } from '@hcengineering/view' import { Filter, ViewOptions } from '@hcengineering/view'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { filterStore } from '../../filter' import { filterStore } from '../../filter'
import view from '../../plugin' import view from '../../plugin'
@ -27,6 +27,7 @@
export let _class: Ref<Class<Doc>> export let _class: Ref<Class<Doc>>
export let query: DocumentQuery<Doc> export let query: DocumentQuery<Doc>
export let viewOptions: ViewOptions | undefined = undefined
const client = getClient() const client = getClient()
const hierarchy = client.getHierarchy() const hierarchy = client.getHierarchy()
@ -79,7 +80,7 @@
} }
async function saveFilteredView () { async function saveFilteredView () {
showPopup(FilterSave, {}) showPopup(FilterSave, { viewOptions })
} }
let loading = false let loading = false

View File

@ -5,25 +5,28 @@
import preference from '@hcengineering/preference' import preference from '@hcengineering/preference'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { filterStore } from '../../filter' import { filterStore } from '../../filter'
import { ViewOptions } from '@hcengineering/view'
import { Doc, Ref } from '@hcengineering/core'
import { getActiveViewletId } from '../../utils'
export let viewOptions: ViewOptions | undefined = undefined
let filterName = '' let filterName = ''
const client = getClient() const client = getClient()
function getFilteredViewData () { async function saveFilter () {
const loc = getCurrentLocation() const loc = getCurrentLocation()
loc.fragment = undefined loc.fragment = undefined
loc.query = undefined loc.query = undefined
const filters = JSON.stringify($filterStore) const filters = JSON.stringify($filterStore)
return { await client.createDoc(view.class.FilteredView, preference.space.Preference, {
name: filterName, name: filterName,
location: loc, location: loc,
filters, filters,
attachedTo: loc.path[2] attachedTo: loc.path[2] as Ref<Doc>,
} viewOptions,
} viewletId: getActiveViewletId()
})
async function saveFilter () {
await client.createDoc(view.class.FilteredView, preference.space.Preference, getFilteredViewData())
} }
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()

View File

@ -34,6 +34,7 @@ import {
AnyComponent, AnyComponent,
ErrorPresenter, ErrorPresenter,
getCurrentLocation, getCurrentLocation,
Location,
getPlatformColorForText, getPlatformColorForText,
locationToUrl locationToUrl
} from '@hcengineering/ui' } from '@hcengineering/ui'
@ -474,16 +475,16 @@ export function isCollectionAttr (hierarchy: Hierarchy, key: KeyedAttribute): bo
return hierarchy.isDerived(key.attr.type._class, core.class.Collection) return hierarchy.isDerived(key.attr.type._class, core.class.Collection)
} }
function makeViewletKey (): string { function makeViewletKey (loc?: Location): string {
const loc = getCurrentLocation() loc = loc ?? getCurrentLocation()
loc.fragment = undefined loc.fragment = undefined
loc.query = undefined loc.query = undefined
return 'viewlet' + locationToUrl(loc) return 'viewlet' + locationToUrl(loc)
} }
export function setActiveViewletId (viewletId: Ref<Viewlet> | null): void { export function setActiveViewletId (viewletId: Ref<Viewlet> | null, loc?: Location): void {
const key = makeViewletKey() const key = makeViewletKey(loc)
if (viewletId !== null) { if (viewletId !== null && viewletId !== undefined) {
localStorage.setItem(key, viewletId) localStorage.setItem(key, viewletId)
} else { } else {
localStorage.removeItem(key) localStorage.removeItem(key)

View File

@ -17,25 +17,25 @@ export function isDropdownType (viewOption: ViewOptionModel): viewOption is Drop
return viewOption.type === 'dropdown' return viewOption.type === 'dropdown'
} }
function makeViewOptionsKey (prefix: string): string { function makeViewOptionsKey (viewlet: Viewlet): string {
const prefix = viewlet?._id + (viewlet?.variant !== undefined ? `-${viewlet.variant}` : '')
const loc = getCurrentLocation() const loc = getCurrentLocation()
loc.fragment = undefined loc.fragment = undefined
loc.query = undefined loc.query = undefined
return `viewOptions:${prefix}:${locationToUrl(loc)}` return `viewOptions:${prefix}:${locationToUrl(loc)}`
} }
function _setViewOptions (prefix: string, options: ViewOptions): void { function _setViewOptions (viewlet: Viewlet, options: ViewOptions): void {
const key = makeViewOptionsKey(prefix) const key = makeViewOptionsKey(viewlet)
localStorage.setItem(key, JSON.stringify(options)) localStorage.setItem(key, JSON.stringify(options))
} }
export function setViewOptions (viewlet: Viewlet, options: ViewOptions): void { export function setViewOptions (viewlet: Viewlet, options: ViewOptions): void {
const viewletKey = viewlet?._id + (viewlet?.variant !== undefined ? `-${viewlet.variant}` : '') _setViewOptions(viewlet, options)
_setViewOptions(viewletKey, options)
} }
function _getViewOptions (prefix: string): ViewOptions | null { function _getViewOptions (viewlet: Viewlet): ViewOptions | null {
const key = makeViewOptionsKey(prefix) const key = makeViewOptionsKey(viewlet)
const options = localStorage.getItem(key) const options = localStorage.getItem(key)
if (options === null) return null if (options === null) return null
return JSON.parse(options) return JSON.parse(options)
@ -45,6 +45,5 @@ export function getViewOptions (viewlet: Viewlet | undefined, defaults = defaulO
if (viewlet === undefined) { if (viewlet === undefined) {
return { ...defaults } return { ...defaults }
} }
const viewletKey = viewlet?._id + (viewlet?.variant !== undefined ? `-${viewlet.variant}` : '') return _getViewOptions(viewlet) ?? defaults
return _getViewOptions(viewletKey) ?? defaults
} }

View File

@ -82,6 +82,8 @@ export interface FilteredView extends Preference {
name: string name: string
location: PlatformLocation location: PlatformLocation
filters: string filters: string
viewOptions?: ViewOptions
viewletId?: Ref<Viewlet> | null
} }
/** /**

View File

@ -13,26 +13,22 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import core, { Doc, Ref, SortingOrder, Space, getCurrentAccount } from '@hcengineering/core' import core, { Doc, getCurrentAccount, Ref, SortingOrder, Space } from '@hcengineering/core'
import { getResource } from '@hcengineering/platform' import { getResource } from '@hcengineering/platform'
import preference, { SpacePreference } from '@hcengineering/preference'
import { createQuery, getClient } from '@hcengineering/presentation' import { createQuery, getClient } from '@hcengineering/presentation'
import { Button, IconEdit, navigate, Scroller, showPopup } from '@hcengineering/ui'
import type { Application, NavigatorModel, SpecialNavModel } from '@hcengineering/workbench'
import setting from '@hcengineering/setting' import setting from '@hcengineering/setting'
import { Button, Scroller, showPopup } from '@hcengineering/ui'
import type { Application, NavigatorModel, SpecialNavModel } from '@hcengineering/workbench'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import preferece, { SpacePreference } from '@hcengineering/preference' import workbench from '../plugin'
import { getSpecialSpaceClass } from '../utils' import { getSpecialSpaceClass } from '../utils'
import preference from '@hcengineering/preference' import HelpAndSupport from './HelpAndSupport.svelte'
import SpacesNav from './navigator/SpacesNav.svelte' import SpacesNav from './navigator/SpacesNav.svelte'
import SpecialElement from './navigator/SpecialElement.svelte' import SpecialElement from './navigator/SpecialElement.svelte'
import StarredNav from './navigator/StarredNav.svelte' import StarredNav from './navigator/StarredNav.svelte'
import TreeSeparator from './navigator/TreeSeparator.svelte' import TreeSeparator from './navigator/TreeSeparator.svelte'
import HelpAndSupport from './HelpAndSupport.svelte' import SavedView from './SavedView.svelte'
import workbench from '../plugin'
import TreeNode from './navigator/TreeNode.svelte'
import TreeItem from './navigator/TreeItem.svelte'
import view, { FilteredView } from '@hcengineering/view'
import { filterStore } from '@hcengineering/view-resources'
export let model: NavigatorModel | undefined export let model: NavigatorModel | undefined
export let currentSpace: Ref<Space> | undefined export let currentSpace: Ref<Space> | undefined
@ -69,7 +65,7 @@
const preferenceQuery = createQuery() const preferenceQuery = createQuery()
preferenceQuery.query(preferece.class.SpacePreference, {}, (res) => { preferenceQuery.query(preference.class.SpacePreference, {}, (res) => {
preferences = new Map( preferences = new Map(
res.map((r) => { res.map((r) => {
return [r.attachedTo, r] return [r.attachedTo, r]
@ -106,18 +102,6 @@
$: if (model) update(model, spaces, preferences) $: if (model) update(model, spaces, preferences)
function removeAction (filteredView: FilteredView) {
return [
{
icon: view.icon.Archive ?? IconEdit,
label: setting.string.Delete,
action: async (ctx: any, evt: Event) => {
await client.removeDoc(view.class.FilteredView, currentSpace, filteredView._id)
}
}
]
}
async function updateSpecials ( async function updateSpecials (
specials: SpecialNavModel[], specials: SpecialNavModel[],
spaces: Space[], spaces: Space[],
@ -141,11 +125,6 @@
return [result, requestIndex] return [result, requestIndex]
} }
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const filteredViewsQuery = createQuery()
let filteredViews: FilteredView[] | undefined
$: filteredViewsQuery.query(view.class.FilteredView, { attachedTo: currentApplication?.alias }, (result) => {
filteredViews = result
})
</script> </script>
{#if model} {#if model}
@ -166,20 +145,7 @@
{/if} {/if}
{#if specials.length > 0}<TreeSeparator />{/if} {#if specials.length > 0}<TreeSeparator />{/if}
{#if filteredViews && filteredViews.length > 0} <SavedView {currentApplication} />
<TreeNode label={view.string.FilteredViews}>
{#each filteredViews as fV}
<TreeItem
title={fV.name}
on:click={() => {
navigate(fV.location)
$filterStore = JSON.parse(fV.filters)
}}
actions={() => removeAction(fV)}
/>
{/each}
</TreeNode>
{/if}
{#if starred.length} {#if starred.length}
<StarredNav label={preference.string.Starred} spaces={starred} on:space {currentSpace} /> <StarredNav label={preference.string.Starred} spaces={starred} on:space {currentSpace} />
{/if} {/if}

View File

@ -0,0 +1,57 @@
<script lang="ts">
import { Doc, Ref } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import setting from '@hcengineering/setting'
import { Action, navigate } from '@hcengineering/ui'
import view, { FilteredView } from '@hcengineering/view'
import { filterStore, setActiveViewletId, setViewOptions } from '@hcengineering/view-resources'
import { Application } from '@hcengineering/workbench'
import TreeItem from './navigator/TreeItem.svelte'
import TreeNode from './navigator/TreeNode.svelte'
export let currentApplication: Application | undefined
const client = getClient()
const filteredViewsQuery = createQuery()
let filteredViews: FilteredView[] | undefined
$: filteredViewsQuery.query(
view.class.FilteredView,
{ attachedTo: currentApplication?.alias as Ref<Doc> },
(result) => {
filteredViews = result
}
)
async function removeAction (filteredView: FilteredView): Promise<Action[]> {
return [
{
icon: view.icon.Delete,
label: setting.string.Delete,
action: async (ctx: any, evt: Event) => {
await client.remove(filteredView)
}
}
]
}
async function load (fv: FilteredView): Promise<void> {
if (fv.viewletId !== undefined && fv.viewletId !== null) {
const viewlet = await client.findOne(view.class.Viewlet, { _id: fv.viewletId })
setActiveViewletId(fv.viewletId, fv.location)
if (viewlet !== undefined && fv.viewOptions !== undefined) {
setViewOptions(viewlet, fv.viewOptions)
}
}
navigate(fv.location)
$filterStore = JSON.parse(fv.filters)
}
</script>
{#if filteredViews && filteredViews.length > 0}
<TreeNode label={view.string.FilteredViews}>
{#each filteredViews as fv}
<TreeItem _id={fv._id} title={fv.name} on:click={() => load(fv)} actions={() => removeAction(fv)} />
{/each}
</TreeNode>
{/if}

View File

@ -18,7 +18,7 @@
import { IntlString } from '@hcengineering/platform' import { IntlString } from '@hcengineering/platform'
import { createQuery } from '@hcengineering/presentation' import { createQuery } from '@hcengineering/presentation'
import { AnyComponent, Component, Loading } from '@hcengineering/ui' import { AnyComponent, Component, Loading } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view' import view, { Viewlet, ViewletPreference, ViewOptions } from '@hcengineering/view'
import { FilterBar } from '@hcengineering/view-resources' import { FilterBar } from '@hcengineering/view-resources'
export let _class: Ref<Class<Doc>> export let _class: Ref<Class<Doc>>
@ -27,6 +27,7 @@
export let viewlet: WithLookup<Viewlet> | undefined export let viewlet: WithLookup<Viewlet> | undefined
export let createItemDialog: AnyComponent | undefined export let createItemDialog: AnyComponent | undefined
export let createItemLabel: IntlString | undefined export let createItemLabel: IntlString | undefined
export let viewOptions: ViewOptions
const preferenceQuery = createQuery() const preferenceQuery = createQuery()
let preference: ViewletPreference | undefined let preference: ViewletPreference | undefined
@ -56,7 +57,7 @@
{#if loading} {#if loading}
<Loading /> <Loading />
{:else} {:else}
<FilterBar {_class} query={searchQuery} on:change={(e) => (resultQuery = e.detail)} /> <FilterBar {_class} query={searchQuery} {viewOptions} on:change={(e) => (resultQuery = e.detail)} />
<Component <Component
is={viewlet.$lookup?.descriptor?.component} is={viewlet.$lookup?.descriptor?.component}
props={{ props={{

View File

@ -17,19 +17,22 @@
import core, { WithLookup } from '@hcengineering/core' import core, { WithLookup } from '@hcengineering/core'
import { IntlString } from '@hcengineering/platform' import { IntlString } from '@hcengineering/platform'
import presentation, { createQuery, getClient } from '@hcengineering/presentation' import presentation, { createQuery, getClient } from '@hcengineering/presentation'
import { AnyComponent, Button, IconAdd, SearchEdit, showPanel, showPopup, TabList } from '@hcengineering/ui'
import view, { Viewlet } from '@hcengineering/view'
import { import {
getActiveViewletId, AnyComponent,
getViewOptions, Button,
setActiveViewletId, deviceOptionsStore as deviceInfo,
ViewletSettingButton IconAdd,
} from '@hcengineering/view-resources' SearchEdit,
showPanel,
showPopup,
TabList
} from '@hcengineering/ui'
import view, { Viewlet, ViewOptions } from '@hcengineering/view'
import { getActiveViewletId, setActiveViewletId, ViewletSettingButton } from '@hcengineering/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 { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
export let spaceId: Ref<Space> | undefined export let spaceId: Ref<Space> | undefined
export let createItemDialog: AnyComponent | undefined export let createItemDialog: AnyComponent | undefined
@ -38,6 +41,7 @@
export let viewlet: WithLookup<Viewlet> | undefined export let viewlet: WithLookup<Viewlet> | undefined
export let viewlets: WithLookup<Viewlet>[] = [] export let viewlets: WithLookup<Viewlet>[] = []
export let _class: Ref<Class<Doc>> | undefined = undefined export let _class: Ref<Class<Doc>> | undefined = undefined
export let viewOptions: ViewOptions
const client = getClient() const client = getClient()
const hierarchy = client.getHierarchy() const hierarchy = client.getHierarchy()
@ -79,6 +83,7 @@
const _id = getActiveViewletId() const _id = getActiveViewletId()
const index = viewlets.findIndex((p) => p._id === (viewlet?._id ?? _id)) const index = viewlets.findIndex((p) => p._id === (viewlet?._id ?? _id))
viewlet = index === -1 ? viewlets[0] : viewlets[index] viewlet = index === -1 ? viewlets[0] : viewlets[index]
setActiveViewletId(viewlet._id)
} }
$: viewslist = viewlets.map((views) => { $: viewslist = viewlets.map((views) => {
return { return {
@ -89,8 +94,6 @@
}) })
$: twoRows = $deviceInfo.twoRows $: twoRows = $deviceInfo.twoRows
$: viewOptions = getViewOptions(viewlet)
</script> </script>
<div class="ac-header withSettings" class:full={!twoRows} class:mini={twoRows}> <div class="ac-header withSettings" class:full={!twoRows} class:mini={twoRows}>
@ -130,6 +133,7 @@
on:select={(result) => { on:select={(result) => {
if (result.detail !== undefined) { if (result.detail !== undefined) {
viewlet = viewlets.find((vl) => vl._id === result.detail.id) viewlet = viewlets.find((vl) => vl._id === result.detail.id)
console.log('set viewlet by space headed')
if (viewlet) setActiveViewletId(viewlet._id) if (viewlet) setActiveViewletId(viewlet._id)
} }
}} }}

View File

@ -18,7 +18,7 @@
import { getClient } from '@hcengineering/presentation' import { getClient } from '@hcengineering/presentation'
import { AnyComponent, Component } from '@hcengineering/ui' import { AnyComponent, Component } from '@hcengineering/ui'
import view, { Viewlet } from '@hcengineering/view' import view, { Viewlet } from '@hcengineering/view'
import { getActiveViewletId } from '@hcengineering/view-resources' import { getActiveViewletId, getViewOptions } from '@hcengineering/view-resources'
import type { ViewConfiguration } from '@hcengineering/workbench' import type { ViewConfiguration } from '@hcengineering/workbench'
import SpaceContent from './SpaceContent.svelte' import SpaceContent from './SpaceContent.svelte'
import SpaceHeader from './SpaceHeader.svelte' import SpaceHeader from './SpaceHeader.svelte'
@ -79,6 +79,8 @@
function setViewlet (e: CustomEvent<WithLookup<Viewlet>>) { function setViewlet (e: CustomEvent<WithLookup<Viewlet>>) {
viewlet = e.detail viewlet = e.detail
} }
$: viewOptions = getViewOptions(viewlet)
</script> </script>
{#if _class && space} {#if _class && space}
@ -95,9 +97,10 @@
{viewlets} {viewlets}
{createItemDialog} {createItemDialog}
{createItemLabel} {createItemLabel}
{viewOptions}
bind:search bind:search
bind:viewlet bind:viewlet
/> />
{/if} {/if}
<SpaceContent space={space._id} {_class} {createItemDialog} {createItemLabel} bind:search {viewlet} /> <SpaceContent space={space._id} {_class} {createItemDialog} {viewOptions} {createItemLabel} bind:search {viewlet} />
{/if} {/if}

View File

@ -29,7 +29,13 @@
showPopup showPopup
} from '@hcengineering/ui' } from '@hcengineering/ui'
import view, { Viewlet, ViewletDescriptor, ViewletPreference } from '@hcengineering/view' import view, { Viewlet, ViewletDescriptor, ViewletPreference } from '@hcengineering/view'
import { FilterBar, FilterButton, getViewOptions, ViewletSettingButton } from '@hcengineering/view-resources' import {
FilterBar,
FilterButton,
getViewOptions,
setActiveViewletId,
ViewletSettingButton
} from '@hcengineering/view-resources'
export let _class: Ref<Class<Doc>> export let _class: Ref<Class<Doc>>
export let space: Ref<Space> | undefined = undefined export let space: Ref<Space> | undefined = undefined
@ -71,6 +77,7 @@
.then((res) => { .then((res) => {
viewlet = res viewlet = res
if (res !== undefined) { if (res !== undefined) {
setActiveViewletId(res._id)
preferenceQuery.query( preferenceQuery.query(
view.class.ViewletPreference, view.class.ViewletPreference,
{ {
@ -120,6 +127,7 @@
<FilterBar <FilterBar
{_class} {_class}
query={searchQuery} query={searchQuery}
{viewOptions}
on:change={(e) => { on:change={(e) => {
resultQuery = e.detail resultQuery = e.detail
}} }}