314 lines
9.5 KiB
TypeScript
314 lines
9.5 KiB
TypeScript
import { useHTTP } from "../http";
|
|
import { usePermissionAPI } from "./permissionAPI";
|
|
import { createContext, PropsWithChildren, useContext } from "react";
|
|
import { pond } from "protobuf-ts/pond";
|
|
import { or } from "utils/types";
|
|
import { User, groupScope } from "models";
|
|
import { pondURL } from "./pond";
|
|
import { AxiosResponse } from "axios";
|
|
import { useGlobalState } from "../StateContainer";
|
|
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
|
|
|
export interface IGroupAPIContext {
|
|
addGroup: (group: pond.GroupSettings) => Promise<any>;
|
|
addDevice: (group: number, device: number) => Promise<any>;
|
|
removeDevice: (group: number, device: number) => Promise<any>;
|
|
updateGroup: (id: number, group: pond.GroupSettings) => Promise<any>;
|
|
removeGroup: (id: number) => Promise<any>;
|
|
getGroup: (id: number) => Promise<any>;
|
|
getGroupAndPermissions: (id: number) => Promise<AxiosResponse<pond.GetGroupAndPermissionsResponse>>;
|
|
getGroupPermissions: (
|
|
id: number,
|
|
keys?: string[],
|
|
types?: string[],
|
|
) => Promise<AxiosResponse<pond.GetPermissionsResponse>>;
|
|
listGroups: (
|
|
limit: number,
|
|
offset: number,
|
|
order?: "asc" | "desc",
|
|
orderBy?: string,
|
|
search?: string,
|
|
asRoot?: boolean,
|
|
keys?: string[],
|
|
types?: string[],
|
|
) => Promise<AxiosResponse<pond.ListGroupsResponse>>;
|
|
listGroupDevices: (
|
|
id: number,
|
|
limit: number,
|
|
offset: number,
|
|
order: "asc" | "desc",
|
|
search?: string,
|
|
comprehensive?: boolean
|
|
) => Promise<AxiosResponse<pond.GetMultiDeviceResponse>>;
|
|
updateGroupPermissions: (id: number, users: User[]) => Promise<any>;
|
|
}
|
|
|
|
function buildQueryString(params: Record<string, string | string[] | number | null | undefined>): string {
|
|
// Filter out null, undefined, or empty string values
|
|
const validParams = Object.entries(params)
|
|
.filter(([_, value]) => value != null && value !== '')
|
|
.map(([key, value]) => `${key}=${value}`);
|
|
|
|
if (validParams.length === 0) {
|
|
return '';
|
|
}
|
|
|
|
// Join parameters with '&' and prepend '?'
|
|
return `?${validParams.join('&')}`;
|
|
}
|
|
|
|
export const GroupAPIContext = createContext<IGroupAPIContext>({} as IGroupAPIContext);
|
|
|
|
interface Props {}
|
|
|
|
export default function GroupProvider(props: PropsWithChildren<Props>) {
|
|
const { children } = props;
|
|
const { get, post, put, del } = useHTTP();
|
|
const permissionAPI = usePermissionAPI();
|
|
const [{ as }] = useGlobalState();
|
|
|
|
const addGroup = (group: pond.GroupSettings) => {
|
|
// let url = pondURL("/groups")
|
|
// let keys = getContextKeys()
|
|
// let types = getContextTypes()
|
|
// if (as) url = pondURL("/groups?as=" + as)
|
|
const params = {
|
|
keys: getContextKeys(),
|
|
types: getContextTypes(),
|
|
as: getContextTypes().includes("team") ? undefined : as
|
|
}
|
|
let url = pondURL(`/groups${buildQueryString(params)}`)
|
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
|
post(url, group).then(resp => {
|
|
return resolve(resp)
|
|
}).catch(err => {
|
|
return reject(err)
|
|
})
|
|
})
|
|
};
|
|
|
|
const addDevice = (group: number, device: number) => {
|
|
let url = "/groups/" + group + "/devices/" + device + "/add";
|
|
if (as) url = url + "?as=" + as
|
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
|
post(pondURL(url), group).then(resp => {
|
|
return resolve(resp)
|
|
}).catch(err => {
|
|
return reject(err)
|
|
})
|
|
})
|
|
};
|
|
|
|
const removeDevice = (group: number, device: number) => {
|
|
let url = "/groups/" + group + "/devices/" + device + "/remove";
|
|
if (as) url = url + "?as=" + as
|
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
|
post(pondURL(url), group).then(resp => {
|
|
return resolve(resp)
|
|
}).catch(err => {
|
|
return reject(err)
|
|
})
|
|
})
|
|
};
|
|
|
|
const updateGroup = (id: number, group: pond.GroupSettings) => {
|
|
let url = pondURL("/groups/" + id)
|
|
if (as) url = pondURL("/groups/" + id + "?as=" + as)
|
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
|
put(url, group).then(resp => {
|
|
return resolve(resp)
|
|
}).catch(err => {
|
|
return reject(err)
|
|
})
|
|
})
|
|
};
|
|
|
|
const removeGroup = (id: number) => {
|
|
const params = {
|
|
keys: getContextKeys(),
|
|
types: getContextTypes(),
|
|
as: getContextTypes().includes("team") ? undefined : as
|
|
}
|
|
pondURL(`/groups/${id}${buildQueryString(params)}`)
|
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
|
del(pondURL(`/groups/${id}${buildQueryString(params)}`)).then(resp => {
|
|
return resolve(resp)
|
|
}).catch(err => {
|
|
return reject(err)
|
|
})
|
|
})
|
|
};
|
|
|
|
const getGroup = (id: number) => {
|
|
let url = pondURL("/groups/" + id)
|
|
if (as) return get(pondURL("/groups/" + id + "?as=" + as));
|
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
|
get(url).then(resp => {
|
|
resolve(resp)
|
|
}).catch(err => {
|
|
reject(err)
|
|
})
|
|
})
|
|
};
|
|
|
|
const getGroupAndPermissions = (
|
|
id: number,
|
|
keys?: string[],
|
|
types?: string[],
|
|
) => {
|
|
keys = keys ? keys : getContextKeys();
|
|
types = types? types : getContextTypes();
|
|
let url = "/groupAndPermissions/" + id
|
|
if (as) {
|
|
url = url + "?as=" + as +
|
|
+
|
|
(keys ? "?keys=" + keys.toString() : "") +
|
|
(types ? "&types=" + types.toString() : "")
|
|
} else {
|
|
url = url +
|
|
(keys ? "?keys=" + keys.toString() : "") +
|
|
(types ? "&types=" + types.toString() : "")
|
|
}
|
|
return new Promise<AxiosResponse<pond.GetGroupAndPermissionsResponse>>((resolve, reject) => {
|
|
get<pond.GetGroupAndPermissionsResponse>(pondURL(url)).then(resp => {
|
|
resp.data = pond.GetGroupAndPermissionsResponse.fromObject(resp.data)
|
|
return resolve(resp)
|
|
}).catch(err => {
|
|
return reject(err)
|
|
})
|
|
})
|
|
};
|
|
|
|
const getGroupPermissions = (
|
|
id: number,
|
|
keys?: string[],
|
|
types?: string[],
|
|
) => {
|
|
// keys = keys ? keys : getContextKeys();
|
|
// types = types? types : getContextTypes();
|
|
// let url = "/groupPermissions/" + id
|
|
// if (as) {
|
|
// url = url + "?as=" + as +
|
|
// +
|
|
// (keys ? "?keys=" + keys.toString() : "") +
|
|
// (types ? "&types=" + types.toString() : "")
|
|
// } else {
|
|
// url = url +
|
|
// (keys ? "?keys=" + keys.toString() : "") +
|
|
// (types ? "&types=" + types.toString() : "")
|
|
// }
|
|
const params = {
|
|
keys: getContextKeys(),
|
|
types: getContextTypes(),
|
|
as: getContextTypes().includes("team") ? undefined : as,
|
|
}
|
|
let url = `/groupPermissions/${id}${buildQueryString(params)}`
|
|
return new Promise<AxiosResponse<pond.GetPermissionsResponse>>((resolve, reject) => {
|
|
get<pond.GetPermissionsResponse>(pondURL(url)).then(resp => {
|
|
resp.data = pond.GetPermissionsResponse.fromObject(resp.data)
|
|
return resolve(resp);
|
|
}).catch(err => {
|
|
return reject(err)
|
|
})
|
|
})
|
|
// return get<pond.GetPermissionsResponse>(pondURL(url));
|
|
};
|
|
|
|
const listGroups = (
|
|
limit: number,
|
|
offset: number,
|
|
order?: "asc" | "desc",
|
|
orderBy?: string,
|
|
search?: string,
|
|
asRoot?: boolean,
|
|
keys?: string[],
|
|
types?: string[]
|
|
) => {
|
|
keys = keys ? keys : getContextKeys();
|
|
types = types? types : getContextTypes();
|
|
types.forEach((type, index) => {
|
|
if (type === "group") {
|
|
types && types.splice(index, 1)
|
|
keys && keys.splice(index, 1)
|
|
}
|
|
})
|
|
let url = pondURL(
|
|
"/groups" +
|
|
"?limit=" +
|
|
limit +
|
|
"&offset=" +
|
|
offset +
|
|
("&order=" + or(order, "asc")) +
|
|
("&orderBy=" + or(orderBy, "id")) +
|
|
(search ? "&search=" + search : "") +
|
|
(asRoot ? "&asRoot=" + asRoot.toString() : "") +
|
|
(as ? "&as=" + as.toString() : "") +
|
|
(keys.length > 0 ? "&keys=" + keys : "") +
|
|
(types.length > 0 ? "&types=" + types : "")
|
|
)
|
|
return new Promise<AxiosResponse<pond.ListGroupsResponse>>((resolve, reject) => {
|
|
get<pond.ListGroupsResponse>(url).then(resp => {
|
|
resp.data = pond.ListGroupsResponse.fromObject(resp.data)
|
|
return resolve(resp)
|
|
}).catch(err => {
|
|
return reject(err)
|
|
})
|
|
})
|
|
};
|
|
|
|
const listGroupDevices = (
|
|
id: number,
|
|
limit: number,
|
|
offset: number,
|
|
order: "asc" | "desc",
|
|
search?: string,
|
|
comprehensive: boolean = false
|
|
) => {
|
|
let url = pondURL(
|
|
"/groups/" +
|
|
id +
|
|
"/devices?limit=" +
|
|
limit +
|
|
"&offset=" +
|
|
offset +
|
|
"&order=" +
|
|
order +
|
|
(search ? "&search=" + search : "") +
|
|
(comprehensive ? "&comprehensive=" + comprehensive.toString() : "") +
|
|
(as ? "&as=" + as.toString() : "")
|
|
)
|
|
return new Promise<AxiosResponse<pond.GetMultiDeviceResponse>>((resolve, reject) => {
|
|
get<pond.GetMultiDeviceResponse>(url).then(resp => {
|
|
resp.data = pond.GetMultiDeviceResponse.fromObject(resp.data)
|
|
return resolve(resp)
|
|
}).catch(err => {
|
|
return reject(err)
|
|
})
|
|
})
|
|
};
|
|
|
|
const updateGroupPermissions = (id: number, users: User[]) => {
|
|
return permissionAPI.updatePermissions(groupScope(id.toString()), users);
|
|
};
|
|
|
|
return (
|
|
<GroupAPIContext.Provider
|
|
value={{
|
|
addGroup,
|
|
addDevice,
|
|
removeDevice,
|
|
updateGroup,
|
|
removeGroup,
|
|
getGroup,
|
|
getGroupPermissions,
|
|
getGroupAndPermissions,
|
|
listGroups,
|
|
listGroupDevices,
|
|
updateGroupPermissions
|
|
}}>
|
|
{children}
|
|
</GroupAPIContext.Provider>
|
|
);
|
|
}
|
|
|
|
export const useGroupAPI = () => useContext(GroupAPIContext);
|