init equipment & change-status

This commit is contained in:
MaKarin
2026-04-03 21:45:13 -07:00
parent c89c23fd1d
commit cec42f08d0
87 changed files with 19086 additions and 86 deletions

167
client/src/dataProvider.ts Normal file
View File

@@ -0,0 +1,167 @@
import type { DataProvider, DeleteManyParams, RaRecord } from 'react-admin';
import { env } from './config/env';
import { ensureFreshToken, getAccessToken } from './auth/keycloak';
type HttpResult<T> = {
data: T;
headers: Headers;
};
async function withAuthHeaders(headers = new Headers()) {
await ensureFreshToken();
const token = getAccessToken();
if (token) {
headers.set('Authorization', `Bearer ${token}`);
}
headers.set('Accept', 'application/json');
headers.set('Content-Type', 'application/json');
return headers;
}
function appendFilterParams(searchParams: URLSearchParams, filter?: Record<string, unknown>) {
if (!filter) {
return;
}
for (const [key, value] of Object.entries(filter)) {
if (value === undefined || value === null || value === '') {
continue;
}
if (Array.isArray(value)) {
value.forEach((entry) => {
if (entry !== undefined && entry !== null && entry !== '') {
searchParams.append(key, String(entry));
}
});
continue;
}
searchParams.append(key, String(value));
}
}
async function http<T>(url: string, init?: RequestInit): Promise<HttpResult<T>> {
const headers = await withAuthHeaders(new Headers(init?.headers));
const response = await fetch(url, {
...init,
headers,
});
if (!response.ok) {
const error = new Error(`Request failed with status ${response.status}`) as Error & { status: number };
error.status = response.status;
throw error;
}
const text = await response.text();
return {
data: text ? (JSON.parse(text) as T) : (null as T),
headers: response.headers,
};
}
function parseTotal(headers: Headers, fallback: number) {
const contentRange = headers.get('Content-Range');
if (!contentRange) {
return fallback;
}
const match = contentRange.match(/\/(\d+)$/);
return match ? Number(match[1]) : fallback;
}
export const dataProvider: DataProvider = {
async getList(resource, params) {
const searchParams = new URLSearchParams({
_start: String(params.pagination.page <= 1 ? 0 : (params.pagination.page - 1) * params.pagination.perPage),
_end: String(params.pagination.page * params.pagination.perPage),
_sort: params.sort.field,
_order: params.sort.order,
});
appendFilterParams(searchParams, params.filter);
const { data, headers } = await http<RaRecord[]>(`${env.apiUrl}/${resource}?${searchParams.toString()}`);
return {
data,
total: parseTotal(headers, data.length),
};
},
async getOne(resource, params) {
const { data } = await http<RaRecord>(`${env.apiUrl}/${resource}/${params.id}`);
return { data };
},
async getMany(resource, params) {
const results = await Promise.all(params.ids.map((id) => http<RaRecord>(`${env.apiUrl}/${resource}/${id}`)));
return { data: results.map((result) => result.data) };
},
async getManyReference(resource, params) {
const searchParams = new URLSearchParams({
_start: String(params.pagination.page <= 1 ? 0 : (params.pagination.page - 1) * params.pagination.perPage),
_end: String(params.pagination.page * params.pagination.perPage),
_sort: params.sort.field,
_order: params.sort.order,
[params.target]: String(params.id),
});
appendFilterParams(searchParams, params.filter);
const { data, headers } = await http<RaRecord[]>(`${env.apiUrl}/${resource}?${searchParams.toString()}`);
return {
data,
total: parseTotal(headers, data.length),
};
},
async create(resource, params) {
const { data } = await http<RaRecord>(`${env.apiUrl}/${resource}`, {
method: 'POST',
body: JSON.stringify(params.data),
});
return { data };
},
async update(resource, params) {
const { data } = await http<RaRecord>(`${env.apiUrl}/${resource}/${params.id}`, {
method: 'PATCH',
body: JSON.stringify(params.data),
});
return { data };
},
async updateMany(resource, params) {
const results = await Promise.all(
params.ids.map((id) =>
http<RaRecord>(`${env.apiUrl}/${resource}/${id}`, {
method: 'PATCH',
body: JSON.stringify(params.data),
}),
),
);
return { data: results.map((result) => result.data.id) };
},
async delete(resource, params) {
const { data } = await http<RaRecord>(`${env.apiUrl}/${resource}/${params.id}`, {
method: 'DELETE',
});
return { data };
},
async deleteMany(resource, params: DeleteManyParams<any>) {
const results = await Promise.all(
params.ids.map((id) =>
http<RaRecord>(`${env.apiUrl}/${resource}/${id}`, {
method: 'DELETE',
}),
),
);
return { data: results.map((result) => result.data.id) };
},
};