Skip to content

Commit 21712dd

Browse files
authored
Merge branch 'main' into housekeeping-sso-cert-expiry
2 parents 550b11f + df3ee49 commit 21712dd

158 files changed

Lines changed: 1515 additions & 686 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/user/envvar.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,17 @@ The image below shows an instance with the following environment variables:
4949
Standard environment variables are set for all Node-RED instances running
5050
within the platform:
5151

52-
- `FF_INSTANCE_ID`
53-
- `FF_INSTANCE_NAME`
52+
- `FF_INSTANCE_ID` - The unique identifier of the instance
53+
- `FF_INSTANCE_NAME` - The name of the instance as set in FlowFuse
54+
- `FF_INSTANCE_URL` - The full URL of the instance (e.g. `https://my-instance.flowfuse.cloud`)
5455

5556
In addition, the following variables are set when running on a device:
5657

57-
- `FF_DEVICE_ID`
58-
- `FF_DEVICE_NAME`
59-
- `FF_DEVICE_TYPE`
60-
- `FF_SNAPSHOT_ID`
61-
- `FF_SNAPSHOT_NAME`
58+
- `FF_DEVICE_ID` - The unique identifier of the device
59+
- `FF_DEVICE_NAME` - The name of the device as set in FlowFuse
60+
- `FF_DEVICE_TYPE` - The device type label assigned in FlowFuse
61+
- `FF_SNAPSHOT_ID` - The unique identifier of the snapshot currently deployed to the device
62+
- `FF_SNAPSHOT_NAME` - The name of the snapshot currently deployed to the device
6263

6364
When deploying the same set of flows out to multiple devices, these variables can
6465
be used by the flows to identify the specific device being run on.

forge/db/controllers/Project.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const crypto = require('crypto')
22

33
const { ControllerError } = require('../../lib/errors')
4-
const { KEY_SETTINGS, KEY_STACK_UPGRADE_HOUR } = require('../models/ProjectSettings')
4+
const { KEY_CUSTOM_HOSTNAME, KEY_SETTINGS, KEY_STACK_UPGRADE_HOUR } = require('../models/ProjectSettings')
55

66
/**
77
* inflightProjectState - when projects are transitioning between states, there
@@ -314,11 +314,20 @@ module.exports = {
314314
const makeVar = (name, value, deprecated) => {
315315
return { name, value: value || '', platform: true, deprecated } // add `platform` and `deprecated` flags for UI
316316
}
317+
318+
let customHostname
319+
if (app.config.features.enabled('customHostnames')) {
320+
const projectURL = URL.parse(project.url)
321+
const hostnameSetting = project.ProjectSettings?.find(setting => setting.key === KEY_CUSTOM_HOSTNAME)
322+
customHostname = hostnameSetting?.value ? `${projectURL.protocol}//${hostnameSetting.value}` : undefined
323+
}
324+
317325
const result = []
318326
result.push(makeVar('FF_INSTANCE_ID', project.id || ''))
319327
result.push(makeVar('FF_INSTANCE_NAME', project.name || ''))
320328
result.push(makeVar('FF_PROJECT_ID', project.id || '', true)) // deprecated as of V1.6.0
321329
result.push(makeVar('FF_PROJECT_NAME', project.name || '', true)) // deprecated as of V1.6.0
330+
result.push(makeVar('FF_INSTANCE_URL', customHostname || project.url || ''))
322331
result.push(...app.db.controllers.Project.removePlatformSpecificEnvVars(envVars))
323332

324333
return result

forge/db/controllers/ProjectSnapshot.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ module.exports = {
382382
}
383383
if (options.settings?.env) {
384384
// derive the project's service env but not the rest
385-
const serviceEnv = ['FF_INSTANCE_ID', 'FF_INSTANCE_NAME', 'FF_PROJECT_ID', 'FF_PROJECT_NAME']
385+
const serviceEnv = ['FF_INSTANCE_ID', 'FF_INSTANCE_NAME', 'FF_PROJECT_ID', 'FF_PROJECT_NAME', 'FF_INSTANCE_URL']
386386
snapshotOptions.settings.env = {
387387
...options.settings.env,
388388
...serviceEnv.reduce((obj, key) => {

frontend/src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export default {
104104
...mapState(useUxDrawersStore, ['hiddenLeftDrawer']),
105105
...mapState(useAccountAuthStore, ['user']),
106106
...mapState(useUxLoadingStore, ['appLoader', 'offline']),
107-
...mapVuexState('account', ['team', 'settings']),
107+
...mapVuexState('account', ['settings']),
108108
loginRequired () {
109109
return this.$route.meta.requiresLogin !== false
110110
},

frontend/src/components/DevicesBrowser.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ import { CogIcon, PlusSmIcon } from '@heroicons/vue/solid'
348348
349349
import { mapActions, mapState } from 'pinia'
350350
import { markRaw } from 'vue'
351-
import { mapGetters, mapState as mapVuexState } from 'vuex'
351+
import { mapGetters } from 'vuex'
352352
353353
import deviceApi from '../api/devices.js'
354354
import teamApi from '../api/team.js'
@@ -386,6 +386,7 @@ import DevicesStatusBar from './charts/DeviceStatusBar.vue'
386386
import AddDeviceToGroupDialog from './dialogs/device-group-management/AddDeviceToGroupDialog.vue'
387387
import RemoveDeviceFromGroupDialog from './dialogs/device-group-management/RemoveDeviceFromGroupDialog.vue'
388388
389+
import { useContextStore } from '@/stores/context.js'
389390
import { useUxDialogStore } from '@/stores/ux-dialog.js'
390391
import { useUxToursStore } from '@/stores/ux-tours.js'
391392
@@ -461,7 +462,7 @@ export default {
461462
}
462463
},
463464
computed: {
464-
...mapVuexState('account', ['team', 'teamMembership']),
465+
...mapState(useContextStore, ['team']),
465466
...mapGetters('account', ['featuresCheck']),
466467
...mapState(useUxDialogStore, ['dialog']),
467468
...mapState(useUxToursStore, ['tours']),
@@ -615,7 +616,7 @@ export default {
615616
if (this.deviceCountDeltaSincePageLoad !== 0) {
616617
// Trigger a refresh of team info to resync following device
617618
// changes
618-
await this.$store.dispatch('account/refreshTeam')
619+
await useContextStore().refreshTeam()
619620
}
620621
},
621622
methods: {

frontend/src/components/NotificationsButton.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,18 @@
1111
import { MailIcon } from '@heroicons/vue/outline'
1212
import { mapActions, mapState } from 'pinia'
1313
import { markRaw } from 'vue'
14-
import { mapGetters } from 'vuex'
1514
1615
import NotificationsDrawer from './drawers/notifications/NotificationsDrawer.vue'
1716
17+
import { useAccountStore } from '@/stores/account.js'
1818
import { useUxDrawersStore } from '@/stores/ux-drawers.js'
1919
2020
export default {
2121
name: 'NotificationsButton',
2222
components: { MailIcon },
2323
computed: {
2424
...mapState(useUxDrawersStore, ['rightDrawer']),
25-
...mapGetters('account', ['hasNotifications']),
26-
...mapGetters('account', ['unreadNotificationsCount']),
25+
...mapState(useAccountStore, ['hasNotifications', 'unreadNotificationsCount']),
2726
notificationsCount: function () {
2827
// Return null if count = 0 so we don't show a 0 in the pill
2928
if (!this.unreadNotificationsCount) {

frontend/src/components/PageHeader.vue

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
import { AcademicCapIcon, AdjustmentsIcon, CogIcon, CursorClickIcon, LogoutIcon, MenuIcon, PlusIcon, QuestionMarkCircleIcon, XIcon } from '@heroicons/vue/solid'
105105
import { mapActions, mapState } from 'pinia'
106106
import { ref } from 'vue'
107-
import { mapGetters, mapState as mapVuexState } from 'vuex'
107+
import { mapGetters } from 'vuex'
108108
109109
import usePermissions from '../composables/Permissions.js'
110110
@@ -120,6 +120,8 @@ import TeamSelection from './TeamSelection.vue'
120120
import GlobalSearch from './global-search/GlobalSearch.vue'
121121
122122
import { useAccountAuthStore } from '@/stores/account-auth.js'
123+
import { useAccountStore } from '@/stores/account.js'
124+
import { useContextStore } from '@/stores/context.js'
123125
import { useUxDrawersStore } from '@/stores/ux-drawers.js'
124126
import { useUxToursStore } from '@/stores/ux-tours.js'
125127
@@ -132,8 +134,9 @@ export default {
132134
},
133135
...mapState(useUxDrawersStore, ['leftDrawer', 'hiddenLeftDrawer']),
134136
...mapState(useAccountAuthStore, ['user']),
135-
...mapVuexState('account', ['team', 'teams']),
136-
...mapGetters('account', ['notifications', 'hasAvailableTeams', 'defaultUserTeam', 'canCreateTeam', 'isTrialAccount', 'featuresCheck']),
137+
...mapState(useContextStore, ['team']),
138+
...mapState(useAccountStore, ['teams', 'notifications', 'hasAvailableTeams', 'defaultUserTeam']),
139+
...mapGetters('account', ['canCreateTeam', 'featuresCheck']),
137140
navigationOptions () {
138141
return [
139142
{

frontend/src/components/TeamSelection.vue

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,16 @@ import {
4242
ListboxOption
4343
} from '@headlessui/vue'
4444
import { PlusIcon, UserAddIcon } from '@heroicons/vue/solid'
45-
import { mapGetters, mapState } from 'vuex'
45+
import { mapState } from 'pinia'
46+
import { mapGetters, mapState as mapVuexState } from 'vuex'
4647
4748
import usePermissions from '../composables/Permissions.js'
4849
4950
import NavItem from './NavItem.vue'
5051
52+
import { useAccountStore } from '@/stores/account.js'
53+
import { useContextStore } from '@/stores/context.js'
54+
5155
export default {
5256
name: 'FFTeamSelection',
5357
emits: ['option-selected'],
@@ -61,8 +65,10 @@ export default {
6165
return { PlusIcon, UserAddIcon, hasPermission }
6266
},
6367
computed: {
64-
...mapState('account', ['team', 'teams', 'settings']),
65-
...mapGetters('account', ['hasAvailableTeams', 'canCreateTeam']),
68+
...mapState(useContextStore, ['team']),
69+
...mapState(useAccountStore, ['teams', 'hasAvailableTeams']),
70+
...mapVuexState('account', ['settings']),
71+
...mapGetters('account', ['canCreateTeam']),
6672
teamOptions () {
6773
return [
6874
...this.teams.map(team => {
@@ -101,7 +107,7 @@ export default {
101107
methods: {
102108
selectTeam (team) {
103109
if (team) {
104-
this.$store.dispatch('account/setTeam', team.slug)
110+
useAccountStore().setTeam(team.slug)
105111
.then(() => this.$router.push({
106112
name: 'Team',
107113
params: {

frontend/src/components/TeamTypeTile.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131

3232
<script>
3333
import { mapState } from 'pinia'
34-
import { mapState as mapVuexState } from 'vuex'
3534
3635
import { useHubspotHelper } from '../composables/Hubspot.js'
3736
3837
import { useAccountAuthStore } from '@/stores/account-auth.js'
38+
import { useAccountStore } from '@/stores/account.js'
3939
4040
export default {
4141
name: 'TeamTypeTile',
@@ -59,7 +59,7 @@ export default {
5959
return { talkToSalesCalendarModal }
6060
},
6161
computed: {
62-
...mapVuexState('account', ['teams']),
62+
...mapState(useAccountStore, ['teams']),
6363
...mapState(useAccountAuthStore, ['user']),
6464
pricing: function () {
6565
const billingDescriptionKey = this.billingInterval === 'year' ? 'yrDescription' : 'description'

frontend/src/components/banners/FeatureUnavailableToTeam.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
<script>
2727
import { SparklesIcon } from '@heroicons/vue/outline'
2828
29-
import { mapState } from 'vuex'
29+
import { mapState } from 'pinia'
30+
31+
import { useContextStore } from '@/stores/context.js'
3032
3133
export default {
3234
name: 'FeatureUnavailableToTeam',
@@ -49,7 +51,7 @@ export default {
4951
}
5052
},
5153
computed: {
52-
...mapState('account', ['team']),
54+
...mapState(useContextStore, ['team']),
5355
upgradePath () {
5456
return { name: 'TeamChangeType', params: { team_slug: this.team.slug } }
5557
}

0 commit comments

Comments
 (0)