Merge branch 'table_column_resize' into staging_environment
This commit is contained in:
commit
2b904a9f93
6 changed files with 180 additions and 56 deletions
14
indexV2.html
Normal file
14
indexV2.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/x-icon" id="favicon-link" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title id="title-id">Adaptive Dashboard</title>
|
||||
<link rel="manifest" id="manifest-link" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/app/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
26
nginx.conf
26
nginx.conf
|
|
@ -52,18 +52,34 @@ http {
|
|||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr error;
|
||||
root /usr/share/nginx/html;
|
||||
index indexV2.html;
|
||||
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr error;
|
||||
|
||||
expires $cache_expires;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
try_files $uri /index.html;
|
||||
# Redirect old /index.html requests to new file
|
||||
location = /index.html {
|
||||
return 301 /indexV2.html;
|
||||
}
|
||||
|
||||
# Serve indexV2.html directly without redirect loop
|
||||
location = /indexV2.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
|
||||
# Fallback for SPA routing — all unmatched routes go to indexV2.html
|
||||
location / {
|
||||
try_files $uri /indexV2.html;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Healthcheck
|
||||
server {
|
||||
listen 8080;
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ export default function CableEstimator() {
|
|||
},
|
||||
{
|
||||
title: "Peak Height" + (getDistanceUnit() === pond.DistanceUnit.DISTANCE_UNIT_FEET ? "(ft)" : "(m)"),
|
||||
sortKey: "PeakHeight",
|
||||
sortKey: "Peak",
|
||||
render: (row: jsonBin) => <Box padding={2}>{distanceConversion(row.Peak).toFixed(2)}</Box>
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Box, Button, Card, Checkbox, CircularProgress, Collapse, darken, Divider, Grid2, IconButton, InputAdornment, ListItemButton, ListItemIcon, ListItemText, Menu, MenuItem, Paper, SxProps, Table, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow, TextField, Theme, Typography } from "@mui/material";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import { ArrowDownward, ArrowUpward, ChevronRight, Close, Search, ViewColumn } from "@mui/icons-material"
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import React from "react";
|
||||
import { useMobile } from "hooks";
|
||||
import classNames from "classnames";
|
||||
|
|
@ -99,7 +99,8 @@ interface Props<T> {
|
|||
order?: string;
|
||||
setOrder?: React.Dispatch<React.SetStateAction<"asc" | "desc">>;
|
||||
endTitleElement?: string | JSX.Element | (() => string | JSX.Element);
|
||||
loadMore?: () => void
|
||||
loadMore?: () => void;
|
||||
resizeable?: boolean;
|
||||
}
|
||||
|
||||
export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
||||
|
|
@ -133,14 +134,15 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
setOrderBy,
|
||||
order,
|
||||
setOrder,
|
||||
loadMore
|
||||
loadMore,
|
||||
// resizeable,
|
||||
} = props
|
||||
const classes = useStyles();
|
||||
const columns = typeof(props.columns) === "function" ? props.columns() : props.columns
|
||||
const subtitle = typeof(props.subtitle) === "function" ? props.subtitle() : props.subtitle
|
||||
const title = typeof(props.title) === "function" ? props.title() : props.title
|
||||
// const order = props.order ? props.order : "asc"
|
||||
const endTitleElement = typeof(props.endTitleElement) === "function" ? props.endTitleElement() : props.endTitleElement
|
||||
const resizeable = props.resizeable === undefined ? false : props.resizeable
|
||||
|
||||
const isMobile = useMobile()
|
||||
|
||||
|
|
@ -148,6 +150,19 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
const [openGutters, setOpenGutters] = useState<number[]>([])
|
||||
const [handler, setHandler] = useState<NodeJS.Timeout | undefined>(undefined);
|
||||
const [columnAnchor, setColumnAnchor] = useState<any>(null)
|
||||
|
||||
const rowKey = window.location.pathname.split('/').pop() + "-table-row-widths";
|
||||
const [rowWidths, setRowWidths] = useState<number[]>(() => {
|
||||
const saved = localStorage.getItem(rowKey);
|
||||
return saved ? JSON.parse(saved) : [];
|
||||
})
|
||||
useEffect(() => {
|
||||
localStorage.setItem(rowKey, JSON.stringify(rowWidths));
|
||||
}, [rowWidths])
|
||||
|
||||
const dragIndexRef = useRef<number | undefined>(undefined);
|
||||
const dragStartRef = useRef<number | undefined>(undefined);
|
||||
const rowWidthsRef = useRef<number[]>([]);
|
||||
|
||||
const filterKey = window.location.pathname.split('/').pop() + "-table-filter-list";
|
||||
|
||||
|
|
@ -274,9 +289,7 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
}
|
||||
|
||||
const renderMobileRow = (row: T, index: number) => {
|
||||
if (renderMobile) return (
|
||||
renderMobile(row, index)
|
||||
)
|
||||
if (renderMobile) return renderMobile(row, index)
|
||||
if (columns) {
|
||||
return (
|
||||
<Grid2 container direction={"row"} spacing={1} >
|
||||
|
|
@ -299,8 +312,7 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
}
|
||||
return (
|
||||
Object.keys(row).map((key, index) => {
|
||||
let value = row[key as keyof typeof row]
|
||||
|
||||
const value = row[key as keyof typeof row]
|
||||
return (
|
||||
<Grid2 container direction={"row"} key={"mobile-list-"+index} spacing={1} padding={1}>
|
||||
<Grid2 size={{ xs: 4 }} alignContent={"center"} >
|
||||
|
|
@ -346,7 +358,6 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
padding: gutterPadding
|
||||
}}
|
||||
onClick={(event) => handleCollapse(index, event)}
|
||||
// style={{pre}}
|
||||
>
|
||||
<IconButton
|
||||
sx={{
|
||||
|
|
@ -401,7 +412,6 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
|
||||
const columnClick = (column: Column<T>) => {
|
||||
const sortKey = column.sortKey ? column.sortKey : column.title.toLowerCase()
|
||||
// console.log(column.sortKey)
|
||||
if (setOrderBy) {
|
||||
if (orderBy === sortKey && setOrder && order) {
|
||||
if (order === "desc") {
|
||||
|
|
@ -409,13 +419,11 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
} else {
|
||||
setOrderBy("")
|
||||
}
|
||||
// setOrder(order === "asc" ? "desc" : "asc")
|
||||
} else {
|
||||
if (setOrder) setOrder("desc")
|
||||
setOrderBy(sortKey)
|
||||
}
|
||||
}
|
||||
// if (setOrder && order) setOrder(order === "asc" ? "desc" : "asc")
|
||||
}
|
||||
|
||||
const showOrderIcon = (column: Column<T>) => {
|
||||
|
|
@ -423,14 +431,60 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
const sortKey = column.sortKey ? column.sortKey : column.title.toLowerCase()
|
||||
if (sortKey === orderBy) {
|
||||
if (order === "asc") {
|
||||
return <ArrowDownward fontSize="small"/>
|
||||
return <ArrowDownward fontSize="small" sx={{ marginLeft: 1 }} />
|
||||
} else {
|
||||
return <ArrowUpward fontSize="small"/>
|
||||
return <ArrowUpward fontSize="small" sx={{ marginLeft: 1 }} />
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const resizeClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>, index: number) => {
|
||||
|
||||
let newWidths: number[] = []
|
||||
event.currentTarget.parentElement?.parentElement?.parentElement?.childNodes.forEach(node => {
|
||||
if (node instanceof HTMLElement) {
|
||||
newWidths.push(node.clientWidth)
|
||||
}
|
||||
})
|
||||
|
||||
rowWidthsRef.current = newWidths
|
||||
dragIndexRef.current = index;
|
||||
dragStartRef.current = event.clientX;
|
||||
|
||||
window.addEventListener('mousemove', resizeDrag);
|
||||
window.addEventListener('mouseup', resizeUnclick);
|
||||
}
|
||||
|
||||
const resizeUnclick = () => {
|
||||
dragIndexRef.current = undefined;
|
||||
dragStartRef.current = undefined;
|
||||
window.removeEventListener('mousemove', resizeDrag);
|
||||
window.removeEventListener('mouseup', resizeUnclick);
|
||||
}
|
||||
|
||||
const resizeDrag = (e: any) => {
|
||||
const index = dragIndexRef.current;
|
||||
const dragStart = dragStartRef.current
|
||||
const rowWidths = rowWidthsRef.current
|
||||
if (index === undefined) return
|
||||
if (rowWidths[index] === undefined) return
|
||||
if (rowWidths[index+1] === undefined) return
|
||||
if (!dragStart) return
|
||||
|
||||
let newWidths: number[] = [...rowWidths]
|
||||
newWidths[index] = newWidths[index] - (dragStart - e.clientX)
|
||||
newWidths.every((width, j) => {
|
||||
if (j <= index || width === 0) return true
|
||||
else if (newWidths[j] !== undefined) {
|
||||
newWidths[j] = newWidths[j] + (dragStart - e.clientX)
|
||||
return false
|
||||
}
|
||||
})
|
||||
setRowWidths(newWidths)
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<TableContainer className={classes.tableContainer} component={Paper}>
|
||||
<Table>
|
||||
|
|
@ -483,15 +537,28 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
{ renderGutter && <TableCell></TableCell>}
|
||||
{ columns ?
|
||||
columns.map((column, index) => {
|
||||
if (filterList.includes(column.title) || column.hidden) return null
|
||||
if (filterList.includes(column.title) || column.hidden) return (
|
||||
<TableCell key={"row-"+index+"cell-"+index} sx={{ width: 0, margin: 0, padding: 0}} ></TableCell>
|
||||
)
|
||||
return (
|
||||
<TableCell
|
||||
key={"header-cell-"+index}
|
||||
onClick={() => !column.disableSort && columnClick(column)}
|
||||
sx={{ cursor: column.disableSort ? "default" : "pointer" }}
|
||||
>
|
||||
<Grid2 container spacing={1} alignItems={"center"}>
|
||||
{column.title} {showOrderIcon(column)}
|
||||
<TableCell key={"header-cell-"+index} width={rowWidths[index] ? rowWidths[index] : undefined}>
|
||||
<Grid2 container spacing={1} justifyContent={"space-between"}>
|
||||
<Grid2
|
||||
alignItems="center"
|
||||
display="flex"
|
||||
onClick={() => !column.disableSort && columnClick(column)}
|
||||
sx={{ cursor: column.disableSort ? "default" : "pointer" }}
|
||||
>
|
||||
{column.title} {showOrderIcon(column)}
|
||||
</Grid2>
|
||||
{index < columns.length-1 && resizeable &&
|
||||
<Grid2
|
||||
sx={{ cursor: "col-resize", userSelect: "none" }}
|
||||
onMouseDown={event => resizeClick(event, index)}
|
||||
>
|
||||
|
|
||||
</Grid2>
|
||||
}
|
||||
</Grid2>
|
||||
</TableCell>
|
||||
)
|
||||
|
|
@ -547,15 +614,17 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
}
|
||||
{columns ?
|
||||
columns.map((column, j) => {
|
||||
if (filterList.includes(column.title) || column.hidden) return null
|
||||
if (filterList.includes(column.title) || column.hidden) return (
|
||||
<TableCell key={"row-"+index+"cell-"+j} sx={{ width: 0, padding: 0, margin: 0}}></TableCell>
|
||||
)
|
||||
if (column.render) return (
|
||||
<TableCell key={"row-"+index+"cell-"+j} sx={column.cellStyle ? column.cellStyle : {padding: 0}}>
|
||||
<TableCell key={"row-"+index+"cell-"+j} sx={{padding: 0, paddingRight: 2, width: rowWidths[j] ? rowWidths[j] : undefined}}>
|
||||
{column.render(row)}
|
||||
</TableCell>
|
||||
)
|
||||
return (
|
||||
<TableCell key={"row-"+index+"cell-"+j}>
|
||||
{Object.values(row)[j].toString()}
|
||||
{Object.values(row)[j] && Object.values(row)[j].toString()}
|
||||
</TableCell>
|
||||
)
|
||||
})
|
||||
|
|
@ -615,9 +684,8 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
<MenuItem
|
||||
onClick={() => filter(column.title)}
|
||||
key={"column-list-"+index}
|
||||
aria-label="Open User Settings"
|
||||
dense
|
||||
sx={{ marginLeft: -0.75 }}
|
||||
sx={{ marginLeft: -0.75, paddingRight: 3 }}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<Checkbox
|
||||
|
|
@ -628,6 +696,11 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
</MenuItem>
|
||||
)
|
||||
})}
|
||||
<MenuItem onClick={() => setRowWidths([])}>
|
||||
<Typography variant="body2" padding={1}>
|
||||
Reset Widths
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</TableContainer>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import StatusSen5x from "common/StatusSen5x";
|
|||
import StatusDust from "common/StatusDust";
|
||||
import StatusGas from "common/StatusGas";
|
||||
import { cloneDeep } from "lodash";
|
||||
import LoadingScreen from "app/LoadingScreen";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => {
|
||||
return ({
|
||||
|
|
@ -56,6 +57,11 @@ const useStyles = makeStyles((theme: Theme) => {
|
|||
width: theme.spacing(10)
|
||||
// justifyContent: "center",
|
||||
},
|
||||
deviceContainer: {
|
||||
margin: theme.spacing(1),
|
||||
display: "flex",
|
||||
width: theme.spacing(10)
|
||||
},
|
||||
descriptionCellContainer: {
|
||||
margin: theme.spacing(1),
|
||||
marginLeft: theme.spacing(2),
|
||||
|
|
@ -67,7 +73,7 @@ const useStyles = makeStyles((theme: Theme) => {
|
|||
margin: theme.spacing(1),
|
||||
marginLeft: theme.spacing(2),
|
||||
display: "flex",
|
||||
width: theme.spacing(18)
|
||||
minWidth: theme.spacing(10)
|
||||
// justifyContent: "center",
|
||||
},
|
||||
green: {
|
||||
|
|
@ -140,9 +146,15 @@ export default function Devices() {
|
|||
// const [totalGroups, setTotalGroups] = useState(0);
|
||||
|
||||
const [groupPermissions, setGroupPermissions] = useState<pond.Permission[]>([])
|
||||
const [groupsLoaded, setGroupsLoaded] = useState(false)
|
||||
|
||||
const groupID = useParams<{ groupID: string }>()?.groupID ?? "all";
|
||||
const [tab, setTab] = useState(groupID==="all" ? groupID : groupID);
|
||||
// const [tab, setTab] = useState(groupID==="all" ? groupID : groupID);
|
||||
const [tab, setTab] = useState(() => {
|
||||
if (groupID!=="all") return groupID
|
||||
const stored = sessionStorage.getItem(location.pathname+"-groups-tab");
|
||||
return stored !== null ? stored : "all";
|
||||
});
|
||||
|
||||
const [selectedGroup, setSelectedGroup] = useState<Group | undefined>(undefined);
|
||||
const [groupSettingsMode, setGroupSettingsMode] = useState<
|
||||
|
|
@ -184,7 +196,7 @@ export default function Devices() {
|
|||
|
||||
useEffect(() => {
|
||||
setGroupPermissions([])
|
||||
if (tab === "all") return
|
||||
if (tab === "all" || !getGroup()) return
|
||||
groupAPI.getGroupPermissions(getGroup().id()).then(resp => {
|
||||
setGroupPermissions(resp.data.permissions)
|
||||
})
|
||||
|
|
@ -232,7 +244,7 @@ export default function Devices() {
|
|||
};
|
||||
|
||||
const getKeys = () => {
|
||||
if (tab !== "all") {
|
||||
if (tab !== "all" && getGroup()) {
|
||||
let keys = getContextKeys()
|
||||
//keys.splice(keys.length - 1, 0, getGroup().id().toString());
|
||||
keys.push(getGroup().id().toString());
|
||||
|
|
@ -274,11 +286,13 @@ export default function Devices() {
|
|||
updateGroups(newGroups)
|
||||
}).finally(() => {
|
||||
setGroupsLoading(false)
|
||||
setGroupsLoaded(true)
|
||||
})
|
||||
}
|
||||
|
||||
const loadDevices = () => {
|
||||
setDevicesLoading(true)
|
||||
if (!groupsLoaded) return
|
||||
deviceAPI.list(
|
||||
limit,
|
||||
page*limit,
|
||||
|
|
@ -316,7 +330,7 @@ export default function Devices() {
|
|||
|
||||
useEffect(() => {
|
||||
loadDevices()
|
||||
}, [limit, page, order, orderBy, fieldContains, search, tab, as])
|
||||
}, [limit, page, order, orderBy, fieldContains, search, tab, as, groupsLoaded])
|
||||
|
||||
useEffect(() => {
|
||||
loadGroups()
|
||||
|
|
@ -352,10 +366,6 @@ export default function Devices() {
|
|||
return '/' + newSegments.join('/');
|
||||
}
|
||||
|
||||
// useEffect(() => {
|
||||
// console.log(devices)
|
||||
// }, [devices])
|
||||
|
||||
const toDevice = (device: Device) => {
|
||||
let url = getGroup() ? insertGroupContext(getGroup().id().toString(), device.id().toString()) : ""
|
||||
if (url.length < 1) url = device.id().toString()
|
||||
|
|
@ -371,12 +381,14 @@ export default function Devices() {
|
|||
let columns: Column<Device>[] = [
|
||||
{
|
||||
title: "State",
|
||||
// cellStyle: {width: 100000},
|
||||
// sortKey: "state",
|
||||
render: (device: Device) => {
|
||||
const status = device.status ?? pond.DeviceStatus.create()
|
||||
const deviceStateHelper = getDeviceStateHelper(status.state);
|
||||
return (
|
||||
<Box className={classes.cellContainer} style={{ width: theme.spacing(0.5)}}>
|
||||
{/* <Box > */}
|
||||
<Tooltip title={deviceStateHelper.description}>{deviceStateHelper.icon}</Tooltip>
|
||||
</Box>
|
||||
)
|
||||
|
|
@ -391,10 +403,12 @@ export default function Devices() {
|
|||
},
|
||||
{
|
||||
title: "Device",
|
||||
cellStyle: { width: 160 },
|
||||
sortKey: "name",
|
||||
render: (device: Device) => {
|
||||
return (
|
||||
<Box className={classes.cellContainer}>
|
||||
<Box className={classes.deviceContainer}>
|
||||
{/* // <Box > */}
|
||||
<Chip
|
||||
variant="outlined"
|
||||
label={device.settings?.name ? device.settings.name : "Device " + device.settings?.deviceId}
|
||||
|
|
@ -406,11 +420,12 @@ export default function Devices() {
|
|||
},
|
||||
{
|
||||
title: "Description",
|
||||
cellStyle: { width: 400 },
|
||||
render: (device: Device) => {
|
||||
const description = device.settings?.description ?? ""
|
||||
let size = (hasCo2 && !groupGas) ? 26 : 36
|
||||
return (
|
||||
<Box className={classes.descriptionCellContainer} width={size*6}>
|
||||
<Box className={classes.descriptionCellContainer} >
|
||||
<Tooltip title={description}>
|
||||
<span>
|
||||
{description.length > size
|
||||
|
|
@ -680,9 +695,7 @@ export default function Devices() {
|
|||
dense
|
||||
>
|
||||
<ListItemIcon>
|
||||
<Checkbox
|
||||
checked={!separateDust}
|
||||
/>
|
||||
<Checkbox checked={!separateDust} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={"Group Dust"} />
|
||||
</MenuItem>
|
||||
|
|
@ -692,10 +705,7 @@ export default function Devices() {
|
|||
dense
|
||||
>
|
||||
<ListItemIcon>
|
||||
<Checkbox
|
||||
checked={groupGas}
|
||||
|
||||
/>
|
||||
<Checkbox checked={groupGas} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={"Group Gas"} />
|
||||
</MenuItem>
|
||||
|
|
@ -703,6 +713,10 @@ export default function Devices() {
|
|||
)
|
||||
}
|
||||
|
||||
if (!groupsLoaded) return (
|
||||
<LoadingScreen message="Loading groups" />
|
||||
)
|
||||
|
||||
return(
|
||||
<PageContainer padding={isMobile ? 0 : 2}>
|
||||
<Box
|
||||
|
|
@ -725,7 +739,7 @@ export default function Devices() {
|
|||
<Tab value={"loading"} label={<Skeleton variant="rectangular" height={24} width={128} animation="pulse" />}/>
|
||||
: groups.map((group, index) => {
|
||||
if (group.id()) return (
|
||||
<Tab className={classes.tab} wrapped value={index} label={<Typography variant="inherit" noWrap>{group.name()}</Typography>} key={"group-tab-"+index}/>
|
||||
<Tab className={classes.tab} wrapped value={index.toString()} label={<Typography variant="inherit" noWrap>{group.name()}</Typography>} key={"group-tab-"+index}/>
|
||||
)
|
||||
})}
|
||||
<Tab wrapped value={"never"} label={<CreateGroupIcon className={classes.green} />} onClick={() => openGroupSettings(undefined, "add")} />
|
||||
|
|
@ -753,6 +767,7 @@ export default function Devices() {
|
|||
orderBy={orderBy}
|
||||
setOrderBy={setOrderBy}
|
||||
endTitleElement={preferencesButton}
|
||||
resizeable
|
||||
loadMore={()=>{
|
||||
let currentRows = cloneDeep(devices)
|
||||
deviceAPI.list(
|
||||
|
|
@ -784,7 +799,7 @@ export default function Devices() {
|
|||
newDevices.push(Device.create(device))
|
||||
})
|
||||
setDevices(currentRows.concat(newDevices))
|
||||
}).catch(err => {
|
||||
}).catch(_err => {
|
||||
|
||||
})
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { defineConfig } from 'vite'
|
|||
import react from '@vitejs/plugin-react'
|
||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||
import { VitePWA } from 'vite-plugin-pwa';
|
||||
import * as path from 'path' // ✅ Import path module
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
|
|
@ -14,7 +15,7 @@ export default defineConfig({
|
|||
globPatterns: ['**/*.{js,css,html,png,jpg,svg}'], // Cache all common asset types
|
||||
maximumFileSizeToCacheInBytes: 20 * 1024 * 1024, // 20 MiB
|
||||
cleanupOutdatedCaches: true,
|
||||
navigateFallback: "/index.html",
|
||||
navigateFallback: "/indexV2.html",
|
||||
runtimeCaching: [
|
||||
{
|
||||
urlPattern: ({ request }) => request.destination === 'document',
|
||||
|
|
@ -39,7 +40,12 @@ export default defineConfig({
|
|||
outDir: './build',
|
||||
sourcemap: true,
|
||||
minify: false,
|
||||
target: 'esnext'
|
||||
target: 'esnext',
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: path.resolve(__dirname, 'indexV2.html')
|
||||
}
|
||||
}
|
||||
},
|
||||
esbuild: {
|
||||
keepNames: true, // Prevent function name mangling
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue