UBERF-9032: Fix proper query initializers (#7563)
Some checks are pending
CI / build (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / docker-build (push) Blocked by required conditions
CI / dist-build (push) Blocked by required conditions

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2024-12-26 22:01:24 +07:00 committed by GitHub
parent 2d64f89584
commit 4214ace603
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 186 additions and 245 deletions

View File

@ -21,6 +21,7 @@ import core, {
TxProcessor,
getCurrentAccount,
reduceCalls,
type Account,
type AnyAttribute,
type ArrOf,
type AttachedDoc,
@ -253,6 +254,18 @@ export function getClient (): TxOperations & Client {
return clientProxy
}
export type OnClientListener = (client: Client, account: Account) => void
const onClientListeners: OnClientListener[] = []
export function onClient (l: OnClientListener): void {
onClientListeners.push(l)
if (client !== undefined) {
setTimeout(() => {
l(client, getCurrentAccount())
})
}
}
let txQueue: Tx[] = []
export type RefreshListener = () => void
@ -306,6 +319,10 @@ export async function setClient (_client: Client): Promise<void> {
if (needRefresh || globalQueries.length > 0) {
await refreshClient(true)
}
const acc = getCurrentAccount()
onClientListeners.forEach((l) => {
l(_client, acc)
})
}
/**
* @public

View File

@ -14,31 +14,21 @@
//
import activity, { type ActivityMessage, type SavedMessage } from '@hcengineering/activity'
import core, { type Ref, SortingOrder, type WithLookup } from '@hcengineering/core'
import { createQuery, onClient } from '@hcengineering/presentation'
import { writable } from 'svelte/store'
import { createQuery, getClient } from '@hcengineering/presentation'
export const savedMessagesStore = writable<Array<WithLookup<SavedMessage>>>([])
export const messageInFocus = writable<Ref<ActivityMessage> | undefined>(undefined)
const savedMessagesQuery = createQuery(true)
export function loadSavedMessages (): void {
const client = getClient()
if (client !== undefined) {
savedMessagesQuery.query(
activity.class.SavedMessage,
{ space: core.space.Workspace },
(res) => {
savedMessagesStore.set(res.filter(({ $lookup }) => $lookup?.attachedTo !== undefined))
},
{ lookup: { attachedTo: activity.class.ActivityMessage }, sort: { modifiedOn: SortingOrder.Descending } }
)
} else {
setTimeout(() => {
loadSavedMessages()
}, 50)
}
}
loadSavedMessages()
onClient(() => {
savedMessagesQuery.query(
activity.class.SavedMessage,
{ space: core.space.Workspace },
(res) => {
savedMessagesStore.set(res.filter(({ $lookup }) => $lookup?.attachedTo !== undefined))
},
{ lookup: { attachedTo: activity.class.ActivityMessage }, sort: { modifiedOn: SortingOrder.Descending } }
)
})

View File

@ -5,12 +5,12 @@ import {
type ReccuringInstance,
generateEventId
} from '@hcengineering/calendar'
import { type IdMap, type Timestamp, getCurrentAccount, toIdMap, type DocumentUpdate } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { showPopup, closePopup, DAY } from '@hcengineering/ui'
import { type DocumentUpdate, type IdMap, type Timestamp, getCurrentAccount, toIdMap } from '@hcengineering/core'
import { createQuery, getClient, onClient } from '@hcengineering/presentation'
import { closePopup, DAY, showPopup } from '@hcengineering/ui'
import { writable } from 'svelte/store'
import calendar from './plugin'
import UpdateRecInstancePopup from './components/UpdateRecInstancePopup.svelte'
import calendar from './plugin'
export function saveUTC (date: Timestamp): Timestamp {
const utcdate = new Date(date)
@ -74,24 +74,14 @@ export const calendarByIdStore = writable<IdMap<Calendar>>(new Map())
export const calendarStore = writable<Calendar[]>([])
export const visibleCalendarStore = writable<Calendar[]>([])
function fillStores (): void {
const client = getClient()
if (client !== undefined) {
const query = createQuery(true)
query.query(calendar.class.Calendar, {}, (res) => {
calendarStore.set(res)
visibleCalendarStore.set(res.filter((p) => !p.hidden))
calendarByIdStore.set(toIdMap(res))
})
} else {
setTimeout(() => {
fillStores()
}, 50)
}
}
fillStores()
const query = createQuery(true)
onClient((client, account) => {
query.query(calendar.class.Calendar, {}, (res) => {
calendarStore.set(res)
visibleCalendarStore.set(res.filter((p) => !p.hidden))
calendarByIdStore.set(toIdMap(res))
})
})
export async function updatePast (ops: DocumentUpdate<Event>, object: ReccuringInstance): Promise<void> {
const client = getClient()

View File

@ -28,7 +28,7 @@ import core, {
} from '@hcengineering/core'
import notification, { type DocNotifyContext } from '@hcengineering/notification'
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
import { createQuery, getClient, MessageBox } from '@hcengineering/presentation'
import { createQuery, getClient, MessageBox, onClient } from '@hcengineering/presentation'
import { type Action, showPopup } from '@hcengineering/ui'
import view from '@hcengineering/view'
import workbench, { type SpecialNavModel } from '@hcengineering/workbench'
@ -364,12 +364,9 @@ function archiveActivityChannels (contexts: DocNotifyContext[]): void {
)
}
const savedAttachmentsQuery = createQuery(true)
export function loadSavedAttachments (): void {
const client = getClient()
if (client !== undefined) {
const savedAttachmentsQuery = createQuery(true)
onClient(() => {
savedAttachmentsQuery.query(
attachment.class.SavedAttachments,
{ space: core.space.Workspace },
@ -378,11 +375,7 @@ export function loadSavedAttachments (): void {
},
{ lookup: { attachedTo: attachment.class.Attachment }, sort: { modifiedOn: SortingOrder.Descending } }
)
} else {
setTimeout(() => {
loadSavedAttachments()
}, 50)
}
})
}
export async function hideActivityChannels (contexts: DocNotifyContext[]): Promise<void> {

View File

@ -52,7 +52,7 @@ import core, {
} from '@hcengineering/core'
import notification, { type DocNotifyContext, type InboxNotification } from '@hcengineering/notification'
import { type IntlString, getEmbeddedLabel, getResource, translate } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, getClient, onClient } from '@hcengineering/presentation'
import { type TemplateDataProvider } from '@hcengineering/templates'
import {
getCurrentResolvedLocation,
@ -323,42 +323,32 @@ export const personByIdStore = derived([personAccountPersonByIdStore, employeeBy
return new Map([...m1, ...m2])
})
function fillStores (): void {
const client = getClient()
const query = createQuery(true)
const accountQ = createQuery(true)
const accountPersonQuery = createQuery(true)
const providerQuery = createQuery(true)
if (client !== undefined) {
const accountPersonQuery = createQuery(true)
onClient(() => {
query.query(contact.mixin.Employee, { active: { $in: [true, false] } }, (res) => {
employeesStore.set(res)
employeeByIdStore.set(toIdMap(res))
})
const query = createQuery(true)
query.query(contact.mixin.Employee, { active: { $in: [true, false] } }, (res) => {
employeesStore.set(res)
employeeByIdStore.set(toIdMap(res))
accountQ.query(contact.class.PersonAccount, {}, (res) => {
personAccountByIdStore.set(toIdMap(res))
const persons = res.map((it) => it.person)
accountPersonQuery.query<Person>(contact.class.Person, { _id: { $in: persons } }, (res) => {
const personIn = toIdMap(res)
personAccountPersonByIdStore.set(personIn)
})
})
const accountQ = createQuery(true)
accountQ.query(contact.class.PersonAccount, {}, (res) => {
personAccountByIdStore.set(toIdMap(res))
const persons = res.map((it) => it.person)
accountPersonQuery.query<Person>(contact.class.Person, { _id: { $in: persons } }, (res) => {
const personIn = toIdMap(res)
personAccountPersonByIdStore.set(personIn)
})
})
const providerQuery = createQuery(true)
providerQuery.query(contact.class.ChannelProvider, {}, (res) => {
channelProviders.set(res)
})
} else {
setTimeout(() => {
fillStores()
}, 50)
}
}
fillStores()
providerQuery.query(contact.class.ChannelProvider, {}, (res) => {
channelProviders.set(res)
})
})
const userStatusesQuery = createQuery(true)

View File

@ -11,7 +11,7 @@ import {
type Room,
type MeetingMinutes
} from '@hcengineering/love'
import { createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, onClient } from '@hcengineering/presentation'
import { derived, get, writable } from 'svelte/store'
import { personIdByAccountId } from '@hcengineering/contact-resources'
import aiBot from '@hcengineering/ai-bot'
@ -79,77 +79,69 @@ function filterParticipantInfo (value: ParticipantInfo[]): ParticipantInfo[] {
export const storePromise = writable<Promise<void>>(new Promise((resolve) => {}))
function fillStores (): void {
const client = getClient()
if (client !== undefined || getCurrentAccount() != null) {
const query = createQuery(true)
const roomPromise = new Promise<void>((resolve) =>
query.query(love.class.Room, {}, (res) => {
rooms.set(res)
resolve()
})
)
const statusQuery = createQuery(true)
const infoPromise = new Promise<void>((resolve) =>
statusQuery.query(love.class.ParticipantInfo, {}, (res) => {
infos.set(filterParticipantInfo(res))
resolve()
})
)
const floorsQuery = createQuery(true)
const floorPromise = new Promise<void>((resolve) =>
floorsQuery.query(love.class.Floor, {}, (res) => {
floors.set(res)
resolve()
})
)
const requestsQuery = createQuery(true)
const requestPromise = new Promise<void>((resolve) =>
requestsQuery.query(
love.class.JoinRequest,
{ person: (getCurrentAccount() as PersonAccount).person, status: RequestStatus.Pending },
(res) => {
myRequests.set(res)
resolve()
}
)
)
const preferencesQuery = createQuery(true)
const preferencePromise = new Promise<void>((resolve) =>
preferencesQuery.query(love.class.DevicesPreference, {}, (res) => {
myPreferences.set(res[0])
$myPreferences = res[0]
resolve()
})
)
const invitesQuery = createQuery(true)
const invitesPromise = new Promise<void>((resolve) =>
invitesQuery.query(love.class.Invite, { status: RequestStatus.Pending }, (res) => {
invites.set(res)
resolve()
})
)
storePromise.set(
new Promise((resolve) => {
void Promise.all([
roomPromise,
infoPromise,
floorPromise,
requestPromise,
preferencePromise,
invitesPromise
]).then(() => {
resolve()
})
})
)
} else {
setTimeout(() => {
fillStores()
}, 50)
}
}
const query = createQuery(true)
const statusQuery = createQuery(true)
const floorsQuery = createQuery(true)
const requestsQuery = createQuery(true)
const preferencesQuery = createQuery(true)
const invitesQuery = createQuery(true)
fillStores()
onClient(() => {
const roomPromise = new Promise<void>((resolve) =>
query.query(love.class.Room, {}, (res) => {
rooms.set(res)
resolve()
})
)
const infoPromise = new Promise<void>((resolve) =>
statusQuery.query(love.class.ParticipantInfo, {}, (res) => {
infos.set(filterParticipantInfo(res))
resolve()
})
)
const floorPromise = new Promise<void>((resolve) =>
floorsQuery.query(love.class.Floor, {}, (res) => {
floors.set(res)
resolve()
})
)
const requestPromise = new Promise<void>((resolve) =>
requestsQuery.query(
love.class.JoinRequest,
{ person: (getCurrentAccount() as PersonAccount).person, status: RequestStatus.Pending },
(res) => {
myRequests.set(res)
resolve()
}
)
)
const preferencePromise = new Promise<void>((resolve) =>
preferencesQuery.query(love.class.DevicesPreference, {}, (res) => {
myPreferences.set(res[0])
$myPreferences = res[0]
resolve()
})
)
const invitesPromise = new Promise<void>((resolve) =>
invitesQuery.query(love.class.Invite, { status: RequestStatus.Pending }, (res) => {
invites.set(res)
resolve()
})
)
storePromise.set(
new Promise((resolve) => {
void Promise.all([
roomPromise,
infoPromise,
floorPromise,
requestPromise,
preferencePromise,
invitesPromise
]).then(() => {
resolve()
})
})
)
})
export const lockedRoom = writable<string>('')

View File

@ -14,8 +14,10 @@
// limitations under the License.
//
import activity from '@hcengineering/activity'
import chunter from '@hcengineering/chunter'
import { type Employee, type PersonAccount } from '@hcengineering/contact'
import core, {
getCurrentAccount,
toIdMap,
type Attribute,
type Class,
@ -27,7 +29,7 @@ import core, {
type TxOperations
} from '@hcengineering/core'
import { type IntlString, type Resources } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, getClient, onClient } from '@hcengineering/presentation'
import task, {
getStatusIndex,
makeRank,
@ -41,9 +43,6 @@ import { getCurrentLocation, navigate, showPopup } from '@hcengineering/ui'
import { type ViewletDescriptor } from '@hcengineering/view'
import { CategoryQuery, groupBy, statusStore } from '@hcengineering/view-resources'
import { get, writable } from 'svelte/store'
import { type Employee, type PersonAccount } from '@hcengineering/contact'
import activity from '@hcengineering/activity'
import chunter from '@hcengineering/chunter'
import AssignedTasks from './components/AssignedTasks.svelte'
import Dashboard from './components/Dashboard.svelte'
@ -69,14 +68,14 @@ import TaskKindSelector from './components/taskTypes/TaskKindSelector.svelte'
import TaskTypeClassPresenter from './components/taskTypes/TaskTypeClassPresenter.svelte'
import TaskTypePresenter from './components/taskTypes/TaskTypePresenter.svelte'
import ProjectTypeSelector from './components/projectTypes/ProjectTypeSelector.svelte'
import { employeeByIdStore, personAccountByIdStore, personByIdStore } from '@hcengineering/contact-resources'
import CreateProjectType from './components/projectTypes/CreateProjectType.svelte'
import ProjectTypeGeneralSectionEditor from './components/projectTypes/ProjectTypeGeneralSectionEditor.svelte'
import ProjectTypeTasksTypeSectionEditor from './components/projectTypes/ProjectTypeTasksTypeSectionEditor.svelte'
import ProjectTypeAutomationsSectionEditor from './components/projectTypes/ProjectTypeAutomationsSectionEditor.svelte'
import ProjectTypeCollectionsSectionEditor from './components/projectTypes/ProjectTypeCollectionsSectionEditor.svelte'
import ProjectTypeGeneralSectionEditor from './components/projectTypes/ProjectTypeGeneralSectionEditor.svelte'
import ProjectTypeSelector from './components/projectTypes/ProjectTypeSelector.svelte'
import ProjectTypeTasksTypeSectionEditor from './components/projectTypes/ProjectTypeTasksTypeSectionEditor.svelte'
import TaskTypeEditor from './components/taskTypes/TaskTypeEditor.svelte'
import { employeeByIdStore, personAccountByIdStore, personByIdStore } from '@hcengineering/contact-resources'
export { default as AssigneePresenter } from './components/AssigneePresenter.svelte'
export { default as TypeSelector } from './components/TypeSelector.svelte'
@ -364,33 +363,24 @@ export const taskTypeStore = writable<IdMap<TaskType>>(new Map())
export const typesOfJoinedProjectsStore = writable<Array<Ref<ProjectType>>>()
export const joinedProjectsStore = writable<Project[]>()
function fillStores (): void {
const client = getClient()
const query = createQuery(true)
const taskQuery = createQuery(true)
const projectQuery = createQuery(true)
if (client !== undefined && getCurrentAccount() != null) {
const query = createQuery(true)
query.query(task.class.ProjectType, {}, (res) => {
typeStore.set(toIdMap(res))
})
onClient((client, user) => {
query.query(task.class.ProjectType, {}, (res) => {
typeStore.set(toIdMap(res))
})
const taskQuery = createQuery(true)
taskQuery.query(task.class.TaskType, {}, (res) => {
taskTypeStore.set(toIdMap(res))
})
taskQuery.query(task.class.TaskType, {}, (res) => {
taskTypeStore.set(toIdMap(res))
})
const projectQuery = createQuery(true)
projectQuery.query(task.class.Project, { members: getCurrentAccount()._id }, (res) => {
typesOfJoinedProjectsStore.set(res.map((r) => r.type).filter((it, idx, arr) => arr.indexOf(it) === idx))
joinedProjectsStore.set(res)
})
} else {
setTimeout(() => {
fillStores()
}, 50)
}
}
fillStores()
projectQuery.query(task.class.Project, { members: user._id }, (res) => {
typesOfJoinedProjectsStore.set(res.map((r) => r.type).filter((it, idx, arr) => arr.indexOf(it) === idx))
joinedProjectsStore.set(res)
})
})
export const selectedTypeStore = writable<Ref<ProjectType> | undefined>(undefined)
export const selectedTaskTypeStore = writable<Ref<TaskType> | undefined>(undefined)

View File

@ -36,7 +36,7 @@ import core, {
type TxUpdateDoc
} from '@hcengineering/core'
import { type IntlString } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, getClient, onClient } from '@hcengineering/presentation'
import task, { getStatusIndex, makeRank, type ProjectType } from '@hcengineering/task'
import { activeProjects as taskActiveProjects, taskTypeStore } from '@hcengineering/task-resources'
import {
@ -577,36 +577,25 @@ export interface IssueRef {
export type IssueReverseRevMap = Map<Ref<Doc>, IssueRef[]>
export const relatedIssues = writable<IssueReverseRevMap>(new Map())
function fillStores (): void {
const client = getClient()
if (client !== undefined) {
const relatedIssuesQuery = createQuery(true)
relatedIssuesQuery.query(
tracker.class.Issue,
{ 'relations._id': { $exists: true } },
(res) => {
const nMap: IssueReverseRevMap = new Map()
for (const r of res) {
for (const rr of r.relations ?? []) {
nMap.set(rr._id, [...(nMap.get(rr._id) ?? []), { _id: r._id, status: r.status }])
}
}
relatedIssues.set(nMap)
},
{
projection: {
relations: 1,
status: 1
const relatedIssuesQuery = createQuery(true)
onClient(() => {
relatedIssuesQuery.query(
tracker.class.Issue,
{ 'relations._id': { $exists: true } },
(res) => {
const nMap: IssueReverseRevMap = new Map()
for (const r of res) {
for (const rr of r.relations ?? []) {
nMap.set(rr._id, [...(nMap.get(rr._id) ?? []), { _id: r._id, status: r.status }])
}
}
)
} else {
setTimeout(() => {
fillStores()
}, 50)
}
}
fillStores()
relatedIssues.set(nMap)
},
{
projection: {
relations: 1,
status: 1
}
}
)
})

View File

@ -14,7 +14,7 @@
//
import core, { type IdMap, type Status, toIdMap } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, onClient } from '@hcengineering/presentation'
import { writable } from 'svelte/store'
interface Store {
@ -28,23 +28,13 @@ export const statusStore = writable<Store>({
array: []
})
function fillStores (): void {
const client = getClient()
if (client !== undefined) {
const query = createQuery(true)
query.query(core.class.Status, {}, (res) => {
const obj = {
byId: toIdMap(res),
array: res
}
statusStore.set(obj)
})
} else {
setTimeout(() => {
fillStores()
}, 50)
}
}
fillStores()
const query = createQuery(true)
onClient(() => {
query.query(core.class.Status, {}, (res) => {
const obj = {
byId: toIdMap(res),
array: res
}
statusStore.set(obj)
})
})