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; addDevice: (group: number, device: number) => Promise; removeDevice: (group: number, device: number) => Promise; updateGroup: (id: number, group: pond.GroupSettings) => Promise; removeGroup: (id: number) => Promise; getGroup: (id: number) => Promise; getGroupAndPermissions: (id: number) => Promise>; getGroupPermissions: ( id: number, keys?: string[], types?: string[], ) => Promise>; listGroups: ( limit: number, offset: number, order?: "asc" | "desc", orderBy?: string, search?: string, asRoot?: boolean, keys?: string[], types?: string[], ) => Promise>; listGroupDevices: ( id: number, limit: number, offset: number, order: "asc" | "desc", search?: string, comprehensive?: boolean ) => Promise>; updateGroupPermissions: (id: number, users: User[]) => Promise; } function buildQueryString(params: Record): 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({} as IGroupAPIContext); interface Props {} export default function GroupProvider(props: PropsWithChildren) { 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((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((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((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((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((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((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>((resolve, reject) => { get(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>((resolve, reject) => { get(pondURL(url)).then(resp => { resp.data = pond.GetPermissionsResponse.fromObject(resp.data) return resolve(resp); }).catch(err => { return reject(err) }) }) // return get(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>((resolve, reject) => { get(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>((resolve, reject) => { get(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 ( {children} ); } export const useGroupAPI = () => useContext(GroupAPIContext);