- {getApplicationsList(data)}
+ {getApplicationsList(apps)}
{shortcuts &&
shortcuts.map((shortcut, index) => (
diff --git a/src/components/FooterLogo/FooterLogo.jsx b/src/components/FooterLogo/FooterLogo.jsx
index 938937d560..6df10ff2d2 100644
--- a/src/components/FooterLogo/FooterLogo.jsx
+++ b/src/components/FooterLogo/FooterLogo.jsx
@@ -1,6 +1,6 @@
import React from 'react'
import { useClient, useQuery } from 'cozy-client'
-import { buildContextQuery } from 'queries'
+import { makeContextQuery } from 'queries'
import Divider from 'cozy-ui/transpiled/react/Divider'
import { useCozyTheme } from 'cozy-ui/transpiled/react/providers/CozyTheme'
@@ -9,8 +9,10 @@ export const FooterLogo = () => {
const { type } = useCozyTheme()
const rootURL = client.getStackClient().uri
- const contextQuery = buildContextQuery()
- const { data } = useQuery(contextQuery.definition, contextQuery.options)
+ const { data } = useQuery(
+ makeContextQuery.definition,
+ makeContextQuery.options
+ )
const logos = data?.logos?.home?.light || []
const secondaries = logos.filter(logos => logos.type === 'secondary')
diff --git a/src/components/Home.jsx b/src/components/Home.jsx
index 9d77b1b04c..cdbba62565 100644
--- a/src/components/Home.jsx
+++ b/src/components/Home.jsx
@@ -18,7 +18,7 @@ import { Announcements } from 'components/Announcements/Announcements'
import styles from './styles.styl'
-const Home = ({ setAppsReady, wrapper }) => {
+const Home = ({ wrapper }) => {
const { pathname } = useLocation()
const { isMobile } = useBreakpoints()
@@ -38,7 +38,7 @@ const Home = ({ setAppsReady, wrapper }) => {
getFlagshipMetadata().immersive
})}
>
-
diff --git a/src/components/Sections/SectionView.tsx b/src/components/Sections/SectionView.tsx
index 5975b5eca3..ccb5fbd78a 100644
--- a/src/components/Sections/SectionView.tsx
+++ b/src/components/Sections/SectionView.tsx
@@ -1,6 +1,7 @@
import React, { useState, useRef } from 'react'
import cx from 'classnames'
+import { useQuery } from 'cozy-client'
import type { IOCozyKonnector } from 'cozy-client/types/types'
import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints'
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
@@ -17,6 +18,7 @@ import {
} from 'components/Sections/SectionsTypes'
import { useSections } from './SectionsContext'
import CandidateServiceTile from 'components/CandidateServiceTile'
+import { makeTriggersWithJobStatusQuery } from 'queries'
export const SectionBody = ({ section }: SectionViewProps): JSX.Element => {
const { isMobile } = useBreakpoints()
@@ -26,6 +28,13 @@ export const SectionBody = ({ section }: SectionViewProps): JSX.Element => {
const shouldOpenStoreModal = section.type === 'category' && section.pristine
const { isRunning, isInMaintenance } = useSections()
+ // This query is useful to fetch the triggers' current_state, used to display
+ // the konnector icon. The data is fetched from the store in KonnectorTile
+ useQuery(
+ makeTriggersWithJobStatusQuery.definition(),
+ makeTriggersWithJobStatusQuery.options
+ )
+
return (
{
+const App = () => {
const { isMobile } = useBreakpoints()
const [contentWrapper, setContentWrapper] = useState(undefined)
- const [isFetching, setIsFetching] = useState(
- [accounts, konnectors, triggers].some(collection =>
- ['pending', 'loading'].includes(collection.fetchStatus)
- )
- )
- const [hasError, setHasError] = useState(false)
- const [isReady, setIsReady] = useState(false)
- const [appsReady, setAppsReady] = useState(false)
+
+ const [didInit, setDidInit] = useState(false)
const webviewIntent = useWebviewIntent()
const theme = useCozyTheme()
@@ -93,48 +86,28 @@ const App = ({ accounts, konnectors, triggers }) => {
const shortcutsDirectories = canHaveShortcuts
? formatShortcuts(folders, customHomeShortcuts)
: null
- const context = useQuery(contextQuery.definition, contextQuery.options)
+
+ const { isFetching, hasError } = useFetchInitialData()
const showAssistantForMobile = isFlagshipApp()
? flag('cozy.searchbar.enabled-for-flagship')
: flag('cozy.searchbar.enabled') && isMobile
- useEffect(() => {
- setIsFetching(
- [accounts, konnectors, triggers, context].some(collection =>
- ['pending', 'loading'].includes(collection.fetchStatus)
- )
- )
- setHasError(
- [accounts, konnectors, triggers, context].find(
- collection => collection.fetchStatus === 'failed'
- )
- )
- }, [accounts, konnectors, triggers, context])
-
- if (context?.attributes?.features) {
- const flags = toFlagNames(context.attributes.features)
- enableFlags(flags)
- }
-
- useEffect(() => {
- setIsReady(
- appsReady &&
- !hasError &&
- !isFetching &&
- shortcutsDirectories !== undefined
- )
- }, [appsReady, hasError, isFetching, shortcutsDirectories])
-
- useEffect(() => {
- if (isReady && webviewIntent) {
+ if (
+ !didInit &&
+ !hasError &&
+ !isFetching &&
+ shortcutsDirectories !== undefined
+ ) {
+ if (webviewIntent) {
webviewIntent.call('setTheme', theme.variant)
webviewIntent.call('hideSplashScreen')
}
- if (isReady && !webviewIntent && __SIMULATE_FLAGSHIP__) {
+ if (!webviewIntent && __SIMULATE_FLAGSHIP__) {
document.getElementById('splashscreen').style.display = 'none'
}
- }, [isReady, theme, webviewIntent])
+ setDidInit(true)
+ }
return (
<>
@@ -145,7 +118,7 @@ const App = ({ accounts, konnectors, triggers }) => {
setContentWrapper(div) : null}
+ ref={didInit ? div => setContentWrapper(div) : null}
>
@@ -167,7 +140,6 @@ const App = ({ accounts, konnectors, triggers }) => {
element={
setAppsReady(true)}
shortcutsDirectories={shortcutsDirectories}
/>
}
@@ -206,4 +178,4 @@ const App = ({ accounts, konnectors, triggers }) => {
)
}
-export default appEntryPoint(App)
+export default App
diff --git a/src/containers/ReloadFocus.jsx b/src/containers/ReloadFocus.jsx
index ffc222ecb0..9011819148 100644
--- a/src/containers/ReloadFocus.jsx
+++ b/src/containers/ReloadFocus.jsx
@@ -1,7 +1,11 @@
import React from 'react'
import PropTypes from 'prop-types'
-
-import { withClient, Q } from 'cozy-client'
+import {
+ makeTriggersWithJobStatusQuery,
+ makeAppsQuery,
+ makeJobsQuery
+} from 'queries'
+import { withClient } from 'cozy-client'
class RealoadFocus extends React.Component {
static contextTypes = {
store: PropTypes.object
@@ -9,13 +13,12 @@ class RealoadFocus extends React.Component {
componentDidMount() {
const client = this.props.client
window.addEventListener('focus', () => {
- client.query(Q('io.cozy.jobs'))
+ client.query(makeJobsQuery.definition(), makeJobsQuery.options)
client.query(
- Q('io.cozy.triggers').where({
- worker: { $in: ['client', 'konnector'] }
- })
+ makeTriggersWithJobStatusQuery.definition(),
+ makeTriggersWithJobStatusQuery.options
)
- client.query(Q('io.cozy.apps'))
+ client.query(makeAppsQuery.definition(), makeAppsQuery.options)
})
}
diff --git a/src/dataproxy/DataProxyProvider.jsx b/src/dataproxy/DataProxyProvider.jsx
deleted file mode 100644
index 1209e3580d..0000000000
--- a/src/dataproxy/DataProxyProvider.jsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import * as Comlink from 'comlink'
-import React, { useContext, useState, useEffect } from 'react'
-
-import { useClient } from 'cozy-client'
-import { isFlagshipApp } from 'cozy-device-helper'
-import flag from 'cozy-flags'
-import Minilog from 'cozy-minilog'
-
-const log = Minilog('👷♂️ [DataProxyProvider]')
-
-export const DataProxyContext = React.createContext()
-
-export const useDataProxy = () => {
- const context = useContext(DataProxyContext)
-
- return context
-}
-
-export const DataProxyProvider = React.memo(({ children }) => {
- const client = useClient()
- const [iframeUrl, setIframeUrl] = useState()
- const [dataProxy, setDataProxy] = useState()
- const [dataProxyServicesAvailable, setDataProxyServicesAvailable] =
- useState(undefined)
-
- useEffect(() => {
- if (!client) return
-
- const initIframe = async () => {
- try {
- if (!flag('cozy.search.enabled')) {
- log.log(
- 'Dataproxy features will be disabled due to missing feature flags'
- )
- setDataProxyServicesAvailable(false)
- return
- }
-
- log.log('Initializing DataProxy intent')
- const result = await client.stackClient.fetchJSON('POST', '/intents', {
- data: {
- type: 'io.cozy.intents',
- attributes: {
- action: 'OPEN',
- type: 'io.cozy.dataproxy',
- permissions: ['GET']
- }
- }
- })
-
- if (!result.data?.attributes?.services?.[0]?.href) {
- log.log(
- 'No dataproxy intent available, dataproxy features will be disabled'
- )
- setDataProxyServicesAvailable(false)
- return
- }
-
- setIframeUrl(result.data.attributes.services[0]?.href)
- setDataProxyServicesAvailable(true)
- } catch (error) {
- setDataProxyServicesAvailable(false)
- log.error(
- 'Error whild initializing Search intent, dataproxy features will be disabled',
- error
- )
- }
- }
-
- if (isFlagshipApp()) {
- setDataProxyServicesAvailable(false)
- } else {
- initIframe()
- }
- }, [client])
-
- const onIframeLoaded = () => {
- const ifr = document.getElementById('DataProxy')
- const remote = Comlink.wrap(Comlink.windowEndpoint(ifr.contentWindow))
- setDataProxy(() => remote)
- }
-
- const search = async search => {
- log.log('Send search query to DataProxy iframe')
-
- const result = await dataProxy.search(search)
-
- return result
- }
-
- const value = {
- dataProxyServicesAvailable,
- search
- }
-
- return (
-
- {children}
- {iframeUrl ? (
-
- ) : undefined}
-
- )
-})
-
-DataProxyProvider.displayName = 'DataProxyProvider'
diff --git a/src/hooks/useFetchInitialData.jsx b/src/hooks/useFetchInitialData.jsx
new file mode 100644
index 0000000000..24ab223aaa
--- /dev/null
+++ b/src/hooks/useFetchInitialData.jsx
@@ -0,0 +1,61 @@
+import { useEffect, useRef } from 'react'
+import { useQuery } from 'cozy-client'
+import {
+ makeAccountsQuery,
+ makeAppsQuery,
+ makeKonnectorsQuery,
+ makeTriggersQuery
+} from 'queries'
+import log from 'cozy-logger'
+
+export const useFetchInitialData = () => {
+ const accountsQuery = useQuery(
+ makeAccountsQuery.definition,
+ makeAccountsQuery.options
+ )
+ const konnectorsQuery = useQuery(
+ makeKonnectorsQuery.definition,
+ makeKonnectorsQuery.options
+ )
+ const appsQuery = useQuery(makeAppsQuery.definition, makeAppsQuery.options)
+ const triggersQuery = useQuery(
+ makeTriggersQuery.definition,
+ makeTriggersQuery.options
+ )
+
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ const allQueries = [accountsQuery, konnectorsQuery, appsQuery, triggersQuery]
+
+ const startTime = useRef(null)
+ const loggedTime = useRef(false)
+
+ useEffect(() => {
+ if (startTime.current === null) {
+ startTime.current = performance.now()
+ }
+
+ const allFetched = allQueries.every(query => query.fetchStatus === 'loaded')
+
+ if (allFetched && !loggedTime.current) {
+ const endTime = performance.now()
+ log('info', `Required data fetched in ${endTime - startTime.current} ms`)
+ loggedTime.current = true
+ }
+ }, [allQueries])
+
+ const isFetching = allQueries.some(
+ query => query.fetchStatus === 'loading' || query.fetchStatus === 'pending'
+ )
+ const hasError = allQueries.some(query => query.fetchStatus === 'failed')
+
+ return {
+ isFetching,
+ hasError,
+ data: {
+ accounts: accountsQuery.data,
+ konnectors: konnectorsQuery.data,
+ apps: appsQuery.data,
+ triggers: triggersQuery.data
+ }
+ }
+}
diff --git a/src/queries.js b/src/queries.js
index c59b1e320a..8b2b58984f 100644
--- a/src/queries.js
+++ b/src/queries.js
@@ -14,16 +14,54 @@ export const konnectorsConn = {
fetchPolicy: defaultFetchPolicy
}
+export const makeJobsQuery = {
+ definition: () => Q('io.cozy.jobs'),
+ options: {
+ as: 'io.cozy.jobs',
+ fetchPolicy: defaultFetchPolicy
+ }
+}
+
+export const makeAppsQuery = {
+ definition: () => Q('io.cozy.apps'),
+ options: {
+ as: 'io.cozy.apps',
+ fetchPolicy: defaultFetchPolicy
+ }
+}
+
+export const makeKonnectorsQuery = {
+ definition: () => Q('io.cozy.konnectors'),
+ options: {
+ as: 'io.cozy.konnectors',
+ fetchPolicy: defaultFetchPolicy
+ }
+}
+
export const makeTriggersQuery = {
definition: () => {
return Q('io.cozy.triggers')
.partialIndex({
- worker: 'konnector'
+ worker: { $in: ['client', 'konnector'] } // client is for CLISK
})
.limitBy(1000)
},
options: {
- as: 'io.cozy.triggers/worker=konnector',
+ as: 'io.cozy.triggers/worker=client-or-konnector',
+ fetchPolicy: defaultFetchPolicy
+ }
+}
+
+export const makeTriggersWithJobStatusQuery = {
+ definition: () => {
+ return Q('io.cozy.triggers')
+ .where({
+ worker: { $in: ['client', 'konnector'] } // client is for CLISK
+ })
+ .limitBy(1000)
+ },
+ options: {
+ as: 'io.cozy.triggers/worker=client-or-konnector/withjobstatus',
fetchPolicy: defaultFetchPolicy
}
}
@@ -133,14 +171,14 @@ export const mkHomeCustomShorcutsConn = foldersId => {
}
}
-export const buildContextQuery = () => ({
+export const makeContextQuery = {
definition: () => Q('io.cozy.settings').getById('io.cozy.settings.context'),
options: {
as: 'io.cozy.settings/io.cozy.settings.context',
fetchPolicy: defaultFetchPolicy,
singleDocData: true
}
-})
+}
export const buildExistingTimeseriesGeojsonQuery = () => ({
definition: Q('io.cozy.timeseries.geojson')
@@ -153,12 +191,3 @@ export const buildExistingTimeseriesGeojsonQuery = () => ({
fetchPolicy: CozyClient.fetchPolicies.olderThan(60 * 60 * 24 * 365 * 1000)
}
})
-
-export const contextQuery = {
- definition: Q('io.cozy.settings').getById('io.cozy.settings.context'),
- options: {
- as: 'io.cozy.settings/io.cozy.settings.context',
- fetchPolicy: defaultFetchPolicy,
- singleDocData: true
- }
-}
diff --git a/yarn.lock b/yarn.lock
index 0195232897..9f76971038 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6079,14 +6079,13 @@ cozy-client@^51.6.0:
sift "^6.0.0"
url-search-params-polyfill "^8.0.0"
-cozy-dataproxy-lib@^1.9.0:
- version "1.9.0"
- resolved "https://registry.yarnpkg.com/cozy-dataproxy-lib/-/cozy-dataproxy-lib-1.9.0.tgz#5e43d49f2ac86e5d6a96bb74260e2567392626eb"
- integrity sha512-ij9a3x20THxCRjvqcG8yR3hJXZhidDWawaTsfQaCT/eQUS5vwGx4Ob2p6Fur4G8GqayMSmbMsrfkGXv4JlEb/g==
+cozy-dataproxy-lib@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/cozy-dataproxy-lib/-/cozy-dataproxy-lib-2.3.0.tgz#c702c36a674c61edffd31e10d3c9e3665f64c4ef"
+ integrity sha512-rDYd3yOykArExr8Iz/hoP+2jI57NX0Z/LIDsPmH3W9vifXnb1SVBfekxE4vNXj9vJKLSZ8vfKgl3OuqYbOKVow==
dependencies:
classnames "2.5.1"
comlink "4.4.1"
- cozy-device-helper "^3.7.1"
cozy-pouch-link "^50.3.1"
flexsearch "0.7.43"
lodash "4.17.21"
@@ -6094,7 +6093,14 @@ cozy-dataproxy-lib@^1.9.0:
react-type-animation "3.2.0"
rooks "7.14.1"
-cozy-device-helper@2.7.0, cozy-device-helper@^2.1.0:
+cozy-device-helper@3.7.1:
+ version "3.7.1"
+ resolved "https://registry.yarnpkg.com/cozy-device-helper/-/cozy-device-helper-3.7.1.tgz#59f11ab3ab92335525a767e78f983b07eeaf4eea"
+ integrity sha512-D0zkEFynUrICNhQixyyYGhRHTwgJL+pf7XtmTwjKePIn2pNHKw5V64IhGg9uLYf6tI9uivkUKvZvFYuKzEvlqA==
+ dependencies:
+ lodash "^4.17.19"
+
+cozy-device-helper@^2.1.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/cozy-device-helper/-/cozy-device-helper-2.7.0.tgz#573749997f18e5a1f11f720faec8c9bf2406beeb"
integrity sha512-jMzW7s4IDuMivbsP8fo1IWW1z5l0wJ0u440E0fQmdsi+Zm/L9GXFKthLuuceYqXlH6c/APUCfpozJqjFMMHU1A==
@@ -6115,13 +6121,6 @@ cozy-device-helper@^3.1.2:
dependencies:
lodash "^4.17.19"
-cozy-device-helper@^3.7.1:
- version "3.7.1"
- resolved "https://registry.yarnpkg.com/cozy-device-helper/-/cozy-device-helper-3.7.1.tgz#59f11ab3ab92335525a767e78f983b07eeaf4eea"
- integrity sha512-D0zkEFynUrICNhQixyyYGhRHTwgJL+pf7XtmTwjKePIn2pNHKw5V64IhGg9uLYf6tI9uivkUKvZvFYuKzEvlqA==
- dependencies:
- lodash "^4.17.19"
-
cozy-devtools@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/cozy-devtools/-/cozy-devtools-1.2.1.tgz#680976ab69ebdf2d2727cffc07243705794d1a83"