Skip to content

Commit

Permalink
Merge pull request #4834 from FlowFuse/use-default-behavior-for-platf…
Browse files Browse the repository at this point in the history
…orm-wide-anchors

Use default behavior for platform wide anchors (part I)
  • Loading branch information
joepavitt authored Dec 6, 2024
2 parents 9bb28ab + d57b40b commit a67c117
Show file tree
Hide file tree
Showing 16 changed files with 204 additions and 107 deletions.
24 changes: 6 additions & 18 deletions frontend/src/components/PageHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
</transition>
</i>
<!-- FlowFuse Logo -->
<img class="ff-logo" src="/ff-logo--wordmark-caps--dark.png" @click="home()">
<router-link :to="homeLink">
<img class="ff-logo" src="/ff-logo--wordmark-caps--dark.png">
</router-link>
<global-search v-if="hasAMinimumTeamRoleOf(Roles.Viewer)" />
<!-- Mobile: Toggle(User Options) -->
<div class="flex ff-mobile-navigation-right" data-el="mobile-nav-right">
Expand Down Expand Up @@ -44,7 +46,7 @@
<div class="hidden lg:flex ff-desktop-navigation-right" data-el="desktop-nav-right">
<ff-team-selection data-action="team-selection" />
<div class="px-4 flex flex-col justify-center" v-if="showInviteButton">
<ff-button kind="secondary" @click="inviteTeamMembers">
<ff-button kind="secondary" type="anchor" :to="{ name: 'team-members', params: { team_slug: team.slug }, query: { action: 'invite' } }">
<template #icon-left><UserAddIcon /></template>
Invite Members
</ff-button>
Expand Down Expand Up @@ -89,7 +91,7 @@ import TeamSelection from './TeamSelection.vue'
import GlobalSearch from './global-search/GlobalSearch.vue'
export default {
name: 'NavBar',
name: 'PageHeader',
mixins: [navigationMixin, permissionsMixin],
computed: {
Roles () {
Expand Down Expand Up @@ -121,7 +123,7 @@ export default {
label: 'Documentation',
icon: QuestionMarkCircleIcon,
tag: 'documentation',
onclick: this.to,
onclick: (route) => window.open(route.url, '_blank'),
onclickparams: { url: 'https://flowfuse.com/docs/' }
},
this.isTrialAccount
Expand Down Expand Up @@ -176,20 +178,6 @@ export default {
},
methods: {
...mapActions('ux', ['toggleLeftDrawer']),
to (route) {
window.open(route.url, '_blank')
},
inviteTeamMembers () {
this.$router.push({
name: 'team-members',
params: {
team_slug: this.team.slug
},
query: {
action: 'invite'
}
})
},
...mapActions('ux', ['activateTour']),
openEducationModal () {
this.activateTour('education')
Expand Down
56 changes: 56 additions & 0 deletions frontend/src/composables/NavigationHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useRouter } from 'vue-router'

export function useNavigationHelper () {
const _router = useRouter()

const openInANewTab = (href) => {
return new Promise(resolve => {
window.open(href, '_blank')
resolve()
})
}

const _isExternalLink = (href) => {
try {
const link = new URL(href, window.location.origin)

return link.origin !== window.location.origin
} catch {
return false
}
}

const navigateTo = (to, $event = null) => {
const internalHref = _router.resolve(to).href
const isMiddleButtonClick = $event?.button === 1
const newTabKeyCombination = $event && ($event?.ctrlKey || $event.metaKey || isMiddleButtonClick)
const isExternalLink = _isExternalLink(to)

switch (true) {
case isExternalLink && newTabKeyCombination:
return openInANewTab(to)

case isExternalLink:
return navigateToExternal(to)

case newTabKeyCombination:
return openInANewTab(internalHref)

default:
return _router.push(to)
}
}

const navigateToExternal = (href) => {
return new Promise(resolve => {
window.location.href = href
resolve()
})
}

return {
openInANewTab,
navigateTo,
navigateToExternal
}
}
16 changes: 8 additions & 8 deletions frontend/src/mixins/Navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ import { mapState } from 'vuex'

export default {
computed: {
...mapState('account', ['team', 'defaultUserTeam'])
},
methods: {
home () {
...mapState('account', ['team', 'defaultUserTeam']),
homeLink () {
if (this.team?.slug) {
this.$router.push({ name: 'Team', params: { team_slug: this.team.slug } })
return { name: 'Team', params: { team_slug: this.team.slug } }
} else if (this.defaultUserTeam?.slug) {
this.$router.push({ name: 'Team', params: { team_slug: this.defaultUserTeam?.slug } })
return { name: 'Team', params: { team_slug: this.defaultUserTeam?.slug } }
} else {
this.$router.push({ name: 'Home' })
return { name: 'Home' }
}
},
}
},
methods: {
signOut () {
this.$router.push({ name: 'Sign out' })
}
Expand Down
16 changes: 13 additions & 3 deletions frontend/src/pages/application/Overview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
v-if="hasPermission('project:create')"
data-action="create-instance"
:to="{ name: 'ApplicationCreateInstance' }"
type="anchor"
>
<template #icon-left><PlusSmIcon /></template>
Add Instance
Expand Down Expand Up @@ -79,6 +80,7 @@
<ff-button
v-if="hasPermission('project:create')"
:to="{ name: 'ApplicationCreateInstance' }"
type="anchor"
>
<template #icon-left><PlusSmIcon /></template>
Add Instance
Expand All @@ -104,6 +106,7 @@ import { mapState } from 'vuex'
import EmptyState from '../../components/EmptyState.vue'
import SectionTopMenu from '../../components/SectionTopMenu.vue'
import { useNavigationHelper } from '../../composables/NavigationHelper.js'
import permissionsMixin from '../../mixins/Permissions.js'
import { Roles } from '../../utils/roles.js'
Expand Down Expand Up @@ -134,6 +137,13 @@ export default {
}
},
emits: ['instance-delete', 'instance-suspend', 'instance-restart', 'instance-start'],
setup () {
const { navigateTo } = useNavigationHelper()
return {
navigateTo
}
},
data () {
return {
searchTerm: ''
Expand Down Expand Up @@ -180,13 +190,13 @@ export default {
}
},
methods: {
selectedCloudRow (cloudInstance) {
this.$router.push({
selectedCloudRow (cloudInstance, event) {
this.navigateTo({
name: 'Instance',
params: {
id: cloudInstance.id
}
})
}, event)
},
updateSearch (searchTerm) {
this.searchTerm = searchTerm
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/application/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ import ConfirmInstanceDeleteDialog from '../instance/Settings/dialogs/ConfirmIns
import ConfirmApplicationDeleteDialog from './Settings/dialogs/ConfirmApplicationDeleteDialog.vue'
export default {
name: 'ProjectPage',
name: 'ApplicationPage',
components: {
ConfirmApplicationDeleteDialog,
ConfirmInstanceDeleteDialog,
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/pages/instance/components/DashboardLink.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<template>
<ff-button
v-if="!hidden"
type="anchor"
kind="secondary"
data-action="open-dashboard"
:to="dashboardURL"
:target="target"
:disabled="buttonDisabled"
class="whitespace-nowrap"
@click.stop.prevent
@mouseup.stop.prevent
>
<template v-if="showText" #icon-left>
<ChartPieIcon />
Expand Down
36 changes: 22 additions & 14 deletions frontend/src/pages/instance/components/EditorLink.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<template>
<div :data-type="`${isImmersiveEditor ? 'immersive' : 'standard'}-editor`" @click.stop="openEditor()">
<div :data-type="`${isImmersiveEditor ? 'immersive' : 'standard'}-editor`" @mouseup.stop.prevent="openEditor">
<slot name="default">
<ff-button
v-ff-tooltip:left="(editorDisabled || disabled) ? disabledReason : undefined"
type="anchor"
:to="editorURL"
kind="secondary"
data-action="open-editor"
:disabled="buttonDisabled"
class="whitespace-nowrap"
@click.stop="openEditor"
:emit-instead-of-navigate="true"
@select="openEditor"
>
<template v-if="showText" #icon-left>
<ProjectIcon />
Expand All @@ -32,6 +31,7 @@ import SemVer from 'semver'
import { mapState } from 'vuex'
import ProjectIcon from '../../../components/icons/Projects.js'
import { useNavigationHelper } from '../../../composables/NavigationHelper.js'
export default {
name: 'InstanceEditorLink',
Expand Down Expand Up @@ -59,6 +59,13 @@ export default {
type: Boolean
}
},
setup () {
const { openInANewTab } = useNavigationHelper()
return {
openInANewTab
}
},
computed: {
...mapState('account', ['team', 'teamMembership']),
isImmersiveEditor () {
Expand All @@ -85,20 +92,21 @@ export default {
},
methods: {
openEditor (evt) {
evt.preventDefault()
if (this.disabled) {
return false
}
let href = this.url
let target = !this.isImmersiveEditor ? '_blank' : '_self'
// On Mac Keyboard, ⌘ + click opens in new tab (⌘ is `metaKey`)
// Otherwise Ctrl + click opens in new tab (Ctrl is `ctrlKey`)
if (evt.ctrlKey || evt.metaKey) {
target = '_blank'
href = this.editorURL
switch (true) {
case !this.isImmersiveEditor:
return this.openInANewTab(this.editorURL)
case evt.ctrlKey || evt.metaKey || evt.button === 1:
// On Mac Keyboard, ⌘ + click opens in new tab (⌘ is `metaKey`)
// Otherwise Ctrl + click opens in new tab (Ctrl is `ctrlKey`)
// Middle mouse button click opens in a new tab (button === 1)
return this.openInANewTab(this.url)
default:
return this.$router.push(this.url)
}
window.open(href, target)
return false
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
<template>
<div class="ff-application-list--app gap-x-4 flex flex-col gap-2 sm:gap-0 justify-between sm:flex-row sm:items-center" data-action="view-application" @click="openApplication(application)">
<router-link
:to="{ name: 'Application', params: { id: application.id } }"
data-action="view-application"
class="ff-application-list--app gap-x-4 flex flex-col gap-2 sm:gap-0 justify-between sm:flex-row sm:items-center"
>
<div class="flex items-cente flex-wrap">
<span class="ff-application-list--icon flex flex-shrink-0 flex-grow-0 whitespace-nowrap gap-2 w-full"><TemplateIcon class="ff-icon text-gray-600" />{{ application.name }}</span>
<span class="!inline-block !flex-shrink !flex-grow italic text-gray-500 dark:text-gray-400 truncate"> {{ application.description }} </span>
<span class="ff-application-list--icon flex flex-shrink-0 flex-grow-0 whitespace-nowrap gap-2 w-full">
<TemplateIcon class="ff-icon text-gray-600" />
{{ application.name }}
</span>
<span class="!inline-block !flex-shrink !flex-grow italic text-gray-500 dark:text-gray-400 truncate">
{{ application.description }}
</span>
</div>
<ApplicationSummaryLabel :application="application" />
</div>
</router-link>
</template>

<script>
Expand All @@ -25,16 +34,6 @@ export default {
required: true,
default: null
}
},
methods: {
openApplication (application) {
this.$router.push({
name: 'Application',
params: {
id: application.id
}
})
}
}
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
</div>
<div class="details">
<div class="detail-wrapper">
<span class="cursor-pointer name" @click="openDevice(device)">{{ device.name }}</span>
<router-link :to="{ name: 'Device', params: { id: device.id } }" class="name" :title="device.name">
{{ device.name }}
</router-link>
</div>
<div class="detail-wrapper">
<span class="detail">
Expand Down Expand Up @@ -69,17 +71,7 @@ export default {
type: Object
}
},
emits: ['device-action'],
methods: {
openDevice (device) {
this.$router.push({
name: 'Device',
params: {
id: device.id
}
})
}
}
emits: ['device-action']
}
</script>

Expand Down
Loading

0 comments on commit a67c117

Please sign in to comment.