@etsoo/materialui
Version:
TypeScript Material-UI Implementation
199 lines (198 loc) • 9.42 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResponsibleContainer = ResponsibleContainer;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importDefault(require("react"));
const react_2 = require("@etsoo/react");
const DataGridEx_1 = require("./DataGridEx");
const MUGlobal_1 = require("./MUGlobal");
const PullToRefreshUI_1 = require("./PullToRefreshUI");
const ScrollerListEx_1 = require("./ScrollerListEx");
const SearchBar_1 = require("./SearchBar");
const Labels_1 = require("./app/Labels");
const GridUtils_1 = require("./GridUtils");
const useMediaQuery_1 = __importDefault(require("@mui/material/useMediaQuery"));
const Box_1 = __importDefault(require("@mui/material/Box"));
const Stack_1 = __importDefault(require("@mui/material/Stack"));
function defaultContainerBoxSx(paddings, hasField, _dataGrid) {
const half = typeof paddings == "number" ? paddings / 2 : MUGlobal_1.MUGlobal.half(paddings);
return {
"& .SearchBox": {
marginBottom: hasField ? half : 0
}
};
}
/**
* Responsible container
* @param props Props
* @returns Layout
*/
function ResponsibleContainer(props) {
// Destruct
const { adjustHeight, adjustFabHeight, cacheKey, cacheMinutes = 15, columns, containerBoxSx = defaultContainerBoxSx, elementReady, fields, fieldTemplate, height, loadData, mRef, paddings = MUGlobal_1.MUGlobal.pagePaddings, pullToRefresh = true, quickAction, sizeReadyMiliseconds = 0, searchBarHeight = 45.6, searchBarBottom = 8, searchBarTop, ...rest } = props;
// Labels
const labels = Labels_1.Labels.CommonPage;
// Refs
const refs = react_1.default.useRef({});
const state = refs.current;
const mRefs = (0, react_2.useCombinedRefs)(mRef, (ref) => {
if (ref == null)
return;
state.ref = ref;
});
// Screen size detection
const showDataGrid = (0, useMediaQuery_1.default)("(min-width:600px)");
// Update mounted state
react_1.default.useEffect(() => {
return () => {
state.mounted = false;
};
}, []);
// Has fields
const hasFields = fields != null && fields.length > 0;
// Load data
const localLoadData = (props, lastItem) => {
state.mounted = true;
return loadData(GridUtils_1.GridUtils.createLoader(props, fieldTemplate, cacheKey, false), lastItem);
};
// Search data
const searchData = (0, react_2.useSearchParamsWithCache)(cacheKey);
// On submit callback
const onSubmit = (data, _reset) => {
if (data == null || state.ref == null)
return;
state.ref.reset({ data });
};
// Watch container
const { dimensions } = (0, react_2.useDimensions)(1, undefined, sizeReadyMiliseconds, (_preRect, rect) => {
// Check
if (rect == null)
return true;
// Last rect
const lastRect = state.rect;
// 32 = scroll bar width
if (lastRect != null &&
state.mounted !== true &&
Math.abs(rect.width - lastRect.width) <= 32 &&
Math.abs(rect.height - lastRect.height) <= 32)
return true;
// Hold the new rect
state.rect = rect;
return false;
});
const onInitLoad = (ref) => {
// Avoid repeatedly load from cache
if (refs.current.initLoaded || !cacheKey)
return undefined;
// Cache data
const cacheData = GridUtils_1.GridUtils.getCacheData(cacheKey, cacheMinutes);
if (cacheData) {
const { rows, state } = cacheData;
GridUtils_1.GridUtils.mergeSearchData(state, searchData);
// Scroll position
const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
if (scrollData) {
if ("resetAfterColumnIndex" in ref) {
const { scrollLeft, scrollTop } = JSON.parse(scrollData);
globalThis.setTimeout(() => ref.scrollTo({ scrollLeft, scrollTop }), 0);
}
else {
const { scrollOffset } = JSON.parse(scrollData);
globalThis.setTimeout(() => ref.scrollTo(scrollOffset), 0);
}
}
// Update flag value
refs.current.initLoaded = true;
// Return cached rows and state
return [rows, state];
}
return undefined;
};
const onListScroll = (props) => {
if (!cacheKey || !refs.current.initLoaded)
return;
sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
};
const onGridScroll = (props) => {
if (!cacheKey || !refs.current.initLoaded)
return;
sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
};
// Rect
const rect = dimensions[0][2];
// Create list
const list = (() => {
// No layout
if (rect == null)
return undefined;
// Height
let heightLocal;
if (height != null) {
heightLocal = height;
}
else {
// Auto calculation
heightLocal =
document.documentElement.clientHeight - Math.round(rect.bottom + 1);
const style = window.getComputedStyle(dimensions[0][1]);
const boxMargin = parseFloat(style.marginBottom);
if (!isNaN(boxMargin))
heightLocal -= boxMargin;
if (adjustHeight != null)
heightLocal -=
typeof adjustHeight === "number"
? adjustHeight
: adjustHeight(heightLocal, rect);
}
if (adjustFabHeight)
heightLocal = adjustFabHeight(heightLocal, showDataGrid);
if (showDataGrid) {
// Delete
delete rest.itemRenderer;
return ((0, jsx_runtime_1.jsx)(Box_1.default, { className: "DataGridBox", children: (0, jsx_runtime_1.jsx)(DataGridEx_1.DataGridEx, { autoLoad: !hasFields, height: heightLocal, width: rect.width, loadData: localLoadData, mRef: mRefs, onDoubleClick: (_, data) => quickAction && quickAction(data), outerRef: (element) => {
if (element != null && elementReady)
elementReady(element, true);
}, onScroll: onGridScroll, columns: columns, onUpdateRows: GridUtils_1.GridUtils.getUpdateRowsHandler(cacheKey), onInitLoad: onInitLoad, ...rest }) }));
}
// Delete
delete rest.checkable;
delete rest.borderRowsCount;
delete rest.bottomHeight;
delete rest.footerItemRenderer;
delete rest.headerHeight;
delete rest.hideFooter;
delete rest.hoverColor;
delete rest.selectable;
return ((0, jsx_runtime_1.jsx)(Box_1.default, { className: "ListBox", sx: { height: heightLocal }, children: (0, jsx_runtime_1.jsx)(ScrollerListEx_1.ScrollerListEx, { autoLoad: !hasFields, height: heightLocal, loadData: localLoadData, onUpdateRows: GridUtils_1.GridUtils.getUpdateRowsHandler(cacheKey), onInitLoad: onInitLoad, mRef: mRefs, onClick: (event, data) => quickAction && react_2.ReactUtils.isSafeClick(event) && quickAction(data), oRef: (element) => {
if (element != null && elementReady)
elementReady(element, false);
}, onScroll: onListScroll, ...rest }) }));
})();
const searchBar = react_1.default.useMemo(() => {
if (!hasFields ||
showDataGrid == null ||
rect?.width == null ||
rect.width < 20)
return;
const f = typeof fields == "function" ? fields(searchData) : fields;
return ((0, jsx_runtime_1.jsx)(SearchBar_1.SearchBar, { fields: f, onSubmit: onSubmit, className: `searchBar${showDataGrid ? "Grid" : "List"}`, width: rect.width, top: searchBarTop }));
}, [showDataGrid, hasFields, searchBarHeight, rect?.width]);
// Pull container
const pullContainer = showDataGrid == null
? undefined
: showDataGrid
? ".DataGridEx-Body"
: ".ScrollerListEx-Body";
// Layout
return ((0, jsx_runtime_1.jsxs)(Box_1.default, { sx: containerBoxSx == null
? undefined
: containerBoxSx(paddings, hasFields, showDataGrid), children: [(0, jsx_runtime_1.jsxs)(Stack_1.default, { children: [(0, jsx_runtime_1.jsx)(Box_1.default, { ref: dimensions[0][0], className: "SearchBox", sx: {
height: hasFields ? searchBarHeight : 0
}, marginBottom: hasFields ? `${searchBarBottom}px!important` : undefined, children: searchBar }), list] }), pullToRefresh && pullContainer && list != null && ((0, jsx_runtime_1.jsx)(PullToRefreshUI_1.PullToRefreshUI, { mainElement: pullContainer, triggerElement: pullContainer, instructionsPullToRefresh: labels.pullToRefresh, instructionsReleaseToRefresh: labels.releaseToRefresh, instructionsRefreshing: labels.refreshing, onRefresh: () => state.ref?.reset(), shouldPullToRefresh: () => {
const container = document.querySelector(pullContainer);
return !container?.scrollTop;
} }))] }));
}