diff --git a/src/assets/icons/Leaf.tsx b/src/assets/icons/Leaf.tsx
new file mode 100644
index 00000000..dc092b28
--- /dev/null
+++ b/src/assets/icons/Leaf.tsx
@@ -0,0 +1,10 @@
+import SvgIcon, { SvgIconProps } from "@mui/material/SvgIcon";
+import { mdiLeaf } from "@mdi/js";
+
+export default function Leaf(props: SvgIconProps) {
+ return (
+
+
+
+ );
+}
diff --git a/src/components/Settings/ProjectSettings/RowyRun.tsx b/src/components/Settings/ProjectSettings/RowyRun.tsx
index 260d9b4d..6af1c0e0 100644
--- a/src/components/Settings/ProjectSettings/RowyRun.tsx
+++ b/src/components/Settings/ProjectSettings/RowyRun.tsx
@@ -17,7 +17,7 @@ import { IProjectSettingsChildProps } from "@src/pages/Settings/ProjectSettings"
import { WIKI_LINKS } from "@src/constants/externalLinks";
import useUpdateCheck from "@src/hooks/useUpdateCheck";
import { runRoutes } from "@src/constants/runRoutes";
-
+import RegionSelect from "@src/components/Settings/RegionSelect";
export default function RowyRun({
settings,
updateSettings,
@@ -191,6 +191,22 @@ export default function RowyRun({
+
+
+
+ updateSettings({ region: v || "" })}
+ fullWidth
+ />
+
+
+ Select the region where your Cloud Functions are deployed. All new
+ deployments of Rowy cloud functions will be deployed to this region.
+
+
+
>
);
}
diff --git a/src/components/Settings/RegionSelect.tsx b/src/components/Settings/RegionSelect.tsx
new file mode 100644
index 00000000..6e81649b
--- /dev/null
+++ b/src/components/Settings/RegionSelect.tsx
@@ -0,0 +1,60 @@
+import MultiSelect from "@rowy/multiselect";
+import { Grid } from "@mui/material";
+import LeafIcon from "@src/assets/icons/Leaf";
+
+import _sortBy from "lodash-es/sortBy";
+import { CLOUD_RUN_REGIONS } from "@src/constants/regions";
+const REGIONS = _sortBy(CLOUD_RUN_REGIONS, ["group", "value"]);
+
+export interface ICloudRunRegionSelectProps {
+ value: string;
+ onChange: (value: string) => void;
+ [key: string]: any;
+}
+
+export default function CloudRunRegionSelect({
+ value,
+ onChange,
+ ...props
+}: ICloudRunRegionSelectProps) {
+ return (
+ (
+
+
+ {option.value}
+
+ {option.city}
+
+
+
+
+ Tier {option.pricingTier} pricing
+
+ {option.lowCO2 && (
+
+ Low CO₂
+
+
+ )}
+
+ )}
+ {...({
+ AutocompleteProps: { groupBy: (option: any) => option.group },
+ } as any)}
+ TextFieldProps={{ style: { maxWidth: 364 }, ...props.TextFieldProps }}
+ />
+ );
+}
diff --git a/src/constants/regions.ts b/src/constants/regions.ts
new file mode 100644
index 00000000..0a2c2f9e
--- /dev/null
+++ b/src/constants/regions.ts
@@ -0,0 +1,381 @@
+export const CLOUD_RUN_REGIONS = [
+ {
+ value: "asia-east1",
+ label: "asia-east1",
+ group: "Asia Pacific",
+ city: "Taiwan",
+ pricingTier: 1,
+ lowCO2: false,
+ },
+ {
+ value: "asia-northeast1",
+ label: "asia-northeast1",
+ group: "Asia Pacific",
+ city: "Tokyo",
+ pricingTier: 1,
+ lowCO2: false,
+ },
+ {
+ value: "asia-northeast2",
+ label: "asia-northeast2",
+ group: "Asia Pacific",
+ city: "Osaka",
+ pricingTier: 1,
+ lowCO2: false,
+ },
+ {
+ value: "europe-north1",
+ label: "europe-north1",
+ group: "Europe",
+ city: "Finland",
+ pricingTier: 1,
+ lowCO2: true,
+ },
+ {
+ value: "europe-west1",
+ label: "europe-west1",
+ group: "Europe",
+ city: "Belgium",
+ pricingTier: 1,
+ lowCO2: true,
+ },
+ {
+ value: "europe-west4",
+ label: "europe-west4",
+ group: "Europe",
+ city: "Netherlands",
+ pricingTier: 1,
+ lowCO2: false,
+ },
+ {
+ value: "us-central1",
+ label: "us-central1",
+ group: "Americas",
+ city: "Iowa",
+ pricingTier: 1,
+ lowCO2: true,
+ },
+ {
+ value: "us-east1",
+ label: "us-east1",
+ group: "Americas",
+ city: "South Carolina",
+ pricingTier: 1,
+ lowCO2: false,
+ },
+ {
+ value: "us-east4",
+ label: "us-east4",
+ group: "Americas",
+ city: "Northern Virginia",
+ pricingTier: 1,
+ lowCO2: false,
+ },
+ {
+ value: "us-west1",
+ label: "us-west1",
+ group: "Americas",
+ city: "Oregon",
+ pricingTier: 1,
+ lowCO2: true,
+ },
+ {
+ value: "asia-east2",
+ label: "asia-east2",
+ group: "Asia Pacific",
+ city: "Hong Kong",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "asia-northeast3",
+ label: "asia-northeast3",
+ group: "Asia Pacific",
+ city: "Seoul, South Korea",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "asia-southeast1",
+ label: "asia-southeast1",
+ group: "Asia Pacific",
+ city: "Singapore",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "asia-southeast2",
+ label: "asia-southeast2",
+ group: "Asia Pacific",
+ city: "Jakarta",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "asia-south1",
+ label: "asia-south1",
+ group: "Asia Pacific",
+ city: "Mumbai, India",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "asia-south2",
+ label: "asia-south2",
+ group: "Asia Pacific",
+ city: "Delhi, India",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "australia-southeast1",
+ label: "australia-southeast1",
+ group: "Asia Pacific",
+ city: "Sydney",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "australia-southeast2",
+ label: "australia-southeast2",
+ group: "Asia Pacific",
+ city: "Melbourne",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "europe-central2",
+ label: "europe-central2",
+ group: "Europe",
+ city: "Warsaw, Poland",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "europe-west2",
+ label: "europe-west2",
+ group: "Europe",
+ city: "London, UK",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "europe-west3",
+ label: "europe-west3",
+ group: "Europe",
+ city: "Frankfurt, Germany",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "europe-west6",
+ label: "europe-west6",
+ group: "Europe",
+ city: "Zurich, Switzerland",
+ pricingTier: 2,
+ lowCO2: true,
+ },
+ {
+ value: "northamerica-northeast1",
+ label: "northamerica-northeast1",
+ group: "Americas",
+ city: "Montreal",
+ pricingTier: 2,
+ lowCO2: true,
+ },
+ {
+ value: "northamerica-northeast2",
+ label: "northamerica-northeast2",
+ group: "Americas",
+ city: "Toronto",
+ pricingTier: 2,
+ lowCO2: true,
+ },
+ {
+ value: "southamerica-east1",
+ label: "southamerica-east1",
+ group: "Americas",
+ city: "Sao Paulo, Brazil",
+ pricingTier: 2,
+ lowCO2: true,
+ },
+ {
+ value: "southamerica-west1",
+ label: "southamerica-west1",
+ group: "Americas",
+ city: "Santiago, Chile",
+ pricingTier: 2,
+ lowCO2: false,
+ },
+ {
+ value: "us-west2",
+ label: "us-west2",
+ group: "Americas",
+ city: "Los Angeles",
+ pricingTier: 2,
+ lowCO2: true,
+ },
+ {
+ value: "us-west3",
+ label: "us-west3",
+ group: "Americas",
+ city: "Salt Lake City",
+ pricingTier: 2,
+ lowCO2: true,
+ },
+ {
+ value: "us-west4",
+ label: "us-west4",
+ group: "Americas",
+ city: "Las Vegas",
+ pricingTier: 2,
+ lowCO2: true,
+ },
+];
+
+// SLA for multi region is 99.999% and for single region is 99.99%
+export const FIRESTORE_LOCATIONS = [
+ {
+ value: "europe-west",
+ label: "europe-west",
+ group: "Multi-region",
+ city: "Europe",
+ multiRegion: true,
+ },
+ {
+ value: "us-central",
+ label: "us-central",
+ group: "Multi-region",
+ city: "United States",
+ multiRegion: true,
+ },
+
+ {
+ value: "us-west1",
+ label: "us-west1",
+ group: "North America",
+ city: "Oregon",
+ },
+ {
+ value: "us-west2",
+ label: "us-west2",
+ group: "North America",
+ city: "Los Angeles",
+ },
+ {
+ value: "us-west3",
+ label: "us-west3",
+ group: "North America",
+ city: "Salt Lake City",
+ },
+ {
+ value: "us-west4",
+ label: "us-west4",
+ group: "North America",
+ city: "Las Vegas",
+ },
+ {
+ value: "northamerica-northeast1",
+ label: "northamerica-northeast1",
+ group: "North America",
+ city: "Montréal",
+ },
+ {
+ value: "us-east1",
+ label: "us-east1",
+ group: "North America",
+ city: "South Carolina",
+ },
+ {
+ value: "us-east4",
+ label: "us-east4",
+ group: "North America",
+ city: "Northern Virginia",
+ },
+ {
+ value: "southamerica-east1",
+ label: "southamerica-east1",
+ group: "South America",
+ city: "Sao Paulo, Brazil",
+ },
+ {
+ value: "europe-west2",
+ label: "europe-west2",
+ group: "Europe",
+ city: "London",
+ },
+ {
+ value: "europe-west3",
+ label: "europe-west3",
+ group: "Europe",
+ city: "Frankfurt",
+ },
+ {
+ value: "europe-central2",
+ label: "europe-central2",
+ group: "Europe",
+ city: "Warsaw",
+ },
+ {
+ value: "europe-west6",
+ label: "europe-west6",
+ group: "Europe",
+ city: "Zürich",
+ },
+ {
+ value: "asia-south1",
+ label: "asia-south1",
+ group: "Asia",
+ city: "Mumbai",
+ },
+ {
+ value: "asia-southeast1",
+ label: "asia-southeast1",
+ group: "Asia",
+ city: "Singapore",
+ },
+ {
+ value: "asia-southeast2",
+ label: "asia-southeast2",
+ group: "Asia",
+ city: "Jakarta",
+ },
+ {
+ value: "asia-east2",
+ label: "asia-east2",
+ group: "Asia",
+ city: "Hong Kong",
+ },
+ {
+ value: "asia-east1",
+ label: "asia-east1",
+ group: "Asia",
+ city: "Taiwan",
+ },
+ {
+ value: "asia-northeast1",
+ label: "asia-northeast1",
+ group: "Asia",
+ city: "Tokyo",
+ },
+ {
+ value: "asia-northeast2",
+ label: "asia-northeast2",
+ group: "Asia",
+ city: "Osaka",
+ },
+ {
+ value: "asia-northeast3",
+ label: "asia-northeast3",
+ group: "Asia",
+ city: "Seoul",
+ },
+ {
+ value: "australia-southeast1",
+ label: "australia-southeast1",
+ group: "Australia",
+ city: "Sydney",
+ },
+];
+
+const CLOUD_FUNCTIONS_REGIONS = [];