Skip to content

Commit daae715

Browse files
authored
Merge pull request #1249 from opencloud-eu/refactor/load-config-authenticated
feat: load config authenticated
2 parents dcd5a96 + 4370a06 commit daae715

File tree

7 files changed

+72
-175
lines changed

7 files changed

+72
-175
lines changed

packages/web-pkg/src/apps/types.ts

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,8 @@ export interface AppNavigationItem {
2424
priority?: number
2525
}
2626

27-
/**
28-
* ApplicationQuickAction describes an application action that is used in the runtime.
29-
*
30-
* @deprecated Quick actions should be registered as extension via the `files.quick-action` scope.
31-
*/
32-
export interface ApplicationQuickAction {
33-
id?: string
34-
label?: (...args: unknown[]) => string | string
35-
icon?: string
36-
iconFillType?: IconFillType
37-
handler?: (...args: unknown[]) => Promise<void> | void
38-
displayed?: (...args: unknown[]) => boolean | boolean
39-
}
40-
4127
export type AppConfigObject = Record<string, any>
4228

43-
/** @deprecated */
44-
export interface ApplicationMenuItem {
45-
enabled: () => boolean
46-
priority?: number
47-
openAsEditor?: boolean
48-
}
49-
5029
export interface ApplicationFileExtension {
5130
app?: string
5231
extension?: string
@@ -77,15 +56,9 @@ export interface ApplicationInformation {
7756
meta?: {
7857
fileSizeLimit?: number
7958
}
80-
/** @deprecated */
81-
isFileEditor?: boolean
8259
extensions?: ApplicationFileExtension[]
8360
defaultExtension?: string
84-
/** @deprecated */
85-
type?: string
8661
translations?: Translations
87-
/** @deprecated */
88-
applicationMenu?: ApplicationMenuItem
8962
}
9063

9164
/**

packages/web-pkg/src/composables/piniaStores/apps.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export const useAppsStore = defineStore('apps', () => {
2222
}
2323

2424
unref(apps)[appInfo.id] = {
25-
applicationMenu: appInfo.applicationMenu || { enabled: () => false },
2625
defaultExtension: appInfo.defaultExtension || '',
2726
icon: 'check_box_outline_blank',
2827
name: appInfo.name || appInfo.id,

packages/web-runtime/src/components/Topbar/TopBar.vue

Lines changed: 58 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -41,175 +41,97 @@
4141
</header>
4242
</template>
4343

44-
<script lang="ts">
44+
<script setup lang="ts">
4545
import { storeToRefs } from 'pinia'
46-
import { computed, unref, PropType, ref, onMounted } from 'vue'
46+
import { computed, unref, ref } from 'vue'
4747
import ApplicationsMenu from './ApplicationsMenu.vue'
4848
import UserMenu from './UserMenu.vue'
4949
import Notifications from './Notifications.vue'
5050
import FeedbackLink from './FeedbackLink.vue'
5151
import SideBarToggle from './SideBarToggle.vue'
5252
import {
53-
ApplicationInformation,
54-
AppMenuItemExtension,
5553
CustomComponentTarget,
5654
useAuthStore,
5755
useCapabilityStore,
5856
useConfigStore,
5957
useEmbedMode,
6058
useExtensionRegistry,
61-
useOpenEmptyEditor,
6259
useRouter,
6360
useThemeStore
6461
} from '@opencloud-eu/web-pkg'
6562
import { routeNames } from '../../router/names'
6663
import { appMenuExtensionPoint, topBarCenterExtensionPoint } from '../../extensionPoints'
6764
import { RouteLocationNormalizedLoaded } from 'vue-router'
65+
import { useGettext } from 'vue3-gettext'
6866
69-
export default {
70-
components: {
71-
ApplicationsMenu,
72-
CustomComponentTarget,
73-
FeedbackLink,
74-
Notifications,
75-
SideBarToggle,
76-
UserMenu
77-
},
78-
props: {
79-
applicationsList: {
80-
type: Array as PropType<ApplicationInformation[]>,
81-
required: false,
82-
default: (): ApplicationInformation[] => []
83-
}
84-
},
85-
setup(props) {
86-
const capabilityStore = useCapabilityStore()
87-
const themeStore = useThemeStore()
88-
const { currentTheme } = storeToRefs(themeStore)
89-
const configStore = useConfigStore()
90-
const { options: configOptions } = storeToRefs(configStore)
91-
const extensionRegistry = useExtensionRegistry()
92-
const { openEmptyEditor } = useOpenEmptyEditor()
93-
94-
const authStore = useAuthStore()
95-
const router = useRouter()
96-
const { isEnabled: isEmbedModeEnabled } = useEmbedMode()
67+
const { $gettext } = useGettext()
68+
const capabilityStore = useCapabilityStore()
69+
const themeStore = useThemeStore()
70+
const { currentTheme } = storeToRefs(themeStore)
71+
const configStore = useConfigStore()
72+
const { options: configOptions } = storeToRefs(configStore)
73+
const extensionRegistry = useExtensionRegistry()
9774
98-
const appMenuExtensions = computed(() => {
99-
return extensionRegistry.requestExtensions(appMenuExtensionPoint)
100-
})
75+
const authStore = useAuthStore()
76+
const router = useRouter()
77+
const { isEnabled: isEmbedModeEnabled } = useEmbedMode()
10178
102-
const logoWidth = ref('150px')
103-
const hideLogo = computed(() => unref(configOptions).hideLogo)
79+
const appMenuExtensions = computed(() => {
80+
return extensionRegistry.requestExtensions(appMenuExtensionPoint)
81+
})
10482
105-
const isNotificationBellEnabled = computed(() => {
106-
return (
107-
authStore.userContextReady && capabilityStore.notificationsOcsEndpoints.includes('list')
108-
)
109-
})
83+
const hideLogo = computed(() => unref(configOptions).hideLogo)
11084
111-
const homeLink = computed(() => {
112-
if (authStore.publicLinkContextReady && !authStore.userContextReady) {
113-
return {
114-
name: 'resolvePublicLink',
115-
params: { token: authStore.publicLinkToken }
116-
}
117-
}
85+
const isNotificationBellEnabled = computed(() => {
86+
return authStore.userContextReady && capabilityStore.notificationsOcsEndpoints.includes('list')
87+
})
11888
119-
return '/'
120-
})
121-
122-
const isRuntimeRoute = (route: RouteLocationNormalizedLoaded) => {
123-
return Object.values(routeNames).includes(route.name.toString())
124-
}
125-
const isSideBarToggleVisible = computed(() => {
126-
return authStore.userContextReady || authStore.publicLinkContextReady
127-
})
128-
const isSideBarToggleDisabled = computed(() => {
129-
return isRuntimeRoute(unref(router.currentRoute))
130-
})
131-
132-
const contentOnLeftPortal = ref(false)
133-
const updateLeftPortal = (newContent: { hasContent: boolean; sources: string[] }) => {
134-
contentOnLeftPortal.value = newContent.hasContent
89+
const homeLink = computed(() => {
90+
if (authStore.publicLinkContextReady && !authStore.userContextReady) {
91+
return {
92+
name: 'resolvePublicLink',
93+
params: { token: authStore.publicLinkToken }
13594
}
95+
}
13696
137-
onMounted(() => {
138-
// FIXME: backwards compatibility for the deprecated applicationMenu prop
139-
const navExtensions = props.applicationsList
140-
.filter((app) => app.applicationMenu?.enabled())
141-
.map((app) => ({
142-
id: app.id,
143-
type: 'appMenuItem',
144-
label: () => app.name,
145-
path: `/${app.id}`,
146-
icon: app.icon,
147-
color: app.color,
148-
extensionPointIds: [appMenuExtensionPoint.id],
149-
priority: app.applicationMenu?.priority || 50,
150-
...((app as any).url && { url: (app as any).url, target: '_blank' }),
151-
...(app.applicationMenu?.openAsEditor && {
152-
handler: () => openEmptyEditor(app.id, app.defaultExtension)
153-
})
154-
})) as AppMenuItemExtension[]
97+
return '/'
98+
})
15599
156-
extensionRegistry.registerExtensions(computed(() => navExtensions))
157-
})
100+
const isRuntimeRoute = (route: RouteLocationNormalizedLoaded) => {
101+
return Object.values(routeNames).includes(route.name.toString())
102+
}
103+
const isSideBarToggleVisible = computed(() => {
104+
return authStore.userContextReady || authStore.publicLinkContextReady
105+
})
106+
const isSideBarToggleDisabled = computed(() => {
107+
return isRuntimeRoute(unref(router.currentRoute))
108+
})
109+
110+
const contentOnLeftPortal = ref(false)
111+
const updateLeftPortal = (newContent: { hasContent: boolean; sources: string[] }) => {
112+
contentOnLeftPortal.value = newContent.hasContent
113+
}
158114
159-
return {
160-
configOptions,
161-
contentOnLeftPortal,
162-
currentTheme,
163-
updateLeftPortal,
164-
isNotificationBellEnabled,
165-
hideLogo,
166-
logoWidth,
167-
isEmbedModeEnabled,
168-
isSideBarToggleVisible,
169-
isSideBarToggleDisabled,
170-
homeLink,
171-
topBarCenterExtensionPoint,
172-
appMenuExtensions
173-
}
174-
},
175-
computed: {
176-
sidebarLogoAlt() {
177-
return this.$gettext('Navigate to personal files page')
178-
},
115+
const sidebarLogoAlt = computed(() => {
116+
return $gettext('Navigate to personal files page')
117+
})
179118
180-
isFeedbackLinkEnabled() {
181-
return !this.configOptions.disableFeedbackLink
182-
},
119+
const isFeedbackLinkEnabled = computed(() => {
120+
return !unref(configOptions).disableFeedbackLink
121+
})
183122
184-
feedbackLinkOptions() {
185-
const feedback = this.configOptions.feedbackLink
186-
if (!this.isFeedbackLinkEnabled || !feedback) {
187-
return {}
188-
}
123+
const feedbackLinkOptions = computed(() => {
124+
const feedback = unref(configOptions).feedbackLink
125+
if (!unref(isFeedbackLinkEnabled) || !feedback) {
126+
return {}
127+
}
189128
190-
return {
191-
...(feedback.href && { href: feedback.href }),
192-
...(feedback.ariaLabel && { ariaLabel: feedback.ariaLabel }),
193-
...(feedback.description && { description: feedback.description })
194-
}
195-
}
196-
},
197-
async created() {
198-
const image = new Image()
199-
const imageDimensions = (await new Promise((resolve) => {
200-
image.onload = () => {
201-
resolve({
202-
height: image.height,
203-
width: image.width
204-
})
205-
}
206-
image.src = this.currentTheme.logo
207-
})) as { height: number; width: number }
208-
// max-height of logo is 38px, so we calculate the width based on the ratio of the image
209-
// and add 70px to account for the width of the left side of the topbar
210-
this.logoWidth = `${imageDimensions.width / (imageDimensions.height / 38) + 70}px`
129+
return {
130+
...(feedback.href && { href: feedback.href }),
131+
...(feedback.ariaLabel && { ariaLabel: feedback.ariaLabel }),
132+
...(feedback.description && { description: feedback.description })
211133
}
212-
}
134+
})
213135
</script>
214136
<style scoped>
215137
@reference '@opencloud-eu/design-system/tailwind';

packages/web-runtime/src/container/bootstrap.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,16 @@ const getEmbedConfigFromQuery = (
138138
*/
139139
export const announceConfiguration = async ({
140140
path,
141-
configStore
141+
configStore,
142+
token
142143
}: {
143144
path: string
144145
configStore: ConfigStore
146+
token?: string
145147
}) => {
146-
const request = await fetch(path, { headers: { 'X-Request-ID': uuidV4() } })
148+
const request = await fetch(path, {
149+
headers: { 'X-Request-ID': uuidV4(), ...(token && { Authorization: `Bearer ${token}` }) }
150+
})
147151
if (request.status !== 200) {
148152
throw new Error(`config could not be loaded. HTTP status-code ${request.status}`)
149153
}

packages/web-runtime/src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ export const bootstrapApp = async (configurationPath: string, appsReadyCallback:
201201
return
202202
}
203203

204+
await announceConfiguration({
205+
path: configurationPath,
206+
configStore,
207+
token: authStore.accessToken
208+
})
209+
204210
const clientService = app.config.globalProperties.$clientService
205211
const previewService = app.config.globalProperties.$previewService
206212
const passwordPolicyService = app.config.globalProperties.passwordPolicyService

packages/web-runtime/src/layouts/Application.vue

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<div v-if="isIE11" class="bg-role-surface-container text-center py-4">
88
<p class="m-0" v-text="ieDeprecationWarning" />
99
</div>
10-
<top-bar :applications-list="Object.values(apps)" />
10+
<top-bar />
1111
</div>
1212
<div
1313
id="web-content-main"
@@ -53,7 +53,6 @@ import orderBy from 'lodash-es/orderBy'
5353
import {
5454
AppLoadingSpinner,
5555
CustomComponentTarget,
56-
useAppsStore,
5756
useAuthStore,
5857
useExtensionRegistry,
5958
useLocalStorage,
@@ -69,7 +68,6 @@ import { useActiveApp, useRoute, useRouteMeta, useSpacesLoading } from '@openclo
6968
import { computed, nextTick, onBeforeUnmount, onMounted, provide, ref, unref, watch } from 'vue'
7069
import { RouteLocationAsRelativeTyped, useRouter } from 'vue-router'
7170
import { useGettext } from 'vue3-gettext'
72-
import { storeToRefs } from 'pinia'
7371
import { progressBarExtensionPoint } from '../extensionPoints'
7472
7573
const MOBILE_BREAKPOINT = 640
@@ -82,9 +80,6 @@ const activeApp = useActiveApp()
8280
const extensionRegistry = useExtensionRegistry()
8381
const { isSideBarOpen } = useSideBar()
8482
85-
const appsStore = useAppsStore()
86-
const { apps } = storeToRefs(appsStore)
87-
8883
const extensionNavItems = computed(() =>
8984
getExtensionNavItems({ extensionRegistry, appId: unref(activeApp) })
9085
)

packages/web-runtime/tests/unit/components/Topbar/TopBar.spec.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,7 @@ const getWrapper = ({
9999
props: {
100100
applicationsList: [
101101
mock<ApplicationInformation>({
102-
type: 'extension',
103-
icon: '',
104-
applicationMenu: undefined
102+
icon: ''
105103
})
106104
]
107105
},

0 commit comments

Comments
 (0)