mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-14 04:08:19 +00:00
TSK-955: Fix status display (#2840)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
948f39d669
commit
57a925b038
@ -40,5 +40,8 @@ export const calcRank = (prev?: { rank: string }, next?: { rank: string }): stri
|
||||
const a = prev?.rank !== undefined ? LexoRank.parse(prev.rank) : LexoRank.min()
|
||||
const b = next?.rank !== undefined ? LexoRank.parse(next.rank) : LexoRank.max()
|
||||
|
||||
if (a.equals(b)) {
|
||||
return a.genNext().toString()
|
||||
}
|
||||
return a.between(b).toString()
|
||||
}
|
||||
|
@ -104,6 +104,10 @@ export function getClient (): TxOperations {
|
||||
* @public
|
||||
*/
|
||||
export function setClient (_client: Client): void {
|
||||
if (liveQuery !== undefined) {
|
||||
void liveQuery.close()
|
||||
}
|
||||
const needRefresh = liveQuery !== undefined
|
||||
liveQuery = new LQ(_client)
|
||||
client = new UIClient(_client, liveQuery)
|
||||
_client.notify = (tx: Tx) => {
|
||||
@ -111,17 +115,23 @@ export function setClient (_client: Client): void {
|
||||
|
||||
txListeners.forEach((it) => it(tx))
|
||||
}
|
||||
if (needRefresh) {
|
||||
refreshClient()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function refreshClient (): void {
|
||||
if (liveQuery !== undefined) {
|
||||
void liveQuery.refreshConnect()
|
||||
void liveQuery?.refreshConnect()
|
||||
for (const q of globalQueries) {
|
||||
q.refreshClient()
|
||||
}
|
||||
}
|
||||
|
||||
const globalQueries: LiveQuery[] = []
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@ -137,6 +147,8 @@ export class LiveQuery {
|
||||
onDestroy(() => {
|
||||
this.unsubscribe()
|
||||
})
|
||||
} else {
|
||||
globalQueries.push(this)
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,11 +161,21 @@ export class LiveQuery {
|
||||
if (!this.needUpdate(_class, query, callback, options)) {
|
||||
return false
|
||||
}
|
||||
return this.doQuery<T>(_class, query, callback, options)
|
||||
}
|
||||
|
||||
private doQuery<T extends Doc>(
|
||||
_class: Ref<Class<T>>,
|
||||
query: DocumentQuery<T>,
|
||||
callback: (result: FindResult<T>) => void,
|
||||
options: FindOptions<T> | undefined
|
||||
): boolean {
|
||||
this.unsubscribe()
|
||||
this.oldCallback = callback
|
||||
this.oldClass = _class
|
||||
this.oldOptions = options
|
||||
this.oldQuery = query
|
||||
|
||||
const unsub = liveQuery.query(_class, query, callback, options)
|
||||
this.unsubscribe = () => {
|
||||
unsub()
|
||||
@ -166,6 +188,16 @@ export class LiveQuery {
|
||||
return true
|
||||
}
|
||||
|
||||
refreshClient (): void {
|
||||
if (this.oldClass !== undefined && this.oldQuery !== undefined && this.oldCallback !== undefined) {
|
||||
const _class = this.oldClass
|
||||
const query = this.oldQuery
|
||||
const callback = this.oldCallback
|
||||
const options = this.oldOptions
|
||||
this.doQuery(_class, query, callback, options)
|
||||
}
|
||||
}
|
||||
|
||||
private needUpdate<T extends Doc>(
|
||||
_class: Ref<Class<T>>,
|
||||
query: DocumentQuery<T>,
|
||||
|
@ -64,7 +64,7 @@ interface Query {
|
||||
* @public
|
||||
*/
|
||||
export class LiveQuery extends TxProcessor implements Client {
|
||||
private readonly client: Client
|
||||
private client: Client
|
||||
private readonly queries: Map<Ref<Class<Doc>>, Query[]> = new Map<Ref<Class<Doc>>, Query[]>()
|
||||
private readonly queue: Query[] = []
|
||||
|
||||
@ -73,6 +73,11 @@ export class LiveQuery extends TxProcessor implements Client {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
async updateClient (client: Client): Promise<void> {
|
||||
this.client = client
|
||||
await this.refreshConnect()
|
||||
}
|
||||
|
||||
async close (): Promise<void> {
|
||||
return await this.client.close()
|
||||
}
|
||||
@ -89,7 +94,20 @@ export class LiveQuery extends TxProcessor implements Client {
|
||||
async refreshConnect (): Promise<void> {
|
||||
for (const q of [...this.queue]) {
|
||||
if (!(await this.removeFromQueue(q))) {
|
||||
await this.refresh(q)
|
||||
try {
|
||||
await this.refresh(q)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const v of this.queries.values()) {
|
||||
for (const q of v) {
|
||||
try {
|
||||
await this.refresh(q)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class RequestPromise {
|
||||
resolve!: (value?: any) => void
|
||||
reject!: (reason?: any) => void
|
||||
reconnect?: () => void
|
||||
constructor () {
|
||||
constructor (readonly method: string, readonly params: any[]) {
|
||||
this.promise = new Promise((resolve, reject) => {
|
||||
this.resolve = resolve
|
||||
this.reject = reject
|
||||
@ -64,6 +64,7 @@ class Connection implements ClientConnection {
|
||||
private lastId = 0
|
||||
private readonly interval: number
|
||||
private readonly sessionId = generateId() as string
|
||||
private closed = false
|
||||
|
||||
constructor (
|
||||
private readonly url: string,
|
||||
@ -80,6 +81,7 @@ class Connection implements ClientConnection {
|
||||
}
|
||||
|
||||
async close (): Promise<void> {
|
||||
this.closed = true
|
||||
clearInterval(this.interval)
|
||||
if (this.websocket !== null) {
|
||||
if (this.websocket instanceof Promise) {
|
||||
@ -158,7 +160,7 @@ class Connection implements ClientConnection {
|
||||
}
|
||||
this.requests.delete(resp.id)
|
||||
if (resp.error !== undefined) {
|
||||
console.log('ERROR', resp.id)
|
||||
console.log('ERROR', promise, resp.id)
|
||||
promise.reject(new PlatformError(resp.error))
|
||||
} else {
|
||||
promise.resolve(resp.result)
|
||||
@ -212,8 +214,11 @@ class Connection implements ClientConnection {
|
||||
// If not defined, on reconnect with timeout, will retry automatically.
|
||||
retry?: () => Promise<boolean>
|
||||
}): Promise<any> {
|
||||
if (this.closed) {
|
||||
throw new PlatformError(unknownError('connection closed'))
|
||||
}
|
||||
const id = this.lastId++
|
||||
const promise = new RequestPromise()
|
||||
const promise = new RequestPromise(data.method, data.params)
|
||||
|
||||
const sendData = async (): Promise<void> => {
|
||||
if (this.websocket instanceof Promise) {
|
||||
|
@ -34,10 +34,8 @@ import { FilterQuery } from '@hcengineering/view-resources'
|
||||
import { get, writable } from 'svelte/store'
|
||||
import contact from './plugin'
|
||||
|
||||
const client = getClient()
|
||||
|
||||
export async function getChannelProviders (): Promise<Map<Ref<ChannelProvider>, ChannelProvider>> {
|
||||
const cp = await client.findAll(contact.class.ChannelProvider, {})
|
||||
const cp = await getClient().findAll(contact.class.ChannelProvider, {})
|
||||
const map = new Map<Ref<ChannelProvider>, ChannelProvider>()
|
||||
for (const provider of cp) {
|
||||
map.set(provider._id, provider)
|
||||
|
@ -39,6 +39,8 @@ export const genRanks = (count: number): Generator<string, void, unknown> =>
|
||||
export const calcRank = (prev?: { rank: string }, next?: { rank: string }): string => {
|
||||
const a = prev?.rank !== undefined ? LexoRank.parse(prev.rank) : LexoRank.min()
|
||||
const b = next?.rank !== undefined ? LexoRank.parse(next.rank) : LexoRank.max()
|
||||
|
||||
if (a.equals(b)) {
|
||||
return a.genNext().toString()
|
||||
}
|
||||
return a.between(b).toString()
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
<svg
|
||||
class="svg-{size}"
|
||||
{fill}
|
||||
id={category._id}
|
||||
style:transform={category._id === tracker.issueStatusCategory.Started ? 'rotate(-90deg)' : ''}
|
||||
viewBox="0 0 14 14"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -4,7 +4,7 @@
|
||||
import { Issue, IssueStatus } from '@hcengineering/tracker'
|
||||
import { Label, ticker } from '@hcengineering/ui'
|
||||
import tracker from '../../plugin'
|
||||
import { statusByIdStore } from '../../utils'
|
||||
import { statusStore } from '../../utils'
|
||||
import Duration from './Duration.svelte'
|
||||
import StatusPresenter from './StatusPresenter.svelte'
|
||||
|
||||
@ -83,7 +83,7 @@
|
||||
displaySt = result
|
||||
}
|
||||
|
||||
$: updateStatus(txes, $statusByIdStore, $ticker)
|
||||
$: updateStatus(txes, $statusStore.byId, $ticker)
|
||||
</script>
|
||||
|
||||
<div class="flex-row mt-4 mb-4">
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
$: if (value.category === tracker.issueStatusCategory.Started) {
|
||||
const _s = [
|
||||
...$statusStore.filter(
|
||||
...$statusStore.statuses.filter(
|
||||
(it) => it.attachedTo === value.attachedTo && it.category === tracker.issueStatusCategory.Started
|
||||
)
|
||||
]
|
||||
|
@ -65,7 +65,7 @@
|
||||
)
|
||||
}
|
||||
|
||||
$: statuses = $statusStore.filter((it) => it.attachedTo === value?.space)
|
||||
$: statuses = $statusStore.statuses.filter((it) => it.attachedTo === value?.space)
|
||||
|
||||
$: selectedStatus = statuses?.find((status) => status._id === value.status) ?? statuses?.[0]
|
||||
$: selectedStatusLabel = shouldShowLabel ? selectedStatus?.name : undefined
|
||||
|
@ -14,7 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { IssueStatus } from '@hcengineering/tracker'
|
||||
import { statusByIdStore } from '../../utils'
|
||||
import { statusStore } from '../../utils'
|
||||
import IssueStatusIcon from './IssueStatusIcon.svelte'
|
||||
|
||||
export let value: IssueStatus | undefined
|
||||
@ -22,7 +22,7 @@
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
{@const icon = $statusByIdStore.get(value._id)?.$lookup?.category?.icon}
|
||||
{@const icon = $statusStore.byId.get(value._id)?.$lookup?.category?.icon}
|
||||
<div class="flex-presenter">
|
||||
{#if icon}
|
||||
<IssueStatusIcon {value} {size} />
|
||||
|
@ -15,7 +15,7 @@
|
||||
<script lang="ts">
|
||||
import { Ref } from '@hcengineering/core'
|
||||
import { IssueStatus } from '@hcengineering/tracker'
|
||||
import { statusByIdStore } from '../../utils'
|
||||
import { statusStore } from '../../utils'
|
||||
import StatusPresenter from './StatusPresenter.svelte'
|
||||
|
||||
export let value: Ref<IssueStatus> | undefined
|
||||
@ -23,5 +23,5 @@
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
<StatusPresenter value={$statusByIdStore.get(value)} {size} />
|
||||
<StatusPresenter value={$statusStore.byId.get(value)} {size} />
|
||||
{/if}
|
||||
|
@ -26,16 +26,16 @@
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
<DocNavLink object={value} {onClick} component={tracker.component.EditIssue} inline shrink={1}>
|
||||
<span
|
||||
class="name overflow-label select-text"
|
||||
class:with-margin={shouldUseMargin}
|
||||
style:max-width={showParent ? `${value.parents.length !== 0 ? 95 : 100}%` : '100%'}
|
||||
title={value.title}
|
||||
>
|
||||
<span
|
||||
class="name overflow-label select-text"
|
||||
class:with-margin={shouldUseMargin}
|
||||
style:max-width={showParent ? `${value.parents.length !== 0 ? 95 : 100}%` : '100%'}
|
||||
title={value.title}
|
||||
>
|
||||
<DocNavLink object={value} {onClick} component={tracker.component.EditIssue} inline shrink={1}>
|
||||
{value.title}
|
||||
</span>
|
||||
</DocNavLink>
|
||||
</DocNavLink>
|
||||
</span>
|
||||
{#if showParent}
|
||||
<ParentNamesPresenter {value} />
|
||||
{/if}
|
||||
|
@ -29,7 +29,7 @@
|
||||
} from '@hcengineering/ui'
|
||||
import { getIssueId } from '../../../issues'
|
||||
import tracker from '../../../plugin'
|
||||
import { statusByIdStore, statusStore, subIssueListProvider } from '../../../utils'
|
||||
import { statusStore, subIssueListProvider } from '../../../utils'
|
||||
|
||||
export let value: WithLookup<Issue>
|
||||
export let currentProject: Project | undefined = undefined
|
||||
@ -77,7 +77,7 @@
|
||||
}
|
||||
|
||||
$: if (subIssues) {
|
||||
const doneStatuses = $statusStore
|
||||
const doneStatuses = $statusStore.statuses
|
||||
.filter((s) => s.category === tracker.issueStatusCategory.Completed)
|
||||
.map((p) => p._id)
|
||||
countComplete = subIssues.filter((si) => doneStatuses.includes(si.status)).length
|
||||
@ -115,7 +115,7 @@
|
||||
id: iss._id,
|
||||
text,
|
||||
isSelected: iss._id === value._id,
|
||||
...getIssueStatusIcon(iss, $statusByIdStore)
|
||||
...getIssueStatusIcon(iss, $statusStore.byId)
|
||||
}
|
||||
}),
|
||||
width: 'large'
|
||||
|
@ -29,7 +29,7 @@
|
||||
} from '@hcengineering/ui'
|
||||
import { getIssueId } from '../../../issues'
|
||||
import tracker from '../../../plugin'
|
||||
import { statusByIdStore, statusStore, subIssueListProvider } from '../../../utils'
|
||||
import { statusStore, subIssueListProvider } from '../../../utils'
|
||||
|
||||
export let object: WithLookup<Doc & { related: number }> | undefined
|
||||
export let value: WithLookup<Doc & { related: number }> | undefined
|
||||
@ -69,7 +69,7 @@
|
||||
}
|
||||
|
||||
$: if (subIssues) {
|
||||
const doneStatuses = $statusStore
|
||||
const doneStatuses = $statusStore.statuses
|
||||
.filter((s) => s.category === tracker.issueStatusCategory.Completed)
|
||||
.map((p) => p._id)
|
||||
countComplete = subIssues.filter((si) => doneStatuses.includes(si.status)).length
|
||||
@ -101,7 +101,7 @@
|
||||
value: subIssues.map((iss) => {
|
||||
const text = currentProject ? `${getIssueId(currentProject, iss)} ${iss.title}` : iss.title
|
||||
|
||||
return { id: iss._id, text, isSelected: false, ...getIssueStatusIcon(iss, $statusByIdStore) }
|
||||
return { id: iss._id, text, isSelected: false, ...getIssueStatusIcon(iss, $statusStore.byId) }
|
||||
}),
|
||||
width: 'large'
|
||||
},
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { Issue } from '@hcengineering/tracker'
|
||||
import { floorFractionDigits, Label } from '@hcengineering/ui'
|
||||
import tracker from '../../plugin'
|
||||
import { statusByIdStore } from '../../utils'
|
||||
import { statusStore } from '../../utils'
|
||||
import EstimationProgressCircle from '../issues/timereport/EstimationProgressCircle.svelte'
|
||||
import TimePresenter from '../issues/timereport/TimePresenter.svelte'
|
||||
export let docs: Issue[] | undefined = undefined
|
||||
@ -28,13 +28,13 @@
|
||||
$: noParents = docs?.filter((it) => !ids.has(it.attachedTo as Ref<Issue>))
|
||||
|
||||
$: rootNoBacklogIssues = noParents?.filter(
|
||||
(it) => $statusByIdStore.get(it.status)?.category !== tracker.issueStatusCategory.Backlog
|
||||
(it) => $statusStore.byId.get(it.status)?.category !== tracker.issueStatusCategory.Backlog
|
||||
)
|
||||
|
||||
$: totalEstimation = floorFractionDigits(
|
||||
(rootNoBacklogIssues ?? [{ estimation: 0, childInfo: [] } as unknown as Issue])
|
||||
.map((it) => {
|
||||
const cat = $statusByIdStore.get(it.status)?.category
|
||||
const cat = $statusStore.byId.get(it.status)?.category
|
||||
|
||||
let retEst = it.estimation
|
||||
if (it.childInfo?.length > 0) {
|
||||
|
@ -66,10 +66,10 @@
|
||||
}
|
||||
|
||||
async function addStatus () {
|
||||
if (editingStatus?.name && editingStatus?.category && $statusStore) {
|
||||
const categoryStatuses = $statusStore.filter((s) => s.category === editingStatus!.category)
|
||||
if (editingStatus?.name && editingStatus?.category) {
|
||||
const categoryStatuses = $statusStore.statuses.filter((s) => s.category === editingStatus!.category)
|
||||
const prevStatus = categoryStatuses[categoryStatuses.length - 1]
|
||||
const nextStatus = $statusStore[$statusStore.findIndex(({ _id }) => _id === prevStatus._id) + 1]
|
||||
const nextStatus = $statusStore.statuses[$statusStore.statuses.findIndex(({ _id }) => _id === prevStatus._id) + 1]
|
||||
|
||||
isSaving = true
|
||||
await client.addCollection(
|
||||
@ -93,9 +93,9 @@
|
||||
}
|
||||
|
||||
async function editStatus () {
|
||||
if ($statusStore && statusCategories && editingStatus?.name && editingStatus?.category && '_id' in editingStatus) {
|
||||
if (statusCategories && editingStatus?.name && editingStatus?.category && '_id' in editingStatus) {
|
||||
const statusId = '_id' in editingStatus ? editingStatus._id : undefined
|
||||
const status = statusId && $statusStore.find(({ _id }) => _id === statusId)
|
||||
const status = statusId && $statusStore.byId.get(statusId)
|
||||
|
||||
if (!status) {
|
||||
return
|
||||
@ -157,12 +157,14 @@
|
||||
},
|
||||
undefined,
|
||||
async (result) => {
|
||||
if (result && project && $statusStore) {
|
||||
if (result && project) {
|
||||
isSaving = true
|
||||
await client.removeDoc(status._class, status.space, status._id)
|
||||
|
||||
if (project.defaultIssueStatus === status._id) {
|
||||
const newDefaultStatus = $statusStore.find((s) => s._id !== status._id && s.category === status.category)
|
||||
const newDefaultStatus = $statusStore.statuses.find(
|
||||
(s) => s._id !== status._id && s.category === status.category && s.space === status.space
|
||||
)
|
||||
if (newDefaultStatus?._id) {
|
||||
await updateProjectDefaultStatus(newDefaultStatus._id)
|
||||
}
|
||||
@ -196,12 +198,12 @@
|
||||
}
|
||||
|
||||
async function handleDrop (toItem: IssueStatus) {
|
||||
if ($statusStore && draggingStatus?._id !== toItem._id && draggingStatus?.category === toItem.category) {
|
||||
if (draggingStatus?._id !== toItem._id && draggingStatus?.category === toItem.category) {
|
||||
const fromIndex = getStatusIndex(draggingStatus)
|
||||
const toIndex = getStatusIndex(toItem)
|
||||
const [prev, next] = [
|
||||
$statusStore[fromIndex < toIndex ? toIndex : toIndex - 1],
|
||||
$statusStore[fromIndex < toIndex ? toIndex + 1 : toIndex]
|
||||
$statusStore.statuses[fromIndex < toIndex ? toIndex : toIndex - 1],
|
||||
$statusStore.statuses[fromIndex < toIndex ? toIndex + 1 : toIndex]
|
||||
]
|
||||
|
||||
isSaving = true
|
||||
@ -213,7 +215,7 @@
|
||||
}
|
||||
|
||||
function getStatusIndex (status: IssueStatus) {
|
||||
return $statusStore?.findIndex(({ _id }) => _id === status._id) ?? -1
|
||||
return $statusStore.statuses.findIndex(({ _id }) => _id === status._id) ?? -1
|
||||
}
|
||||
|
||||
function resetDrag () {
|
||||
@ -242,14 +244,14 @@
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
{#if project === undefined || statusCategories === undefined || $statusStore === undefined}
|
||||
{#if project === undefined || statusCategories === undefined || $statusStore.statuses.length === 0}
|
||||
<Loading />
|
||||
{:else}
|
||||
<Scroller>
|
||||
<div class="popupPanel-body__main-content py-10 clear-mins">
|
||||
{#each statusCategories as category}
|
||||
{@const statuses =
|
||||
$statusStore?.filter((s) => s.attachedTo === projectId && s.category === category._id) ?? []}
|
||||
$statusStore.statuses.filter((s) => s.attachedTo === projectId && s.category === category._id) ?? []}
|
||||
{@const isSingle = statuses.length === 1}
|
||||
<div class="flex-between category-name">
|
||||
<Label label={category.label} />
|
||||
|
@ -677,16 +677,27 @@ export async function removeProject (project: Project): Promise<void> {
|
||||
await client.removeDoc(tracker.class.Project, core.space.Space, project._id)
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface StatusStore {
|
||||
statuses: Array<WithLookup<IssueStatus>>
|
||||
byId: IdMap<WithLookup<IssueStatus>>
|
||||
version: number
|
||||
}
|
||||
// Issue status live query
|
||||
export const statusByIdStore = writable<IdMap<WithLookup<IssueStatus>>>(new Map())
|
||||
export const statusStore = writable<Array<WithLookup<IssueStatus>>>([])
|
||||
export const statusStore = writable<StatusStore>({ statuses: [], byId: new Map(), version: 0 })
|
||||
|
||||
const query = createQuery(true)
|
||||
query.query(
|
||||
tracker.class.IssueStatus,
|
||||
{},
|
||||
(res) => {
|
||||
statusStore.set(res)
|
||||
statusByIdStore.set(toIdMap(res))
|
||||
statusStore.update((old) => ({
|
||||
version: old.version + 1,
|
||||
statuses: res,
|
||||
byId: toIdMap(res)
|
||||
}))
|
||||
},
|
||||
{
|
||||
lookup: {
|
||||
|
@ -39,6 +39,8 @@ export const genRanks = (count: number): Generator<string, void, unknown> =>
|
||||
export const calcRank = (prev?: { rank: string }, next?: { rank: string }): string => {
|
||||
const a = prev?.rank !== undefined ? LexoRank.parse(prev.rank) : LexoRank.min()
|
||||
const b = next?.rank !== undefined ? LexoRank.parse(next.rank) : LexoRank.max()
|
||||
|
||||
if (a.equals(b)) {
|
||||
return a.genNext().toString()
|
||||
}
|
||||
return a.between(b).toString()
|
||||
}
|
||||
|
@ -39,6 +39,8 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
}
|
||||
_token = token
|
||||
|
||||
let clientSet = false
|
||||
|
||||
const clientFactory = await getResource(client.function.GetClient)
|
||||
_client = await clientFactory(
|
||||
token,
|
||||
@ -54,7 +56,15 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
})
|
||||
},
|
||||
// We need to refresh all active live queries and clear old queries.
|
||||
refreshClient
|
||||
() => {
|
||||
try {
|
||||
if (clientSet) {
|
||||
refreshClient()
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
)
|
||||
console.log('logging in as', email)
|
||||
|
||||
@ -72,6 +82,7 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
|
||||
// Update on connect, so it will be triggered
|
||||
setClient(_client)
|
||||
clientSet = true
|
||||
return
|
||||
}
|
||||
|
||||
@ -105,6 +116,7 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
|
||||
return _client
|
||||
}
|
||||
|
||||
function clearMetadata (ws: string): void {
|
||||
const tokens = fetchMetadataLocalStorage(login.metadata.LoginTokens)
|
||||
if (tokens !== null) {
|
||||
|
@ -16,8 +16,8 @@
|
||||
"dev-uitest": "cross-env PLATFORM_URI=http://localhost:8080 PLATFORM_TRANSACTOR=ws://localhost:3333 SETTING=storage-dev.json playwright test --browser chromium --reporter list,html -c ./tests/playwright.config.ts",
|
||||
"debug": "playwright test --browser chromium -c ./tests/playwright.config.ts --debug --headed",
|
||||
"dev-debug": "cross-env PLATFORM_URI=http://localhost:8080 PLATFORM_TRANSACTOR=ws://localhost:3333 SETTING=storage-dev.json playwright test --browser chromium -c ./tests/playwright.config.ts --debug --headed",
|
||||
"codegen": "playwright codegen --load-storage storage.json http://localhost:8083/workbench",
|
||||
"dev-codegen": "cross-env playwright codegen --load-storage storage-dev.json http://localhost:8080/workbench"
|
||||
"codegen": "playwright codegen --load-storage storage.json http://localhost:8083/workbench/sanity-ws/",
|
||||
"dev-codegen": "cross-env playwright codegen --load-storage storage-dev.json http://localhost:8080/workbench/sanity-ws/"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hcengineering/platform-rig": "^0.6.0",
|
||||
|
@ -205,9 +205,7 @@ test('create-issue-draft', async ({ page }) => {
|
||||
|
||||
// Click text=Issues >> nth=1
|
||||
await page.locator('text=Issues').nth(1).click()
|
||||
await expect(page).toHaveURL(
|
||||
'http://localhost:8083/workbench/sanity-ws/tracker/tracker%3Aproject%3ADefaultProject/issues'
|
||||
)
|
||||
await expect(page).toHaveURL(/.*\/workbench\/sanity-ws\/tracker\/tracker%3Aproject%3ADefaultProject\/issues/)
|
||||
await expect(page.locator('#new-issue')).toHaveText('New issue')
|
||||
// Click button:has-text("New issue")
|
||||
await page.locator('#new-issue').click()
|
||||
|
Loading…
Reference in New Issue
Block a user