Skip to content

Commit

Permalink
refactor: make use of menu items extension point
Browse files Browse the repository at this point in the history
Refactors apps to use the new `appMenuItem` extension point instead of the deprecated `applicationMenu` property.
  • Loading branch information
JammingBen committed Jul 26, 2024
1 parent 3dc9a0b commit f554f91
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 136 deletions.
61 changes: 40 additions & 21 deletions packages/web-app-admin-settings/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import General from './views/General.vue'
import Users from './views/Users.vue'
import Groups from './views/Groups.vue'
import Spaces from './views/Spaces.vue'
import { Ability } from '@ownclouders/web-client'
import { Ability, urlJoin } from '@ownclouders/web-client'
import {
ApplicationInformation,
AppMenuItemExtension,
AppNavigationItem,
defineWebApplication,
useAbility,
useUserStore
} from '@ownclouders/web-pkg'
import { RouteRecordRaw } from 'vue-router'
import { computed } from 'vue'

// just a dummy function to trick gettext tools
function $gettext(msg: string) {
Expand Down Expand Up @@ -152,29 +155,45 @@ export default defineWebApplication({
const { can } = useAbility()
const userStore = useUserStore()

const appInfo: ApplicationInformation = {
name: $gettext('Admin Settings'),
id: appId,
icon: 'settings-4',
color: '#2b2b2b',
isFileEditor: false
}

const menuItems = computed<AppMenuItemExtension[]>(() => {
const items: AppMenuItemExtension[] = []

const menuItemAvailable =
userStore.user &&
(can('read-all', 'Setting') ||
can('read-all', 'Account') ||
can('read-all', 'Group') ||
can('read-all', 'Drive'))

if (menuItemAvailable) {
items.push({
id: `app.${appInfo.id}.menuItem`,
type: 'appMenuItem',
label: () => appInfo.name,
color: appInfo.color,
icon: appInfo.icon,
priority: 40,
path: urlJoin(appInfo.id)
})
}

return items
})

return {
appInfo: {
name: $gettext('Admin Settings'),
id: appId,
icon: 'settings-4',
color: '#2b2b2b',
isFileEditor: false,
applicationMenu: {
enabled: () => {
return (
userStore.user &&
(can('read-all', 'Setting') ||
can('read-all', 'Account') ||
can('read-all', 'Group') ||
can('read-all', 'Drive'))
)
},
priority: 40
}
},
appInfo,
routes,
navItems,
translations
translations,
extensions: menuItems
}
}
})
22 changes: 19 additions & 3 deletions packages/web-app-files/src/extensions.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import {
ApplicationInformation,
Extension,
useCapabilityStore,
useConfigStore,
useFileActionsCopyQuickLink,
useFileActionsShowShares,
useRouter,
useSearch
useSearch,
useUserStore
} from '@ownclouders/web-pkg'
import { computed, unref } from 'vue'
import { SDKSearch } from './search'
import { useSideBarPanels } from './composables/extensions/useFileSideBars'
import { useFolderViews } from './composables/extensions/useFolderViews'
import { quickActionsExtensionPoint } from './extensionPoints'
import { urlJoin } from '@ownclouders/web-client'

export const extensions = () => {
export const extensions = (appInfo: ApplicationInformation) => {
const capabilityStore = useCapabilityStore()
const configStore = useConfigStore()
const userStore = useUserStore()
const router = useRouter()
const { search: searchFunction } = useSearch()

Expand Down Expand Up @@ -45,6 +49,18 @@ export const extensions = () => {
extensionPointIds: [quickActionsExtensionPoint.id],
type: 'action',
action: unref(quickLinkActions)[0]
}
},
...((userStore.user && [
{
id: `app.${appInfo.id}.menuItem`,
type: 'appMenuItem',
label: () => appInfo.name,
color: appInfo.color,
icon: appInfo.icon,
priority: 10,
path: urlJoin(appInfo.id)
}
]) ||
[])
])
}
14 changes: 2 additions & 12 deletions packages/web-app-files/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,8 @@ export const navItems = (context: ComponentCustomProperties): AppNavigationItem[

export default defineWebApplication({
setup() {
const userStore = useUserStore()

return {
appInfo: {
...appInfo,
applicationMenu: {
enabled: () => {
return !!userStore.user
},
priority: 10
}
},
appInfo,
routes: buildRoutes({
App,
Favorites,
Expand All @@ -159,7 +149,7 @@ export default defineWebApplication({
}),
navItems,
translations,
extensions: extensions(),
extensions: extensions(appInfo),
extensionPoints: extensionPoints()
}
}
Expand Down
20 changes: 17 additions & 3 deletions packages/web-app-ocm/src/extensions.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import {
ApplicationInformation,
FileActionOptions,
useClientService,
useConfigStore,
useMessages,
useUserStore,
useWindowOpen
} from '@ownclouders/web-pkg'
import { useGettext } from 'vue3-gettext'
import { computed } from 'vue'
import { Extension } from '@ownclouders/web-pkg'
import { OCM_PROVIDER_ID } from '@ownclouders/web-client'
import { OCM_PROVIDER_ID, urlJoin } from '@ownclouders/web-client'

export const extensions = () => {
export const extensions = (appInfo: ApplicationInformation) => {
const { showErrorMessage } = useMessages()
const clientService = useClientService()
const configStore = useConfigStore()
const userStore = useUserStore()
const { $gettext } = useGettext()
const { openUrl } = useWindowOpen()

Expand Down Expand Up @@ -69,6 +72,17 @@ export const extensions = () => {
componentType: 'button',
class: 'oc-files-actions-open-file-remote'
}
}
},
...((userStore.user && [
{
id: `app.${appInfo.id}.menuItem`,
type: 'appMenuItem',
label: () => appInfo.name,
color: appInfo.color,
icon: appInfo.icon,
path: urlJoin(appInfo.id)
}
]) ||
[])
])
}
14 changes: 4 additions & 10 deletions packages/web-app-ocm/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import App from './views/App.vue'
import { defineWebApplication, useRouter, useUserStore } from '@ownclouders/web-pkg'
import { ApplicationInformation, defineWebApplication, useRouter } from '@ownclouders/web-pkg'
import translations from '../l10n/translations.json'
import { extensions } from './extensions'
import { RouteRecordRaw } from 'vue-router'
Expand Down Expand Up @@ -27,19 +27,13 @@ export default defineWebApplication({
setup() {
const { $gettext } = useGettext()
const router = useRouter()
const userStore = useUserStore()

const appInfo = {
const appInfo: ApplicationInformation = {
name: $gettext('ScienceMesh'),
id: 'ocm',
color: '#AE291D',
icon: 'contacts-book',
isFileEditor: false,
applicationMenu: {
enabled: () => {
return !!userStore.user
}
}
isFileEditor: false
}

router.addRoute({
Expand All @@ -64,7 +58,7 @@ export default defineWebApplication({
appInfo,
routes,
navItems,
extensions: extensions(),
extensions: extensions(appInfo),
translations
}
}
Expand Down
67 changes: 44 additions & 23 deletions packages/web-app-text-editor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@ import { useGettext } from 'vue3-gettext'
import translations from '../l10n/translations.json'
import TextEditor from './App.vue'
import {
AppMenuItemExtension,
AppWrapperRoute,
ApplicationFileExtension,
ApplicationInformation,
defineWebApplication,
useOpenEmptyEditor,
useUserStore
} from '@ownclouders/web-pkg'
import { computed } from 'vue'
import { urlJoin } from '@ownclouders/web-client'

export default defineWebApplication({
setup({ applicationConfig }) {
const { $gettext } = useGettext()
const userStore = useUserStore()
const { openEmptyEditor } = useOpenEmptyEditor()

const appId = 'text-editor'

Expand Down Expand Up @@ -93,32 +99,47 @@ export default defineWebApplication({
}
]

return {
appInfo: {
name: $gettext('Text Editor'),
id: appId,
icon: 'file-text',
color: '#0D856F',
isFileEditor: true,
applicationMenu: {
enabled: () => {
return !!userStore.user
},
const appInfo: ApplicationInformation = {
name: $gettext('Text Editor'),
id: appId,
icon: 'file-text',
color: '#0D856F',
isFileEditor: true,
defaultExtension: 'txt',
extensions: fileExtensions().map((extensionItem) => {
return {
extension: extensionItem.extension,
...(Object.prototype.hasOwnProperty.call(extensionItem, 'newFileMenu') && {
newFileMenu: extensionItem.newFileMenu
})
}
})
}

const menuItems = computed<AppMenuItemExtension[]>(() => {
const items: AppMenuItemExtension[] = []

if (userStore.user) {
items.push({
id: `app.${appInfo.id}.menuItem`,
type: 'appMenuItem',
label: () => appInfo.name,
color: appInfo.color,
icon: appInfo.icon,
priority: 20,
openAsEditor: true
},
defaultExtension: 'txt',
extensions: fileExtensions().map((extensionItem) => {
return {
extension: extensionItem.extension,
...(Object.prototype.hasOwnProperty.call(extensionItem, 'newFileMenu') && {
newFileMenu: extensionItem.newFileMenu
})
}
path: urlJoin(appInfo.id),
handler: () => openEmptyEditor(appInfo.id, appInfo.defaultExtension)
})
},
}

return items
})

return {
appInfo,
routes,
translations
translations,
extensions: menuItems
}
}
})
1 change: 1 addition & 0 deletions packages/web-pkg/src/composables/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export * from './spaces'
export * from './types'

export * from './useActionsShowDetails'
export * from './useOpenEmptyEditor'
export * from './useOpenWithDefaultApp'
export * from './useWindowOpen'
54 changes: 54 additions & 0 deletions packages/web-pkg/src/composables/actions/useOpenEmptyEditor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { useGettext } from 'vue3-gettext'
import { useGetMatchingSpace } from '../spaces'
import { useAppsStore, useResourcesStore, useSpacesStore } from '../piniaStores'
import { useClientService } from '../clientService'
import { EDITOR_MODE_EDIT, useFileActions } from './files'
import { storeToRefs } from 'pinia'
import { unref } from 'vue'
import { resolveFileNameDuplicate } from '../../helpers'
import { urlJoin } from '@ownclouders/web-client'

// open an editor with an empty file within the current folder
export const useOpenEmptyEditor = () => {
const { getMatchingSpace } = useGetMatchingSpace()
const spacesStore = useSpacesStore()
const appsStore = useAppsStore()
const resourcesStore = useResourcesStore()
const clientService = useClientService()
const { $gettext } = useGettext()
const { openEditor } = useFileActions()
const { resources, currentFolder } = storeToRefs(resourcesStore)

const openEmptyEditor = async (appId: string, extension: string) => {
let destinationSpace = unref(currentFolder) ? getMatchingSpace(unref(currentFolder)) : null
let destinationFiles = unref(resources)
let filePath = unref(currentFolder)?.path

if (!destinationSpace || !unref(currentFolder).canCreate()) {
destinationSpace = spacesStore.personalSpace
destinationFiles = (await clientService.webdav.listFiles(destinationSpace)).children
filePath = ''
}

let fileName = $gettext('New file') + `.${extension}`

if (destinationFiles.some((f) => f.name === fileName)) {
fileName = resolveFileNameDuplicate(fileName, extension, destinationFiles)
}

const emptyResource = await clientService.webdav.putFileContents(destinationSpace, {
path: urlJoin(filePath, fileName)
})

const space = getMatchingSpace(emptyResource)
const appFileExtension = appsStore.fileExtensions.find(
({ app, extension: ext }) => app === appId && ext === extension
)

openEditor(appFileExtension, space, emptyResource, EDITOR_MODE_EDIT)
}

return {
openEmptyEditor
}
}
Loading

0 comments on commit f554f91

Please sign in to comment.