packages/react/src/account/create-account-action.ts (152 lines of code) (raw):
import { createForm, getNotifier } from "@azure/bonito-core";
import { AbstractAction } from "@azure/bonito-core/lib/action";
import {
Form,
StringListParameter,
StringParameter,
ValidationStatus,
} from "@azure/bonito-core/lib/form";
import { translate } from "@azure/bonito-core/lib/localization";
import { delayedCallback } from "@azure/bonito-core/lib/util";
import {
LocationParameter,
ResourceGroupParameter,
StorageAccountParameter,
SubscriptionParameter,
} from "@azure/bonito-ui/lib/form";
export type CreateAccountFormValues = {
accountName?: string;
subscriptionId?: string;
resourceGroupId?: string;
location?: string;
storageAccountId?: string;
identityType?: string;
publicNetworkAccess?: string;
poolAllocationMode?: string;
allowedAuthenticationModes?: string[];
tags?: Record<string, string>;
};
export class CreateAccountAction extends AbstractAction<CreateAccountFormValues> {
actionName = "CreateAccount";
private _initialValues: CreateAccountFormValues = {};
async onInitialize(): Promise<CreateAccountFormValues> {
return this._initialValues;
}
constructor(initialValues: CreateAccountFormValues) {
super();
if (initialValues) {
this._initialValues = initialValues;
}
}
buildForm(
initialValues: CreateAccountFormValues
): Form<CreateAccountFormValues> {
const form = createForm<CreateAccountFormValues>({
title: "Create Account",
values: initialValues,
});
form.param("subscriptionId", SubscriptionParameter, {
label: translate("bonito.core.arm.subscription"),
required: true,
});
form.param("resourceGroupId", ResourceGroupParameter, {
dependencies: {
subscriptionId: "subscriptionId",
},
label: translate("bonito.core.arm.resourceGroup"),
required: true,
});
form.param("accountName", StringParameter, {
label: translate("lib.react.account.parameter.name.label"),
required: true,
description:
"This is how you identify your Batch account. It must be unique.",
dynamic: {
placeholder: (values) => {
// TODO: Probably better to use a custom control here like
// we do in the existing account creation form.
// Also needs to handle other clouds (and i18n)
const locationId = values.location;
if (locationId) {
const locationName = locationId.slice(
locationId.lastIndexOf("/") + 1
);
return `{account}.${locationName}.batch.azure.com`;
}
return "";
},
},
onValidateAsync: async (value) => {
if (value && !(await isAccountNameAvailable(value))) {
return new ValidationStatus(
"error",
`An account named ${value} already exists`
);
}
return new ValidationStatus("ok");
},
});
form.param("location", LocationParameter, {
dependencies: {
subscriptionId: "subscriptionId",
},
label: translate("bonito.core.arm.location"),
required: true,
});
form.param("storageAccountId", StorageAccountParameter, {
dependencies: {
subscriptionId: "subscriptionId",
},
label: translate("bonito.core.arm.storageAccount"),
description:
"Optional. For best performance we recommend a storage account (general purpose v2) located in the same region as the associated Batch account.",
});
const advancedSection = form.section("Advanced");
advancedSection.param("identityType", StringParameter, {
label: "Identity type",
});
advancedSection.param("publicNetworkAccess", StringParameter, {
label: "Public network access",
});
advancedSection.param("poolAllocationMode", StringParameter, {
label: "Pool allocation mode",
});
advancedSection.param(
"allowedAuthenticationModes",
StringListParameter,
{
label: "Authentication modes",
}
);
const tagsSection = form.section("Tags");
tagsSection.param("tags", StringParameter, {
hideLabel: true,
});
return form;
}
onValidateSync(): ValidationStatus {
return new ValidationStatus("ok");
}
async onValidateAsync(): Promise<ValidationStatus> {
return new ValidationStatus("ok");
}
async onExecute(formValues: CreateAccountFormValues): Promise<void> {
getNotifier().info(
"Account created",
"Would write form values:\n" +
JSON.stringify(formValues, undefined, 4)
);
}
}
async function isAccountNameAvailable(accountName: string): Promise<boolean> {
// TODO: Replace this with a real implementation and create a
// parameter type for account name
const existingAccountNames = new Set<string>([
"one",
"two",
"three",
"test",
]);
return delayedCallback(() => {
let isAvailable = true;
if (accountName && existingAccountNames.has(accountName)) {
isAvailable = false;
}
return isAvailable;
}, 200);
}