mirror of https://github.com/nextcloud/server.git
Merge pull request #44259 from nextcloud/feat/app-discover-app-links
feat(settings): Allow app discover section links to open app routes or the appstore pagepull/44279/head
commit
133a17aa96
@ -0,0 +1,117 @@
|
||||
<!--
|
||||
- @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
-
|
||||
- @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
-
|
||||
- @license AGPL-3.0-or-later
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
<template>
|
||||
<a v-if="linkProps" v-bind="linkProps">
|
||||
<slot />
|
||||
</a>
|
||||
<RouterLink v-else-if="routerProps" v-bind="routerProps">
|
||||
<slot />
|
||||
</RouterLink>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { RouterLinkProps } from 'vue-router/types/router.js'
|
||||
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { defineComponent } from 'vue'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
const knownRoutes = Object.fromEntries(
|
||||
Object.entries(
|
||||
loadState<Record<string, { app?: string, href: string }>>('core', 'apps'),
|
||||
).map(([k, v]) => [v.app ?? k, v.href]),
|
||||
)
|
||||
|
||||
/**
|
||||
* This component either shows a native link to the installed app or external size - or a router link to the appstore page of the app if not installed
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'AppLink',
|
||||
|
||||
components: { RouterLink },
|
||||
|
||||
props: {
|
||||
href: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
routerProps: undefined as RouterLinkProps|undefined,
|
||||
linkProps: undefined as Record<string, string>|undefined,
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
href: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
const match = this.href.match(/^app:\/\/([^/]+)(\/.+)?$/)
|
||||
this.routerProps = undefined
|
||||
this.linkProps = undefined
|
||||
|
||||
// not an app url
|
||||
if (match === null) {
|
||||
this.linkProps = {
|
||||
href: this.href,
|
||||
target: '_blank',
|
||||
rel: 'noreferrer noopener',
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const appId = match[1]
|
||||
// Check if specific route was requested
|
||||
if (match[2]) {
|
||||
// we do no know anything about app internal path so we only allow generic app paths
|
||||
this.linkProps = {
|
||||
href: generateUrl(`/apps/${appId}${match[2]}`),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// If we know any route for that app we open it
|
||||
if (appId in knownRoutes) {
|
||||
this.linkProps = {
|
||||
href: knownRoutes[appId],
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Fallback to show the app store entry
|
||||
this.routerProps = {
|
||||
to: {
|
||||
name: 'apps-details',
|
||||
params: {
|
||||
category: this.$route.params?.category ?? 'discover',
|
||||
id: appId,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue