mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
refactor
This commit is contained in:
@@ -34,9 +34,10 @@ const VerifyEmail: FunctionComponent = () => {
|
||||
emailverificationToken,
|
||||
EmailVerificationToken,
|
||||
FormType.Create,
|
||||
apiUrl,
|
||||
{},
|
||||
{}
|
||||
{
|
||||
overrideRequestUrl: apiUrl,
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
setError(API.getFriendlyMessage(err));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import BadDataException from './Exception/BadDataException';
|
||||
import { JSONObject } from './JSON';
|
||||
import PositiveNumber from './PositiveNumber';
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
@@ -373,8 +375,18 @@ export default class OneUptimeDate {
|
||||
return moment(date).isAfter(new Date());
|
||||
}
|
||||
|
||||
public static fromString(date: string): Date {
|
||||
return moment(date).toDate();
|
||||
public static fromString(date: string | JSONObject): Date {
|
||||
|
||||
if(typeof date === 'string') {
|
||||
return moment(date).toDate();
|
||||
}
|
||||
|
||||
if(date && date['value'] && typeof date['value'] === 'string'){
|
||||
return moment(date['value']).toDate();
|
||||
}
|
||||
|
||||
throw new BadDataException('Invalid date');
|
||||
|
||||
}
|
||||
|
||||
public static asDateForDatabaseQuery(date: string | Date): string {
|
||||
|
||||
56
CommonServer/API/ProbeAPI.ts
Normal file
56
CommonServer/API/ProbeAPI.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import Probe from 'Model/Models/Probe';
|
||||
import UserMiddleware from '../Middleware/UserAuthorization';
|
||||
import ProbeService, {
|
||||
Service as ProbeServiceType,
|
||||
} from '../Services/ProbeService';
|
||||
import {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
NextFunction,
|
||||
} from '../Utils/Express';
|
||||
import Response from '../Utils/Response';
|
||||
import BaseAPI from './BaseAPI';
|
||||
import LIMIT_MAX from 'Common/Types/Database/LimitMax';
|
||||
import PositiveNumber from 'Common/Types/PositiveNumber';
|
||||
|
||||
export default class ProbeAPI extends BaseAPI<
|
||||
Probe,
|
||||
ProbeServiceType
|
||||
> {
|
||||
public constructor() {
|
||||
super(Probe, ProbeService);
|
||||
|
||||
this.router.post(
|
||||
`${new this.entityType().getCrudApiPath()?.toString()}/global-probes`,
|
||||
UserMiddleware.getUserMiddleware,
|
||||
async (
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
next: NextFunction
|
||||
) => {
|
||||
try {
|
||||
const probes = await ProbeService.findBy({
|
||||
query: {
|
||||
isGlobalProbe: true,
|
||||
},
|
||||
select: {
|
||||
name: true,
|
||||
description: true,
|
||||
lastAlive: true,
|
||||
iconFileId: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
skip: 0,
|
||||
limit: LIMIT_MAX
|
||||
})
|
||||
|
||||
return Response.sendEntityArrayResponse(req, res, probes, new PositiveNumber(probes.length), Probe);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,9 @@ const FilePicker: FunctionComponent<ComponentProps> = (
|
||||
(await ModelAPI.create<FileModel>(
|
||||
fileModel,
|
||||
FileModel,
|
||||
CommonURL.fromURL(FILE_URL).addRoute('/file')
|
||||
{
|
||||
overrideRequestUrl: CommonURL.fromURL(FILE_URL).addRoute('/file')
|
||||
}
|
||||
)) as HTTPResponse<FileModel>;
|
||||
filesResult.push(result.data as FileModel);
|
||||
}
|
||||
|
||||
@@ -453,11 +453,11 @@ const ModelForm: Function = <TBaseModel extends BaseModel>(
|
||||
tBaseModel as TBaseModel,
|
||||
props.modelType,
|
||||
props.formType,
|
||||
props.apiUrl,
|
||||
miscDataProps,
|
||||
{
|
||||
...props.saveRequestOptions,
|
||||
requestHeaders: props.requestHeaders,
|
||||
overrideRequestUrl: props.apiUrl,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -31,13 +31,13 @@ export interface ListResult<TBaseModel extends BaseModel> extends JSONObject {
|
||||
export interface RequestOptions {
|
||||
isMultiTenantRequest?: boolean | undefined;
|
||||
requestHeaders?: Dictionary<string> | undefined;
|
||||
overrideRequestUrl?: URL | undefined;
|
||||
}
|
||||
|
||||
export default class ModelAPI {
|
||||
public static async create<TBaseModel extends BaseModel>(
|
||||
model: TBaseModel,
|
||||
modelType: { new (): TBaseModel },
|
||||
apiUrlOverride?: URL,
|
||||
requestOptions?: RequestOptions | undefined
|
||||
): Promise<
|
||||
HTTPResponse<JSONObject | JSONArray | TBaseModel | Array<TBaseModel>>
|
||||
@@ -46,7 +46,6 @@ export default class ModelAPI {
|
||||
model,
|
||||
modelType,
|
||||
FormType.Create,
|
||||
apiUrlOverride,
|
||||
{},
|
||||
requestOptions
|
||||
);
|
||||
@@ -55,7 +54,6 @@ export default class ModelAPI {
|
||||
public static async update<TBaseModel extends BaseModel>(
|
||||
model: TBaseModel,
|
||||
modelType: { new (): TBaseModel },
|
||||
apiUrlOverride?: URL
|
||||
): Promise<
|
||||
HTTPResponse<JSONObject | JSONArray | TBaseModel | Array<TBaseModel>>
|
||||
> {
|
||||
@@ -63,7 +61,6 @@ export default class ModelAPI {
|
||||
model,
|
||||
modelType,
|
||||
FormType.Update,
|
||||
apiUrlOverride
|
||||
);
|
||||
}
|
||||
|
||||
@@ -118,13 +115,12 @@ export default class ModelAPI {
|
||||
model: TBaseModel,
|
||||
modelType: { new (): TBaseModel },
|
||||
formType: FormType,
|
||||
apiUrlOverride?: URL,
|
||||
miscDataProps?: JSONObject,
|
||||
requestOptions?: RequestOptions | undefined
|
||||
): Promise<
|
||||
HTTPResponse<JSONObject | JSONArray | TBaseModel | Array<TBaseModel>>
|
||||
> {
|
||||
let apiUrl: URL | null = apiUrlOverride || null;
|
||||
let apiUrl: URL | null = requestOptions?.overrideRequestUrl || null;
|
||||
|
||||
if (!apiUrl) {
|
||||
const apiPath: Route | null = model.getCrudApiPath();
|
||||
@@ -190,10 +186,14 @@ export default class ModelAPI {
|
||||
);
|
||||
}
|
||||
|
||||
const apiUrl: URL = URL.fromURL(DASHBOARD_API_URL)
|
||||
let apiUrl: URL = URL.fromURL(DASHBOARD_API_URL)
|
||||
.addRoute(apiPath)
|
||||
.addRoute('/get-list');
|
||||
|
||||
if(requestOptions?.overrideRequestUrl){
|
||||
apiUrl = requestOptions.overrideRequestUrl;
|
||||
}
|
||||
|
||||
if (!apiUrl) {
|
||||
throw new BadDataException(
|
||||
'This model does not support list operations.'
|
||||
@@ -257,10 +257,14 @@ export default class ModelAPI {
|
||||
);
|
||||
}
|
||||
|
||||
const apiUrl: URL = URL.fromURL(DASHBOARD_API_URL)
|
||||
let apiUrl: URL = URL.fromURL(DASHBOARD_API_URL)
|
||||
.addRoute(apiPath)
|
||||
.addRoute('/count');
|
||||
|
||||
if(requestOptions?.overrideRequestUrl){
|
||||
apiUrl = requestOptions.overrideRequestUrl;
|
||||
}
|
||||
|
||||
if (!apiUrl) {
|
||||
throw new BadDataException(
|
||||
'This model does not support count operations.'
|
||||
@@ -335,11 +339,15 @@ export default class ModelAPI {
|
||||
);
|
||||
}
|
||||
|
||||
const apiUrl: URL = URL.fromURL(DASHBOARD_API_URL)
|
||||
let apiUrl: URL = URL.fromURL(DASHBOARD_API_URL)
|
||||
.addRoute(apiPath)
|
||||
.addRoute('/' + id.toString())
|
||||
.addRoute('/get-item');
|
||||
|
||||
if(requestOptions?.overrideRequestUrl){
|
||||
apiUrl = requestOptions.overrideRequestUrl;
|
||||
}
|
||||
|
||||
if (!apiUrl) {
|
||||
throw new BadDataException(
|
||||
'This model does not support get operations.'
|
||||
|
||||
@@ -19,6 +19,8 @@ import ProbeElement from '../../Components/Probe/Probe';
|
||||
import Statusbubble from 'CommonUI/src/Components/StatusBubble/StatusBubble';
|
||||
import { Green, Red } from 'Common/Types/BrandColors';
|
||||
import OneUptimeDate from 'Common/Types/Date';
|
||||
import URL from 'Common/Types/API/URL';
|
||||
import { DASHBOARD_API_URL } from 'CommonUI/src/Config';
|
||||
|
||||
const ProbePage: FunctionComponent<PageComponentProps> = (
|
||||
_props: PageComponentProps
|
||||
@@ -56,6 +58,75 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
|
||||
>
|
||||
|
||||
<>
|
||||
|
||||
<ModelTable<Probe>
|
||||
modelType={Probe}
|
||||
id="probes-table"
|
||||
name="Settings > Global Probes"
|
||||
isDeleteable={false}
|
||||
isEditable={false}
|
||||
isCreateable={false}
|
||||
cardProps={{
|
||||
icon: IconProp.Signal,
|
||||
title: 'Global Probes',
|
||||
description:
|
||||
'Global Probes help you monitor external resources from different locations around the world.',
|
||||
}}
|
||||
fetchRequestOptions={{
|
||||
overrideRequestUrl: URL.fromString(DASHBOARD_API_URL.toString()).addRoute('/probe/global-probes')
|
||||
}}
|
||||
noItemsMessage={'No probes found.'}
|
||||
|
||||
|
||||
showRefreshButton={true}
|
||||
showFilterButton={true}
|
||||
|
||||
columns={[
|
||||
|
||||
{
|
||||
field: {
|
||||
name: true,
|
||||
},
|
||||
title: 'Name',
|
||||
type: FieldType.Text,
|
||||
isFilterable: true,
|
||||
getElement: (item: JSONObject): ReactElement => {
|
||||
return (
|
||||
<ProbeElement probe={item}/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
field: {
|
||||
description: true,
|
||||
},
|
||||
title: 'Description',
|
||||
type: FieldType.Text,
|
||||
isFilterable: true,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
lastAlive: true,
|
||||
},
|
||||
title: 'Status',
|
||||
type: FieldType.Text,
|
||||
isFilterable: false,
|
||||
getElement: (item: JSONObject): ReactElement => {
|
||||
|
||||
if(item && item['lastAlive'] && OneUptimeDate.getNumberOfMinutesBetweenDates(OneUptimeDate.fromString(item['lastAlive'] as string), OneUptimeDate.getCurrentDate()) < 5){
|
||||
return <Statusbubble text={'Connected'} color={Green}/>
|
||||
}
|
||||
|
||||
return (
|
||||
<Statusbubble text={'Disconnected'} color={Red}/>
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
]}
|
||||
/>
|
||||
|
||||
|
||||
<ModelTable<Probe>
|
||||
modelType={Probe}
|
||||
query={{
|
||||
@@ -168,8 +239,8 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
|
||||
isFilterable: false,
|
||||
getElement: (item: JSONObject): ReactElement => {
|
||||
|
||||
if(item && item['lastAlive'] && OneUptimeDate.getNumberOfMinutesBetweenDates(item['lastAlive'] as Date, OneUptimeDate.getCurrentDate()) < 5){
|
||||
<Statusbubble text={'Connected'} color={Green}/>
|
||||
if(item && item['lastAlive'] && OneUptimeDate.getNumberOfMinutesBetweenDates(OneUptimeDate.fromString(item['lastAlive'] as string), OneUptimeDate.getCurrentDate()) < 5){
|
||||
return <Statusbubble text={'Connected'} color={Green}/>
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -45,10 +45,6 @@ import WorkflowVariableService, {
|
||||
Service as WorkflowVariableServiceType,
|
||||
} from 'CommonServer/Services/WorkflowVariableService';
|
||||
|
||||
import Probe from 'Model/Models/Probe';
|
||||
import ProbeService, {
|
||||
Service as ProbeServiceType,
|
||||
} from 'CommonServer/Services/ProbeService';
|
||||
|
||||
import MonitorProbe from 'Model/Models/MonitorProbe';
|
||||
import MonitorProbeService, {
|
||||
@@ -214,6 +210,8 @@ import StatusPageDomainService, {
|
||||
|
||||
import StatusPageAPI from 'CommonServer/API/StatusPageAPI';
|
||||
|
||||
import ProbeAPI from 'CommonServer/API/ProbeAPI';
|
||||
|
||||
import StatusPageSubscriberAPI from 'CommonServer/API/StatusPageSubscriberAPI';
|
||||
|
||||
// Custom Fields API
|
||||
@@ -255,12 +253,6 @@ app.use(
|
||||
);
|
||||
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<Probe, ProbeServiceType>(Probe, ProbeService).getRouter()
|
||||
);
|
||||
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<MonitorProbe, MonitorProbeServiceType>(MonitorProbe, MonitorProbeService).getRouter()
|
||||
@@ -518,6 +510,9 @@ app.use(
|
||||
);
|
||||
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new StatusPageAPI().getRouter());
|
||||
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new ProbeAPI().getRouter());
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new StatusPageSubscriberAPI().getRouter()
|
||||
|
||||
@@ -410,4 +410,29 @@ export default class Probe extends BaseModel {
|
||||
transformer: ObjectID.getDatabaseTransformer(),
|
||||
})
|
||||
public createdByUserId?: ObjectID = undefined;
|
||||
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
|
||||
],
|
||||
read: [
|
||||
|
||||
],
|
||||
update: [
|
||||
|
||||
]
|
||||
})
|
||||
@TableColumn({
|
||||
isDefaultValueColumn: true,
|
||||
required: true,
|
||||
type: TableColumnType.Boolean,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
nullable: false,
|
||||
unique: false,
|
||||
default: false,
|
||||
})
|
||||
public isGlobalProbe?: boolean = undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user