frontend/src/providers/pond/binAPI.tsx

679 lines
21 KiB
TypeScript

import { useHTTP, usePermissionAPI } from "hooks";
import { createContext, PropsWithChildren, useContext } from "react";
import { pond } from "protobuf-ts/pond";
import { has, or } from "utils/types";
import { User, binScope } from "models";
import { pondURL } from "./pond";
import { AxiosResponse } from "axios";
import { dateRange } from "providers/http";
import { useGlobalState } from "providers";
import { quack } from "protobuf-ts/quack";
export interface IBinAPIContext {
addBin: (bin: pond.BinSettings, otherTeam?: string) => Promise<AxiosResponse<pond.AddBinResponse>>;
updateBin: (key: string, bin: pond.BinSettings, otherTeam?: string) => Promise<AxiosResponse<pond.UpdateBinResponse>>;
bulkBinUpdate: (bins: pond.BinSettings[], otherTeam?: string) => Promise<AxiosResponse<pond.BulkBinUpdateResponse>>;
updateBinStatus: (
key: string,
binStatus: pond.BinStatus,
otherTeam?: string
) => Promise<AxiosResponse<pond.UpdateBinResponse>>;
removeBin: (key: string, otherTeam?: string) => Promise<AxiosResponse<pond.RemoveBinResponse>>;
getBin: (key: string, otherTeam?: string) => Promise<AxiosResponse<pond.Bin>>;
addComponent: (
bin: string,
device: number,
component: string,
preferences?: pond.BinComponentPreferences,
otherTeam?: string
) => Promise<AxiosResponse<pond.AddBinComponentResponse>>;
removeComponent: (
bin: string,
component: string,
otherTeam?: string
) => Promise<AxiosResponse<pond.RemoveBinComponentResponse>>;
removeAllComponents: (bin: string, otherTeam?: string) => Promise<AxiosResponse<pond.RemoveAllBinComponentsResponse>>;
updateComponentPreferences: (
bin: string,
component: string,
preferences: pond.BinComponentPreferences,
otherTeam?: string
) => Promise<AxiosResponse<pond.UpdateBinComponentPreferencesResponse>>;
getBinPageData: (binKey: string, userKey: string, showErrors?: boolean, otherTeam?: string) => Promise<AxiosResponse<pond.GetBinPageDataResponse>>;
listBins: (
limit: number,
offset: number,
order?: "asc" | "desc",
orderBy?: string,
search?: string,
otherTeam?: string,
asRoot?: boolean,
numerical?: boolean,
keys?: string[],
types?: string[]
) => Promise<AxiosResponse<pond.ListBinsResponse>>;
listBinsAndData: (
limit: number,
offset: number,
order?: "asc" | "desc",
orderBy?: string,
search?: string,
otherTeam?: string,
asRoot?: boolean,
keys?: string[],
types?: string[]
) => Promise<AxiosResponse<pond.ListBinsAndDataResponse>>;
listHistory: (
id: string,
limit: number,
offset: number
) => Promise<AxiosResponse<pond.ListBinHistoryResponse>>;
listHistoryBetween: (
id: string,
limit: number,
start: string,
end: string
) => Promise<AxiosResponse<pond.ListBinHistoryResponse>>;
listBinStatus: (
key: string,
startDate: any,
endDate: any,
limit: number,
offset: number,
order?: "asc" | "desc",
asRoot?: boolean
) => Promise<AxiosResponse<pond.ListBinStatusResponse>>;
listBinComponents: (key: string) => Promise<AxiosResponse<pond.ListBinComponentsResponse>>;
listBinComponentsMeasurements: (
key: string,
start: string,
end: string,
showErrors?: boolean,
allNodes?: boolean,
otherTeam?: string
) => Promise<AxiosResponse<pond.ListBinComponentsMeasurementsResponse>>;
updateBinPermissions: (
key: string,
users: User[]
) => Promise<AxiosResponse<pond.UpdateBinResponse>>;
getBinMetrics: (search?: string, otherTeam?: string) => Promise<AxiosResponse<pond.GetBinMetricsResponse>>;
listBinLiters: (
key: string,
start: string,
end: string,
moisture: number,
plenum: string,
cable: string,
pressure: string,
fan?: string, // the fan controller is optional so that if they don't have one the fan is assumed on
otherTeam?: string
) => Promise<AxiosResponse<pond.ListBinLiterResponse>>;
listBinPrefs: (key: string) => Promise<AxiosResponse<pond.ListBinComponentPreferencesResponse>>;
updateTopNodes: (
key: string,
newTopNodes: pond.NewTopNode[],
otherTeam?: string
) => Promise<AxiosResponse<pond.UpdateTopNodesResponse>>;
listBinMeasurements: (
key: string,
startDate: any,
endDate: any,
limit: number,
offset: number,
order: string,
measurementType?: number | quack.MeasurementType,
keys?: string[],
types?: string[],
showErrors?: boolean,
otherTeam?: string
) => Promise<AxiosResponse<pond.ListObjectMeasurementsResponse>>;
getBinsTrendData: (
bins: string[],
days: number
) => Promise<AxiosResponse<pond.GetBinsTrendDataResponse>>;
}
export const BinAPIContext = createContext<IBinAPIContext>({} as IBinAPIContext);
interface Props {}
export default function BinProvider(props: PropsWithChildren<Props>) {
const { children } = props;
const { get, post, put, del } = useHTTP();
const permissionAPI = usePermissionAPI();
const [{ as }] = useGlobalState();
const addBin = (bin: pond.BinSettings, otherTeam?: string) => {
const view = otherTeam ? otherTeam : as
const url = "/bins" + (view ? "?as=" + view : "")
return new Promise<AxiosResponse<pond.AddBinResponse>>((resolve, reject)=>{
post<pond.AddBinResponse>(pondURL(url), bin).then(resp => {
resp.data = pond.AddBinResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const updateBin = (key: string, bin: pond.BinSettings, otherTeam?: string) => {
const view = otherTeam ? otherTeam : as
const url = "/bins/" + key + (view ? "?as=" + view : "")
return new Promise<AxiosResponse<pond.UpdateBinResponse>>((resolve, reject)=>{
put<pond.UpdateBinResponse>(pondURL(url), bin).then(resp => {
resp.data = pond.UpdateBinResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const bulkBinUpdate = (bins: pond.BinSettings[], otherTeam?: string) => {
let url = "/bulkBins/update"
const view = otherTeam ? otherTeam : as
if (view) url = url + "?as=" + view
return new Promise<AxiosResponse<pond.BulkBinUpdateResponse>>((resolve, reject)=>{
put<pond.BulkBinUpdateResponse>(pondURL(url), { bins: bins }).then(resp => {
resp.data = pond.BulkBinUpdateResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const updateBinStatus = (key: string, binStatus: pond.BinStatus, otherTeam?: string) => {
let url = "/bins/" + key + "/status"
const view = otherTeam ? otherTeam : as
if (view) url = url + "?as=" + view
return new Promise<AxiosResponse<pond.UpdateBinStatusResponse>>((resolve, reject)=>{
put<pond.UpdateBinStatusResponse>(pondURL(url), binStatus).then(resp=>{
resp.data = pond.UpdateBinStatusResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err=>{
return reject(err)
})
})
};
const removeBin = (key: string, otherTeam?: string) => {
let url = "/bins/" + key
const view = otherTeam ? otherTeam : as
if (view) url = url + "?as=" + view
return new Promise<AxiosResponse<pond.RemoveBinResponse>>((resolve, reject) => {
del<pond.RemoveBinResponse>(pondURL(url)).then(resp => {
resp.data = pond.RemoveBinResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const getBin = (key: string, otherTeam?: string) => {
const view = otherTeam ? otherTeam : as
const url = "/bins/" + key + (view ? "?as=" + view : "")
return new Promise<AxiosResponse<pond.Bin>>((resolve, reject)=>{
get<pond.Bin>(pondURL(url))
.then(resp => {
resp.data = pond.Bin.fromObject(resp.data)
resolve(resp)
})
.catch(err => {
reject(err)
})
})
};
const addComponent = (
bin: string,
device: number,
component: string,
preferences?: pond.BinComponentPreferences,
otherTeam?: string
) => {
const view = otherTeam ? otherTeam : as
let url = "/bins/" + bin + "/addComponent/" + device + "/" + component;
if (view) {
url =
url +
"?as=" +
view +
(preferences ? "&binPref=" + preferences.type + "&fillNode=" + preferences.node : "");
} else if (preferences) {
url = url + "?binPref=" + preferences.type + "&fillNode=" + preferences.node;
}
return new Promise<AxiosResponse<pond.AddBinComponentResponse>>((resolve, reject)=>{
post<pond.AddBinComponentResponse>(pondURL(url)).then(resp => {
resp.data = pond.AddBinComponentResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const removeComponent = (bin: string, component: string, otherTeam?: string) => {
const view = otherTeam ? otherTeam : as
let url = "/bins/" + bin + "/removeComponent/" + component;
if (view) url = url + "?as=" + view;
return new Promise<AxiosResponse<pond.RemoveBinComponentResponse>>((resolve, reject)=>{
post<pond.RemoveBinComponentResponse>(pondURL(url)).then(resp => {
resp.data = pond.RemoveBinComponentResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const removeAllComponents = (bin: string, otherTeam?: string) => {
const view = otherTeam ? otherTeam : as
let url = "/bins/" + bin + "/removeAllComponents";
if (view) url = url + "?as=" + view;
return new Promise<AxiosResponse<pond.RemoveAllBinComponentsResponse>>((resolve, reject)=>{
post<pond.RemoveAllBinComponentsResponse>(pondURL(url)).then(resp => {
resp.data = pond.RemoveAllBinComponentsResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const updateComponentPreferences = (
bin: string,
component: string,
preferences: pond.BinComponentPreferences,
otherTeam?: string
) => {
const view = otherTeam ? otherTeam : as
let url = "/bins/" + bin + "/updateComponent/" + component + "/preferences";
if (view) url = url + "?as=" + view;
interface request {
preferences: Object;
}
let body: request = { preferences: pond.BinComponentPreferences.toObject(preferences) };
return new Promise<AxiosResponse<pond.UpdateBinComponentPreferencesResponse>>((resolve,reject)=>{
put<pond.UpdateBinComponentPreferencesResponse>(pondURL(url), body).then(resp => {
resp.data = pond.UpdateBinComponentPreferencesResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const getBinPageData = (binKey: string, userKey: string, showErrors = true, otherTeam?: string) => {
const view = otherTeam ? otherTeam : as
const url = "/bins/" +
binKey +
"/users/" +
userKey +
(showErrors ? "?showErrors=true" : "?showErrors=false") +
(view ? "&as=" + view : "")
return new Promise<AxiosResponse<pond.GetBinPageDataResponse>>((resolve, reject)=>{
get<pond.GetBinPageDataResponse>(pondURL(url))
.then(resp => {
resp.data = pond.GetBinPageDataResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const listBins = (
limit: number,
offset: number,
order?: "asc" | "desc",
orderBy?: string,
search?: string,
otherTeam?: string,
asRoot?: boolean,
numerical?: boolean,
keys?: string[],
types?: string[]
) => {
return new Promise<AxiosResponse<pond.ListBinsResponse>>((resolve, reject)=>{
const view = otherTeam ? otherTeam : as
get<pond.ListBinsResponse>(
pondURL(
"/bins" +
"?limit=" +
limit +
"&offset=" +
offset +
("&order=" + or(order, "asc")) +
("&by=" + or(orderBy, "key")) +
(numerical ? "&numerical=true" : "") +
(view ? "&as=" + view : "") +
(asRoot ? "&asRoot=" + asRoot.toString() : "") +
(search ? "&search=" + search : "") +
(keys ? "&keys=" + keys.join(",") : "") +
(types ? "&types=" + types.join(",") : "")
)
).then(resp => {
resp.data = pond.ListBinsResponse.fromObject(resp.data);
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const listBinsAndData = (
limit: number,
offset: number,
order?: "asc" | "desc",
orderBy?: string,
search?: string,
otherTeam?: string,
asRoot?: boolean,
keys?: string[],
types?: string[]
) => {
const view = otherTeam ? otherTeam : as
const url = "/binsAndData" +
"?limit=" +
limit +
"&offset=" +
offset +
("&order=" + or(order, "asc")) +
("&by=" + or(orderBy, "key")) +
(view ? "&as=" + view : "") +
(asRoot ? "&asRoot=" + asRoot.toString() : "") +
(search ? "&search=" + search : "") +
(keys ? "&keys=" + keys.join(",") : "") +
(types ? "&types=" + types.join(",") : "")
return new Promise<AxiosResponse<pond.ListBinsAndDataResponse>>((resolve, reject)=>{
get<pond.ListBinsAndDataResponse>(pondURL(url)).then(resp => {
resp.data = pond.ListBinsAndDataResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const listBinStatus = (
key: string,
startDate: any,
endDate: any,
limit: number,
offset: number,
order?: "asc" | "desc",
asRoot?: boolean
) => {
const url = "/bins/" +
key +
"/status" +
dateRange(startDate, endDate) +
"?limit=" +
limit +
"&offset=" +
offset +
("&order=" + or(order, "asc")) +
(asRoot ? "&asRoot=" + asRoot.toString() : "")
return new Promise<AxiosResponse<pond.ListBinStatusResponse>>((resolve, reject)=>{
get<pond.ListBinStatusResponse>(
pondURL(url)
).then(resp => {
resp.data = pond.ListBinStatusResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const listBinComponents = (key: string) => {
return new Promise<AxiosResponse<pond.ListBinComponentsResponse>>((resolve, reject)=>{
get<pond.ListBinComponentsResponse>(pondURL("/bins/" + key + "/components"))
.then(resp => {
resp.data = pond.ListBinComponentsResponse.fromObject(resp.data)
return resolve(resp)
})
.catch(err => {
return reject(err)
})
})
};
const listBinComponentsMeasurements = (
key: string,
start: string,
end: string,
showErrors = false,
allNodes = false,
otherTeam?: string
) => {
const view = otherTeam ? otherTeam : as
let url = "/bins/" +
key +
"/components/measurements?start=" +
start +
"&end=" +
end +
(view ? "&as=" + view : "") +
(showErrors ? "&showErrors=true" : "&showErrors=false") +
(allNodes ? "&allNodes=true" : "&allNodes=false")
return new Promise<AxiosResponse<pond.ListBinComponentsMeasurementsResponse>>((resolve, reject) => {
get<pond.ListBinComponentsMeasurementsResponse>(pondURL(url))
.then(resp => {
resp.data = pond.ListBinComponentsMeasurementsResponse.fromObject(resp.data)
return resolve(resp)
})
.catch(err => {
return reject(err)
})
}
)
};
const listHistory = (id: string, limit: number, offset: number) => {
let url = "/bins/" + id + "/history?limit=" + limit + "&offset=" + offset
return new Promise<AxiosResponse<pond.ListBinHistoryResponse>>((resolve, reject)=>{
get<pond.ListBinHistoryResponse>(
pondURL(url)
).then(resp => {
resp.data = pond.ListBinHistoryResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const listHistoryBetween = (id: string, limit: number, start: string, end: string) => {
let url = "/bins/" + id + "/historyBetween?limit=" + limit + "&start=" + start + "&end=" + end
return new Promise<AxiosResponse<pond.ListBinHistoryResponse>>((resolve, reject)=>{
get<pond.ListBinHistoryResponse>(
pondURL(url)
).then(resp => {
resp.data = pond.ListBinHistoryResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const updateBinPermissions = (key: string, users: User[]) => {
return permissionAPI.updatePermissions(binScope(key.toString()), users);
};
const getBinMetrics = (search?: string, otherTeam?: string) => {
const view = otherTeam ? otherTeam : as
let url = "/metrics/bins" + (search ? "?search=" + search : "")
if (view) {
if (search){
url = "/metrics/bins/?search=" + search + "&as=" + view
}
url = "/metrics/bins/?as=" + view;
}
return new Promise<AxiosResponse<pond.GetBinMetricsResponse>>((resolve, reject)=>{
get<pond.GetBinMetricsResponse>(pondURL(url)).then(resp => {
resp.data = pond.GetBinMetricsResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const listBinLiters = (
key: string,
start: string,
end: string,
moisture: number,
plenum: string,
cable: string,
pressure: string,
fan?: string,
otherTeam?: string
) => {
const view = otherTeam ? otherTeam : as
const url = "/bins/" +
key +
"/liters?start=" +
start +
"&end=" +
end +
"&moisture=" +
moisture +
"&plenum=" +
plenum +
"&cable=" +
cable +
"&pressure=" +
pressure +
(fan ? "&fan=" + fan : "") +
(view ? "&as=" + view : "")
return new Promise<AxiosResponse<pond.ListBinLiterResponse>>((resolve, reject)=>{
get<pond.ListBinLiterResponse>(pondURL(url))
.then(resp => {
resp.data = pond.ListBinLiterResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const listBinPrefs = (key: string, otherTeam?: string) => {
const view = otherTeam ? otherTeam : as
const url = "/bins/" + key + "/componentPreferences?as=" + view
return new Promise<AxiosResponse<pond.ListBinComponentPreferencesResponse>>((resolve, reject)=>{
get<pond.ListBinComponentPreferencesResponse>(pondURL(url))
.then(resp => {
resp.data = pond.ListBinComponentPreferencesResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const updateTopNodes = (key: string, newTopNodes: pond.NewTopNode[], otherTeam?: string) => {
let body: pond.TopNodeList = pond.TopNodeList.create({ newTopNodes: newTopNodes });
const view = otherTeam ? otherTeam : as
let url = "/bins/" + key + "/updateTopNodes" + (view ? "?as=" + view : "")
return new Promise<AxiosResponse<pond.UpdateTopNodesResponse>>((resolve,response) => {
post<pond.UpdateTopNodesResponse>(pondURL(url),body).then(resp => {
resp.data = pond.UpdateTopNodesResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return response(err)
})
})
};
const listBinMeasurements = (
key: string,
startDate: any,
endDate: any,
limit: number,
offset: number,
order: string,
measurementType?: number | quack.MeasurementType,
keys?: string[],
types?: string[],
showErrors?: boolean,
otherTeam?: string
) => {
const view = otherTeam ? otherTeam : as
const url = pondURL(
"/objects/" +
key +
"/1/unitMeasurements" +
dateRange(startDate, endDate) +
"&limit=" +
limit +
"&offset=" +
offset +
"&order=" +
order +
(measurementType ? "&type=" + measurementType : "") +
(view ? "&as=" + view : "") +
(keys ? "&keys=" + keys : "") +
(types ? "&types=" + types : "") +
(showErrors ? "&showErrors=true" : "&showErrors=false")
);
return new Promise<AxiosResponse<pond.ListObjectMeasurementsResponse>>((resolve, reject) => {
get<pond.ListObjectMeasurementsResponse>(url)
.then(resp => {
resp.data = pond.ListObjectMeasurementsResponse.fromObject(resp.data)
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
};
const getBinsTrendData = (bins: string[], days: number) => {
return get<pond.GetBinsTrendDataResponse>(
pondURL("/binTrends?bins=" + bins.toString() + "&days=" + days + (as ? "&as=" + as : ""))
);
};
return (
<BinAPIContext.Provider
value={{
addBin,
updateBin,
bulkBinUpdate,
updateBinStatus,
removeBin,
listBinComponents,
listBinComponentsMeasurements,
listBinStatus,
getBin,
addComponent,
removeComponent,
removeAllComponents,
updateComponentPreferences,
getBinPageData,
listBins,
listBinsAndData,
listHistory,
updateBinPermissions,
getBinMetrics,
listBinLiters,
listHistoryBetween,
listBinPrefs,
updateTopNodes,
listBinMeasurements,
getBinsTrendData
}}>
{children}
</BinAPIContext.Provider>
);
}
export const useBinAPI = () => useContext(BinAPIContext);