Set up an alert
Select the GPU and the demand scenario you wish to get notified for.
-
-
- GPU
-
-
-
-
Demand Scenario
-
+ {demandHardwareOptions ? (
+ <>
+
+
+ GPU
+
+
+
+ Demand Scenario
+
+
+
+
+ {createNewSubscriptionErrorText &&
{createNewSubscriptionErrorText}}
+ >
+ ) : (
+
+
-
-
)
}
diff --git a/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/DemandAlertsSetUpContainer.tsx b/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/DemandAlertsSetUpContainer.tsx
new file mode 100644
index 000000000..7a32a4325
--- /dev/null
+++ b/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/DemandAlertsSetUpContainer.tsx
@@ -0,0 +1,13 @@
+import { connect } from '../../../../connect'
+import type { RootStore } from '../../../../Store'
+import { DemandAlertsSetUp } from './DemandAlertsSetUp'
+
+const mapStoreToProps = (store: RootStore): any => ({
+ demandedHardwarePerformanceList: store.demandMonitor.demandedHardwarePerformanceList,
+ fetchDemandedHardwarePerformanceList: store.demandMonitor.fetchDemandedHardwarePerformanceList,
+ setSubscribeToDemandAlertStatus: store.demandAlerts.setSubscribeToDemandAlertStatus,
+ subscribeToDemandAlert: store.demandAlerts.subscribeToDemandAlert,
+ subscribeToDemandAlertStatus: store.demandAlerts.subscribeToDemandAlertStatus,
+})
+
+export const DemandAlertsSetUpContainer = connect(mapStoreToProps, DemandAlertsSetUp)
diff --git a/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/index.ts b/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/index.ts
index cdea4a166..a68b7de21 100644
--- a/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/index.ts
+++ b/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/index.ts
@@ -1 +1 @@
-export * from './DemandAlertsSetUp'
+export * from './DemandAlertsSetUpContainer'
diff --git a/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/utils.ts b/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/utils.ts
new file mode 100644
index 000000000..4649f17fa
--- /dev/null
+++ b/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPage/DemandAlertsSetUp/utils.ts
@@ -0,0 +1,16 @@
+import { SubscribeToDemandAlertStatus } from '../../DemandAlertsStore'
+
+export const getCreateNewSubscriptionErrorText = (
+ subscribeToDemandAlertStatus: SubscribeToDemandAlertStatus,
+): string | null => {
+ switch (subscribeToDemandAlertStatus) {
+ case SubscribeToDemandAlertStatus.FAILURE:
+ return 'Something went wrong. Please try again later'
+ case SubscribeToDemandAlertStatus.ALREADY_EXISTS:
+ return 'An alert with this GPU and Demand Scenario already exists.'
+ case SubscribeToDemandAlertStatus.INVALID_GPU:
+ return 'The GPU configuration provided is invalid.'
+ default:
+ return null
+ }
+}
diff --git a/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPageContainer.tsx b/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPageContainer.tsx
deleted file mode 100644
index 804688495..000000000
--- a/packages/web-app/src/modules/demand-alerts-views/DemandAlertsPageContainer.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import { connect } from '../../connect'
-import type { RootStore } from '../../Store'
-import { DemandAlertsPage } from './DemandAlertsPage'
-
-const mapStoreToProps = (_store: RootStore): any => ({})
-
-export const DemandAlertsPageContainer = connect(mapStoreToProps, DemandAlertsPage)
diff --git a/packages/web-app/src/modules/demand-alerts-views/DemandAlertsStore.tsx b/packages/web-app/src/modules/demand-alerts-views/DemandAlertsStore.tsx
new file mode 100644
index 000000000..0afe7fd00
--- /dev/null
+++ b/packages/web-app/src/modules/demand-alerts-views/DemandAlertsStore.tsx
@@ -0,0 +1,102 @@
+import type { AxiosInstance } from 'axios'
+import { action, flow, observable } from 'mobx'
+import { demandSubscriptionsPath } from './constants'
+
+export interface DemandedSubscription {
+ createdAt: string
+ gpuDisplayName: string
+ gpuName: string
+ id: string
+ utilizationPct: number
+}
+
+export enum SubscribeToDemandAlertStatus {
+ UNKNOWN = 'unknown',
+ SUBMITTING = 'submitting',
+ SUCCESS = 'success',
+ FAILURE = 'failure',
+ ALREADY_EXISTS = 'failure:subscription-already-exists',
+ INVALID_GPU = 'failure:invalid-gpu',
+}
+export enum UnsubscribeFromDemandAlertStatus {
+ UNKNOWN = 'unknown',
+ SUBMITTING = 'submitting',
+ SUCCESS = 'success',
+ FAILURE = 'failure',
+}
+
+export class DemandAlertsStore {
+ constructor(private readonly axios: AxiosInstance) {}
+
+ @observable
+ public subscribeToDemandAlertStatus: SubscribeToDemandAlertStatus = SubscribeToDemandAlertStatus.UNKNOWN
+
+ @observable
+ public unsubscribeFromDemandAlertStatus: UnsubscribeFromDemandAlertStatus = UnsubscribeFromDemandAlertStatus.UNKNOWN
+
+ @observable
+ public demandAlertSubscriptionList?: DemandedSubscription[]
+
+ @action.bound
+ fetchDemandAlertSubscriptionList = flow(function* (this: DemandAlertsStore) {
+ try {
+ const demandAlertSubscriptionListResponse = yield this.axios.get(demandSubscriptionsPath)
+ this.demandAlertSubscriptionList = demandAlertSubscriptionListResponse.data
+ } catch (error) {
+ console.error('DemandAlertsStore -> fetchDemandAlertSubscriptionList: ', error)
+ }
+ })
+
+ @action.bound
+ subscribeToDemandAlert = flow(function* (this: DemandAlertsStore, gpuName: string, utilizationPct: number) {
+ try {
+ this.subscribeToDemandAlertStatus = SubscribeToDemandAlertStatus.SUBMITTING
+ yield this.axios.post(demandSubscriptionsPath, {
+ gpuName,
+ utilizationPct,
+ })
+ this.fetchDemandAlertSubscriptionList()
+ this.subscribeToDemandAlertStatus = SubscribeToDemandAlertStatus.SUCCESS
+ } catch (error) {
+ this.subscribeToDemandAlertStatus = this.mapErrorToSubscribeToDemandAlertStatus(error)
+ console.error('DemandAlertsStore -> subscribeToDemandAlert: ', error)
+ }
+ })
+
+ private mapErrorToSubscribeToDemandAlertStatus(error: any): SubscribeToDemandAlertStatus {
+ if (!error || typeof error !== 'object') return SubscribeToDemandAlertStatus.FAILURE
+
+ const errorResponse = error.response?.data
+ switch (errorResponse?.type) {
+ case 'subscription:create:already-exists':
+ return SubscribeToDemandAlertStatus.ALREADY_EXISTS
+ case 'subscription:create:invalid-gpu':
+ return SubscribeToDemandAlertStatus.INVALID_GPU
+ default:
+ return SubscribeToDemandAlertStatus.FAILURE
+ }
+ }
+
+ @action.bound
+ setSubscribeToDemandAlertStatus = (subscribeToDemandAlertStatus: SubscribeToDemandAlertStatus) => {
+ this.subscribeToDemandAlertStatus = subscribeToDemandAlertStatus
+ }
+
+ @action.bound
+ unsubscribeFromDemandAlert = flow(function* (this: DemandAlertsStore, subscriptionId: string) {
+ try {
+ this.unsubscribeFromDemandAlertStatus = UnsubscribeFromDemandAlertStatus.SUBMITTING
+ yield this.axios.delete(`${demandSubscriptionsPath}/${subscriptionId}`)
+ this.fetchDemandAlertSubscriptionList()
+ this.unsubscribeFromDemandAlertStatus = UnsubscribeFromDemandAlertStatus.SUCCESS
+ } catch (error) {
+ this.unsubscribeFromDemandAlertStatus = UnsubscribeFromDemandAlertStatus.FAILURE
+ console.error('DemandAlertsStore -> unsubscribeFromDemandAlert: ', error)
+ }
+ })
+
+ @action.bound
+ setUnsubscribeFromDemandAlertStatus = (unsubscribeFromDemandAlertStatus: UnsubscribeFromDemandAlertStatus) => {
+ this.unsubscribeFromDemandAlertStatus = unsubscribeFromDemandAlertStatus
+ }
+}
diff --git a/packages/web-app/src/modules/demand-alerts-views/constants.ts b/packages/web-app/src/modules/demand-alerts-views/constants.ts
index 3bcfbabbf..132a422f9 100644
--- a/packages/web-app/src/modules/demand-alerts-views/constants.ts
+++ b/packages/web-app/src/modules/demand-alerts-views/constants.ts
@@ -1,11 +1,15 @@
+import type { DropdownOption } from "../../components/Dropdown"
+
+export const demandSubscriptionsPath = '/api/v2/demand-monitor/subscriptions'
+
export const mockedGpuNames = [
{ label: 'NVIDIA RTX 4090', value: 'NVIDIA RTX 4090' },
{ label: 'NVIDIA RTX 4080', value: 'NVIDIA RTX 4080' },
{ label: 'NVIDIA RTX 4070 Ti Super', value: 'NVIDIA RTX 4070 Ti Super' },
]
-export const demandScenarios = [
- { label: 'High Demand', value: 'highDemand' },
- { label: 'Moderate Demand', value: 'moderateDemand' },
- { label: 'Low Demand', value: 'lowDemand' },
-]
+export const demandScenario: Record
= {
+ 80: { label: 'High Demand', value: '80' },
+ 50: { label: 'Moderate Demand', value: '50' },
+ 0: { label: 'Low Demand', value: '0' },
+}
diff --git a/packages/web-app/src/modules/demand-alerts-views/index.ts b/packages/web-app/src/modules/demand-alerts-views/index.ts
index a1409c7bd..6710c64a6 100644
--- a/packages/web-app/src/modules/demand-alerts-views/index.ts
+++ b/packages/web-app/src/modules/demand-alerts-views/index.ts
@@ -1,2 +1 @@
-export * from './DemandAlertsPageContainer'
-
+export * from './DemandAlertsPage'