[UBER-178] New way of All/Active/Backlog should be in URI (#3228)

Signed-off-by: Ruslan Bayandinov <wazsone@ya.ru>
This commit is contained in:
Ruslan Bayandinov 2023-05-24 13:47:58 +07:00 committed by GitHub
parent 1a0cbb71d1
commit 30a0413dc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 65 deletions

View File

@ -825,6 +825,7 @@ export function createModel (builder: Builder): void {
const milestonesId = 'milestones' const milestonesId = 'milestones'
const templatesId = 'templates' const templatesId = 'templates'
const myIssuesId = 'my-issues' const myIssuesId = 'my-issues'
const allIssuesId = 'all-issues'
// const scrumsId = 'scrums' // const scrumsId = 'scrums'
builder.mixin(tracker.class.Issue, core.class.Class, view.mixin.ObjectPresenter, { builder.mixin(tracker.class.Issue, core.class.Class, view.mixin.ObjectPresenter, {
@ -999,10 +1000,17 @@ export function createModel (builder: Builder): void {
position: 'top', position: 'top',
label: tracker.string.MyIssues, label: tracker.string.MyIssues,
icon: tracker.icon.MyIssues, icon: tracker.icon.MyIssues,
component: tracker.component.MyIssues component: tracker.component.MyIssues,
componentProps: {
config: [
['assigned', view.string.Assigned, {}],
['created', view.string.Created, { value: 2 }],
['subscribed', view.string.Subscribed, {}]
]
}
}, },
{ {
id: 'all-issues', id: allIssuesId,
position: 'top', position: 'top',
label: tracker.string.AllIssues, label: tracker.string.AllIssues,
icon: tracker.icon.Issues, icon: tracker.icon.Issues,
@ -1010,7 +1018,12 @@ export function createModel (builder: Builder): void {
componentProps: { componentProps: {
baseQuery: { '$lookup.space.archived': false }, baseQuery: { '$lookup.space.archived': false },
space: undefined, space: undefined,
title: tracker.string.AllIssues title: tracker.string.AllIssues,
config: [
['all', tracker.string.All, {}],
['active', tracker.string.Active, {}],
['backlog', tracker.string.Backlog, {}]
]
} }
} }
], ],
@ -1028,7 +1041,12 @@ export function createModel (builder: Builder): void {
icon: tracker.icon.Issues, icon: tracker.icon.Issues,
component: tracker.component.Issues, component: tracker.component.Issues,
componentProps: { componentProps: {
title: tracker.string.Issues title: tracker.string.Issues,
config: [
['all', tracker.string.All, {}],
['active', tracker.string.Active, {}],
['backlog', tracker.string.Backlog, {}]
]
} }
}, },
{ {

View File

@ -13,23 +13,25 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte'
import { DocumentQuery, Ref } from '@hcengineering/core' import { DocumentQuery, Ref } from '@hcengineering/core'
import { Issue, Project } from '@hcengineering/tracker' import { Issue, Project } from '@hcengineering/tracker'
import tracker from '../../plugin'
import IssuesView from './IssuesView.svelte'
import { IntlString } from '@hcengineering/platform' import { IntlString } from '@hcengineering/platform'
import { createQuery } from '@hcengineering/presentation' import { createQuery } from '@hcengineering/presentation'
import { resolvedLocationStore } from '@hcengineering/ui'
import { IModeSelector } from '@hcengineering/ui' import { IModeSelector } from '@hcengineering/ui'
import tracker from '../../plugin'
import IssuesView from './IssuesView.svelte'
export let currentSpace: Ref<Project> | undefined = undefined export let currentSpace: Ref<Project> | undefined = undefined
export let baseQuery: DocumentQuery<Issue> = {} export let baseQuery: DocumentQuery<Issue> = {}
export let title: IntlString export let title: IntlString
export let config: [string, IntlString, object][]
const config: [string, IntlString, object][] = [ const dispatch = createEventDispatcher()
['all', tracker.string.All, {}], let query: DocumentQuery<Issue> | undefined = undefined
['active', tracker.string.Active, {}], let modeSelectorProps: IModeSelector | undefined = undefined
['backlog', tracker.string.Backlog, {}]
]
$: spaceQuery = currentSpace ? { space: currentSpace } : {} $: spaceQuery = currentSpace ? { space: currentSpace } : {}
@ -58,23 +60,23 @@
} }
) )
let [[mode]] = config $: queries = { all, active, backlog }
function handleChangeMode (newMode: string) { $: mode = $resolvedLocationStore.query?.mode ?? undefined
if (newMode === mode) return $: if (mode === undefined || queries[mode] === undefined) {
mode = newMode ;[[mode]] = config
} }
$: if (mode !== undefined) {
function getQuery (mode: string, queries: { [key: string]: DocumentQuery<Issue> }) { query = { ...queries[mode], '$lookup.space.archived': false }
return { ...queries[mode], '$lookup.space.archived': false } modeSelectorProps = {
config,
mode,
onChange: (newMode: string) => dispatch('action', { mode: newMode })
}
} }
$: query = getQuery(mode, { all, active, backlog })
$: modeSelectorProps = {
config,
mode,
onChange: handleChangeMode
} as IModeSelector
</script> </script>
{#key query && currentSpace} {#if query !== undefined && modeSelectorProps !== undefined}
<IssuesView {query} space={currentSpace} {title} {modeSelectorProps} /> {#key query && currentSpace}
{/key} <IssuesView {query} space={currentSpace} {title} {modeSelectorProps} />
{/key}
{/if}

View File

@ -13,26 +13,28 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte'
import type { EmployeeAccount } from '@hcengineering/contact' import type { EmployeeAccount } from '@hcengineering/contact'
import { Doc, DocumentQuery, getCurrentAccount, Ref } from '@hcengineering/core' import { Doc, DocumentQuery, getCurrentAccount, Ref } from '@hcengineering/core'
import type { IntlString } from '@hcengineering/platform' import type { IntlString } from '@hcengineering/platform'
import { createQuery } from '@hcengineering/presentation' import { createQuery } from '@hcengineering/presentation'
import type { Issue } from '@hcengineering/tracker' import type { Issue } from '@hcengineering/tracker'
import { resolvedLocationStore } from '@hcengineering/ui'
import { IModeSelector } from '@hcengineering/ui'
import tracker from '../../plugin' import tracker from '../../plugin'
import IssuesView from '../issues/IssuesView.svelte' import IssuesView from '../issues/IssuesView.svelte'
import { IModeSelector } from '@hcengineering/ui'
import view from '@hcengineering/view'
const config: [string, IntlString, object][] = [ export let config: [string, IntlString, object][] = []
['assigned', view.string.Assigned, {}],
['created', view.string.Created, {}], const dispatch = createEventDispatcher()
['subscribed', view.string.Subscribed, {}]
]
const currentUser = getCurrentAccount() as EmployeeAccount const currentUser = getCurrentAccount() as EmployeeAccount
const assigned = { assignee: currentUser.employee } const assigned = { assignee: currentUser.employee }
const created = { createdBy: currentUser._id } const created = { createdBy: currentUser._id }
let subscribed = { _id: { $in: [] as Ref<Issue>[] } } let subscribed = { _id: { $in: [] as Ref<Issue>[] } }
let query: DocumentQuery<Issue> | undefined = undefined
let modeSelectorProps: IModeSelector | undefined = undefined
let mode: string | undefined = undefined
const subscribedQuery = createQuery() const subscribedQuery = createQuery()
$: subscribedQuery.query( $: subscribedQuery.query(
@ -48,21 +50,23 @@
{ sort: { _id: 1 } } { sort: { _id: 1 } }
) )
let [[mode]] = config $: queries = { assigned, created, subscribed }
function handleChangeMode (newMode: string) { $: mode = $resolvedLocationStore.query?.mode ?? undefined
if (newMode === mode) return $: if (mode === undefined || queries[mode] === undefined) {
mode = newMode ;[[mode]] = config
} }
$: if (mode !== undefined) {
function getQuery (mode: string, queries: { [key: string]: DocumentQuery<Issue> }) { query = { ...queries[mode], '$lookup.space.archived': false }
return { ...queries[mode], '$lookup.space.archived': false } modeSelectorProps = {
config,
mode,
onChange: (newMode: string) => dispatch('action', { mode: newMode })
}
} }
$: query = getQuery(mode, { assigned, created, subscribed })
$: modeSelectorProps = {
config,
mode,
onChange: handleChangeMode
} as IModeSelector
</script> </script>
<IssuesView {query} space={undefined} title={tracker.string.MyIssues} {modeSelectorProps} /> {#if query !== undefined && modeSelectorProps !== undefined}
{#key query}
<IssuesView {query} space={undefined} title={tracker.string.MyIssues} {modeSelectorProps} />
{/key}
{/if}

View File

@ -21,7 +21,6 @@
async function saveFilter () { async function saveFilter () {
const loc = getCurrentResolvedLocation() const loc = getCurrentResolvedLocation()
loc.fragment = undefined loc.fragment = undefined
loc.query = undefined
const filters = JSON.stringify($filterStore) const filters = JSON.stringify($filterStore)
await client.createDoc(view.class.FilteredView, preference.space.Preference, { await client.createDoc(view.class.FilteredView, preference.space.Preference, {
name: filterName, name: filterName,

View File

@ -39,6 +39,7 @@
closePopup, closePopup,
closeTooltip, closeTooltip,
deviceOptionsStore as deviceInfo, deviceOptionsStore as deviceInfo,
getCurrentLocation,
location, location,
navigate, navigate,
openPanel, openPanel,
@ -583,21 +584,6 @@
selected={currentAppAlias === notificationId || inboxPopup !== undefined} selected={currentAppAlias === notificationId || inboxPopup !== undefined}
on:click={(e) => { on:click={(e) => {
if (e.metaKey || e.ctrlKey) return if (e.metaKey || e.ctrlKey) return
// if (inboxPopup) {
// inboxPopup.close()
// } else {
// inboxPopup = showPopup(
// notification.component.Inbox,
// { visibileNav: true },
// 'content',
// undefined,
// undefined,
// {
// category: 'popup',
// overlay: false
// }
// )
// }
if (currentAppAlias === notificationId && lastLoc !== undefined) { if (currentAppAlias === notificationId && lastLoc !== undefined) {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
@ -690,6 +676,13 @@
<Component <Component
is={specialComponent.component} is={specialComponent.component}
props={{ model: navigatorModel, ...specialComponent.componentProps, currentSpace, visibileNav }} props={{ model: navigatorModel, ...specialComponent.componentProps, currentSpace, visibileNav }}
on:action={(e) => {
if (e?.detail) {
const loc = getCurrentLocation()
loc.query = { ...loc.query, ...e.detail }
navigate(loc)
}
}}
/> />
{:else if currentView?.component !== undefined} {:else if currentView?.component !== undefined}
<Component is={currentView.component} props={{ ...currentView.componentProps, currentView, visibileNav }} /> <Component is={currentView.component} props={{ ...currentView.componentProps, currentView, visibileNav }} />

View File

@ -39,7 +39,7 @@ test('create-issue-and-sub-issue', async ({ page }) => {
await checkIssue(page, props) await checkIssue(page, props)
props.name = `sub${props.name}` props.name = `sub${props.name}`
await createSubissue(page, props) await createSubissue(page, props)
await page.click(`.antiList__row:has-text("${props.name}") .name a`) await openIssue(page, props.name)
await checkIssue(page, props) await checkIssue(page, props)
}) })