added route preview with updated dnd
This commit is contained in:
parent
4dd149f2af
commit
029a2de97e
@ -11,6 +11,7 @@
|
|||||||
"@mui/lab": "^6.0.0-beta.14",
|
"@mui/lab": "^6.0.0-beta.14",
|
||||||
"@mui/material": "^6.1.7",
|
"@mui/material": "^6.1.7",
|
||||||
"@mui/x-data-grid": "^7.22.2",
|
"@mui/x-data-grid": "^7.22.2",
|
||||||
|
"@photo-sphere-viewer/core": "^5.13.1",
|
||||||
"@react-three/drei": "^10.0.6",
|
"@react-three/drei": "^10.0.6",
|
||||||
"@react-three/fiber": "^9.1.2",
|
"@react-three/fiber": "^9.1.2",
|
||||||
"@refinedev/cli": "^2.16.21",
|
"@refinedev/cli": "^2.16.21",
|
||||||
@ -31,9 +32,9 @@
|
|||||||
"i18next": "^24.2.2",
|
"i18next": "^24.2.2",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"react": "^18.0.0",
|
"react": "19.0.0",
|
||||||
"react-beautiful-dnd": "^13.1.1",
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
"react-dom": "^18.0.0",
|
"react-dom": "19.0.0",
|
||||||
"react-draggable": "^4.4.6",
|
"react-draggable": "^4.4.6",
|
||||||
"react-dropzone": "^14.3.8",
|
"react-dropzone": "^14.3.8",
|
||||||
"react-hook-form": "^7.30.0",
|
"react-hook-form": "^7.30.0",
|
||||||
|
8589
pnpm-lock.yaml
8589
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -75,9 +75,14 @@ import {
|
|||||||
} from "./components/ui/Icons";
|
} from "./components/ui/Icons";
|
||||||
import SidebarTitle from "./components/ui/SidebarTitle";
|
import SidebarTitle from "./components/ui/SidebarTitle";
|
||||||
import { AdminOnly } from "./components/AdminOnly";
|
import { AdminOnly } from "./components/AdminOnly";
|
||||||
|
import { Dashboard } from "./preview/widgets/dashboard/Dashboard";
|
||||||
|
import { QueryClient } from "@tanstack/react-query";
|
||||||
|
import { QueryClientProvider } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
const queryClient = new QueryClient();
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
|
<QueryClientProvider client={queryClient}>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<ColorModeContextProvider>
|
<ColorModeContextProvider>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
@ -257,6 +262,7 @@ function App() {
|
|||||||
/>
|
/>
|
||||||
<Route path="show/:id" element={<CountryShow />} />
|
<Route path="show/:id" element={<CountryShow />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="dashboard" element={<Dashboard />} />
|
||||||
|
|
||||||
<Route path="/city">
|
<Route path="/city">
|
||||||
<Route index element={<CityList />} />
|
<Route index element={<CityList />} />
|
||||||
@ -421,6 +427,7 @@ function App() {
|
|||||||
</RefineSnackbarProvider>
|
</RefineSnackbarProvider>
|
||||||
</ColorModeContextProvider>
|
</ColorModeContextProvider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
</QueryClientProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,15 +19,13 @@ import {
|
|||||||
TableRow,
|
TableRow,
|
||||||
Paper,
|
Paper,
|
||||||
TableBody,
|
TableBody,
|
||||||
|
IconButton,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||||
|
import DragIndicatorIcon from "@mui/icons-material/DragIndicator";
|
||||||
import { axiosInstance } from "../providers/data";
|
import { axiosInstance } from "../providers/data";
|
||||||
|
|
||||||
import { Link } from "react-router";
|
|
||||||
import { TOKEN_KEY } from "../authProvider";
|
import { TOKEN_KEY } from "../authProvider";
|
||||||
import { Droppable, Draggable, DragDropContext } from "@hello-pangea/dnd";
|
import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
|
||||||
|
|
||||||
// TODO: ДОДЕЛАТЬ
|
|
||||||
|
|
||||||
type Field<T> = {
|
type Field<T> = {
|
||||||
label: string;
|
label: string;
|
||||||
@ -52,11 +50,10 @@ type LinkedItemsProps<T> = {
|
|||||||
extraField?: ExtraFieldConfig;
|
extraField?: ExtraFieldConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
const reorder = (list, startIndex, endIndex) => {
|
const reorder = (list: any[], startIndex: number, endIndex: number) => {
|
||||||
const result = Array.from(list);
|
const result = Array.from(list);
|
||||||
const [removed] = result.splice(startIndex, 1);
|
const [removed] = result.splice(startIndex, 1);
|
||||||
result.splice(endIndex, 0, removed);
|
result.splice(endIndex, 0, removed);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,18 +73,20 @@ export const LinkedItems = <T extends { id: number; [key: string]: any }>({
|
|||||||
const [mediaOrder, setMediaOrder] = useState<number>(1);
|
const [mediaOrder, setMediaOrder] = useState<number>(1);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const onDragEnd = (result) => {
|
const onDragEnd = (result: any) => {
|
||||||
// ドロップ先がない
|
if (!result.destination) return;
|
||||||
if (!result.destination) {
|
|
||||||
return;
|
const reorderedItems = reorder(
|
||||||
}
|
linkedItems,
|
||||||
// 配列の順序を入れ替える
|
result.source.index,
|
||||||
let movedItems = reorder(
|
result.destination.index
|
||||||
linkedItems, // 順序を入れ変えたい配列
|
|
||||||
result.source.index, // 元の配列の位置
|
|
||||||
result.destination.index // 移動先の配列の位置
|
|
||||||
);
|
);
|
||||||
setLinkedItems(movedItems);
|
|
||||||
|
setLinkedItems(reorderedItems);
|
||||||
|
|
||||||
|
// If you need to save the new order to the backend, you would add that here
|
||||||
|
// For example:
|
||||||
|
// saveNewOrder(reorderedItems);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -212,57 +211,68 @@ export const LinkedItems = <T extends { id: number; [key: string]: any }>({
|
|||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
|
|
||||||
<AccordionDetails sx={{ background: theme.palette.background.paper }}>
|
<AccordionDetails sx={{ background: theme.palette.background.paper }}>
|
||||||
|
<Stack gap={2}>
|
||||||
|
<DragDropContext onDragEnd={onDragEnd}>
|
||||||
<TableContainer component={Paper}>
|
<TableContainer component={Paper}>
|
||||||
<Table aria-label="simple table">
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>ID</TableCell>
|
{type === "edit" && <TableCell width="40px"></TableCell>}
|
||||||
<TableCell>Name</TableCell>
|
{fields.map((field) => (
|
||||||
<TableCell>Действие</TableCell>
|
<TableCell key={String(field.data)}>
|
||||||
|
{field.label}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
{type === "edit" && (
|
||||||
|
<TableCell width="120px">Действие</TableCell>
|
||||||
|
)}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<DragDropContext onDragEnd={onDragEnd}>
|
|
||||||
<Droppable droppableId="droppable">
|
<Droppable droppableId="droppable">
|
||||||
{(provided) => (
|
{(provided) => (
|
||||||
<TableBody
|
<TableBody
|
||||||
ref={provided.innerRef}
|
ref={provided.innerRef}
|
||||||
{...provided.droppableProps}
|
{...provided.droppableProps}
|
||||||
>
|
>
|
||||||
{linkedItems.length > 0 &&
|
{linkedItems.map((item, index) => (
|
||||||
linkedItems.map((item, index) => (
|
|
||||||
<Draggable
|
<Draggable
|
||||||
key={item.id}
|
key={item.id}
|
||||||
draggableId={"q" + item.id.toString()}
|
draggableId={"q" + String(item.id)}
|
||||||
index={index}
|
index={index}
|
||||||
|
isDragDisabled={type !== "edit"}
|
||||||
>
|
>
|
||||||
{(provided) => (
|
{(provided) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
ref={provided.innerRef}
|
ref={provided.innerRef}
|
||||||
{...provided.dragHandleProps}
|
|
||||||
{...provided.draggableProps}
|
{...provided.draggableProps}
|
||||||
style={{
|
hover
|
||||||
...provided.draggableProps.style,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<TableCell style={{ flex: 1, minWidth: "100px" }}>
|
{type === "edit" && (
|
||||||
{item.id}
|
<TableCell {...provided.dragHandleProps}>
|
||||||
|
<IconButton size="small">
|
||||||
|
<DragIndicatorIcon />
|
||||||
|
</IconButton>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell style={{ flex: 1, minWidth: "100px" }}>
|
)}
|
||||||
{item.name}
|
{fields.map((field) => (
|
||||||
|
<TableCell key={String(field.data)}>
|
||||||
|
{field.render
|
||||||
|
? field.render(item[field.data])
|
||||||
|
: item[field.data]}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell style={{ flex: 1, minWidth: "100px" }}>
|
))}
|
||||||
|
{type === "edit" && (
|
||||||
|
<TableCell>
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="error"
|
color="error"
|
||||||
size="small"
|
size="small"
|
||||||
onClick={(e) => {
|
onClick={() => deleteItem(item.id)}
|
||||||
e.preventDefault();
|
|
||||||
deleteItem(item.id);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Отвязать
|
Отвязать
|
||||||
</Button>
|
</Button>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
)}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)}
|
)}
|
||||||
</Draggable>
|
</Draggable>
|
||||||
@ -271,85 +281,18 @@ export const LinkedItems = <T extends { id: number; [key: string]: any }>({
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
)}
|
)}
|
||||||
</Droppable>
|
</Droppable>
|
||||||
</DragDropContext>
|
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
</DragDropContext>
|
||||||
|
|
||||||
{/* <Stack gap={2}>
|
{linkedItems.length === 0 && !isLoading && (
|
||||||
<Grid container gap={1.25}>
|
<Typography color="textSecondary" textAlign="center" py={2}>
|
||||||
{isLoading ? (
|
{title} не найдены
|
||||||
<Typography>Загрузка...</Typography>
|
|
||||||
) : linkedItems.length > 0 ? (
|
|
||||||
linkedItems.map((item, index) => (
|
|
||||||
<Box
|
|
||||||
component={Link}
|
|
||||||
to={`/${childResource}/show/${item.id}`}
|
|
||||||
key={index}
|
|
||||||
sx={{
|
|
||||||
marginTop: "8px",
|
|
||||||
padding: "14px",
|
|
||||||
borderRadius: 2,
|
|
||||||
border: `2px solid ${theme.palette.divider}`,
|
|
||||||
width: childResource === "article" ? "100%" : "auto",
|
|
||||||
textDecoration: "none",
|
|
||||||
color: "inherit",
|
|
||||||
display: "block",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.action.hover,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Stack gap={0.25}>
|
|
||||||
{childResource === "media" && item.id && (
|
|
||||||
<img
|
|
||||||
src={`${import.meta.env.VITE_KRBL_MEDIA}/${
|
|
||||||
item.iimport { DragDropContext } from 'react-beautiful-dnd';
|
|
||||||
d
|
|
||||||
}/download?token=${localStorage.getItem(TOKEN_KEY)}`}
|
|
||||||
alt={String(item.media_name)}
|
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
height: "120px",
|
|
||||||
objectFit: "contain",
|
|
||||||
marginBottom: "8px",
|
|
||||||
borderRadius: 4,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{fields.map(({ label, data, render }) => (
|
|
||||||
<Typography
|
|
||||||
variant="body2"
|
|
||||||
color="textSecondary"
|
|
||||||
key={String(data)}
|
|
||||||
>
|
|
||||||
<strong>{label}:</strong>{" "}
|
|
||||||
{render ? render(item[data]) : item[data]}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
))}
|
|
||||||
{type === "edit" && (
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
color="error"
|
|
||||||
size="small"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
deleteItem(item.id);
|
|
||||||
}}
|
|
||||||
sx={{ mt: 1.5 }}
|
|
||||||
>
|
|
||||||
Отвязать
|
|
||||||
</Button>
|
|
||||||
)}
|
)}
|
||||||
</Stack>
|
|
||||||
</Box>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<Typography color="textSecondary">{title} не найдены</Typography>
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{type === "edit" && (
|
{type === "edit" && (
|
||||||
<Stack gap={2}>
|
<Stack gap={2} mt={2}>
|
||||||
<Typography variant="subtitle1">Добавить {title}</Typography>
|
<Typography variant="subtitle1">Добавить {title}</Typography>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
fullWidth
|
fullWidth
|
||||||
@ -373,7 +316,6 @@ d
|
|||||||
option.id === value?.id
|
option.id === value?.id
|
||||||
}
|
}
|
||||||
filterOptions={(options, { inputValue }) => {
|
filterOptions={(options, { inputValue }) => {
|
||||||
// return options.filter((option) => String(option[fields[0].data]).toLowerCase().includes(inputValue.toLowerCase()))
|
|
||||||
const searchWords = inputValue
|
const searchWords = inputValue
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.split(" ")
|
.split(" ")
|
||||||
@ -398,7 +340,7 @@ d
|
|||||||
value={pageNum}
|
value={pageNum}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const newValue = Number(e.target.value);
|
const newValue = Number(e.target.value);
|
||||||
const minValue = linkedItems.length + 1; // page number on articles lenght
|
const minValue = linkedItems.length + 1;
|
||||||
setPageNum(newValue < minValue ? minValue : newValue);
|
setPageNum(newValue < minValue ? minValue : newValue);
|
||||||
}}
|
}}
|
||||||
fullWidth
|
fullWidth
|
||||||
@ -407,7 +349,7 @@ d
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{childResource === "media" && type === "edit" && (
|
{childResource === "media" && (
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
<TextField
|
<TextField
|
||||||
type="number"
|
type="number"
|
||||||
@ -429,12 +371,13 @@ d
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={linkItem}
|
onClick={linkItem}
|
||||||
disabled={!selectedItemId}
|
disabled={!selectedItemId}
|
||||||
|
sx={{ alignSelf: "flex-start" }}
|
||||||
>
|
>
|
||||||
Добавить
|
Добавить
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
</Stack> */}
|
</Stack>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
);
|
);
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
import {Box, TextField} from '@mui/material'
|
import { Icons } from "../../preview/components";
|
||||||
import {Edit} from '@refinedev/mui'
|
import { Box, TextField } from "@mui/material";
|
||||||
import {useForm} from '@refinedev/react-hook-form'
|
import { Edit } from "@refinedev/mui";
|
||||||
|
import { useForm } from "@refinedev/react-hook-form";
|
||||||
|
|
||||||
export const CountryEdit = () => {
|
export const CountryEdit = () => {
|
||||||
const {
|
const {
|
||||||
saveButtonProps,
|
saveButtonProps,
|
||||||
register,
|
register,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = useForm({})
|
} = useForm({});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Edit saveButtonProps={saveButtonProps}>
|
<Edit saveButtonProps={saveButtonProps}>
|
||||||
<Box component="form" sx={{display: 'flex', flexDirection: 'column'}} autoComplete="off">
|
<Box
|
||||||
|
component="form"
|
||||||
|
sx={{ display: "flex", flexDirection: "column" }}
|
||||||
|
autoComplete="off"
|
||||||
|
>
|
||||||
<TextField
|
<TextField
|
||||||
{...register('code', {
|
{...register("code", {
|
||||||
required: 'Это поле является обязательным',
|
required: "Это поле является обязательным",
|
||||||
})}
|
})}
|
||||||
error={!!(errors as any)?.code}
|
error={!!(errors as any)?.code}
|
||||||
helperText={(errors as any)?.code?.message}
|
helperText={(errors as any)?.code?.message}
|
||||||
@ -22,12 +27,12 @@ export const CountryEdit = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
InputLabelProps={{ shrink: true }}
|
InputLabelProps={{ shrink: true }}
|
||||||
type="text"
|
type="text"
|
||||||
label={'Код *'}
|
label={"Код *"}
|
||||||
name="code"
|
name="code"
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
{...register('name', {
|
{...register("name", {
|
||||||
required: 'Это поле является обязательным',
|
required: "Это поле является обязательным",
|
||||||
})}
|
})}
|
||||||
error={!!(errors as any)?.name}
|
error={!!(errors as any)?.name}
|
||||||
helperText={(errors as any)?.name?.message}
|
helperText={(errors as any)?.name?.message}
|
||||||
@ -35,10 +40,10 @@ export const CountryEdit = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
InputLabelProps={{ shrink: true }}
|
InputLabelProps={{ shrink: true }}
|
||||||
type="text"
|
type="text"
|
||||||
label={'Название *'}
|
label={"Название *"}
|
||||||
name="name"
|
name="name"
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Edit>
|
</Edit>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import cn from 'classnames';
|
import cn from "classnames";
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
import './AttractionMedia.css';
|
import "./AttractionMedia.css";
|
||||||
import ModelViewer from '../../model-viewer/ModelViewer';
|
import ModelViewer from "../../model-viewer/ModelViewer";
|
||||||
import { Icons, useLightboxContext } from '@mt/components';
|
import { Icons, useLightboxContext } from "@mt/components";
|
||||||
import { Object3DLightboxData } from '@mt/common-types';
|
import { Object3DLightboxData } from "@mt/common-types";
|
||||||
|
|
||||||
interface Object3DMediaProps {
|
interface Object3DMediaProps {
|
||||||
url: string;
|
url: string;
|
||||||
@ -19,7 +19,7 @@ export const Object3DMedia = ({ url, watermarkUrl }: Object3DMediaProps) => {
|
|||||||
const handle3DFullscreenOpen = () => {
|
const handle3DFullscreenOpen = () => {
|
||||||
setAutoRotate(false);
|
setAutoRotate(false);
|
||||||
setData({
|
setData({
|
||||||
type: 'OBJECT_3D',
|
type: "OBJECT_3D",
|
||||||
modelUrl: url,
|
modelUrl: url,
|
||||||
watermarkUrl,
|
watermarkUrl,
|
||||||
});
|
});
|
||||||
@ -33,12 +33,14 @@ export const Object3DMedia = ({ url, watermarkUrl }: Object3DMediaProps) => {
|
|||||||
return (
|
return (
|
||||||
<div className="widget-media__wrapper">
|
<div className="widget-media__wrapper">
|
||||||
<div
|
<div
|
||||||
className={cn('widget-3d-model', {
|
className={cn("widget-3d-model", {
|
||||||
'media-with-watermark': watermarkUrl !== null,
|
"media-with-watermark": watermarkUrl !== null,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<ModelViewer key={url} pathToModel={url} autoRotate={autoRotate} />
|
<ModelViewer key={url} pathToModel={url} autoRotate={autoRotate} />
|
||||||
{watermarkUrl && <img src={watermarkUrl} alt="Watermark" className="watermark" />}
|
{watermarkUrl && (
|
||||||
|
<img src={watermarkUrl} alt="Watermark" className="watermark" />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Icons.FullscreenIcon
|
<Icons.FullscreenIcon
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import cn from 'classnames';
|
import cn from "classnames";
|
||||||
import { HTMLAttributes, ReactNode } from 'react';
|
import { HTMLAttributes, ReactNode } from "react";
|
||||||
|
|
||||||
import { StyledDrawer } from './Drawer.styles';
|
import { StyledDrawer } from "./Drawer.styles";
|
||||||
import { Icons } from '@mt/components';
|
import { Icons } from "@mt/components";
|
||||||
import { Locale, LocaleSwitcher } from '@mt/i18n';
|
import { Locale, LocaleSwitcher } from "@mt/i18n";
|
||||||
|
|
||||||
export interface DrawerProps extends HTMLAttributes<HTMLDivElement> {
|
export interface DrawerProps extends HTMLAttributes<HTMLDivElement> {
|
||||||
onToggle: (isOpened: boolean) => void;
|
onToggle: (isOpened: boolean) => void;
|
||||||
@ -24,11 +24,17 @@ export function Drawer({
|
|||||||
...props
|
...props
|
||||||
}: DrawerProps) {
|
}: DrawerProps) {
|
||||||
return (
|
return (
|
||||||
<StyledDrawer className={cn('g-flex-column', { 'nav-widget--opened': isOpen })} {...props}>
|
<StyledDrawer
|
||||||
|
className={cn("g-flex-column", { "nav-widget--opened": isOpen })}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
<div className="g-flex actions">
|
<div className="g-flex actions">
|
||||||
<div className="action-btn toggle-btn" onPointerUp={() => onToggle(!isOpen)}>
|
<div
|
||||||
|
className="action-btn toggle-btn"
|
||||||
|
onPointerUp={() => onToggle(!isOpen)}
|
||||||
|
>
|
||||||
<Icons.ArrowBtn />
|
<Icons.ArrowBtn />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -5,9 +5,20 @@ import {
|
|||||||
} from "react-simple-maps";
|
} from "react-simple-maps";
|
||||||
import styles from "./MapWidget.module.css";
|
import styles from "./MapWidget.module.css";
|
||||||
import { mapCanvasProps, useMapWidgetContext } from "../../MapWidgetContext";
|
import { mapCanvasProps, useMapWidgetContext } from "../../MapWidgetContext";
|
||||||
import { useState } from "react";
|
import { useState, FC, ReactNode } from "react";
|
||||||
import { MapContent } from "./MapContent";
|
import { MapContent } from "./MapContent";
|
||||||
|
|
||||||
|
// Create wrapper components to handle type issues
|
||||||
|
const ComposableMapWrapper: FC<any> = (props) => {
|
||||||
|
// @ts-ignore - Ignore type issues with the ComposableMap component
|
||||||
|
return <ComposableMap {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ZoomableGroupWrapper: FC<ZoomableGroupProps> = (props) => {
|
||||||
|
// @ts-ignore - Ignore type issues with the ZoomableGroup component
|
||||||
|
return <ZoomableGroup {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
// default coordinates for 3a route: 59.943, 30.331
|
// default coordinates for 3a route: 59.943, 30.331
|
||||||
export const MapWidget = () => {
|
export const MapWidget = () => {
|
||||||
const { onMapCenterMoved, projection, isDragMode, rotateAngle } =
|
const { onMapCenterMoved, projection, isDragMode, rotateAngle } =
|
||||||
@ -34,13 +45,12 @@ export const MapWidget = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ComposableMap
|
<ComposableMapWrapper
|
||||||
// Cast to any need due to error in react-simple-maps typings
|
|
||||||
projection={projection as any}
|
projection={projection as any}
|
||||||
className={styles.mapWidget}
|
className={styles.mapWidget}
|
||||||
{...mapCanvasProps}
|
{...mapCanvasProps}
|
||||||
>
|
>
|
||||||
<ZoomableGroup
|
<ZoomableGroupWrapper
|
||||||
key={key}
|
key={key}
|
||||||
center={projection.center()}
|
center={projection.center()}
|
||||||
onMoveEnd={handleMoveEnd}
|
onMoveEnd={handleMoveEnd}
|
||||||
@ -49,7 +59,7 @@ export const MapWidget = () => {
|
|||||||
maxZoom={1}
|
maxZoom={1}
|
||||||
>
|
>
|
||||||
<MapContent />
|
<MapContent />
|
||||||
</ZoomableGroup>
|
</ZoomableGroupWrapper>
|
||||||
</ComposableMap>
|
</ComposableMapWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Marker, Point } from "react-simple-maps";
|
import { Point, Marker } from "react-simple-maps";
|
||||||
import { Icons } from "@mt/components";
|
import { Icons } from "@mt/components";
|
||||||
import { AttractionGroupIconSizeType } from "@mt/common-types";
|
import { AttractionGroupIconSizeType } from "@mt/common-types";
|
||||||
|
|
||||||
|
7
src/preview/components/MyComponent/index.tsx
Normal file
7
src/preview/components/MyComponent/index.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export const MyComponent = () => {
|
||||||
|
return (
|
||||||
|
<div style={{ width: "100px", height: "100px", backgroundColor: "red" }}>
|
||||||
|
MyComponent
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import { HTMLAttributes, ReactNode } from "react";
|
import { HTMLAttributes, ReactNode } from "react";
|
||||||
|
|
||||||
import { Icons } from "../icons";
|
import { Icons } from "../Icons";
|
||||||
import { TransportType } from "@mt/common-types";
|
import { TransportType } from "@mt/common-types";
|
||||||
|
|
||||||
const transportStopIcons: Record<TransportType, ReactNode> = {
|
const transportStopIcons: Record<TransportType, ReactNode> = {
|
||||||
|
@ -8,4 +8,5 @@ export * from "./MapWidget";
|
|||||||
export * from "./Drawer";
|
export * from "./Drawer";
|
||||||
export * from "./lightbox";
|
export * from "./lightbox";
|
||||||
export * from "./model-viewer";
|
export * from "./model-viewer";
|
||||||
export * from "./icons";
|
export { Icons } from "./Icons";
|
||||||
|
export * from "./MyComponent";
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React from 'react';
|
import React from "react";
|
||||||
import { useLightboxContext } from './LightboxContext';
|
import { useLightboxContext } from "./LightboxContext";
|
||||||
|
|
||||||
import './Lightbox.css';
|
import "./Lightbox.css";
|
||||||
import { LightboxData } from '@mt/common-types';
|
import { LightboxData } from "@mt/common-types";
|
||||||
import { LightboxContent } from './LightboxContent';
|
import { LightboxContent } from "./LightboxContent";
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
export const Lightbox = () => {
|
export const Lightbox = () => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
@ -13,14 +13,24 @@ export const Lightbox = () => {
|
|||||||
return lightboxActive ? (
|
return lightboxActive ? (
|
||||||
<div className="lightbox-overlay">
|
<div className="lightbox-overlay">
|
||||||
<div className="lightbox-content">
|
<div className="lightbox-content">
|
||||||
<div className="lightbox-content__wrapper" style={{ height: '749px', width: '1220px' }}>
|
<div
|
||||||
|
className="lightbox-content__wrapper"
|
||||||
|
style={{ height: "749px", width: "1220px" }}
|
||||||
|
>
|
||||||
<LightboxContent />
|
<LightboxContent />
|
||||||
|
|
||||||
{data.watermarkUrl && (
|
{data.watermarkUrl && (
|
||||||
<img src={data.watermarkUrl} alt="Watermark" className="watermark" />
|
<img
|
||||||
|
src={data.watermarkUrl}
|
||||||
|
alt="Watermark"
|
||||||
|
className="watermark"
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<button className="lightbox-content__close-btn" onPointerUp={closeLightbox}>
|
<button
|
||||||
|
className="lightbox-content__close-btn"
|
||||||
|
onPointerUp={closeLightbox}
|
||||||
|
>
|
||||||
<FormattedMessage id="close" />
|
<FormattedMessage id="close" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from "react";
|
||||||
// TODO: resolve circular deps (probably we should move icons to a separate lib)
|
// TODO: resolve circular deps (probably we should move icons to a separate lib)
|
||||||
import { Icons } from '@mt/components';
|
import { Icons } from "@mt/components";
|
||||||
import { Locale, localesMap } from '../i18n.interface';
|
import { Locale, localesMap } from "../i18n.interface";
|
||||||
import './LocaleSwitcher.css';
|
import "./LocaleSwitcher.css";
|
||||||
|
|
||||||
interface LocaleSwitcherProps {
|
interface LocaleSwitcherProps {
|
||||||
onLocaleChange: (locale: Locale) => void;
|
onLocaleChange: (locale: Locale) => void;
|
||||||
@ -10,7 +10,7 @@ interface LocaleSwitcherProps {
|
|||||||
|
|
||||||
export const LocaleSwitcher = ({ onLocaleChange }: LocaleSwitcherProps) => {
|
export const LocaleSwitcher = ({ onLocaleChange }: LocaleSwitcherProps) => {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [selectedLocale, setSelectedLocale] = useState<Locale>('ru');
|
const [selectedLocale, setSelectedLocale] = useState<Locale>("ru");
|
||||||
|
|
||||||
const handleLocaleChange = useCallback(
|
const handleLocaleChange = useCallback(
|
||||||
(locale: Locale) => {
|
(locale: Locale) => {
|
||||||
@ -24,7 +24,10 @@ export const LocaleSwitcher = ({ onLocaleChange }: LocaleSwitcherProps) => {
|
|||||||
return (
|
return (
|
||||||
<div className="locale-switcher">
|
<div className="locale-switcher">
|
||||||
{!isOpen ? (
|
{!isOpen ? (
|
||||||
<button className="locale-switcher__button" onPointerUp={() => setIsOpen(!isOpen)}>
|
<button
|
||||||
|
className="locale-switcher__button"
|
||||||
|
onPointerUp={() => setIsOpen(!isOpen)}
|
||||||
|
>
|
||||||
<Icons.I18NIcon />
|
<Icons.I18NIcon />
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
@ -32,7 +35,9 @@ export const LocaleSwitcher = ({ onLocaleChange }: LocaleSwitcherProps) => {
|
|||||||
{Object.entries(localesMap).map(([label, locale]) => (
|
{Object.entries(localesMap).map(([label, locale]) => (
|
||||||
<button
|
<button
|
||||||
key={locale}
|
key={locale}
|
||||||
className={`locale-switcher__option ${selectedLocale === locale ? 'selected' : ''}`}
|
className={`locale-switcher__option ${
|
||||||
|
selectedLocale === locale ? "selected" : ""
|
||||||
|
}`}
|
||||||
onPointerUp={() => handleLocaleChange(locale)}
|
onPointerUp={() => handleLocaleChange(locale)}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
|
@ -2,7 +2,6 @@ import {
|
|||||||
LongPollingQueryOptions,
|
LongPollingQueryOptions,
|
||||||
useLongPollingQuery,
|
useLongPollingQuery,
|
||||||
} from "./useLongPollingQuery";
|
} from "./useLongPollingQuery";
|
||||||
import { useId } from "react";
|
|
||||||
|
|
||||||
export type EventQueryData<T> = T & {
|
export type EventQueryData<T> = T & {
|
||||||
["@type"]: string;
|
["@type"]: string;
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
import { MapWidget, useMapWidgetContext } from '@mt/components';
|
import { MapWidget, useMapWidgetContext } from "@mt/components";
|
||||||
import { useGetMapData } from './useGetMapData';
|
import { useGetMapData } from "./useGetMapData";
|
||||||
import { EventQueryData, useEventQuery, useLoading } from '@mt/utils';
|
import { EventQueryData, useEventQuery, useLoading } from "@mt/utils";
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from "react";
|
||||||
// TODO: resolve circular deps
|
// TODO: resolve circular deps
|
||||||
import { Coordinates } from '@mt/common-types';
|
import { Coordinates } from "@mt/common-types";
|
||||||
|
|
||||||
export const MapWidgetContainer = () => {
|
export const MapWidgetContainer = () => {
|
||||||
const { isLoading } = useLoading();
|
const { isLoading } = useLoading();
|
||||||
const { data, refetch } = useGetMapData();
|
const { data, refetch } = useGetMapData();
|
||||||
const { currentPosition, setCurrentPosition, onMapDataFetched } = useMapWidgetContext();
|
const { currentPosition, setCurrentPosition, onMapDataFetched } =
|
||||||
|
useMapWidgetContext();
|
||||||
|
|
||||||
const { data: events = [], isSuccess } = useEventQuery('/widgets/route-map/events', [
|
const { data: events = [], isSuccess } = useEventQuery(
|
||||||
'REFRESH_DATA',
|
"/widgets/route-map/events",
|
||||||
'UPDATE_CURRENT_POINT_ON_TRACK',
|
["REFRESH_DATA", "UPDATE_CURRENT_POINT_ON_TRACK"]
|
||||||
]);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
@ -28,7 +29,7 @@ export const MapWidgetContainer = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events.some((e) => e['@type'] === 'REFRESH_DATA')) {
|
if (events.some((e) => e["@type"] === "REFRESH_DATA")) {
|
||||||
refetch();
|
refetch();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import styled from "@emotion/styled";
|
import styled from "@emotion/styled";
|
||||||
import { AttractionWidgetContainer } from "../attractions-widget/AttractionWidgetContainer";
|
import { Drawer } from "@mt/components";
|
||||||
import { WeatherWidgetContainer } from "../WeatherWidget/WeatherWidgetContainer";
|
import { Locale } from "@mt/i18n";
|
||||||
import { OperativeInfoWidget } from "../operative-info-widget/operative-info-widget";
|
|
||||||
import { NavWidgetContainer } from "../nav-widget/nav-widget-container";
|
import { NavWidgetContainer } from "../nav-widget/nav-widget-container";
|
||||||
import { MapWidgetContainer } from "../MapWidgetContainer";
|
|
||||||
import { RouteInfoWidgetContainer } from "../RouteInfoWidgetContainer/RouteInfoWidgetContainer";
|
import { RouteInfoWidgetContainer } from "../RouteInfoWidgetContainer/RouteInfoWidgetContainer";
|
||||||
|
import { WeatherWidgetContainer } from "../WeatherWidget/WeatherWidgetContainer";
|
||||||
|
import { MapWidgetContainer } from "../MapWidgetContainer/MapWidgetContainer";
|
||||||
|
import { OperativeInfoWidget } from "../operative-info-widget/operative-info-widget";
|
||||||
|
import { AttractionWidgetContainer } from "../attractions-widget/AttractionWidgetContainer";
|
||||||
|
|
||||||
const StyledDashboard = styled.div`
|
const StyledDashboard = styled.div`
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
@ -49,6 +51,16 @@ const StyledDashboard = styled.div`
|
|||||||
export function Dashboard() {
|
export function Dashboard() {
|
||||||
return (
|
return (
|
||||||
<StyledDashboard>
|
<StyledDashboard>
|
||||||
|
<Drawer
|
||||||
|
onToggle={function (isOpened: boolean): void {
|
||||||
|
throw new Error("Function not implemented.");
|
||||||
|
}}
|
||||||
|
isOpen={false}
|
||||||
|
onLocaleChange={function (locale: Locale): void {
|
||||||
|
throw new Error("Function not implemented.");
|
||||||
|
}}
|
||||||
|
></Drawer>
|
||||||
|
|
||||||
<NavWidgetContainer />
|
<NavWidgetContainer />
|
||||||
|
|
||||||
<div className="container">
|
<div className="container">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { HTMLAttributes } from 'react';
|
import { HTMLAttributes } from "react";
|
||||||
import { NavWidget } from './nav-widget';
|
import { NavWidget } from "./nav-widget";
|
||||||
import { useGetStations } from './hooks/useGetStations';
|
import { useGetStations } from "./hooks/useGetStations";
|
||||||
import { useGetAttractions } from './hooks';
|
import { useGetAttractions } from "./hooks";
|
||||||
|
|
||||||
export function NavWidgetContainer(props: HTMLAttributes<HTMLDivElement>) {
|
export function NavWidgetContainer(props: HTMLAttributes<HTMLDivElement>) {
|
||||||
const { data: stations } = useGetStations();
|
const { data: stations } = useGetStations();
|
||||||
|
@ -1,16 +1,23 @@
|
|||||||
import cn from 'classnames';
|
import cn from "classnames";
|
||||||
import { HTMLAttributes, ReactNode, useContext, useEffect, useMemo, useState } from 'react';
|
import {
|
||||||
import { LocalizationContext, useServerLocalization } from '@mt/i18n';
|
HTMLAttributes,
|
||||||
import { Order, uuid } from '@mt/common-types';
|
ReactNode,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
import { LocalizationContext, useServerLocalization } from "@mt/i18n";
|
||||||
|
import { Order, uuid } from "@mt/common-types";
|
||||||
|
|
||||||
import { AttractionCard, AccordionListTab, NestedItems } from './components';
|
import { AttractionCard, AccordionListTab, NestedItems } from "./components";
|
||||||
import { Drawer, Icons } from '@mt/components';
|
import { Drawer, Icons } from "@mt/components";
|
||||||
|
|
||||||
import { Attraction, Station } from './nav-widget.interface';
|
import { Attraction, Station } from "./nav-widget.interface";
|
||||||
import { HomeTab } from './components';
|
import { HomeTab } from "./components";
|
||||||
import { StyledNavWidget } from './nav-widget.styles';
|
import { StyledNavWidget } from "./nav-widget.styles";
|
||||||
|
|
||||||
export type NavTabs = 'stationsTab' | 'attractionsTab';
|
export type NavTabs = "stationsTab" | "attractionsTab";
|
||||||
|
|
||||||
export interface NavWidgetProps extends HTMLAttributes<HTMLDivElement> {
|
export interface NavWidgetProps extends HTMLAttributes<HTMLDivElement> {
|
||||||
stations: Station[];
|
stations: Station[];
|
||||||
@ -22,14 +29,19 @@ export function NavWidget({ stations, attractions }: NavWidgetProps) {
|
|||||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||||
const [openedTab, setOpenedTab] = useState<NavTabs | null>(null);
|
const [openedTab, setOpenedTab] = useState<NavTabs | null>(null);
|
||||||
const [attractionId, setAttractionId] = useState<uuid | null>(null);
|
const [attractionId, setAttractionId] = useState<uuid | null>(null);
|
||||||
const [attractionOrder, setAttractionOrder] = useState<Order>('asc');
|
const [attractionOrder, setAttractionOrder] = useState<Order>("asc");
|
||||||
|
|
||||||
const sortAttractionsBtn: ReactNode = useMemo(() => {
|
const sortAttractionsBtn: ReactNode = useMemo(() => {
|
||||||
if (openedTab === 'attractionsTab') {
|
if (openedTab === "attractionsTab") {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn([{ 'order-btn-inverse': attractionOrder === 'desc' }, 'action-btn'])}
|
className={cn([
|
||||||
onPointerUp={() => setAttractionOrder((prev) => (prev === 'asc' ? 'desc' : 'asc'))}
|
{ "order-btn-inverse": attractionOrder === "desc" },
|
||||||
|
"action-btn",
|
||||||
|
])}
|
||||||
|
onPointerUp={() =>
|
||||||
|
setAttractionOrder((prev) => (prev === "asc" ? "desc" : "asc"))
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Icons.SortIcon />
|
<Icons.SortIcon />
|
||||||
</div>
|
</div>
|
||||||
@ -64,8 +76,10 @@ export function NavWidget({ stations, attractions }: NavWidgetProps) {
|
|||||||
}))
|
}))
|
||||||
.sort(
|
.sort(
|
||||||
(a, b) =>
|
(a, b) =>
|
||||||
localizeText(a.name).toLowerCase().localeCompare(localizeText(b.name).toLowerCase()) *
|
localizeText(a.name)
|
||||||
(attractionOrder === 'asc' ? 1 : -1)
|
.toLowerCase()
|
||||||
|
.localeCompare(localizeText(b.name).toLowerCase()) *
|
||||||
|
(attractionOrder === "asc" ? 1 : -1)
|
||||||
);
|
);
|
||||||
}, [attractions, attractionOrder, locale]);
|
}, [attractions, attractionOrder, locale]);
|
||||||
|
|
||||||
@ -74,7 +88,7 @@ export function NavWidget({ stations, attractions }: NavWidgetProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
className={cn({ 'nav-widget--opened': isOpen })}
|
className={cn({ "nav-widget--opened": isOpen })}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onToggle={setIsOpen}
|
onToggle={setIsOpen}
|
||||||
onHomeBtnClick={() => setOpenedTab(null)}
|
onHomeBtnClick={() => setOpenedTab(null)}
|
||||||
@ -86,14 +100,14 @@ export function NavWidget({ stations, attractions }: NavWidgetProps) {
|
|||||||
|
|
||||||
<AccordionListTab
|
<AccordionListTab
|
||||||
titleId="stops"
|
titleId="stops"
|
||||||
isOpened={openedTab === 'stationsTab'}
|
isOpened={openedTab === "stationsTab"}
|
||||||
items={mappedStations}
|
items={mappedStations}
|
||||||
onNestedItemClick={setAttractionId}
|
onNestedItemClick={setAttractionId}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AccordionListTab
|
<AccordionListTab
|
||||||
titleId="attractions"
|
titleId="attractions"
|
||||||
isOpened={openedTab === 'attractionsTab'}
|
isOpened={openedTab === "attractionsTab"}
|
||||||
items={mappedAttractions}
|
items={mappedAttractions}
|
||||||
onExpandChange={handleExpandChange}
|
onExpandChange={handleExpandChange}
|
||||||
/>
|
/>
|
||||||
|
@ -5,22 +5,23 @@
|
|||||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||||
"allowJs": false,
|
"allowJs": false,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"esModuleInterop": false,
|
"esModuleInterop": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"moduleResolution": "Node",
|
"moduleResolution": "Node",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": false,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@mt/common-types": ["./src/preview/types"],
|
"@mt/common-types": ["src/preview/types"],
|
||||||
"@mt/components": ["./src/preview/components"],
|
"@mt/components": ["src/preview/components"],
|
||||||
"@mt/i18n": ["./src/preview/i18n"],
|
"@mt/i18n": ["src/preview/i18n"],
|
||||||
"@mt/widgets": ["./src/preview/widgets"],
|
"@mt/widgets": ["src/preview/widgets"],
|
||||||
"@mt/utils": ["./src/preview/utils"]
|
"@mt/utils": ["src/preview/utils"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
|
@ -2,7 +2,17 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"moduleResolution": "node"
|
"moduleResolution": "node",
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@mt/common-types": ["src/preview/types"],
|
||||||
|
"@mt/components": ["src/preview/components"],
|
||||||
|
"@mt/i18n": ["src/preview/i18n"],
|
||||||
|
"@mt/widgets": ["src/preview/widgets"],
|
||||||
|
"@mt/utils": ["src/preview/utils"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"include": ["vite.config.ts"]
|
"include": ["vite.config.ts"]
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import react from "@vitejs/plugin-react";
|
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import svgr from "vite-plugin-svgr";
|
import svgr from "vite-plugin-svgr";
|
||||||
|
import react from "@vitejs/plugin-react";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), svgr()],
|
plugins: [react(), svgr()],
|
||||||
|
Loading…
Reference in New Issue
Block a user