Skip to content
This repository was archived by the owner on Jun 26, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/img/channels/community/blockbax.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions assets/js/components/channels/ChannelConnectionDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import GoogleSheetForm from "./community/google_sheets/GoogleSheetUpdateForm.jsx
import MicroshareForm from "./community/microshare/MicroshareUpdateForm.jsx";
import TagoForm from "./community/tago/TagoUpdateForm.jsx";
import UbidotsForm from "./community/ubidots/UbidotsUpdateForm.jsx";
import BlockbaxForm from "./community/blockbax/BlockbaxUpdateForm";
const { Panel } = Collapse

function DetailsUpdateWrapper({ handleUpdateDetailsChange, validInput, children, mobile }) {
Expand Down Expand Up @@ -62,6 +63,17 @@ function DetailsUpdateWrapper({ handleUpdateDetailsChange, validInput, children,

export default ({ channel, handleUpdateDetailsInput, handleUpdateDetailsChange, validInput, mobile}) => {
switch (channel.type) {
case "blockbax":
return (
<DetailsUpdateWrapper handleUpdateDetailsChange={handleUpdateDetailsChange} validInput={validInput} mobile={mobile}>
<BlockbaxForm
onValidInput={handleUpdateDetailsInput}
type="update"
channel={channel}
mobile={mobile}
/>
</DetailsUpdateWrapper>
)
case "aws":
return (
<DetailsUpdateWrapper handleUpdateDetailsChange={handleUpdateDetailsChange} validInput={validInput} mobile={mobile}>
Expand Down
3 changes: 3 additions & 0 deletions assets/js/components/channels/ChannelNew.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import MobileLayout from "../mobile/MobileLayout";
import ArrowLeftOutlined from "@ant-design/icons/ArrowLeftOutlined";
import { CORE_INTEGRATION_TYPES, COMMUNITY_INTEGRATION_TYPES, getAllowedIntegrations } from "../../util/integrationInfo";
import { isMobile } from "../../util/constants";
import BlockbaxForm from "./community/blockbax/BlockbaxForm.jsx";

@connect(null, mapDispatchToProps)
class ChannelNew extends Component {
Expand Down Expand Up @@ -64,6 +65,8 @@ class ChannelNew extends Component {
const { type } = this.state

switch (type) {
case "blockbax":
return <BlockbaxForm mobile={mobile} type={type} reset={this.resetType} createChannel={this.props.createChannel} />
case "cargo":
return <CargoForm mobile={mobile} type={type} reset={this.resetType} createChannel={this.props.createChannel} />
case "my_devices":
Expand Down
134 changes: 134 additions & 0 deletions assets/js/components/channels/community/blockbax/BlockbaxForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React, { Component } from "react";
import { IntegrationTypeTileSimple } from "../../IntegrationTypeTileSimple";
import { Link } from "react-router-dom";
import ChannelNameForm from "../../default/ChannelNameForm.jsx";
import analyticsLogger from "../../../../util/analyticsLogger";
import { Card, Typography, Input, Button, Row, Col } from "antd";
const { Text } = Typography;

class BlockbaxForm extends Component {
state = {
showNextSteps: false,
blockbaxAccessToken: "",
blockbaxInboundConnectorEndpoint: "",
validInput: true,
channelName: "",
};

handleInputUpdate = (e) => {
this.setState({ [e.target.name]: e.target.value }, () => {
const { blockbaxAccessToken, blockbaxInboundConnectorEndpoint } =
this.state;

if (
blockbaxAccessToken.length > 0 &&
blockbaxInboundConnectorEndpoint.length > 0
) {
this.setState({
showNextSteps: true,
validInput: true,
});
} else {
this.setState({
validInput: false,
});
}
});
};

handleNameInput = (e) => {
this.setState({ channelName: e.target.value });
};

onSubmit = () => {
const {
blockbaxAccessToken,
blockbaxInboundConnectorEndpoint,
channelName,
} = this.state;

const payload = {
channel: {
name: channelName,
type: this.props.type,
blockbaxInboundConnectorEndpoint,
credentials: {
blockbaxAccessToken,
},
},
};

this.props.createChannel(payload);

const topic = this.props.mobile
? "ACTION_CREATE_CHANNEL_MOBILE"
: "ACTION_CREATE_CHANNEL";

analyticsLogger.logEvent(topic, {
name: channelName,
type: this.props.type,
});
};

render() {
const { type } = this.props;

return (
<>
<Card title="Step 1 – Choose an Integration Type">
<div>
<IntegrationTypeTileSimple type={this.props.type} />
<Link
to="#"
onClick={(e) => {
e.preventDefault();
this.props.reset();
}}
>
<Button style={{ marginTop: 15 }}>Change</Button>
</Link>
</div>
</Card>

<Card title="Step 2 - Blockbax Endpoint Details">
<Text>
{`${type === "update" ? "Update" : "Enter"} your Blockbax details`}
</Text>

<Row gutter={16} style={{ marginBottom: 16, marginTop: 20 }}>
<Col sm={12}>
<Text>Blockbax Access Token</Text>
<Input
placeholder="Blockbax Access Token"
name="blockbaxAccessToken"
value={this.state.blockbaxAccessToken}
onChange={this.handleInputUpdate}
/>
</Col>
<Col sm={12}>
<Text>Blockbax Inbdound Connector Endpoint</Text>
<Input
placeholder="Blockbax Inbound Connector Endpoint"
name="blockbaxInboundConnectorEndpoint"
value={this.state.blockbaxInboundConnectorEndpoint}
onChange={this.handleInputUpdate}
/>
</Col>
</Row>
</Card>

{this.state.showNextSteps && (
<ChannelNameForm
channelName={this.state.channelName}
onInputUpdate={this.handleNameInput}
validInput={this.state.validInput}
submit={this.onSubmit}
mobile={this.props.mobile}
/>
)}
</>
);
}
}

export default BlockbaxForm;
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { Component } from "react";
import { Typography, Input, Row, Col } from "antd";
const { Text } = Typography;

class BlockbaxUpdateForm extends Component {
state = {
blockbaxAccessToken: "",
blockbaxInboundConnectorEndpoint: "",
};

handleInputUpdate = (e) => {
this.setState({ [e.target.name]: e.target.value }, () => {
const { blockbaxAccessToken, blockbaxInboundConnectorEndpoint } =
this.state;

if (
blockbaxAccessToken.length > 0 &&
blockbaxInboundConnectorEndpoint.length > 0
) {
this.props.onValidInput(
{
blockbaxAccessToken,
blockbaxInboundConnectorEndpoint,
},
true
);
} else {
this.props.onValidInput(
{
blockbaxAccessToken: "",
blockbaxInboundConnectorEndpoint: "",
},
false
);
}
});
};

render() {
return (
<>
<Text>Enter your Blockbax Integration Details</Text>

<Row gutter={16} style={{ marginBottom: 16, marginTop: 20 }}>
<Col sm={12}>
<Text>Blockbax Access Token</Text>
<Input
placeholder="Blockbax Access Token"
name="blockbaxAccessToken"
value={this.state.blockbaxAccessToken}
onChange={this.handleInputUpdate}
/>
</Col>
<Col sm={12}>
<Text>Blockbax Inbound Connector Endpoint</Text>
<Input
placeholder="Blockbax Inbound Connector Endpoint"
name="blockbaxInboundConnectorEndpoint"
value={this.state.blockbaxInboundConnectorEndpoint}
onChange={this.handleInputUpdate}
/>
</Col>
</Row>
</>
);
}
}

export default BlockbaxUpdateForm;
18 changes: 17 additions & 1 deletion assets/js/util/integrationInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ import TagoDark from "../../img/channels/community/flows/tago-dark.png";
import Ubidots from "../../img/channels/community/ubidots.png";
import UbidotsDark from "../../img/channels/community/flows/ubidots-dark.png";
import UbidotsIntro from "../../img/channels/community/intro_screens/ubidots.png";
import Blockbax from "../../img/channels/community/blockbax.png"
import BlockbaxDark from "../../img/channels/community/flows/blockbax-dark.png"
import BlockbaxIntro from "../../img/channels/community/intro_screens/blockbax.png"

export const integrationImgMap = {
blockbax: BlockbaxDark,
adafruit: AdafruitDark,
aws: AwsDark,
azure: AzureDark,
Expand All @@ -49,7 +53,7 @@ export const integrationImgMap = {
akenza: AkenzaDark,
};

export const http_integrations = ["http", "cargo", "my_devices", "akenza", "datacake", "microshare", "tago", "ubidots", "google_sheets"]
export const http_integrations = ["http", "blockbax", "cargo", "my_devices", "akenza", "datacake", "microshare", "tago", "ubidots", "google_sheets"]
export const mqtt_integrations = ["mqtt", "adafruit"]

export const getAllowedIntegrations = () => {
Expand Down Expand Up @@ -96,6 +100,18 @@ export const CORE_INTEGRATION_TYPES = [
];

export const COMMUNITY_INTEGRATION_TYPES = [
{
name: "Blockbax",
type: "blockbax",
img: `${Blockbax}`,
info: {
title: "Blockbax Low-Code IoT Platform",
desc: "Join the future of smart operations, automate your business through sensor and machine data without coding.",
docLink: "https://blockbax.com/docs/integrations/helium/",
externalLink: "https://blockbax.com/"
},
introImg: `${BlockbaxIntro}`
},
{
name: "Helium Cargo",
type: "cargo",
Expand Down
3 changes: 2 additions & 1 deletion lib/console/channels/channel.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ defmodule Console.Channels.Channel do
alias Console.Organizations.Organization
alias Console.Channels.Channel

@http_types ~w(http cargo my_devices akenza datacake microshare tago ubidots google_sheets)
@http_types ~w(blockbax http cargo my_devices akenza datacake microshare tago ubidots google_sheets)
@long_type_names %{
"blockbax" => "Blockbax",
"aws" => "AWS IoT",
"azure" => "Azure IoT Hub",
"iot_central" => "Azure IoT Central",
Expand Down
15 changes: 15 additions & 0 deletions lib/console/community/community_channels.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
defmodule Console.CommunityChannels do
def append_connection_details(channel) do
case channel.type do
"blockbax" ->
channel
|> Map.put(:endpoint, "#{channel.credentials["blockbaxInboundConnectorEndpoint"]}")
|> Map.put(:method, "post")
|> Map.put(:headers, Jason.encode!(%{ "Content-Type" => "application/json" }))
|> Map.put(:headers, Jason.encode!(%{ "Authorization" => "ApiKey #{channel.credentials["blockbaxAccessToken"]}" }))
"cargo" ->
channel
|> Map.put(:endpoint, "https://cargo.helium.com/api/payloads")
Expand Down Expand Up @@ -60,6 +66,15 @@ defmodule Console.CommunityChannels do

def inject_credentials(channel, show_underlying_type \\ true) do
case channel.type do
"blockbax" ->
channel
|> Map.put(:credentials, %{
"endpoint" => "#{channel.credentials["inboundConnectorEndpoint"]}",
"headers" => %{ "Authorization" => "ApiKey #{channel.credentials["accessToken"]}" },
"method" => "post",
"url_params" => %{}
})
|> Map.put(:type, (if show_underlying_type, do: "http", else: channel.type))
"cargo" ->
channel
|> Map.put(:credentials, %{
Expand Down
9 changes: 9 additions & 0 deletions lib/console_web/controllers/v1/channel_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ defmodule ConsoleWeb.V1.ChannelController do
if type in allowed_types do
channel_params =
case type do
"blockbax" ->
%{
"name" => name,
"type" => type,
"organization_id" => current_organization.id,
"credentials" => %{
"blockbaxAccessToken" => token,
}
}
"akenza" ->
%{
"credentials" => %{
Expand Down