Skip to content

Commit

Permalink
Updated alerts model, frontend tweaks for subscription, using paginat…
Browse files Browse the repository at this point in the history
…ion for unackw query, updated API

Signed-off-by: Aaron Chong <[email protected]>
  • Loading branch information
aaronchongth committed Jul 5, 2024
1 parent 06e5475 commit ce5d761
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 31 deletions.
53 changes: 49 additions & 4 deletions packages/api-client/lib/openapi/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,31 @@ export interface MutexGroups {
*/
requesting?: Array<string>;
}
/**
*
* @export
* @interface Pagination
*/
export interface Pagination {
/**
*
* @type {number}
* @memberof Pagination
*/
limit: number;
/**
*
* @type {number}
* @memberof Pagination
*/
offset: number;
/**
*
* @type {Array<string>}
* @memberof Pagination
*/
order_by: Array<string>;
}
/**
*
* @export
Expand Down Expand Up @@ -5033,10 +5058,12 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio
/**
* Returns the list of alert IDs that have yet to be responded to, while a response was required.
* @summary Get Unresponded Alerts
* @param {Pagination} [pagination]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getUnrespondedAlertsAlertsUnrespondedRequestsGet: async (
pagination?: Pagination,
options: AxiosRequestConfig = {},
): Promise<RequestArgs> => {
const localVarPath = `/alerts/unresponded_requests`;
Expand All @@ -5051,13 +5078,20 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;

localVarHeaderParameter['Content-Type'] = 'application/json';

setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {
...localVarHeaderParameter,
...headersFromBaseOptions,
...options.headers,
};
localVarRequestOptions.data = serializeDataIfNeeded(
pagination,
localVarRequestOptions,
configuration,
);

return {
url: toPathString(localVarUrlObj),
Expand Down Expand Up @@ -5199,14 +5233,19 @@ export const AlertsApiFp = function (configuration?: Configuration) {
/**
* Returns the list of alert IDs that have yet to be responded to, while a response was required.
* @summary Get Unresponded Alerts
* @param {Pagination} [pagination]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async getUnrespondedAlertsAlertsUnrespondedRequestsGet(
pagination?: Pagination,
options?: AxiosRequestConfig,
): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AlertRequest>>> {
const localVarAxiosArgs =
await localVarAxiosParamCreator.getUnrespondedAlertsAlertsUnrespondedRequestsGet(options);
await localVarAxiosParamCreator.getUnrespondedAlertsAlertsUnrespondedRequestsGet(
pagination,
options,
);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
Expand Down Expand Up @@ -5306,14 +5345,16 @@ export const AlertsApiFactory = function (
/**
* Returns the list of alert IDs that have yet to be responded to, while a response was required.
* @summary Get Unresponded Alerts
* @param {Pagination} [pagination]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getUnrespondedAlertsAlertsUnrespondedRequestsGet(
pagination?: Pagination,
options?: any,
): AxiosPromise<Array<AlertRequest>> {
return localVarFp
.getUnrespondedAlertsAlertsUnrespondedRequestsGet(options)
.getUnrespondedAlertsAlertsUnrespondedRequestsGet(pagination, options)
.then((request) => request(axios, basePath));
},
/**
Expand Down Expand Up @@ -5410,13 +5451,17 @@ export class AlertsApi extends BaseAPI {
/**
* Returns the list of alert IDs that have yet to be responded to, while a response was required.
* @summary Get Unresponded Alerts
* @param {Pagination} [pagination]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof AlertsApi
*/
public getUnrespondedAlertsAlertsUnrespondedRequestsGet(options?: AxiosRequestConfig) {
public getUnrespondedAlertsAlertsUnrespondedRequestsGet(
pagination?: Pagination,
options?: AxiosRequestConfig,
) {
return AlertsApiFp(this.configuration)
.getUnrespondedAlertsAlertsUnrespondedRequestsGet(options)
.getUnrespondedAlertsAlertsUnrespondedRequestsGet(pagination, options)
.then((request) => request(this.axios, this.basePath));
}

Expand Down
2 changes: 1 addition & 1 deletion packages/api-client/lib/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { version as rmfModelVer } from 'rmf-models';

export const version = {
rmfModels: rmfModelVer,
rmfServer: 'cb1b563ab8f827756f9a453ec944362d92a3ab57',
rmfServer: '06e5475f096ec8f2eae05aae7c939a612aaa11e6',
openapiGenerator: '6.2.1',
};
19 changes: 19 additions & 0 deletions packages/api-client/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ export default {
description:
'Returns the list of alert IDs that have yet to be responded to, while a\nresponse was required.',
operationId: 'get_unresponded_alerts_alerts_unresponded_requests_get',
requestBody: {
content: { 'application/json': { schema: { $ref: '#/components/schemas/Pagination' } } },
},
responses: {
'200': {
description: 'Successful Response',
Expand All @@ -255,6 +258,12 @@ export default {
},
},
},
'422': {
description: 'Validation Error',
content: {
'application/json': { schema: { $ref: '#/components/schemas/HTTPValidationError' } },
},
},
},
},
},
Expand Down Expand Up @@ -3470,6 +3479,16 @@ export default {
},
},
},
Pagination: {
title: 'Pagination',
required: ['limit', 'offset', 'order_by'],
type: 'object',
properties: {
limit: { title: 'Limit', type: 'integer' },
offset: { title: 'Offset', type: 'integer' },
order_by: { title: 'Order By', type: 'array', items: { type: 'string' } },
},
},
Param: {
title: 'Param',
required: ['name', 'type', 'value_int', 'value_float', 'value_string', 'value_bool'],
Expand Down
1 change: 1 addition & 0 deletions packages/api-server/api_server/models/alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ async def save(self) -> None:
self.unix_millis_response_time / 1000
),
"response": self.response,
"data": self.json(),
},
id=self.id,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class AlertResponse(Model):
id = CharField(255, pk=True)
response_time = DatetimeField(null=False, index=True)
response = CharField(255, null=False, index=True)
data = JSONField()
alert_request = OneToOneField(
"models.AlertRequest", null=False, related_name="alert_response"
)
Expand Down
16 changes: 10 additions & 6 deletions packages/api-server/api_server/repositories/alerts.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from datetime import datetime
from typing import List
from typing import List, Optional

from api_server.exceptions import AlreadyExistsError, InvalidInputError, NotFoundError
from api_server.models import AlertRequest, AlertResponse
from api_server.models import AlertRequest, AlertResponse, Pagination
from api_server.models import tortoise_models as ttm


Expand Down Expand Up @@ -51,6 +51,7 @@ async def create_response(self, alert_id: str, response: str) -> AlertResponse:
alert_response_model.unix_millis_response_time / 1000
),
response=response,
data=alert_response_model.json(),
alert_request=alert,
)
return alert_response_model
Expand Down Expand Up @@ -78,8 +79,11 @@ async def get_alerts_of_task(
alert_models = [AlertRequest.from_tortoise(alert) for alert in task_id_alerts]
return alert_models

async def get_unresponded_alerts(self) -> List[AlertRequest]:
unresponded_alerts = await ttm.AlertRequest.filter(
alert_response=None, response_expected=True
)
async def get_unresponded_alerts(
self, pagination: Optional[Pagination]
) -> List[AlertRequest]:
query = ttm.AlertRequest.filter(alert_response=None, response_expected=True)
if pagination:
query = query.limit(pagination.limit).offset(pagination.offset)
unresponded_alerts = await query.all()
return [AlertRequest.from_tortoise(alert) for alert in unresponded_alerts]
11 changes: 7 additions & 4 deletions packages/api-server/api_server/routes/alerts.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from typing import List
from typing import List, Optional

from fastapi import Depends, HTTPException
from tortoise.exceptions import IntegrityError

from api_server.exceptions import AlreadyExistsError, InvalidInputError, NotFoundError
from api_server.fast_io import FastIORouter, SubscriptionRequest
from api_server.gateway import rmf_gateway
from api_server.models import AlertRequest, AlertResponse
from api_server.models import AlertRequest, AlertResponse, Pagination
from api_server.repositories import AlertRepository
from api_server.rmf_io import alert_events

Expand Down Expand Up @@ -107,9 +107,12 @@ async def get_alerts_of_task(


@router.get("/unresponded_requests", response_model=List[AlertRequest])
async def get_unresponded_alerts(repo: AlertRepository = Depends(AlertRepository)):
async def get_unresponded_alerts(
repo: AlertRepository = Depends(AlertRepository),
pagination: Optional[Pagination] = None,
):
"""
Returns the list of alert IDs that have yet to be responded to, while a
response was required.
"""
return await repo.get_unresponded_alerts()
return await repo.get_unresponded_alerts(pagination)
25 changes: 11 additions & 14 deletions packages/dashboard/src/components/alert-manager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ const AlertDialog = React.memo((props: AlertDialogProps) => {
}}
onClick={async () => {
await respondToAlert(alertRequest.id, response);
AppEvents.refreshAlert.next();
setIsOpen(false);
}}
>
Expand Down Expand Up @@ -297,36 +296,34 @@ export const AlertManager = React.memo(() => {
[alertRequest.id]: alertRequest,
};
});
AppEvents.refreshAlert.next();
return;
}
};

const subs: Subscription[] = [];

subs.push(
rmf.alertRequestsObsStore.subscribe(
async (alertRequest) => await pushAlertsToBeDisplayed(alertRequest),
rmf.alertRequestsObsStore.subscribe((alertRequest) =>
AppEvents.alertListOpenedAlert.next(alertRequest),
),
);

subs.push(
AppEvents.alertListOpenedAlert.subscribe(async (alertRequest) => {
if (!alertRequest) {
return;
}
await pushAlertsToBeDisplayed(alertRequest);
}),
);

subs.push(
rmf.alertResponsesObsStore.subscribe((alertResponse) => {
setOpenAlerts((prev) => {
return Object.fromEntries(
Object.entries(prev).filter(([key]) => key !== alertResponse.id),
);
});
AppEvents.refreshAlert.next();
}),
);

subs.push(
AppEvents.alertListOpenedAlert.subscribe(async (alertRequest) => {
if (!alertRequest) {
return;
}
await pushAlertsToBeDisplayed(alertRequest);
}),
);

Expand Down
1 change: 0 additions & 1 deletion packages/dashboard/src/components/app-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export const AppEvents = {
refreshTaskApp: new Subject<void>(),
refreshFavoriteTasks: new Subject<void>(),
refreshTaskSchedule: new Subject<void>(),
refreshAlert: new Subject<void>(),
alertListOpenedAlert: new Subject<AlertRequest | null>(),
disabledLayers: new ReplaySubject<Record<string, boolean>>(),
zoom: new BehaviorSubject<number | null>(null),
Expand Down
3 changes: 2 additions & 1 deletion packages/dashboard/src/components/appbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea
};

const subs: Subscription[] = [];
subs.push(AppEvents.refreshAlert.subscribe(updateUnrespondedAlerts));
subs.push(rmf.alertRequestsObsStore.subscribe(updateUnrespondedAlerts));
subs.push(rmf.alertResponsesObsStore.subscribe(updateUnrespondedAlerts));

// Get the initial number of unacknowledged alerts
updateUnrespondedAlerts();
Expand Down

0 comments on commit ce5d761

Please sign in to comment.