Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1797af7ba9 | ||
|
|
25c9bc21b3 |
Vendored
+6671
-7002
File diff suppressed because it is too large
Load Diff
Generated
+32
-39
@@ -25,8 +25,8 @@
|
||||
"@mui/lab": "7.0.0-beta.14",
|
||||
"@mui/material": "^7.3.5",
|
||||
"@mui/system": "7.2.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ant-design/colors": {
|
||||
@@ -131,6 +131,13 @@
|
||||
"url": "https://opencollective.com/babel"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/core/node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
|
||||
@@ -378,13 +385,6 @@
|
||||
"stylis": "4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
||||
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@emotion/cache": {
|
||||
"version": "11.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",
|
||||
@@ -2140,9 +2140,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.10.30",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.30.tgz",
|
||||
"integrity": "sha512-xjOFN16Ha1+Rz4nFYKqHU/LSB+gx/Vi3yQLX7r7sAW+Wa+8hhF2h4pvqTrTMc8+WcDBEunnUurr46Jvv0jk3Vg==",
|
||||
"version": "2.10.31",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.31.tgz",
|
||||
"integrity": "sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
@@ -2260,11 +2260,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
||||
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/cosmiconfig": {
|
||||
"version": "7.1.0",
|
||||
@@ -2342,9 +2342,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.357",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.357.tgz",
|
||||
"integrity": "sha512-NHlTIQDK8fmVwHwuIzmXYEJ1Ewq3D9wDNc0cWXxDGysP6Pb21giwGNkxiTifyKy/4SoPuN5l6GLP1W9Sv7zB2g==",
|
||||
"version": "1.5.359",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.359.tgz",
|
||||
"integrity": "sha512-8lPELWuYZIWk7NDvCNthtmMw/7Q5Wu25NpM4djFMHBmk8DubPAtL4YTOp7ou0e7HyJtwkVlWv8XMLURnrtgJQw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -2960,30 +2960,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
||||
"version": "19.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
|
||||
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||
"version": "19.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
|
||||
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"scheduler": "^0.23.2"
|
||||
"scheduler": "^0.26.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.3.1"
|
||||
"react": "^19.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
@@ -3098,14 +3094,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.23.2",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
||||
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
|
||||
"version": "0.26.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
|
||||
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
|
||||
+2
-2
@@ -18,8 +18,8 @@
|
||||
"@emotion/cache": "11.14.0",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"@mui/base": "5.0.0-beta.70",
|
||||
"@mui/icons-material": "^7.3.5",
|
||||
"@mui/lab": "7.0.0-beta.14",
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import ListVirtual from "./components/ListVirtual";
|
||||
import { ApiProvider } from "./components/ApiContext";
|
||||
import { API_TOKEN } from "./config/constants";
|
||||
|
||||
const Testing = () => {
|
||||
const token = API_TOKEN;
|
||||
return (
|
||||
<div style={{ padding: 8, marginTop: 12 }}>
|
||||
<ApiProvider
|
||||
headers={{
|
||||
Authorization: `Bearer ${token}`,
|
||||
}}
|
||||
>
|
||||
<ListVirtual
|
||||
id="company-select"
|
||||
label="Company"
|
||||
name="name"
|
||||
url="/company"
|
||||
defaultValue={"442"}
|
||||
size="small"
|
||||
/>
|
||||
</ApiProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Testing;
|
||||
+54
-36
@@ -1,3 +1,5 @@
|
||||
// src/api/request.js
|
||||
|
||||
import { formatApiResponse } from '../utils/response';
|
||||
import { oslogApi, apiGo } from './axiosClient';
|
||||
|
||||
@@ -10,31 +12,26 @@ const request = async ({
|
||||
endpoint = '',
|
||||
suffix = '',
|
||||
data = null,
|
||||
params = {},
|
||||
headers = {},
|
||||
customUrl = '',
|
||||
axiosConfig = {},
|
||||
axiosConfig = {}
|
||||
}) => {
|
||||
const url = customUrl || `${endpoint}${suffix}`;
|
||||
|
||||
try {
|
||||
const client = isApiGo ? apiGo : oslogApi;
|
||||
|
||||
const response = await client({
|
||||
method,
|
||||
url,
|
||||
data,
|
||||
params,
|
||||
headers,
|
||||
...axiosConfig,
|
||||
|
||||
// highest priority
|
||||
...axiosConfig
|
||||
});
|
||||
|
||||
return formatApiResponse(response);
|
||||
} catch (error) {
|
||||
const responseError = formatApiResponse(error);
|
||||
|
||||
//logError(`at endpoint: ${url} error: `, responseError);
|
||||
|
||||
return responseError;
|
||||
return formatApiResponse(error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,65 +39,86 @@ const request = async ({
|
||||
* CREATE NEW
|
||||
* POST /endpoint/new
|
||||
*/
|
||||
export const newRequest = (endpoint, data = null, config = {}) =>
|
||||
export const newRequest = (
|
||||
endpoint,
|
||||
data = null,
|
||||
axiosConfig = {}
|
||||
) =>
|
||||
request({
|
||||
method: 'post',
|
||||
endpoint,
|
||||
suffix: '/new',
|
||||
data,
|
||||
...config,
|
||||
axiosConfig
|
||||
});
|
||||
|
||||
/**
|
||||
* ADD
|
||||
* POST /endpoint/add
|
||||
*/
|
||||
export const addRequest = (endpoint, data = null, config = {}) =>
|
||||
export const addRequest = (
|
||||
endpoint,
|
||||
data = null,
|
||||
axiosConfig = {}
|
||||
) =>
|
||||
request({
|
||||
method: 'post',
|
||||
endpoint,
|
||||
suffix: '/add',
|
||||
data,
|
||||
...config,
|
||||
axiosConfig
|
||||
});
|
||||
|
||||
/**
|
||||
* GET BY ID
|
||||
* GET /endpoint/:id
|
||||
*/
|
||||
export const getByIdRequest = (id, endpoint, params = {}, config = {}) =>
|
||||
export const getByIdRequest = (
|
||||
id,
|
||||
endpoint,
|
||||
axiosConfig = {}
|
||||
) =>
|
||||
request({
|
||||
method: 'get',
|
||||
endpoint,
|
||||
suffix: `/${id}`,
|
||||
params,
|
||||
...config,
|
||||
axiosConfig
|
||||
});
|
||||
|
||||
/**
|
||||
* EDIT
|
||||
* PUT /endpoint/edit/:id
|
||||
*/
|
||||
export const editRequest = (id, endpoint, data = null, config = {}) =>
|
||||
export const editRequest = (
|
||||
id,
|
||||
endpoint,
|
||||
data = null,
|
||||
axiosConfig = {}
|
||||
) =>
|
||||
request({
|
||||
method: 'put',
|
||||
endpoint,
|
||||
suffix: `/edit/${id}`,
|
||||
data,
|
||||
...config,
|
||||
axiosConfig
|
||||
});
|
||||
|
||||
/**
|
||||
* DELETE
|
||||
* DELETE /endpoint/delete/:id
|
||||
*/
|
||||
export const deleteRequest = (id, endpoint, data = null, config = {}) =>
|
||||
export const deleteRequest = (
|
||||
id,
|
||||
endpoint,
|
||||
data = null,
|
||||
axiosConfig = {}
|
||||
) =>
|
||||
request({
|
||||
method: 'delete',
|
||||
endpoint,
|
||||
suffix: `/delete/${id}`,
|
||||
data,
|
||||
...config,
|
||||
axiosConfig
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -110,8 +128,7 @@ export const deleteRequest = (id, endpoint, data = null, config = {}) =>
|
||||
export const searchRequest = (
|
||||
endpoint,
|
||||
data = null,
|
||||
params = {},
|
||||
config = {},
|
||||
axiosConfig = {}
|
||||
) => {
|
||||
const timezone = -new Date().getTimezoneOffset() / 60;
|
||||
|
||||
@@ -120,37 +137,38 @@ export const searchRequest = (
|
||||
endpoint,
|
||||
suffix: '/search',
|
||||
data,
|
||||
|
||||
axiosConfig: {
|
||||
...axiosConfig,
|
||||
|
||||
params: {
|
||||
tz: timezone,
|
||||
...params,
|
||||
},
|
||||
...config,
|
||||
...(axiosConfig.params || {})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* CUSTOM REQUEST
|
||||
* untuk endpoint bebas / beda sendiri
|
||||
*/
|
||||
export const customRequest = ({
|
||||
method = 'get',
|
||||
url = '',
|
||||
data = null,
|
||||
params = {},
|
||||
headers = {},
|
||||
axiosConfig = {},
|
||||
isApiGo = false,
|
||||
axiosConfig = {}
|
||||
}) =>
|
||||
request({
|
||||
method,
|
||||
customUrl: url,
|
||||
data,
|
||||
params,
|
||||
headers,
|
||||
axiosConfig,
|
||||
isApiGo,
|
||||
axiosConfig
|
||||
});
|
||||
|
||||
/**
|
||||
* Optional Export Object
|
||||
* EXPORT OBJECT
|
||||
*/
|
||||
export const apiRequest = {
|
||||
new: newRequest,
|
||||
@@ -159,5 +177,5 @@ export const apiRequest = {
|
||||
edit: editRequest,
|
||||
delete: deleteRequest,
|
||||
search: searchRequest,
|
||||
custom: customRequest,
|
||||
custom: customRequest
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
import React, { createContext, useContext } from "react";
|
||||
|
||||
// Sentinel value to reliably detect if the hook is called outside the provider
|
||||
const sentinel = {};
|
||||
|
||||
/**
|
||||
* ApiContext created using the React Context API.
|
||||
* Defaults to a sentinel value to detect out-of-provider usage.
|
||||
*/
|
||||
export const ApiContext = createContext(sentinel);
|
||||
|
||||
/**
|
||||
* ApiProvider component that accepts a `headers` prop and provides it through context.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {Object} props.headers - The headers to provide to API requests
|
||||
* @param {React.ReactNode} props.children - Child components
|
||||
*/
|
||||
export function ApiProvider({ headers, children }) {
|
||||
return React.createElement(
|
||||
ApiContext.Provider,
|
||||
{ value: headers },
|
||||
children
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom hook `useApiHeaders()` that returns the current headers from context.
|
||||
* Throws a clear error if called outside of `ApiProvider`.
|
||||
*
|
||||
* @returns {Object} The current headers from context
|
||||
*/
|
||||
export function useApiHeaders() {
|
||||
const context = useContext(ApiContext);
|
||||
if (context === sentinel) {
|
||||
throw new Error("useApiHeaders must be used within an ApiProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
import ClearIcon from "@mui/icons-material/Clear";
|
||||
import FilterTableBuilder from "../utils/filterTableBuilder";
|
||||
import { apiRequest } from "../api/request";
|
||||
import { useApiHeaders } from "./ApiContext";
|
||||
|
||||
export default function ListVirtual({
|
||||
id,
|
||||
@@ -33,8 +34,8 @@ export default function ListVirtual({
|
||||
helperText,
|
||||
filter,
|
||||
isApiGo = false,
|
||||
headersRequest,
|
||||
}) {
|
||||
const headersRequest = useApiHeaders();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [search, setSearch] = useState("");
|
||||
const [rows, setRows] = useState([]);
|
||||
@@ -72,11 +73,10 @@ export default function ListVirtual({
|
||||
const res = await apiRequest.search(
|
||||
url,
|
||||
payload.build(),
|
||||
{},
|
||||
{
|
||||
isApiGo,
|
||||
headers: headersRequest
|
||||
}
|
||||
},
|
||||
isApiGo,
|
||||
);
|
||||
const incomingData = res.data || [];
|
||||
|
||||
@@ -128,11 +128,10 @@ export default function ListVirtual({
|
||||
const res = await apiRequest.search(
|
||||
url,
|
||||
payload.build(),
|
||||
{},
|
||||
{
|
||||
isApiGo,
|
||||
headers: headersRequest
|
||||
}
|
||||
},
|
||||
isApiGo,
|
||||
);
|
||||
|
||||
const data = res.data?.[0];
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as ListVirtual } from "./ListVirtual";
|
||||
export * from "./ApiContext";
|
||||
+3
-1
@@ -1 +1,3 @@
|
||||
export { default as ListVirtual } from './components/ListVirtual.jsx';
|
||||
export * from './api/request';
|
||||
export * from './components';
|
||||
//export * from './utils';
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// src/main.jsx
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
|
||||
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
||||
import { CssBaseline } from '@mui/material';
|
||||
|
||||
import App from './App'
|
||||
|
||||
const theme = createTheme({
|
||||
palette: {
|
||||
mode: 'light',
|
||||
|
||||
primary: {
|
||||
main: '#2563eb'
|
||||
},
|
||||
|
||||
background: {
|
||||
default: '#f8fafc'
|
||||
}
|
||||
},
|
||||
|
||||
shape: {
|
||||
borderRadius: 12
|
||||
},
|
||||
|
||||
typography: {
|
||||
fontFamily:
|
||||
'"Inter", "Roboto", "Helvetica", "Arial", sans-serif',
|
||||
|
||||
h5: {
|
||||
fontWeight: 700
|
||||
},
|
||||
|
||||
button: {
|
||||
textTransform: 'none',
|
||||
fontWeight: 600
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
MuiPaper: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 16
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
MuiButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 10,
|
||||
paddingInline: 16
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
MuiOutlinedInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<App />
|
||||
</ThemeProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
Reference in New Issue
Block a user