Skip to content

Commit

Permalink
Merge branch '3rd-party-broker' into update-broker-guards
Browse files Browse the repository at this point in the history
  • Loading branch information
hardillb authored Feb 11, 2025
2 parents 0a19e87 + d14ce19 commit cb726fb
Show file tree
Hide file tree
Showing 29 changed files with 756 additions and 385 deletions.
26 changes: 24 additions & 2 deletions .github/workflows/branch-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ on:
description: 'flowfuse/nr-file-nodes branch name'
required: true
default: 'main'
nr_assistant_branch:
description: 'flowfuse/nr-assistant branch name'
required: true
default: 'main'
pull_request:
types:
- opened
Expand Down Expand Up @@ -120,16 +124,34 @@ jobs:
secrets:
npm_registry_token: ${{ secrets.NPM_PUBLISH_TOKEN }}

publish_nr_assistant:
name: Build and publish nr-assistant package
needs: validate-user
if: |
needs.validate-user.outputs.is_org_member == 'true' &&
github.event_name == 'workflow_dispatch' &&
inputs.nr_assistant_branch != 'main'
uses: 'flowfuse/github-actions-workflows/.github/workflows/[email protected]'
with:
package_name: nr-assistant
publish_package: true
repository_name: 'FlowFuse/nr-assistant'
branch_name: ${{ inputs.nr_assistant_branch }}
release_name: "pre-staging-${{ inputs.nr_assistant_branch }}"
secrets:
npm_registry_token: ${{ secrets.NPM_PUBLISH_TOKEN }}

publish_nr_launcher:
name: Build and publish nr-launcher package
needs:
- validate-user
- publish_nr_project_nodes
- publish_nr_file_nodes
- publish_nr_assistant
if: |
needs.validate-user.outputs.is_org_member == 'true' &&
github.event_name == 'workflow_dispatch' &&
(always() && inputs.nr_launcher_branch != 'main') || needs.publish_nr_project_nodes.result == 'success' || needs.publish_nr_file_nodes.result == 'success'
(always() && inputs.nr_launcher_branch != 'main') || needs.publish_nr_project_nodes.result == 'success' || needs.publish_nr_file_nodes.result == 'success' || needs.publish_nr_assistant.result == 'success'
uses: 'flowfuse/github-actions-workflows/.github/workflows/[email protected]'
with:
package_name: flowfuse-nr-launcher
Expand All @@ -140,7 +162,7 @@ jobs:
package_dependencies: |
@flowfuse/nr-project-nodes=${{ inputs.nr_project_nodes_branch != 'main' && needs.publish_nr_project_nodes.outputs.release_name || 'nightly' }}
@flowfuse/nr-file-nodes=${{ inputs.nr_file_nodes_branch != 'main' && needs.publish_nr_file_nodes.outputs.release_name || 'nightly' }}
@flowfuse/nr-assistant=nightly
@flowfuse/nr-assistant=${{ inputs.nr_assistant_branch != 'main' && needs.publish_nr_assistant.outputs.release_name || 'nightly' }}
secrets:
npm_registry_token: ${{ secrets.NPM_PUBLISH_TOKEN }}

Expand Down
2 changes: 1 addition & 1 deletion docs/install/docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ The following guide walks through a full production-ready deployment. If you wan
Before you begin, ensure you have the following:

1. **Domain Name & DNS:** A domain name that you own and can configure DNS settings for (explained in [DNS](#dns))
2. **Install Docker:** [Docker Engine](https://docs.docker.com/engine/) and [Docker Compose](https://docs.docker.com/compose/install/) must be installed on your system (either as a standalone binary or as docker plugin)
2. **Install Docker:** [Docker Engine](https://docs.docker.com/engine/) and [Docker Compose](https://docs.docker.com/compose/install/) (in `2.23.1` version or higher) must be installed on your system (either as a standalone binary or as docker plugin).

For a production-ready environment, we also recommend:
* **Database:** Prepare dedicated database on a external database server (see [FAQ](#how-to-use-external-database-server%3F) for more details)
Expand Down
2 changes: 1 addition & 1 deletion docs/quick-start/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ For a full installation guide, including how to setup FlowFuse in a production e

## Prerequisites

Before you begin, ensure you have [Docker](https://docs.docker.com/engine/install/) and [Docker Compose](https://docs.docker.com/compose/install/) installed on your system (either as a standalone binary or as docker plugin)
Before you begin, ensure you have [Docker](https://docs.docker.com/engine/install/) and [Docker Compose](https://docs.docker.com/compose/install/) (in `2.23.1` version or higher) installed on your system (either as a standalone binary or as docker plugin)

## Step 1: Configure Domain

Expand Down
23 changes: 0 additions & 23 deletions docs/upgrade/open-source-to-premium.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,3 @@ a restart of the `forge` app is required.
After the forge application has restarted, the Node-RED runtimes need to be
updated to leverage these features. As restarting Node-RED might need to be
coordinated, FlowFuse will not automatically restart all instances.

## Enabling FlowFuse User Authentication for @flowfuse/node-red-dashboard

Included with the Enterprise licensed FlowFuse is the ability to use
FlowFuse Authentication to control access to Dashboards and to have the
user information passed to the Node-RED Flow.

This is enabled by installing a Node-RED plugin `@flowfuse/node-red-dashboard-2-user-addon`.
To install this plugin you will require a npm authentication token. To request
one please contact <a href="mailto:[email protected]?subject=Dashboard 2 User addon">[email protected]</a>.

Once you have been supplied with a authentication token please follow these steps:

1. Under the Admin Settings page, open the Templates tab and edit the template
2. On the Palette page of the Template settings add the following to the "Node Catalogues" list `https://catalog.flowfuse.com/catalogue.json`
3. In the "NPM configuration file" section you will need to add
```
//registry.npmjs.org/:_authToken=<npm_auth_token>
```
replacing `<npm_auth_token>` with the token supplied earlier
4. Click on the "Save changes" button
5. Any existing Node-RED instances will need to be restarted to pick up the changes to the template
6. Once restarted you should be able to install the `@flowfuse/node-red-dashboard-2-user-addon` from the Palette Manage menu in the Node-RED instance.
14 changes: 13 additions & 1 deletion forge/routes/api/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,19 @@ module.exports = async function (app) {
const currentSettings = await request.device.getAllSettings()
// remove any extra properties from env to ensure they match the format of the body data
// and prevent updates from being logged for unchanged values
currentSettings.env = (currentSettings.env || []).map(e => ({ name: e.name, value: e.value }))
currentSettings.env = (currentSettings.env || []).map(e => ({ name: e.name, value: e.value, hidden: e.hidden ?? false }))
if (request.body.env) {
request.body.env.map(env => {
if (env.hidden === true && env.value === '') {
// we need to re-map the hidden value so it won't get overwritten
const existingVar = currentSettings.env.find(currentEnv => currentEnv.name === env.name)
if (existingVar) {
env.value = existingVar.value
}
}
return env
})
}
const captureUpdates = (key) => {
if (key === 'env') {
// transform the env array to a map for better logging format
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/components/DevicesBrowser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,10 @@
@device-updated="deviceUpdated"
>
<template #description>
<p>
<p v-if="!featuresCheck?.isHostedInstancesEnabledForTeam && tours['first-device']">
Describe your new Remote Instance here.
</p>
<p v-else>
Remote Instances are managed using the <a href="https://flowfuse.com/docs/user/devices/" target="_blank">FlowFuse Device Agent</a>. The agent will need to be setup on the hardware where you want your Remote Instance to run.
</p>
</template>
Expand Down Expand Up @@ -314,7 +317,7 @@ import { ClockIcon } from '@heroicons/vue/outline'
import { PlusSmIcon } from '@heroicons/vue/solid'
import { markRaw } from 'vue'
import { mapState } from 'vuex'
import { mapGetters, mapState } from 'vuex'
import deviceApi from '../api/devices.js'
import teamApi from '../api/team.js'
Expand Down Expand Up @@ -402,6 +405,8 @@ export default {
},
computed: {
...mapState('account', ['team', 'teamMembership']),
...mapState('ux', ['tours']),
...mapGetters('account', ['featuresCheck']),
columns () {
const columns = [
{ label: 'Remote Instance', key: 'name', sortable: !this.moreThanOnePage, component: { is: markRaw(DeviceLink) } },
Expand Down
27 changes: 25 additions & 2 deletions frontend/src/components/NavItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,25 @@
<span v-if="featureUnavailable" data-el="premium-feature" v-ff-tooltip="'Not available in this Tier'">
<SparklesIcon class="ff-icon transition-fade--color hollow" style="stroke-width: 1;" />
</span>
<span v-if="alert" data-el="nav-alert" v-ff-tooltip="alert.title ?? 'Attention required'" @click="onAlertClick">
<ExclamationCircleIcon class="ff-icon transition-fade--color hollow " style="stroke-width: 1.5;" />
</span>
</div>
<ff-notification-pill v-if="notifications > 0" :count="notifications" />
</li>
</template>

<script>
import { SparklesIcon } from '@heroicons/vue/outline'
import { ExclamationCircleIcon, SparklesIcon } from '@heroicons/vue/outline'
import { useNavigationHelper } from '../composables/NavigationHelper.js'
export default {
name: 'NavItem',
components: {
SparklesIcon
SparklesIcon,
ExclamationCircleIcon
},
props: {
icon: {
Expand All @@ -41,6 +47,23 @@ export default {
notifications: {
type: Number,
default: () => 0
},
alert: {
type: Object,
default: null
}
},
setup () {
const { openInANewTab } = useNavigationHelper()
return {
openInANewTab
}
},
methods: {
onAlertClick () {
if (this.alert.url) {
this.openInANewTab(this.alert.url)
}
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/components/PageHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default {
},
...mapState('account', ['user', 'team', 'teams']),
...mapState('ux', ['leftDrawer']),
...mapGetters('account', ['notifications', 'hasAvailableTeams', 'defaultUserTeam', 'canCreateTeam', 'isTrialAccount']),
...mapGetters('account', ['notifications', 'hasAvailableTeams', 'defaultUserTeam', 'canCreateTeam', 'isTrialAccount', 'featuresCheck']),
...mapGetters('ux', ['hiddenLeftDrawer']),
navigationOptions () {
return [
Expand All @@ -126,7 +126,7 @@ export default {
onclick: (route) => window.open(route.url, '_blank'),
onclickparams: { url: 'https://flowfuse.com/docs/' }
},
this.isTrialAccount
this.isTrialAccount || !this.featuresCheck?.isHostedInstancesEnabledForTeam
? {
label: 'Getting Started',
icon: AcademicCapIcon,
Expand Down Expand Up @@ -177,8 +177,7 @@ export default {
}
},
methods: {
...mapActions('ux', ['toggleLeftDrawer']),
...mapActions('ux', ['activateTour']),
...mapActions('ux', ['toggleLeftDrawer', 'activateTour']),
openEducationModal () {
this.activateTour('education')
product.capture('clicked-open-education-modal')
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/components/drawers/navigation/MainNav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
:label="entry.label"
:icon="entry.icon"
:featureUnavailable="entry.featureUnavailable"
:alert="entry.alert ?? null"
/>
</router-link>
</li>
Expand Down Expand Up @@ -93,7 +94,14 @@ export default {
return { ...defaultBackToRoute, ...this.nearestMetaMenu.backTo }
case isNearestMenuAnObject && hasBackToProp && typeof this.nearestMetaMenu.backTo === 'function':
return { ...defaultBackToRoute, ...this.nearestMetaMenu.backTo({ team_slug: this.team?.slug }) }
return {
...defaultBackToRoute,
...this.nearestMetaMenu.backTo({
params: this.$route.params,
query: this.$route.query,
team: this.team
})
}
case typeof this.nearestMetaMenu === 'string':
default:
Expand Down
11 changes: 7 additions & 4 deletions frontend/src/components/pipelines/Stage.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div v-if="stage" class="ff-pipeline-stage" data-el="ff-pipeline-stage" :class="{'ff-pipeline-stage--error': inDeveloperMode}">
<div v-if="stage" class="ff-pipeline-stage" data-el="ff-pipeline-stage" :class="{'ff-pipeline-stage--error': inDeveloperMode && stageIndex > 0}">
<div class="ff-pipeline-stage-banner">
<div class="ff-pipeline-stage-banner-name">
<label>{{ stage.name }}</label>
Expand Down Expand Up @@ -33,7 +33,7 @@
v-if="stage.stageType !== StageType.DEVICEGROUP"
v-ff-tooltip:right="'Run Pipeline Stage'"
data-action="stage-run"
:class="{'ff-disabled': !playEnabled || !pipeline?.id || deploying || inDeveloperMode}"
:class="{'ff-disabled': !playEnabled || !pipeline?.id || deploying }"
@click="runStage"
>
<PlayIcon
Expand Down Expand Up @@ -213,6 +213,9 @@ export default {
},
emits: ['stage-deleted', 'stage-deploy-starting', 'stage-deploy-started', 'stage-deploy-failed'],
computed: {
stageIndex () {
return this.pipeline.stages.indexOf(this.stage)
},
deploying () {
return this.stage.isDeploying
},
Expand Down Expand Up @@ -258,9 +261,9 @@ export default {
}
}
if (this.pipeline.stages.length > 0 && this.pipeline.stages.indexOf(this.stage) > 0) {
if (this.pipeline.stages.length > 0 && this.stageIndex > 0) {
route.query = {
sourceStage: this.pipeline.stages[this.pipeline.stages.indexOf(this.stage)].id
sourceStage: this.pipeline.stages[this.stageIndex].id
}
}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/pages/UnverifiedEmail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export default {
await userApi.verifyEmailToken(this.token)
clearTimeout(this.resendTimeout)
this.$store.dispatch('ux/activateTour', 'welcome')
this.$store.dispatch('ux/setNewlyCreatedUser', true)
this.$router.go()
} catch (err) {
console.error(err)
Expand Down
Loading

0 comments on commit cb726fb

Please sign in to comment.