Formatted all .ts files
This commit is contained in:
@@ -7,178 +7,170 @@ type MethodTypes = "get" | "delete" | "head" | "options";
|
|||||||
type MethodTypesWithBody = "post" | "put" | "patch";
|
type MethodTypesWithBody = "post" | "put" | "patch";
|
||||||
|
|
||||||
const dataProvider = (
|
const dataProvider = (
|
||||||
apiUrl: string,
|
apiUrl: string,
|
||||||
httpClient: AxiosInstance = axiosInstance,
|
httpClient: AxiosInstance = axiosInstance
|
||||||
): Omit<
|
): Omit<Required<DataProvider>, "createMany" | "updateMany" | "deleteMany"> => ({
|
||||||
Required<DataProvider>,
|
getList: async ({ resource, meta, pagination, sorters, filters }) => {
|
||||||
"createMany" | "updateMany" | "deleteMany"
|
const url = `${apiUrl}/${resource}`;
|
||||||
> => ({
|
|
||||||
getList: async ({ resource, meta, pagination, sorters, filters }) => {
|
|
||||||
const url = `${apiUrl}/${resource}`;
|
|
||||||
|
|
||||||
const { headers: headersFromMeta, method } = meta ?? {};
|
const { headers: headersFromMeta, method } = meta ?? {};
|
||||||
const queryParams: Record<string, string | number> = meta?.queryParams ?? {};
|
const queryParams: Record<string, string | number> = meta?.queryParams ?? {};
|
||||||
const requestMethod = (method as MethodTypes) ?? "get";
|
const requestMethod = (method as MethodTypes) ?? "get";
|
||||||
|
|
||||||
if (pagination && pagination.mode == "server") {
|
if (pagination && pagination.mode == "server") {
|
||||||
const pageSize = pagination.pageSize ?? 10;
|
const pageSize = pagination.pageSize ?? 10;
|
||||||
const offset = ((pagination.current ?? 1) - 1) * pageSize;
|
const offset = ((pagination.current ?? 1) - 1) * pageSize;
|
||||||
queryParams["limit"] = pageSize;
|
queryParams["limit"] = pageSize;
|
||||||
queryParams["offset"] = offset;
|
queryParams["offset"] = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sorters && sorters.length > 0) {
|
||||||
|
queryParams["sort"] = sorters
|
||||||
|
.map((sort) => {
|
||||||
|
const field = sort.field;
|
||||||
|
return `${field}:${sort.order}`;
|
||||||
|
})
|
||||||
|
.join(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters && filters.length > 0) {
|
||||||
|
filters.forEach((filter) => {
|
||||||
|
if (!("field" in filter)) {
|
||||||
|
throw Error("Filter must be a LogicalFilter.");
|
||||||
}
|
}
|
||||||
|
const field = filter.field;
|
||||||
|
if (filter.value.length > 0) {
|
||||||
|
const filterValueArray = Array.isArray(filter.value) ? filter.value : [filter.value];
|
||||||
|
|
||||||
if (sorters && sorters.length > 0) {
|
const filterValue = filterValueArray
|
||||||
queryParams["sort"] = sorters.map((sort) => {
|
.map((value) => {
|
||||||
const field = sort.field
|
if (value === "<empty>") {
|
||||||
return `${field}:${sort.order}`;
|
return "";
|
||||||
}).join(",")
|
}
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
.join(",");
|
||||||
|
|
||||||
|
queryParams[field] = filterValue;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (filters && filters.length > 0) {
|
const { data, headers } = await httpClient[requestMethod](`${url}`, {
|
||||||
filters.forEach(filter => {
|
headers: headersFromMeta,
|
||||||
if (!("field" in filter)) {
|
params: queryParams,
|
||||||
throw Error("Filter must be a LogicalFilter.")
|
});
|
||||||
}
|
|
||||||
const field = filter.field
|
|
||||||
if (filter.value.length > 0) {
|
|
||||||
const filterValueArray = Array.isArray(filter.value) ? filter.value : [filter.value]
|
|
||||||
|
|
||||||
const filterValue = filterValueArray.map((value) => {
|
// console.log(url, requestMethod, queryParams, data, headers)
|
||||||
if (value === "<empty>") {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}).join(",")
|
|
||||||
|
|
||||||
queryParams[field] = filterValue
|
return {
|
||||||
}
|
data,
|
||||||
});
|
total: parseInt(headers["x-total-count"]) ?? 100,
|
||||||
}
|
};
|
||||||
|
},
|
||||||
|
|
||||||
const { data, headers } = await httpClient[requestMethod](
|
getMany: async () => {
|
||||||
`${url}`,
|
throw new Error("getMany not implemented");
|
||||||
{
|
},
|
||||||
headers: headersFromMeta,
|
|
||||||
params: queryParams,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// console.log(url, requestMethod, queryParams, data, headers)
|
create: async ({ resource, variables, meta }) => {
|
||||||
|
const url = `${apiUrl}/${resource}`;
|
||||||
|
|
||||||
return {
|
const { headers, method } = meta ?? {};
|
||||||
data,
|
const requestMethod = (method as MethodTypesWithBody) ?? "post";
|
||||||
total: parseInt(headers["x-total-count"]) ?? 100,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
getMany: async () => {
|
const { data } = await httpClient[requestMethod](url, variables, {
|
||||||
throw new Error("getMany not implemented");
|
headers,
|
||||||
},
|
});
|
||||||
|
|
||||||
create: async ({ resource, variables, meta }) => {
|
return {
|
||||||
const url = `${apiUrl}/${resource}`;
|
data,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
const { headers, method } = meta ?? {};
|
update: async ({ resource, id, variables, meta }) => {
|
||||||
const requestMethod = (method as MethodTypesWithBody) ?? "post";
|
const url = `${apiUrl}/${resource}/${id}`;
|
||||||
|
|
||||||
const { data } = await httpClient[requestMethod](url, variables, {
|
const { headers, method } = meta ?? {};
|
||||||
headers,
|
const requestMethod = (method as MethodTypesWithBody) ?? "patch";
|
||||||
|
|
||||||
|
const { data } = await httpClient[requestMethod](url, variables, {
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getOne: async ({ resource, id, meta }) => {
|
||||||
|
const url = `${apiUrl}/${resource}/${id}`;
|
||||||
|
|
||||||
|
const { headers, method } = meta ?? {};
|
||||||
|
const requestMethod = (method as MethodTypes) ?? "get";
|
||||||
|
|
||||||
|
const { data } = await httpClient[requestMethod](url, { headers });
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteOne: async ({ resource, id, variables, meta }) => {
|
||||||
|
const url = `${apiUrl}/${resource}/${id}`;
|
||||||
|
|
||||||
|
const { headers, method } = meta ?? {};
|
||||||
|
const requestMethod = (method as MethodTypesWithBody) ?? "delete";
|
||||||
|
|
||||||
|
const { data } = await httpClient[requestMethod](url, {
|
||||||
|
data: variables,
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getApiUrl: () => {
|
||||||
|
return apiUrl;
|
||||||
|
},
|
||||||
|
|
||||||
|
custom: async ({ url, method, payload, query, headers }) => {
|
||||||
|
let requestUrl = `${url}?`;
|
||||||
|
|
||||||
|
if (query) {
|
||||||
|
requestUrl = `${requestUrl}&${stringify(query)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers) {
|
||||||
|
httpClient.defaults.headers = {
|
||||||
|
...httpClient.defaults.headers,
|
||||||
|
...headers,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let axiosResponse;
|
||||||
|
switch (method) {
|
||||||
|
case "put":
|
||||||
|
case "post":
|
||||||
|
case "patch":
|
||||||
|
axiosResponse = await httpClient[method](url, payload);
|
||||||
|
break;
|
||||||
|
case "delete":
|
||||||
|
axiosResponse = await httpClient.delete(url, {
|
||||||
|
data: payload,
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
axiosResponse = await httpClient.get(requestUrl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
const { data } = axiosResponse;
|
||||||
data,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
update: async ({ resource, id, variables, meta }) => {
|
return Promise.resolve({ data });
|
||||||
const url = `${apiUrl}/${resource}/${id}`;
|
},
|
||||||
|
|
||||||
const { headers, method } = meta ?? {};
|
|
||||||
const requestMethod = (method as MethodTypesWithBody) ?? "patch";
|
|
||||||
|
|
||||||
const { data } = await httpClient[requestMethod](url, variables, {
|
|
||||||
headers,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
data,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
getOne: async ({ resource, id, meta }) => {
|
|
||||||
const url = `${apiUrl}/${resource}/${id}`;
|
|
||||||
|
|
||||||
const { headers, method } = meta ?? {};
|
|
||||||
const requestMethod = (method as MethodTypes) ?? "get";
|
|
||||||
|
|
||||||
const { data } = await httpClient[requestMethod](url, { headers });
|
|
||||||
|
|
||||||
return {
|
|
||||||
data,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
deleteOne: async ({ resource, id, variables, meta }) => {
|
|
||||||
const url = `${apiUrl}/${resource}/${id}`;
|
|
||||||
|
|
||||||
const { headers, method } = meta ?? {};
|
|
||||||
const requestMethod = (method as MethodTypesWithBody) ?? "delete";
|
|
||||||
|
|
||||||
const { data } = await httpClient[requestMethod](url, {
|
|
||||||
data: variables,
|
|
||||||
headers,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
data,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
getApiUrl: () => {
|
|
||||||
return apiUrl;
|
|
||||||
},
|
|
||||||
|
|
||||||
custom: async ({
|
|
||||||
url,
|
|
||||||
method,
|
|
||||||
payload,
|
|
||||||
query,
|
|
||||||
headers,
|
|
||||||
}) => {
|
|
||||||
let requestUrl = `${url}?`;
|
|
||||||
|
|
||||||
if (query) {
|
|
||||||
requestUrl = `${requestUrl}&${stringify(query)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (headers) {
|
|
||||||
httpClient.defaults.headers = {
|
|
||||||
...httpClient.defaults.headers,
|
|
||||||
...headers,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let axiosResponse;
|
|
||||||
switch (method) {
|
|
||||||
case "put":
|
|
||||||
case "post":
|
|
||||||
case "patch":
|
|
||||||
axiosResponse = await httpClient[method](url, payload);
|
|
||||||
break;
|
|
||||||
case "delete":
|
|
||||||
axiosResponse = await httpClient.delete(url, {
|
|
||||||
data: payload,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
axiosResponse = await httpClient.get(requestUrl);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = axiosResponse;
|
|
||||||
|
|
||||||
return Promise.resolve({ data });
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default dataProvider;
|
export default dataProvider;
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import { BaseKey, LiveEvent, LiveProvider } from "@refinedev/core";
|
|||||||
* A spoolman websocket event.
|
* A spoolman websocket event.
|
||||||
*/
|
*/
|
||||||
interface Event {
|
interface Event {
|
||||||
type: "updated" | "deleted" | "added";
|
type: "updated" | "deleted" | "added";
|
||||||
resource: "filament" | "spool" | "vendor";
|
resource: "filament" | "spool" | "vendor";
|
||||||
date: string;
|
date: string;
|
||||||
payload: {
|
payload: {
|
||||||
id: number;
|
id: number;
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,25 +21,24 @@ interface Event {
|
|||||||
* @returns The WebSocket URL
|
* @returns The WebSocket URL
|
||||||
*/
|
*/
|
||||||
function toWebsocketURL(apiUrl: string) {
|
function toWebsocketURL(apiUrl: string) {
|
||||||
if (apiUrl[0] === "/") {
|
if (apiUrl[0] === "/") {
|
||||||
// Relative URL, e.g. "/api/v1/..."
|
// Relative URL, e.g. "/api/v1/..."
|
||||||
|
|
||||||
// Get the current browser URL
|
// Get the current browser URL
|
||||||
const currentURL = window.location.href;
|
const currentURL = window.location.href;
|
||||||
|
|
||||||
// Split the URL to separate the protocol, host, and path
|
// Split the URL to separate the protocol, host, and path
|
||||||
const urlParts = currentURL.split('/');
|
const urlParts = currentURL.split("/");
|
||||||
const host = urlParts[2];
|
const host = urlParts[2];
|
||||||
|
|
||||||
// Create the WebSocket URL by adding "ws://" as the protocol and the relative URL as the path
|
// Create the WebSocket URL by adding "ws://" as the protocol and the relative URL as the path
|
||||||
return `ws://${host}${apiUrl}`;
|
return `ws://${host}${apiUrl}`;
|
||||||
}
|
} else {
|
||||||
else {
|
// Absolute URL, e.g. "https://example.com/api/v1/..."
|
||||||
// Absolute URL, e.g. "https://example.com/api/v1/..."
|
|
||||||
|
|
||||||
// Replace the protocol with "ws://"
|
// Replace the protocol with "ws://"
|
||||||
return apiUrl.replace(/^http/, 'ws');
|
return apiUrl.replace(/^http/, "ws");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,77 +50,72 @@ function toWebsocketURL(apiUrl: string) {
|
|||||||
* @param id Specific ID to subscribe to, if any. If not specified, subscribes to all IDs.
|
* @param id Specific ID to subscribe to, if any. If not specified, subscribes to all IDs.
|
||||||
* @returns A function to unsubscribe from the resource
|
* @returns A function to unsubscribe from the resource
|
||||||
*/
|
*/
|
||||||
function subscribeSingle(apiUrl: string, channel: string, resource: string, callback: (event: LiveEvent) => void, id?: BaseKey) {
|
function subscribeSingle(
|
||||||
// Verify that WebSockets are supported
|
apiUrl: string,
|
||||||
if (!('WebSocket' in window)) {
|
channel: string,
|
||||||
console.warn("WebSockets are not supported in this browser. Live updates will not be available.");
|
resource: string,
|
||||||
return () => { };
|
callback: (event: LiveEvent) => void,
|
||||||
}
|
id?: BaseKey
|
||||||
|
) {
|
||||||
|
// Verify that WebSockets are supported
|
||||||
|
if (!("WebSocket" in window)) {
|
||||||
|
console.warn("WebSockets are not supported in this browser. Live updates will not be available.");
|
||||||
|
return () => {};
|
||||||
|
}
|
||||||
|
|
||||||
const websocketURL = id ? toWebsocketURL(`${apiUrl}/${resource}/${id}`) : toWebsocketURL(`${apiUrl}/${resource}`);
|
const websocketURL = id ? toWebsocketURL(`${apiUrl}/${resource}/${id}`) : toWebsocketURL(`${apiUrl}/${resource}`);
|
||||||
|
|
||||||
const ws = new WebSocket(websocketURL);
|
const ws = new WebSocket(websocketURL);
|
||||||
ws.onmessage = (message) => {
|
ws.onmessage = (message) => {
|
||||||
const data: Event = JSON.parse(message.data);
|
const data: Event = JSON.parse(message.data);
|
||||||
const type = data.type === "added" ? "created" : data.type;
|
const type = data.type === "added" ? "created" : data.type;
|
||||||
const date = new Date(data.date);
|
const date = new Date(data.date);
|
||||||
|
|
||||||
const liveEvent: LiveEvent = {
|
const liveEvent: LiveEvent = {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
type: type,
|
type: type,
|
||||||
payload: {
|
payload: {
|
||||||
data: data.payload,
|
data: data.payload,
|
||||||
ids: [data.payload.id],
|
ids: [data.payload.id],
|
||||||
},
|
},
|
||||||
date: date,
|
date: date,
|
||||||
}
|
|
||||||
|
|
||||||
callback(liveEvent);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return () => {
|
callback(liveEvent);
|
||||||
ws.close();
|
};
|
||||||
};
|
|
||||||
|
return () => {
|
||||||
|
ws.close();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const liveProvider = (
|
const liveProvider = (apiUrl: string): LiveProvider => ({
|
||||||
apiUrl: string,
|
subscribe: ({ channel, params, callback }) => {
|
||||||
): LiveProvider => ({
|
const { resource, subscriptionType, id, ids } = params ?? {};
|
||||||
subscribe: ({ channel, params, callback }) => {
|
|
||||||
const {
|
|
||||||
resource,
|
|
||||||
subscriptionType,
|
|
||||||
id,
|
|
||||||
ids,
|
|
||||||
} = params ?? {};
|
|
||||||
|
|
||||||
if (!subscriptionType) {
|
if (!subscriptionType) {
|
||||||
throw new Error(
|
throw new Error("[useSubscription]: `subscriptionType` is required in `params`");
|
||||||
"[useSubscription]: `subscriptionType` is required in `params`",
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
throw new Error(
|
throw new Error("[useSubscription]: `resource` is required in `params`");
|
||||||
"[useSubscription]: `resource` is required in `params`",
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let idList: BaseKey[];
|
let idList: BaseKey[];
|
||||||
if (ids) idList = ids;
|
if (ids) idList = ids;
|
||||||
else if (id) idList = [id];
|
else if (id) idList = [id];
|
||||||
else {
|
else {
|
||||||
// No ID specified, subscribe to all IDs
|
// No ID specified, subscribe to all IDs
|
||||||
return [subscribeSingle(apiUrl, channel, resource, callback)]
|
return [subscribeSingle(apiUrl, channel, resource, callback)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return idList.map((id) => {
|
return idList.map((id) => {
|
||||||
return subscribeSingle(apiUrl, channel, resource, callback, id);
|
return subscribeSingle(apiUrl, channel, resource, callback, id);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
unsubscribe: (closers: (() => void)[]) => {
|
unsubscribe: (closers: (() => void)[]) => {
|
||||||
closers.forEach((fn) => fn());
|
closers.forEach((fn) => fn());
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
export default liveProvider;
|
export default liveProvider;
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import { ISpool } from "./model";
|
import { ISpool } from "./model";
|
||||||
|
|
||||||
|
|
||||||
export async function setSpoolArchived(spool: ISpool, archived: boolean) {
|
export async function setSpoolArchived(spool: ISpool, archived: boolean) {
|
||||||
const apiEndpoint = import.meta.env.VITE_APIURL;
|
const apiEndpoint = import.meta.env.VITE_APIURL;
|
||||||
const init: RequestInit = {
|
const init: RequestInit = {
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
archived: archived,
|
archived: archived,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
const request = new Request(apiEndpoint + "/spool/" + spool.id);
|
const request = new Request(apiEndpoint + "/spool/" + spool.id);
|
||||||
await fetch(request, init);
|
await fetch(request, init);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { CrudFilter, CrudOperators } from "@refinedev/core";
|
import { CrudFilter, CrudOperators } from "@refinedev/core";
|
||||||
|
|
||||||
interface TypedCrudFilter<Obj> {
|
interface TypedCrudFilter<Obj> {
|
||||||
field: keyof Obj;
|
field: keyof Obj;
|
||||||
operator: Exclude<CrudOperators, "or" | "and">;
|
operator: Exclude<CrudOperators, "or" | "and">;
|
||||||
value: string[];
|
value: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function typeFilters<Obj>(filters: CrudFilter[]): TypedCrudFilter<Obj>[] {
|
export function typeFilters<Obj>(filters: CrudFilter[]): TypedCrudFilter<Obj>[] {
|
||||||
return filters as TypedCrudFilter<Obj>[]; // <-- Unsafe cast
|
return filters as TypedCrudFilter<Obj>[]; // <-- Unsafe cast
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,12 +16,15 @@ export function typeFilters<Obj>(filters: CrudFilter[]): TypedCrudFilter<Obj>[]
|
|||||||
* @param field The field to get the filter values for.
|
* @param field The field to get the filter values for.
|
||||||
* @returns An array of filter values for the given field.
|
* @returns An array of filter values for the given field.
|
||||||
*/
|
*/
|
||||||
export function getFiltersForField<Obj, Field extends keyof Obj>(filters: TypedCrudFilter<Obj>[], field: Field): string[] {
|
export function getFiltersForField<Obj, Field extends keyof Obj>(
|
||||||
const filterValues: string[] = [];
|
filters: TypedCrudFilter<Obj>[],
|
||||||
filters.forEach((filter) => {
|
field: Field
|
||||||
if (filter.field === field) {
|
): string[] {
|
||||||
filterValues.push(...filter.value as string[]);
|
const filterValues: string[] = [];
|
||||||
}
|
filters.forEach((filter) => {
|
||||||
});
|
if (filter.field === field) {
|
||||||
return filterValues;
|
filterValues.push(...(filter.value as string[]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return filterValues;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,74 +3,74 @@ import { CrudFilter, CrudSort } from "@refinedev/core";
|
|||||||
import { isLocalStorageAvailable } from "./support";
|
import { isLocalStorageAvailable } from "./support";
|
||||||
|
|
||||||
interface Pagination {
|
interface Pagination {
|
||||||
current: number;
|
current: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TableState {
|
export interface TableState {
|
||||||
sorters: CrudSort[];
|
sorters: CrudSort[];
|
||||||
filters: CrudFilter[];
|
filters: CrudFilter[];
|
||||||
pagination: Pagination;
|
pagination: Pagination;
|
||||||
showColumns?: string[];
|
showColumns?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useInitialTableState(tableId: string): TableState {
|
export function useInitialTableState(tableId: string): TableState {
|
||||||
const [initialState] = React.useState(() => {
|
const [initialState] = React.useState(() => {
|
||||||
const savedSorters = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-sorters`) : null;
|
const savedSorters = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-sorters`) : null;
|
||||||
const savedFilters = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-filters`) : null;
|
const savedFilters = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-filters`) : null;
|
||||||
const savedPagination = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-pagination`) : null;
|
const savedPagination = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-pagination`) : null;
|
||||||
const savedShowColumns = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-showColumns`) : null;
|
const savedShowColumns = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-showColumns`) : null;
|
||||||
|
|
||||||
const sorters = savedSorters ? JSON.parse(savedSorters) : [{ field: "id", order: "asc" }];
|
const sorters = savedSorters ? JSON.parse(savedSorters) : [{ field: "id", order: "asc" }];
|
||||||
const filters = savedFilters ? JSON.parse(savedFilters) : [];
|
const filters = savedFilters ? JSON.parse(savedFilters) : [];
|
||||||
const pagination = savedPagination ? JSON.parse(savedPagination) : { page: 1, pageSize: 20 };
|
const pagination = savedPagination ? JSON.parse(savedPagination) : { page: 1, pageSize: 20 };
|
||||||
const showColumns = savedShowColumns ? JSON.parse(savedShowColumns) : undefined;
|
const showColumns = savedShowColumns ? JSON.parse(savedShowColumns) : undefined;
|
||||||
return { sorters, filters, pagination, showColumns };
|
return { sorters, filters, pagination, showColumns };
|
||||||
});
|
});
|
||||||
return initialState;
|
return initialState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useStoreInitialState(tableId: string, state: TableState) {
|
export function useStoreInitialState(tableId: string, state: TableState) {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isLocalStorageAvailable) {
|
if (isLocalStorageAvailable) {
|
||||||
localStorage.setItem(`${tableId}-sorters`, JSON.stringify(state.sorters));
|
localStorage.setItem(`${tableId}-sorters`, JSON.stringify(state.sorters));
|
||||||
}
|
}
|
||||||
}, [tableId, state.sorters]);
|
}, [tableId, state.sorters]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isLocalStorageAvailable) {
|
if (isLocalStorageAvailable) {
|
||||||
localStorage.setItem(`${tableId}-filters`, JSON.stringify(state.filters));
|
localStorage.setItem(`${tableId}-filters`, JSON.stringify(state.filters));
|
||||||
}
|
}
|
||||||
}, [tableId, state.filters]);
|
}, [tableId, state.filters]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isLocalStorageAvailable) {
|
if (isLocalStorageAvailable) {
|
||||||
localStorage.setItem(`${tableId}-pagination`, JSON.stringify(state.pagination));
|
localStorage.setItem(`${tableId}-pagination`, JSON.stringify(state.pagination));
|
||||||
}
|
}
|
||||||
}, [tableId, state.pagination]);
|
}, [tableId, state.pagination]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isLocalStorageAvailable) {
|
if (isLocalStorageAvailable) {
|
||||||
if (state.showColumns === undefined) {
|
if (state.showColumns === undefined) {
|
||||||
localStorage.removeItem(`${tableId}-showColumns`);
|
localStorage.removeItem(`${tableId}-showColumns`);
|
||||||
} else {
|
} else {
|
||||||
localStorage.setItem(`${tableId}-showColumns`, JSON.stringify(state.showColumns));
|
localStorage.setItem(`${tableId}-showColumns`, JSON.stringify(state.showColumns));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [tableId, state.showColumns]);
|
}, [tableId, state.showColumns]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useSavedState<T>(id: string, defaultValue: T) {
|
export function useSavedState<T>(id: string, defaultValue: T) {
|
||||||
const [state, setState] = React.useState<T>(() => {
|
const [state, setState] = React.useState<T>(() => {
|
||||||
const savedState = isLocalStorageAvailable ? localStorage.getItem(`savedStates-${id}`) : null;
|
const savedState = isLocalStorageAvailable ? localStorage.getItem(`savedStates-${id}`) : null;
|
||||||
return savedState ? JSON.parse(savedState) : defaultValue;
|
return savedState ? JSON.parse(savedState) : defaultValue;
|
||||||
});
|
});
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isLocalStorageAvailable) {
|
if (isLocalStorageAvailable) {
|
||||||
localStorage.setItem(`savedStates-${id}`, JSON.stringify(state));
|
localStorage.setItem(`savedStates-${id}`, JSON.stringify(state));
|
||||||
}
|
}
|
||||||
}, [id, state]);
|
}, [id, state]);
|
||||||
|
|
||||||
return [state, setState] as const;
|
return [state, setState] as const;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { CrudSort } from "@refinedev/core";
|
import { CrudSort } from "@refinedev/core";
|
||||||
import { SortOrder } from "antd/es/table/interface";
|
import { SortOrder } from "antd/es/table/interface";
|
||||||
|
|
||||||
|
|
||||||
interface TypedCrudSort<Obj> {
|
interface TypedCrudSort<Obj> {
|
||||||
field: keyof Obj;
|
field: keyof Obj;
|
||||||
order: "asc" | "desc";
|
order: "asc" | "desc";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,14 +12,17 @@ interface TypedCrudSort<Obj> {
|
|||||||
* @param field The field to get the sort order for.
|
* @param field The field to get the sort order for.
|
||||||
* @returns The sort order for the given field, or undefined if the field is not being sorted.
|
* @returns The sort order for the given field, or undefined if the field is not being sorted.
|
||||||
*/
|
*/
|
||||||
export function getSortOrderForField<Obj, Field extends keyof Obj>(sorters: TypedCrudSort<Obj>[], field: Field): SortOrder | undefined {
|
export function getSortOrderForField<Obj, Field extends keyof Obj>(
|
||||||
const sorter = sorters.find((s) => s.field === field);
|
sorters: TypedCrudSort<Obj>[],
|
||||||
if (sorter) {
|
field: Field
|
||||||
return sorter.order === "asc" ? "ascend" : "descend";
|
): SortOrder | undefined {
|
||||||
}
|
const sorter = sorters.find((s) => s.field === field);
|
||||||
return undefined;
|
if (sorter) {
|
||||||
|
return sorter.order === "asc" ? "ascend" : "descend";
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function typeSorters<Obj>(sorters: CrudSort[]): TypedCrudSort<Obj>[] {
|
export function typeSorters<Obj>(sorters: CrudSort[]): TypedCrudSort<Obj>[] {
|
||||||
return sorters as TypedCrudSort<Obj>[]; // <-- Unsafe cast
|
return sorters as TypedCrudSort<Obj>[]; // <-- Unsafe cast
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
|
|
||||||
function _isLocalStorageAvailable(): boolean {
|
function _isLocalStorageAvailable(): boolean {
|
||||||
try {
|
try {
|
||||||
localStorage.setItem('test', 'test');
|
localStorage.setItem("test", "test");
|
||||||
localStorage.removeItem('test');
|
localStorage.removeItem("test");
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isLocalStorageAvailable = _isLocalStorageAvailable();
|
export const isLocalStorageAvailable = _isLocalStorageAvailable();
|
||||||
|
|||||||
Reference in New Issue
Block a user