Skip to content

Commit

Permalink
[openMFP] Move luigiContext and isInIframe to own composables (#2223)
Browse files Browse the repository at this point in the history
* move luigiContext and isInIframe to own composables

* rename to useOpenMFP

* PR feedback

* PR feedback II
  • Loading branch information
petersutter authored Dec 10, 2024
1 parent a55826d commit 8754a10
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 98 deletions.
4 changes: 0 additions & 4 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import { useLoginStore } from '@/store/login'
import { useLocalStorageStore } from '@/store/localStorage'
import { useShootStore } from '@/store/shoot'
import { useProjectStore } from '@/store/project'
import { useAppStore } from '@/store/app'

import { useCustomColors } from '@/composables/useCustomColors'

Expand All @@ -45,11 +44,8 @@ const configStore = useConfigStore()
const loginStore = useLoginStore()
const shootStore = useShootStore()
const projectStore = useProjectStore()
const appStore = useAppStore()
const logger = inject('logger')

appStore.setRoute(route)

async function setCustomColors () {
try {
await useCustomColors(() => configStore.themes ?? loginStore.themes ?? null, theme)
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/dialogs/GProjectDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ import {
} from '@vuelidate/validators'
import { useRouter } from 'vue-router'

import { useAppStore } from '@/store/app'
import { useConfigStore } from '@/store/config'
import { useProjectStore } from '@/store/project'

Expand All @@ -115,6 +114,7 @@ import GProjectCostObject from '@/components/GProjectCostObject.vue'

import { useLogger } from '@/composables/useLogger'
import { useProvideProjectContext } from '@/composables/useProjectContext'
import { useOpenMFP } from '@/composables/useOpenMFP'

import {
messageFromErrors,
Expand Down Expand Up @@ -146,7 +146,7 @@ const emit = defineEmits([
])

const logger = useLogger()
const appStore = useAppStore()
const openMFP = useOpenMFP()
const configStore = useConfigStore()
const projectStore = useProjectStore()
const router = useRouter()
Expand All @@ -157,7 +157,7 @@ const {
description,
purpose,
} = useProvideProjectContext({
appStore,
openMFP,
configStore,
})

Expand Down
12 changes: 12 additions & 0 deletions frontend/src/composables/useIsInIframe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors
//
// SPDX-License-Identifier: Apache-2.0
//

import { computed } from 'vue'
import { createGlobalState } from '@vueuse/core'

export const useIsInIframe = createGlobalState(() => {
return computed(() => window.self !== window.top)
})
77 changes: 77 additions & 0 deletions frontend/src/composables/useOpenMFP.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors
//
// SPDX-License-Identifier: Apache-2.0
//

import { useRoute } from 'vue-router'
import {
until,
createGlobalState,
} from '@vueuse/core'
import LuigiClient from '@luigi-project/client'
import {
computed,
ref,
toRef,
watch,
} from 'vue'

import { useLogger } from '@/composables/useLogger'
import { useIsInIframe } from '@/composables/useIsInIframe'

export const useOpenMFP = createGlobalState((options = {}) => {
const {
logger = useLogger(),
isInIframe = useIsInIframe(),
route = useRoute(),
} = options

const luigiContext = ref(null)

if (isInIframe.value) {
logger.debug('Registering listener for Luigi context initialization and context updates')
LuigiClient.addInitListener(context => setLuigiContext(context))
LuigiClient.addContextUpdateListener(context => setLuigiContext(context))
const pathname = toRef(route, 'path')
watch(pathname, value => {
if (value) {
LuigiClient.linkManager().fromVirtualTreeRoot().withoutSync().navigate(value)
}
}, {
immediate: true,
})
}

function setLuigiContext (value) {
luigiContext.value = value
}

const accountId = computed(() => luigiContext.value?.accountId)

async function getLuigiContext () {
if (!isInIframe.value) {
return null
}
if (luigiContext.value !== null) {
return luigiContext.value
}
const timeout = 3000
try {
await until(luigiContext).toBeTruthy({
timeout,
throwOnTimeout: true,
})
return luigiContext.value
} catch (err) {
logger.error('The initialization of the Luigi Client has timed out after %d milliseconds', timeout)
return null
}
}

return {
accountId,
luigiContext,
getLuigiContext,
}
})
15 changes: 7 additions & 8 deletions frontend/src/composables/useProjectContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ import {
provide,
} from 'vue'

import { useAppStore } from '@/store/app'
import { useConfigStore } from '@/store/config'

import { cleanup } from '@/composables/helper'

import { useProjectShootCustomFields } from './useProjectShootCustomFields'
import { useProjectMetadata } from './useProjectMetadata'
import { useProjectCostObject } from './useProjectCostObject'
import { useOpenMFP } from '@/composables/useOpenMFP'
import { useProjectShootCustomFields } from '@/composables/useProjectShootCustomFields'
import { useProjectMetadata } from '@/composables/useProjectMetadata'
import { useProjectCostObject } from '@/composables/useProjectCostObject'

import cloneDeep from 'lodash/cloneDeep'
import get from 'lodash/get'
Expand All @@ -28,7 +27,7 @@ import set from 'lodash/set'

export function createProjectContextComposable (options = {}) {
const {
appStore = useAppStore(),
openMFP = useOpenMFP(),
configStore = useConfigStore(),
} = options

Expand Down Expand Up @@ -63,9 +62,9 @@ export function createProjectContextComposable (options = {}) {

function createProjectManifest () {
manifest.value = {}
if (appStore.accountId) {
if (openMFP.accountId) {
set(manifest.value, ['metadata', 'label', 'openmfp.org/managed-by'], 'true')
set(manifest.value, ['metadata', 'annotations', 'openmfp.org/account-id'], appStore.accountId)
set(manifest.value, ['metadata', 'annotations', 'openmfp.org/account-id'], openMFP.accountId)
}
initialManifest.value = cloneDeep(normalizedManifest.value)
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/layouts/GDefault.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ SPDX-License-Identifier: Apache-2.0
import {
ref,
computed,
toRef,
onMounted,
} from 'vue'
import { onBeforeRouteUpdate } from 'vue-router'
Expand All @@ -49,15 +48,16 @@ import GNotify from '@/components/GNotify.vue'
import GBreadcrumbs from '@/components/GBreadcrumbs.vue'

import { useLogger } from '@/composables/useLogger'
import { useIsInIframe } from '@/composables/useIsInIframe'

import get from 'lodash/get'

const logger = useLogger()
const isInIframe = useIsInIframe()
const appStore = useAppStore()
const authnStore = useAuthnStore()

// refs
const isInIframe = toRef(appStore, 'isInIframe')
const app = ref(null)
const mainContent = ref(null)

Expand Down
4 changes: 3 additions & 1 deletion frontend/src/router/guards.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useSeedStore } from '@/store/seed'
import { useShootStore } from '@/store/shoot'
import { useTerminalStore } from '@/store/terminal'

import { useOpenMFP } from '@/composables/useOpenMFP'
import { useLogger } from '@/composables/useLogger'
import { useApi } from '@/composables/useApi'

Expand Down Expand Up @@ -50,7 +51,8 @@ export function createGlobalBeforeGuards () {
return true
}

const context = await appStore.getLuigiContext()
const openMFP = useOpenMFP()
const context = await openMFP.getLuigiContext()
if (context) {
logger.debug('Luigi context:', context)
const token = context.token
Expand Down
71 changes: 1 addition & 70 deletions frontend/src/store/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,16 @@ import {
defineStore,
acceptHMRUpdate,
} from 'pinia'
import {
ref,
watch,
toRef,
computed,
} from 'vue'
import LuigiClient from '@luigi-project/client'
import { ref } from 'vue'
import { useNotification } from '@kyvg/vue3-notification'

import { useLogger } from '@/composables/useLogger'

import { parseWarningHeader } from '@/utils/headerWarnings'
import { errorDetailsFromError } from '@/utils/error'
import moment from '@/utils/moment'

import assign from 'lodash/assign'

export const useAppStore = defineStore('app', () => {
const logger = useLogger()

const ready = ref(false)
const sidebar = ref(true)
const redirectPath = ref(null)
Expand All @@ -38,63 +28,9 @@ export const useAppStore = defineStore('app', () => {
const splitpaneResize = ref(0)
const fromRoute = ref(null)
const routerError = ref(null)
const luigiContext = ref(null)

const { notify } = useNotification()

const isInIframe = computed(() => window.self !== window.top)

if (isInIframe.value) {
logger.debug('Registering listener for Luigi context initialization and context updates')
LuigiClient.addInitListener(context => setLuigiContext(context))
LuigiClient.addContextUpdateListener(context => setLuigiContext(context))
}

function setLuigiContext (value) {
luigiContext.value = value
}

const accountId = computed(() => luigiContext.value?.accountId)

function getLuigiContext () {
if (!isInIframe.value) {
return Promise.resolve(null)
}
if (luigiContext.value !== null) {
return Promise.resolve(luigiContext.value)
}
return new Promise(resolve => {
const timeout = 3000
const timeoutId = setTimeout(() => {
unwatch()
logger.error('The initialization of the Luigi Client has timed out after %d milliseconds', timeout)
resolve(null)
}, timeout)
const unwatch = watch(luigiContext, context => {
if (context !== null) {
clearTimeout(timeoutId)
unwatch()
resolve(context)
}
}, {
immediate: true,
})
})
}

function setRoute (route) {
if (isInIframe.value) {
const pathname = toRef(route, 'path')
watch(pathname, value => {
if (value) {
LuigiClient.linkManager().fromVirtualTreeRoot().withoutSync().navigate(value)
}
}, {
immediate: true,
})
}
}

function updateSplitpaneResize () {
splitpaneResize.value = Date.now()
}
Expand Down Expand Up @@ -149,12 +85,7 @@ export const useAppStore = defineStore('app', () => {
focusedElementId,
splitpaneResize,
fromRoute,
isInIframe,
setRoute,
routerError,
accountId,
luigiContext,
getLuigiContext,
updateSplitpaneResize,
setError,
setHeaderWarning,
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/views/GAdministration.vue
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ import GShootCustomFieldsConfiguration from '@/components/GShootCustomFieldsConf
import GResourceQuotaHelp from '@/components/GResourceQuotaHelp.vue'
import GTextRouterLink from '@/components/GTextRouterLink.vue'

import { useOpenMFP } from '@/composables/useOpenMFP'
import { useProvideProjectItem } from '@/composables/useProjectItem'
import { useProvideProjectContext } from '@/composables/useProjectContext'
import { useLogger } from '@/composables/useLogger'
Expand All @@ -528,6 +529,7 @@ import set from 'lodash/set'
import includes from 'lodash/includes'

const logger = useLogger()
const openMFP = useOpenMFP()
const appStore = useAppStore()
const configStore = useConfigStore()
const quotaStore = useQuotaStore()
Expand All @@ -540,7 +542,10 @@ const kubeconfigStore = useKubeconfigStore()
const route = useRoute()
const router = useRouter()

useProvideProjectContext()
useProvideProjectContext({
openMFP,
configStore,
})

const color = ref('primary')
const errorMessage = ref(undefined)
Expand Down Expand Up @@ -646,9 +651,9 @@ async function updateProperty (key, value, options = {}) {
metadata: { name },
spec: { namespace },
}
if (appStore.accountId && !get(projectStore.project, ['metadata', 'annotations', 'openmfp.org/account-id'])) {
if (openMFP.accountId && !get(projectStore.project, ['metadata', 'annotations', 'openmfp.org/account-id'])) {
set(mergePatchDocument, ['metadata', 'labels', 'openmfp.org/managed-by'], 'true')
set(mergePatchDocument, ['metadata', 'annotations', 'openmfp.org/account-id'], appStore.accountId)
set(mergePatchDocument, ['metadata', 'annotations', 'openmfp.org/account-id'], openMFP.accountId)
}
set(mergePatchDocument, ['spec', key], value)
await projectStore.patchProject(mergePatchDocument)
Expand Down
Loading

0 comments on commit 8754a10

Please sign in to comment.