diff --git a/htmlui/src/SetupAzure.js b/htmlui/src/SetupAzure.js
new file mode 100644
index 000000000..992ad5d8b
--- /dev/null
+++ b/htmlui/src/SetupAzure.js
@@ -0,0 +1,29 @@
+import React, { Component } from 'react';
+import Form from 'react-bootstrap/Form';
+import { handleChange, OptionalField, RequiredField, validateRequiredFields } from './forms';
+
+export class SetupAzure extends Component {
+ constructor() {
+ super();
+
+ this.state = {};
+ this.handleChange = handleChange.bind(this);
+ }
+
+ validate() {
+ return validateRequiredFields(this, ["container", "storageAccount", "storageKey"])
+ }
+
+ render() {
+ return <>
+
+ {RequiredField(this, "Container", "container", { placeholder: "enter container name" })}
+ {OptionalField(this, "Object Name Prefix", "prefix", { placeholder: "enter object name prefix or leave empty", type: "password" })}
+
+
+ {RequiredField(this, "Access Key ID", "storageAccount", { placeholder: "enter access key ID" })}
+ {RequiredField(this, "Secret Access Key", "storageKey", { placeholder: "enter secret access key", type: "password" })}
+
+ >;
+ }
+}
diff --git a/htmlui/src/SetupRepository.js b/htmlui/src/SetupRepository.js
index 1bef7c437..af9103c6b 100644
--- a/htmlui/src/SetupRepository.js
+++ b/htmlui/src/SetupRepository.js
@@ -8,6 +8,7 @@ import { handleChange, RequiredField, validateRequiredFields } from './forms';
import { SetupFilesystem } from './SetupFilesystem';
import { SetupGCS } from './SetupGCS';
import { SetupS3 } from './SetupS3';
+import { SetupAzure } from './SetupAzure';
import { SetupSFTP } from './SetupSFTP';
import { SetupToken } from './SetupToken';
import { SetupWebDAV } from './SetupWebDAV';
@@ -16,6 +17,7 @@ const supportedProviders = [
{ provider: "filesystem", description: "Filesystem", component: SetupFilesystem },
{ provider: "gcs", description: "Google Cloud Storage", component: SetupGCS },
{ provider: "s3", description: "Amazon S3, Minio, Wasabi, etc.", component: SetupS3 },
+ { provider: "azureBlob", description: "Azure Blob Storage", component: SetupAzure },
{ provider: "sftp", description: "SFTP server", component: SetupSFTP },
{ provider: "webdav", description: "WebDAV server", component: SetupWebDAV },
{ provider: "_token", description: "(use token)", component: SetupToken },
diff --git a/htmlui/src/tests/SetupAzure.test.js b/htmlui/src/tests/SetupAzure.test.js
new file mode 100644
index 000000000..6bd834723
--- /dev/null
+++ b/htmlui/src/tests/SetupAzure.test.js
@@ -0,0 +1,26 @@
+import { render } from '@testing-library/react';
+import React from 'react';
+import { SetupAzure } from '../SetupAzure';
+import { changeControlValue } from './testutils';
+
+it('can set fields', async () => {
+ let ref = React.createRef();
+ const { getByTestId } = render()
+
+ expect(ref.current.validate()).toBe(false);
+ // required
+ changeControlValue(getByTestId("control-container"), "some-container");
+ changeControlValue(getByTestId("control-storageAccount"), "some-storageAccount");
+ changeControlValue(getByTestId("control-storageKey"), "some-storageKey");
+ expect(ref.current.validate()).toBe(true);
+ // optional
+ changeControlValue(getByTestId("control-prefix"), "some-prefix");
+ expect(ref.current.validate()).toBe(true);
+
+ expect(ref.current.state).toStrictEqual({
+ "storageAccount": "some-storageAccount",
+ "container": "some-container",
+ "prefix": "some-prefix",
+ "storageKey": "some-storageKey",
+ });
+});