Client: Reformatted all files with new line length
This commit is contained in:
@@ -1,13 +1,7 @@
|
|||||||
import { Refine } from "@refinedev/core";
|
import { Refine } from "@refinedev/core";
|
||||||
import { RefineKbar, RefineKbarProvider } from "@refinedev/kbar";
|
import { RefineKbar, RefineKbarProvider } from "@refinedev/kbar";
|
||||||
|
|
||||||
import {
|
import { ErrorComponent, notificationProvider, ThemedLayoutV2, ThemedSiderV2, ThemedTitleV2 } from "@refinedev/antd";
|
||||||
ErrorComponent,
|
|
||||||
notificationProvider,
|
|
||||||
ThemedLayoutV2,
|
|
||||||
ThemedSiderV2,
|
|
||||||
ThemedTitleV2,
|
|
||||||
} from "@refinedev/antd";
|
|
||||||
import "@refinedev/antd/dist/reset.css";
|
import "@refinedev/antd/dist/reset.css";
|
||||||
|
|
||||||
import routerBindings, {
|
import routerBindings, {
|
||||||
@@ -21,11 +15,7 @@ import { BrowserRouter, Outlet, Route, Routes } from "react-router-dom";
|
|||||||
import { Header } from "./components/header";
|
import { Header } from "./components/header";
|
||||||
import { ColorModeContextProvider } from "./contexts/color-mode";
|
import { ColorModeContextProvider } from "./contexts/color-mode";
|
||||||
import { ReactComponent as Logo } from "./icon.svg";
|
import { ReactComponent as Logo } from "./icon.svg";
|
||||||
import {
|
import { FileOutlined, HighlightOutlined, UserOutlined } from "@ant-design/icons";
|
||||||
FileOutlined,
|
|
||||||
HighlightOutlined,
|
|
||||||
UserOutlined,
|
|
||||||
} from "@ant-design/icons";
|
|
||||||
import { ConfigProvider } from "antd";
|
import { ConfigProvider } from "antd";
|
||||||
import { Footer } from "antd/es/layout/layout";
|
import { Footer } from "antd/es/layout/layout";
|
||||||
import { Version } from "./components/version";
|
import { Version } from "./components/version";
|
||||||
@@ -40,14 +30,10 @@ interface PageProps {
|
|||||||
mode?: "create" | "clone";
|
mode?: "create" | "clone";
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoadablePage = loadable(
|
const LoadablePage = loadable((props: PageProps) => import(`./pages/${props.resource}/${props.page}.tsx`), {
|
||||||
(props: PageProps) => import(`./pages/${props.resource}/${props.page}.tsx`),
|
fallback: <div>Page is Loading...</div>,
|
||||||
{
|
cacheKey: (props: PageProps) => `${props.resource}-${props.page}-${props.mode ?? ""}`,
|
||||||
fallback: <div>Page is Loading...</div>,
|
});
|
||||||
cacheKey: (props: PageProps) =>
|
|
||||||
`${props.resource}-${props.page}-${props.mode ?? ""}`,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
@@ -63,9 +49,7 @@ function App() {
|
|||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const fetchLocale = async () => {
|
const fetchLocale = async () => {
|
||||||
const locale = await import(
|
const locale = await import(
|
||||||
`./../node_modules/antd/es/locale/${languages[
|
`./../node_modules/antd/es/locale/${languages[i18n.language].fullCode.replace("-", "_")}.js`
|
||||||
i18n.language
|
|
||||||
].fullCode.replace("-", "_")}.js`
|
|
||||||
);
|
);
|
||||||
setAntdLocale(locale.default);
|
setAntdLocale(locale.default);
|
||||||
};
|
};
|
||||||
@@ -77,8 +61,8 @@ function App() {
|
|||||||
<>
|
<>
|
||||||
<h1>Missing API URL</h1>
|
<h1>Missing API URL</h1>
|
||||||
<p>
|
<p>
|
||||||
App was built without an API URL. Please set the VITE_APIURL
|
App was built without an API URL. Please set the VITE_APIURL environment variable to the URL of your Spoolman
|
||||||
environment variable to the URL of your Spoolman API.
|
API.
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@@ -154,11 +138,7 @@ function App() {
|
|||||||
<ThemedSiderV2
|
<ThemedSiderV2
|
||||||
fixed
|
fixed
|
||||||
Title={({ collapsed }) => (
|
Title={({ collapsed }) => (
|
||||||
<ThemedTitleV2
|
<ThemedTitleV2 collapsed={collapsed} text="Spoolman" icon={<Logo />} />
|
||||||
collapsed={collapsed}
|
|
||||||
text="Spoolman"
|
|
||||||
icon={<Logo />}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -172,117 +152,30 @@ function App() {
|
|||||||
</ThemedLayoutV2>
|
</ThemedLayoutV2>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Route
|
<Route index element={<NavigateToResource resource="spool" />} />
|
||||||
index
|
|
||||||
element={<NavigateToResource resource="spool" />}
|
|
||||||
/>
|
|
||||||
<Route path="/spool">
|
<Route path="/spool">
|
||||||
<Route
|
<Route index element={<LoadablePage resource="spools" page="list" />} />
|
||||||
index
|
<Route path="create" element={<LoadablePage resource="spools" page="create" mode="create" />} />
|
||||||
element={<LoadablePage resource="spools" page="list" />}
|
<Route path="clone/:id" element={<LoadablePage resource="spools" page="create" mode="clone" />} />
|
||||||
/>
|
<Route path="edit/:id" element={<LoadablePage resource="spools" page="edit" />} />
|
||||||
<Route
|
<Route path="show/:id" element={<LoadablePage resource="spools" page="show" />} />
|
||||||
path="create"
|
|
||||||
element={
|
|
||||||
<LoadablePage
|
|
||||||
resource="spools"
|
|
||||||
page="create"
|
|
||||||
mode="create"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="clone/:id"
|
|
||||||
element={
|
|
||||||
<LoadablePage
|
|
||||||
resource="spools"
|
|
||||||
page="create"
|
|
||||||
mode="clone"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="edit/:id"
|
|
||||||
element={<LoadablePage resource="spools" page="edit" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="show/:id"
|
|
||||||
element={<LoadablePage resource="spools" page="show" />}
|
|
||||||
/>
|
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/filament">
|
<Route path="/filament">
|
||||||
<Route
|
<Route index element={<LoadablePage resource="filaments" page="list" />} />
|
||||||
index
|
<Route path="create" element={<LoadablePage resource="filaments" page="create" mode="create" />} />
|
||||||
element={
|
|
||||||
<LoadablePage resource="filaments" page="list" />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="create"
|
|
||||||
element={
|
|
||||||
<LoadablePage
|
|
||||||
resource="filaments"
|
|
||||||
page="create"
|
|
||||||
mode="create"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
<Route
|
||||||
path="clone/:id"
|
path="clone/:id"
|
||||||
element={
|
element={<LoadablePage resource="filaments" page="create" mode="clone" />}
|
||||||
<LoadablePage
|
|
||||||
resource="filaments"
|
|
||||||
page="create"
|
|
||||||
mode="clone"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="edit/:id"
|
|
||||||
element={
|
|
||||||
<LoadablePage resource="filaments" page="edit" />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="show/:id"
|
|
||||||
element={
|
|
||||||
<LoadablePage resource="filaments" page="show" />
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
|
<Route path="edit/:id" element={<LoadablePage resource="filaments" page="edit" />} />
|
||||||
|
<Route path="show/:id" element={<LoadablePage resource="filaments" page="show" />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/vendor">
|
<Route path="/vendor">
|
||||||
<Route
|
<Route index element={<LoadablePage resource="vendors" page="list" />} />
|
||||||
index
|
<Route path="create" element={<LoadablePage resource="vendors" page="create" mode="create" />} />
|
||||||
element={<LoadablePage resource="vendors" page="list" />}
|
<Route path="clone/:id" element={<LoadablePage resource="vendors" page="create" mode="clone" />} />
|
||||||
/>
|
<Route path="edit/:id" element={<LoadablePage resource="vendors" page="edit" />} />
|
||||||
<Route
|
<Route path="show/:id" element={<LoadablePage resource="vendors" page="show" />} />
|
||||||
path="create"
|
|
||||||
element={
|
|
||||||
<LoadablePage
|
|
||||||
resource="vendors"
|
|
||||||
page="create"
|
|
||||||
mode="create"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="clone/:id"
|
|
||||||
element={
|
|
||||||
<LoadablePage
|
|
||||||
resource="vendors"
|
|
||||||
page="create"
|
|
||||||
mode="clone"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="edit/:id"
|
|
||||||
element={<LoadablePage resource="vendors" page="edit" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="show/:id"
|
|
||||||
element={<LoadablePage resource="vendors" page="show" />}
|
|
||||||
/>
|
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="*" element={<ErrorComponent />} />
|
<Route path="*" element={<ErrorComponent />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
import { Col, Row, Table } from "antd";
|
import { Col, Row, Table } from "antd";
|
||||||
import { ColumnProps as AntdColumnProps } from "antd/es/table";
|
import { ColumnProps as AntdColumnProps } from "antd/es/table";
|
||||||
import { ColumnFilterItem } from "antd/es/table/interface";
|
import { ColumnFilterItem } from "antd/es/table/interface";
|
||||||
import {
|
import { getFiltersForField, typeFilters, useListFiltersForField } from "../utils/filtering";
|
||||||
getFiltersForField,
|
|
||||||
typeFilters,
|
|
||||||
useListFiltersForField,
|
|
||||||
} from "../utils/filtering";
|
|
||||||
import { TableState } from "../utils/saveload";
|
import { TableState } from "../utils/saveload";
|
||||||
import { getSortOrderForField, typeSorters } from "../utils/sorting";
|
import { getSortOrderForField, typeSorters } from "../utils/sorting";
|
||||||
import { NumberFieldUnit } from "./numberField";
|
import { NumberFieldUnit } from "./numberField";
|
||||||
@@ -40,14 +36,9 @@ interface CustomColumnProps<Obj> {
|
|||||||
) => React.HTMLAttributes<any> | React.TdHTMLAttributes<any>;
|
) => React.HTMLAttributes<any> | React.TdHTMLAttributes<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Column<Obj>(
|
function Column<Obj>(props: BaseColumnProps<Obj> & FilteredColumnProps & CustomColumnProps<Obj>) {
|
||||||
props: BaseColumnProps<Obj> & FilteredColumnProps & CustomColumnProps<Obj>
|
|
||||||
) {
|
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
if (
|
if (props.tableState.showColumns && !props.tableState.showColumns.includes(props.id)) {
|
||||||
props.tableState.showColumns &&
|
|
||||||
!props.tableState.showColumns.includes(props.id)
|
|
||||||
) {
|
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
const typedSorters = typeSorters<Obj>(props.tableState.sorters);
|
const typedSorters = typeSorters<Obj>(props.tableState.sorters);
|
||||||
|
|||||||
@@ -1,15 +1,7 @@
|
|||||||
import { DownOutlined } from "@ant-design/icons";
|
import { DownOutlined } from "@ant-design/icons";
|
||||||
import type { RefineThemedLayoutV2HeaderProps } from "@refinedev/antd";
|
import type { RefineThemedLayoutV2HeaderProps } from "@refinedev/antd";
|
||||||
import { useGetLocale, useSetLocale } from "@refinedev/core";
|
import { useGetLocale, useSetLocale } from "@refinedev/core";
|
||||||
import {
|
import { Button, Dropdown, Layout as AntdLayout, MenuProps, Space, Switch, theme } from "antd";
|
||||||
Button,
|
|
||||||
Dropdown,
|
|
||||||
Layout as AntdLayout,
|
|
||||||
MenuProps,
|
|
||||||
Space,
|
|
||||||
Switch,
|
|
||||||
theme,
|
|
||||||
} from "antd";
|
|
||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
import { ColorModeContext } from "../../contexts/color-mode";
|
import { ColorModeContext } from "../../contexts/color-mode";
|
||||||
|
|
||||||
@@ -19,9 +11,7 @@ import QRCodeScannerModal from "../qrCodeScanner";
|
|||||||
|
|
||||||
const { useToken } = theme;
|
const { useToken } = theme;
|
||||||
|
|
||||||
export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
|
export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({ sticky }) => {
|
||||||
sticky,
|
|
||||||
}) => {
|
|
||||||
const { token } = useToken();
|
const { token } = useToken();
|
||||||
const locale = useGetLocale();
|
const locale = useGetLocale();
|
||||||
const changeLanguage = useSetLocale();
|
const changeLanguage = useSetLocale();
|
||||||
@@ -29,19 +19,12 @@ export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
|
|||||||
|
|
||||||
const currentLocale = locale();
|
const currentLocale = locale();
|
||||||
|
|
||||||
const menuItems: MenuProps["items"] = [...(Object.keys(languages) || [])]
|
const menuItems: MenuProps["items"] = [...(Object.keys(languages) || [])].sort().map((lang: string) => ({
|
||||||
.sort()
|
key: lang,
|
||||||
.map((lang: string) => ({
|
onClick: () => changeLanguage(lang),
|
||||||
key: lang,
|
icon: <span className={"fi fi-" + languages[lang].countryCode} style={{ marginRight: 8 }} />,
|
||||||
onClick: () => changeLanguage(lang),
|
label: languages[lang].name,
|
||||||
icon: (
|
}));
|
||||||
<span
|
|
||||||
className={"fi fi-" + languages[lang].countryCode}
|
|
||||||
style={{ marginRight: 8 }}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
label: languages[lang].name,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const headerStyles: React.CSSProperties = {
|
const headerStyles: React.CSSProperties = {
|
||||||
backgroundColor: token.colorBgElevated,
|
backgroundColor: token.colorBgElevated,
|
||||||
@@ -69,11 +52,7 @@ export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
|
|||||||
>
|
>
|
||||||
<Button type="text">
|
<Button type="text">
|
||||||
<Space>
|
<Space>
|
||||||
<span
|
<span className={"fi fi-" + languages[currentLocale ?? "en"].countryCode} />
|
||||||
className={
|
|
||||||
"fi fi-" + languages[currentLocale ?? "en"].countryCode
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{languages[currentLocale ?? "en"].name}
|
{languages[currentLocale ?? "en"].name}
|
||||||
<DownOutlined />
|
<DownOutlined />
|
||||||
</Space>
|
</Space>
|
||||||
|
|||||||
@@ -5,11 +5,7 @@ import { NumberFieldProps } from "@refinedev/antd/dist/components/fields/types";
|
|||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
function toLocaleStringSupportsOptions() {
|
function toLocaleStringSupportsOptions() {
|
||||||
return !!(
|
return !!(typeof Intl == "object" && Intl && typeof Intl.NumberFormat == "function");
|
||||||
typeof Intl == "object" &&
|
|
||||||
Intl &&
|
|
||||||
typeof Intl.NumberFormat == "function"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = NumberFieldProps & {
|
type Props = NumberFieldProps & {
|
||||||
@@ -21,20 +17,12 @@ type Props = NumberFieldProps & {
|
|||||||
*
|
*
|
||||||
* @see {@link https://refine.dev/docs/ui-frameworks/antd/components/fields/number} for more details.
|
* @see {@link https://refine.dev/docs/ui-frameworks/antd/components/fields/number} for more details.
|
||||||
*/
|
*/
|
||||||
export const NumberFieldUnit: React.FC<Props> = ({
|
export const NumberFieldUnit: React.FC<Props> = ({ value, locale, options, ...rest }) => {
|
||||||
value,
|
|
||||||
locale,
|
|
||||||
options,
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const number = Number(value);
|
const number = Number(value);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Text {...rest}>
|
<Text {...rest}>
|
||||||
{toLocaleStringSupportsOptions()
|
{toLocaleStringSupportsOptions() ? number.toLocaleString(locale, options) : number} {rest.unit}
|
||||||
? number.toLocaleString(locale, options)
|
|
||||||
: number}{" "}
|
|
||||||
{rest.unit}
|
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,18 +22,8 @@ const QRCodeScannerModal: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FloatButton
|
<FloatButton type="primary" onClick={() => setVisible(true)} icon={<CameraOutlined />} shape="circle" />
|
||||||
type="primary"
|
<Modal open={visible} onCancel={() => setVisible(false)} footer={null} title={t("scanner.title")}>
|
||||||
onClick={() => setVisible(true)}
|
|
||||||
icon={<CameraOutlined />}
|
|
||||||
shape="circle"
|
|
||||||
/>
|
|
||||||
<Modal
|
|
||||||
open={visible}
|
|
||||||
onCancel={() => setVisible(false)}
|
|
||||||
footer={null}
|
|
||||||
title={t("scanner.title")}
|
|
||||||
>
|
|
||||||
<Space direction="vertical" style={{ width: "100%" }}>
|
<Space direction="vertical" style={{ width: "100%" }}>
|
||||||
<p>{t("scanner.description")}</p>
|
<p>{t("scanner.description")}</p>
|
||||||
<QrScanner
|
<QrScanner
|
||||||
@@ -60,8 +50,7 @@ const QRCodeScannerModal: React.FC = () => {
|
|||||||
setLastError(t("scanner.error.notAllowed"));
|
setLastError(t("scanner.error.notAllowed"));
|
||||||
} else if (
|
} else if (
|
||||||
error.name === "InsecureContextError" ||
|
error.name === "InsecureContextError" ||
|
||||||
(location.protocol !== "https:" &&
|
(location.protocol !== "https:" && navigator.mediaDevices === undefined)
|
||||||
navigator.mediaDevices === undefined)
|
|
||||||
) {
|
) {
|
||||||
setLastError(t("scanner.error.insecureContext"));
|
setLastError(t("scanner.error.insecureContext"));
|
||||||
} else if (error.name === "StreamApiNotSupportedError") {
|
} else if (error.name === "StreamApiNotSupportedError") {
|
||||||
|
|||||||
@@ -20,12 +20,7 @@ interface ISpoolCollapsed extends ISpool {
|
|||||||
material?: string;
|
material?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SpoolSelectModal: React.FC<Props> = ({
|
const SpoolSelectModal: React.FC<Props> = ({ visible, description, onCancel, onContinue }) => {
|
||||||
visible,
|
|
||||||
description,
|
|
||||||
onCancel,
|
|
||||||
onContinue,
|
|
||||||
}) => {
|
|
||||||
const [selectedItems, setSelectedItems] = useState<number[]>([]);
|
const [selectedItems, setSelectedItems] = useState<number[]>([]);
|
||||||
const [showArchived, setShowArchived] = useState(false);
|
const [showArchived, setShowArchived] = useState(false);
|
||||||
const [messageApi, contextHolder] = message.useMessage();
|
const [messageApi, contextHolder] = message.useMessage();
|
||||||
@@ -65,8 +60,7 @@ const SpoolSelectModal: React.FC<Props> = ({
|
|||||||
if (element.filament.vendor && "name" in element.filament.vendor) {
|
if (element.filament.vendor && "name" in element.filament.vendor) {
|
||||||
filament_name = `${element.filament.vendor.name} - ${element.filament.name}`;
|
filament_name = `${element.filament.vendor.name} - ${element.filament.name}`;
|
||||||
} else {
|
} else {
|
||||||
filament_name =
|
filament_name = element.filament.name ?? element.filament.id.toString();
|
||||||
element.filament.name ?? element.filament.id.toString();
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...element,
|
...element,
|
||||||
@@ -91,9 +85,7 @@ const SpoolSelectModal: React.FC<Props> = ({
|
|||||||
// Function to add/remove all filtered items from selected items
|
// Function to add/remove all filtered items from selected items
|
||||||
const selectUnselectFiltered = (select: boolean) => {
|
const selectUnselectFiltered = (select: boolean) => {
|
||||||
setSelectedItems((prevSelected) => {
|
setSelectedItems((prevSelected) => {
|
||||||
const filtered = filteredDataSource
|
const filtered = filteredDataSource.map((spool) => spool.id).filter((spool) => !prevSelected.includes(spool));
|
||||||
.map((spool) => spool.id)
|
|
||||||
.filter((spool) => !prevSelected.includes(spool));
|
|
||||||
return select ? [...prevSelected, ...filtered] : filtered;
|
return select ? [...prevSelected, ...filtered] : filtered;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -101,16 +93,12 @@ const SpoolSelectModal: React.FC<Props> = ({
|
|||||||
// Handler for selecting/unselecting individual items
|
// Handler for selecting/unselecting individual items
|
||||||
const handleSelectItem = (item: number) => {
|
const handleSelectItem = (item: number) => {
|
||||||
setSelectedItems((prevSelected) =>
|
setSelectedItems((prevSelected) =>
|
||||||
prevSelected.includes(item)
|
prevSelected.includes(item) ? prevSelected.filter((selected) => selected !== item) : [...prevSelected, item]
|
||||||
? prevSelected.filter((selected) => selected !== item)
|
|
||||||
: [...prevSelected, item]
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// State for the select/unselect all checkbox
|
// State for the select/unselect all checkbox
|
||||||
const isAllFilteredSelected = filteredDataSource.every((spool) =>
|
const isAllFilteredSelected = filteredDataSource.every((spool) => selectedItems.includes(spool.id));
|
||||||
selectedItems.includes(spool.id)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
@@ -125,9 +113,7 @@ const SpoolSelectModal: React.FC<Props> = ({
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onContinue(
|
onContinue(dataSource.filter((spool) => selectedItems.includes(spool.id)));
|
||||||
dataSource.filter((spool) => selectedItems.includes(spool.id))
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
width={600}
|
width={600}
|
||||||
>
|
>
|
||||||
@@ -144,10 +130,7 @@ const SpoolSelectModal: React.FC<Props> = ({
|
|||||||
<Table.Column
|
<Table.Column
|
||||||
width={50}
|
width={50}
|
||||||
render={(_, item: ISpool) => (
|
render={(_, item: ISpool) => (
|
||||||
<Checkbox
|
<Checkbox checked={selectedItems.includes(item.id)} onChange={() => handleSelectItem(item.id)} />
|
||||||
checked={selectedItems.includes(item.id)}
|
|
||||||
onChange={() => handleSelectItem(item.id)}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{SortedColumn({
|
{SortedColumn({
|
||||||
@@ -197,9 +180,7 @@ const SpoolSelectModal: React.FC<Props> = ({
|
|||||||
// Remove archived spools from selected items
|
// Remove archived spools from selected items
|
||||||
setSelectedItems((prevSelected) =>
|
setSelectedItems((prevSelected) =>
|
||||||
prevSelected.filter(
|
prevSelected.filter(
|
||||||
(selected) =>
|
(selected) => dataSource.find((spool) => spool.id === selected)?.archived !== true
|
||||||
dataSource.find((spool) => spool.id === selected)
|
|
||||||
?.archived !== true
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,22 +7,14 @@ type ColorModeContextType = {
|
|||||||
setMode: (mode: string) => void;
|
setMode: (mode: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ColorModeContext = createContext<ColorModeContextType>(
|
export const ColorModeContext = createContext<ColorModeContextType>({} as ColorModeContextType);
|
||||||
{} as ColorModeContextType
|
|
||||||
);
|
|
||||||
|
|
||||||
export const ColorModeContextProvider: React.FC<PropsWithChildren> = ({
|
export const ColorModeContextProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
children,
|
|
||||||
}) => {
|
|
||||||
const colorModeFromLocalStorage = localStorage.getItem("colorMode");
|
const colorModeFromLocalStorage = localStorage.getItem("colorMode");
|
||||||
const isSystemPreferenceDark = window?.matchMedia(
|
const isSystemPreferenceDark = window?.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||||
"(prefers-color-scheme: dark)"
|
|
||||||
).matches;
|
|
||||||
|
|
||||||
const systemPreference = isSystemPreferenceDark ? "dark" : "light";
|
const systemPreference = isSystemPreferenceDark ? "dark" : "light";
|
||||||
const [mode, setMode] = useState(
|
const [mode, setMode] = useState(colorModeFromLocalStorage || systemPreference);
|
||||||
colorModeFromLocalStorage || systemPreference
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.localStorage.setItem("colorMode", mode);
|
window.localStorage.setItem("colorMode", mode);
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ interface CreateOrCloneProps {
|
|||||||
mode: "create" | "clone";
|
mode: "create" | "clone";
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FilamentCreate: React.FC<
|
export const FilamentCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps> = (props) => {
|
||||||
IResourceComponentsProps & CreateOrCloneProps
|
|
||||||
> = (props) => {
|
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
|
|
||||||
const { formProps, saveButtonProps, formLoading } = useForm<IFilament>();
|
const { formProps, saveButtonProps, formLoading } = useForm<IFilament>();
|
||||||
@@ -96,12 +94,7 @@ export const FilamentCreate: React.FC<
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber min={0} precision={2} formatter={numberFormatter} parser={numberParser} />
|
||||||
min={0}
|
|
||||||
precision={2}
|
|
||||||
formatter={numberFormatter}
|
|
||||||
parser={numberParser}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("filament.fields.density")}
|
label={t("filament.fields.density")}
|
||||||
@@ -112,13 +105,7 @@ export const FilamentCreate: React.FC<
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber min={0} addonAfter="g/cm³" precision={3} formatter={numberFormatter} parser={numberParser} />
|
||||||
min={0}
|
|
||||||
addonAfter="g/cm³"
|
|
||||||
precision={3}
|
|
||||||
formatter={numberFormatter}
|
|
||||||
parser={numberParser}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("filament.fields.diameter")}
|
label={t("filament.fields.diameter")}
|
||||||
@@ -129,13 +116,7 @@ export const FilamentCreate: React.FC<
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber min={0} addonAfter="mm" precision={2} formatter={numberFormatter} parser={numberParser} />
|
||||||
min={0}
|
|
||||||
addonAfter="mm"
|
|
||||||
precision={2}
|
|
||||||
formatter={numberFormatter}
|
|
||||||
parser={numberParser}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("filament.fields.weight")}
|
label={t("filament.fields.weight")}
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { IResourceComponentsProps, useTranslate } from "@refinedev/core";
|
import { IResourceComponentsProps, useTranslate } from "@refinedev/core";
|
||||||
import { Edit, useForm, useSelect } from "@refinedev/antd";
|
import { Edit, useForm, useSelect } from "@refinedev/antd";
|
||||||
import {
|
import { Form, Input, DatePicker, Select, InputNumber, ColorPicker } from "antd";
|
||||||
Form,
|
|
||||||
Input,
|
|
||||||
DatePicker,
|
|
||||||
Select,
|
|
||||||
InputNumber,
|
|
||||||
ColorPicker,
|
|
||||||
} from "antd";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import TextArea from "antd/es/input/TextArea";
|
import TextArea from "antd/es/input/TextArea";
|
||||||
import { numberFormatter, numberParser } from "../../utils/parsing";
|
import { numberFormatter, numberParser } from "../../utils/parsing";
|
||||||
@@ -26,8 +19,7 @@ export const FilamentEdit: React.FC<IResourceComponentsProps> = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (formProps.initialValues) {
|
if (formProps.initialValues) {
|
||||||
formProps.initialValues["vendor_id"] =
|
formProps.initialValues["vendor_id"] = formProps.initialValues["vendor"]?.id;
|
||||||
formProps.initialValues["vendor"]?.id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -124,12 +116,7 @@ export const FilamentEdit: React.FC<IResourceComponentsProps> = () => {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber min={0} precision={2} formatter={numberFormatter} parser={numberParser} />
|
||||||
min={0}
|
|
||||||
precision={2}
|
|
||||||
formatter={numberFormatter}
|
|
||||||
parser={numberParser}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("filament.fields.density")}
|
label={t("filament.fields.density")}
|
||||||
@@ -140,13 +127,7 @@ export const FilamentEdit: React.FC<IResourceComponentsProps> = () => {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber min={0} addonAfter="g/cm³" precision={3} formatter={numberFormatter} parser={numberParser} />
|
||||||
min={0}
|
|
||||||
addonAfter="g/cm³"
|
|
||||||
precision={3}
|
|
||||||
formatter={numberFormatter}
|
|
||||||
parser={numberParser}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("filament.fields.diameter")}
|
label={t("filament.fields.diameter")}
|
||||||
@@ -157,13 +138,7 @@ export const FilamentEdit: React.FC<IResourceComponentsProps> = () => {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber min={0} addonAfter="mm" precision={2} formatter={numberFormatter} parser={numberParser} />
|
||||||
min={0}
|
|
||||||
addonAfter="mm"
|
|
||||||
precision={2}
|
|
||||||
formatter={numberFormatter}
|
|
||||||
parser={numberParser}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("filament.fields.weight")}
|
label={t("filament.fields.weight")}
|
||||||
|
|||||||
@@ -1,16 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import { IResourceComponentsProps, BaseRecord, useTranslate } from "@refinedev/core";
|
||||||
IResourceComponentsProps,
|
import { useTable, List, EditButton, ShowButton, CloneButton } from "@refinedev/antd";
|
||||||
BaseRecord,
|
|
||||||
useTranslate,
|
|
||||||
} from "@refinedev/core";
|
|
||||||
import {
|
|
||||||
useTable,
|
|
||||||
List,
|
|
||||||
EditButton,
|
|
||||||
ShowButton,
|
|
||||||
CloneButton,
|
|
||||||
} from "@refinedev/antd";
|
|
||||||
import { Table, Space, Button, Dropdown } from "antd";
|
import { Table, Space, Button, Dropdown } from "antd";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
@@ -18,18 +8,8 @@ import { IFilament } from "./model";
|
|||||||
import { genericSorter, typeSorters } from "../../utils/sorting";
|
import { genericSorter, typeSorters } from "../../utils/sorting";
|
||||||
import { genericFilterer, typeFilters } from "../../utils/filtering";
|
import { genericFilterer, typeFilters } from "../../utils/filtering";
|
||||||
import { EditOutlined, FilterOutlined } from "@ant-design/icons";
|
import { EditOutlined, FilterOutlined } from "@ant-design/icons";
|
||||||
import {
|
import { TableState, useInitialTableState, useStoreInitialState } from "../../utils/saveload";
|
||||||
TableState,
|
import { DateColumn, FilteredColumn, NumberColumn, SortedColumn, SpoolIconColumn } from "../../components/column";
|
||||||
useInitialTableState,
|
|
||||||
useStoreInitialState,
|
|
||||||
} from "../../utils/saveload";
|
|
||||||
import {
|
|
||||||
DateColumn,
|
|
||||||
FilteredColumn,
|
|
||||||
NumberColumn,
|
|
||||||
SortedColumn,
|
|
||||||
SpoolIconColumn,
|
|
||||||
} from "../../components/column";
|
|
||||||
|
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
|
|
||||||
@@ -44,32 +24,23 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
const initialState = useInitialTableState("filamentList");
|
const initialState = useInitialTableState("filamentList");
|
||||||
|
|
||||||
// Fetch data from the API
|
// Fetch data from the API
|
||||||
const {
|
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent, setPageSize } =
|
||||||
tableProps,
|
useTable<IFilament>({
|
||||||
sorters,
|
syncWithLocation: false,
|
||||||
setSorters,
|
pagination: {
|
||||||
filters,
|
mode: "off", // Perform pagination in antd's Table instead. Otherwise client-side sorting/filtering doesn't work.
|
||||||
setFilters,
|
current: initialState.pagination.current,
|
||||||
current,
|
pageSize: initialState.pagination.pageSize,
|
||||||
pageSize,
|
},
|
||||||
setCurrent,
|
sorters: {
|
||||||
setPageSize,
|
mode: "off", // Disable server-side sorting
|
||||||
} = useTable<IFilament>({
|
initial: initialState.sorters,
|
||||||
syncWithLocation: false,
|
},
|
||||||
pagination: {
|
filters: {
|
||||||
mode: "off", // Perform pagination in antd's Table instead. Otherwise client-side sorting/filtering doesn't work.
|
mode: "off", // Disable server-side filtering
|
||||||
current: initialState.pagination.current,
|
initial: initialState.filters,
|
||||||
pageSize: initialState.pagination.pageSize,
|
},
|
||||||
},
|
});
|
||||||
sorters: {
|
|
||||||
mode: "off", // Disable server-side sorting
|
|
||||||
initial: initialState.sorters,
|
|
||||||
},
|
|
||||||
filters: {
|
|
||||||
mode: "off", // Disable server-side filtering
|
|
||||||
initial: initialState.filters,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create state for the columns to show
|
// Create state for the columns to show
|
||||||
const allColumns: (keyof IFilamentCollapsed & string)[] = [
|
const allColumns: (keyof IFilamentCollapsed & string)[] = [
|
||||||
@@ -89,15 +60,10 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
"comment",
|
"comment",
|
||||||
];
|
];
|
||||||
const defaultColumns = allColumns.filter(
|
const defaultColumns = allColumns.filter(
|
||||||
(column_id) =>
|
(column_id) => ["registered", "density", "diameter", "spool_weight"].indexOf(column_id) === -1
|
||||||
["registered", "density", "diameter", "spool_weight"].indexOf(
|
|
||||||
column_id
|
|
||||||
) === -1
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const [showColumns, setShowColumns] = React.useState<string[]>(
|
const [showColumns, setShowColumns] = React.useState<string[]>(initialState.showColumns ?? defaultColumns);
|
||||||
initialState.showColumns ?? defaultColumns
|
|
||||||
);
|
|
||||||
|
|
||||||
// Type the sorters and filters
|
// Type the sorters and filters
|
||||||
const typedSorters = typeSorters<IFilamentCollapsed>(sorters);
|
const typedSorters = typeSorters<IFilamentCollapsed>(sorters);
|
||||||
@@ -290,24 +256,9 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
title={t("table.actions")}
|
title={t("table.actions")}
|
||||||
render={(_, record: BaseRecord) => (
|
render={(_, record: BaseRecord) => (
|
||||||
<Space>
|
<Space>
|
||||||
<EditButton
|
<EditButton hideText title={t("buttons.edit")} size="small" recordItemId={record.id} />
|
||||||
hideText
|
<ShowButton hideText title={t("buttons.show")} size="small" recordItemId={record.id} />
|
||||||
title={t("buttons.edit")}
|
<CloneButton hideText title={t("buttons.clone")} size="small" recordItemId={record.id} />
|
||||||
size="small"
|
|
||||||
recordItemId={record.id}
|
|
||||||
/>
|
|
||||||
<ShowButton
|
|
||||||
hideText
|
|
||||||
title={t("buttons.show")}
|
|
||||||
size="small"
|
|
||||||
recordItemId={record.id}
|
|
||||||
/>
|
|
||||||
<CloneButton
|
|
||||||
hideText
|
|
||||||
title={t("buttons.clone")}
|
|
||||||
size="small"
|
|
||||||
recordItemId={record.id}
|
|
||||||
/>
|
|
||||||
</Space>
|
</Space>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import { IResourceComponentsProps, useShow, useTranslate } from "@refinedev/core";
|
||||||
IResourceComponentsProps,
|
|
||||||
useShow,
|
|
||||||
useTranslate,
|
|
||||||
} from "@refinedev/core";
|
|
||||||
import { Show, NumberField, DateField, TextField } from "@refinedev/antd";
|
import { Show, NumberField, DateField, TextField } from "@refinedev/antd";
|
||||||
import { Typography } from "antd";
|
import { Typography } from "antd";
|
||||||
import { NumberFieldUnit } from "../../components/numberField";
|
import { NumberFieldUnit } from "../../components/numberField";
|
||||||
@@ -79,10 +75,7 @@ export const FilamentShow: React.FC<IResourceComponentsProps> = () => {
|
|||||||
{!record?.settings_extruder_temp ? (
|
{!record?.settings_extruder_temp ? (
|
||||||
<TextField value="Not Set" />
|
<TextField value="Not Set" />
|
||||||
) : (
|
) : (
|
||||||
<NumberFieldUnit
|
<NumberFieldUnit value={record?.settings_extruder_temp ?? ""} unit="°C" />
|
||||||
value={record?.settings_extruder_temp ?? ""}
|
|
||||||
unit="°C"
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<Title level={5}>{t("filament.fields.settings_bed_temp")}</Title>
|
<Title level={5}>{t("filament.fields.settings_bed_temp")}</Title>
|
||||||
{!record?.settings_bed_temp ? (
|
{!record?.settings_bed_temp ? (
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ interface CreateOrCloneProps {
|
|||||||
mode: "create" | "clone";
|
mode: "create" | "clone";
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SpoolCreate: React.FC<
|
export const SpoolCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps> = (props) => {
|
||||||
IResourceComponentsProps & CreateOrCloneProps
|
|
||||||
> = (props) => {
|
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
|
|
||||||
const { formProps, saveButtonProps, formLoading } = useForm<ISpool>();
|
const { formProps, saveButtonProps, formLoading } = useForm<ISpool>();
|
||||||
@@ -55,11 +53,7 @@ export const SpoolCreate: React.FC<
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Create
|
<Create
|
||||||
title={
|
title={props.mode === "create" ? t("spool.titles.create") : t("spool.titles.clone")}
|
||||||
props.mode === "create"
|
|
||||||
? t("spool.titles.create")
|
|
||||||
: t("spool.titles.clone")
|
|
||||||
}
|
|
||||||
saveButtonProps={saveButtonProps}
|
saveButtonProps={saveButtonProps}
|
||||||
isLoading={formLoading}
|
isLoading={formLoading}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -38,8 +38,7 @@ export const SpoolEdit: React.FC<IResourceComponentsProps> = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (formProps.initialValues) {
|
if (formProps.initialValues) {
|
||||||
formProps.initialValues["filament_id"] =
|
formProps.initialValues["filament_id"] = formProps.initialValues["filament"].id;
|
||||||
formProps.initialValues["filament"].id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,41 +1,15 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import { IResourceComponentsProps, useInvalidate, useTranslate } from "@refinedev/core";
|
||||||
IResourceComponentsProps,
|
import { useTable, List, EditButton, ShowButton, CloneButton } from "@refinedev/antd";
|
||||||
useInvalidate,
|
|
||||||
useTranslate,
|
|
||||||
} from "@refinedev/core";
|
|
||||||
import {
|
|
||||||
useTable,
|
|
||||||
List,
|
|
||||||
EditButton,
|
|
||||||
ShowButton,
|
|
||||||
CloneButton,
|
|
||||||
} from "@refinedev/antd";
|
|
||||||
import { Table, Space, Button, Dropdown, Modal } from "antd";
|
import { Table, Space, Button, Dropdown, Modal } from "antd";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
import { genericSorter, typeSorters } from "../../utils/sorting";
|
import { genericSorter, typeSorters } from "../../utils/sorting";
|
||||||
import { genericFilterer, typeFilters } from "../../utils/filtering";
|
import { genericFilterer, typeFilters } from "../../utils/filtering";
|
||||||
import { ISpool } from "./model";
|
import { ISpool } from "./model";
|
||||||
import {
|
import { TableState, useInitialTableState, useSavedState, useStoreInitialState } from "../../utils/saveload";
|
||||||
TableState,
|
import { EditOutlined, FilterOutlined, InboxOutlined, ToTopOutlined } from "@ant-design/icons";
|
||||||
useInitialTableState,
|
import { DateColumn, FilteredColumn, NumberColumn, SortedColumn, SpoolIconColumn } from "../../components/column";
|
||||||
useSavedState,
|
|
||||||
useStoreInitialState,
|
|
||||||
} from "../../utils/saveload";
|
|
||||||
import {
|
|
||||||
EditOutlined,
|
|
||||||
FilterOutlined,
|
|
||||||
InboxOutlined,
|
|
||||||
ToTopOutlined,
|
|
||||||
} from "@ant-design/icons";
|
|
||||||
import {
|
|
||||||
DateColumn,
|
|
||||||
FilteredColumn,
|
|
||||||
NumberColumn,
|
|
||||||
SortedColumn,
|
|
||||||
SpoolIconColumn,
|
|
||||||
} from "../../components/column";
|
|
||||||
import { setSpoolArchived } from "./functions";
|
import { setSpoolArchived } from "./functions";
|
||||||
import SelectAndPrint from "../../components/selectAndPrintDialog";
|
import SelectAndPrint from "../../components/selectAndPrintDialog";
|
||||||
|
|
||||||
@@ -56,43 +30,31 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
const initialState = useInitialTableState("spoolList");
|
const initialState = useInitialTableState("spoolList");
|
||||||
|
|
||||||
// State for the switch to show archived spools
|
// State for the switch to show archived spools
|
||||||
const [showArchived, setShowArchived] = useSavedState(
|
const [showArchived, setShowArchived] = useSavedState("spoolList-showArchived", false);
|
||||||
"spoolList-showArchived",
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
// Fetch data from the API
|
// Fetch data from the API
|
||||||
const {
|
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent, setPageSize } =
|
||||||
tableProps,
|
useTable<ISpool>({
|
||||||
sorters,
|
meta: {
|
||||||
setSorters,
|
queryParams: {
|
||||||
filters,
|
["allow_archived"]: showArchived,
|
||||||
setFilters,
|
},
|
||||||
current,
|
|
||||||
pageSize,
|
|
||||||
setCurrent,
|
|
||||||
setPageSize,
|
|
||||||
} = useTable<ISpool>({
|
|
||||||
meta: {
|
|
||||||
queryParams: {
|
|
||||||
["allow_archived"]: showArchived,
|
|
||||||
},
|
},
|
||||||
},
|
syncWithLocation: false,
|
||||||
syncWithLocation: false,
|
pagination: {
|
||||||
pagination: {
|
mode: "off", // Perform pagination in antd's Table instead. Otherwise client-side sorting/filtering doesn't work.
|
||||||
mode: "off", // Perform pagination in antd's Table instead. Otherwise client-side sorting/filtering doesn't work.
|
current: initialState.pagination.current,
|
||||||
current: initialState.pagination.current,
|
pageSize: initialState.pagination.pageSize,
|
||||||
pageSize: initialState.pagination.pageSize,
|
},
|
||||||
},
|
sorters: {
|
||||||
sorters: {
|
mode: "off", // Disable server-side sorting
|
||||||
mode: "off", // Disable server-side sorting
|
initial: initialState.sorters,
|
||||||
initial: initialState.sorters,
|
},
|
||||||
},
|
filters: {
|
||||||
filters: {
|
mode: "off", // Disable server-side filtering
|
||||||
mode: "off", // Disable server-side filtering
|
initial: initialState.filters,
|
||||||
initial: initialState.filters,
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Create state for the columns to show
|
// Create state for the columns to show
|
||||||
const allColumns: (keyof ISpoolCollapsed & string)[] = [
|
const allColumns: (keyof ISpoolCollapsed & string)[] = [
|
||||||
@@ -111,14 +73,9 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
"comment",
|
"comment",
|
||||||
];
|
];
|
||||||
const defaultColumns = allColumns.filter(
|
const defaultColumns = allColumns.filter(
|
||||||
(column_id) =>
|
(column_id) => ["registered", "used_length", "remaining_length", "lot_nr"].indexOf(column_id) === -1
|
||||||
["registered", "used_length", "remaining_length", "lot_nr"].indexOf(
|
|
||||||
column_id
|
|
||||||
) === -1
|
|
||||||
);
|
|
||||||
const [showColumns, setShowColumns] = React.useState<string[]>(
|
|
||||||
initialState.showColumns ?? defaultColumns
|
|
||||||
);
|
);
|
||||||
|
const [showColumns, setShowColumns] = React.useState<string[]>(initialState.showColumns ?? defaultColumns);
|
||||||
|
|
||||||
// Type the sorters and filters
|
// Type the sorters and filters
|
||||||
const typedSorters = typeSorters<ISpoolCollapsed>(sorters);
|
const typedSorters = typeSorters<ISpoolCollapsed>(sorters);
|
||||||
@@ -141,8 +98,7 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
if (element.filament.vendor && "name" in element.filament.vendor) {
|
if (element.filament.vendor && "name" in element.filament.vendor) {
|
||||||
filament_name = `${element.filament.vendor.name} - ${element.filament.name}`;
|
filament_name = `${element.filament.vendor.name} - ${element.filament.name}`;
|
||||||
} else {
|
} else {
|
||||||
filament_name =
|
filament_name = element.filament.name ?? element.filament.id.toString();
|
||||||
element.filament.name ?? element.filament.id.toString();
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...element,
|
...element,
|
||||||
@@ -200,9 +156,7 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
setShowArchived(!showArchived);
|
setShowArchived(!showArchived);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{showArchived
|
{showArchived ? t("buttons.hideArchived") : t("buttons.showArchived")}
|
||||||
? t("buttons.hideArchived")
|
|
||||||
: t("buttons.showArchived")}
|
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -361,24 +315,9 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
title={t("table.actions")}
|
title={t("table.actions")}
|
||||||
render={(_, record: ISpoolCollapsed) => (
|
render={(_, record: ISpoolCollapsed) => (
|
||||||
<Space>
|
<Space>
|
||||||
<EditButton
|
<EditButton hideText title={t("buttons.edit")} size="small" recordItemId={record.id} />
|
||||||
hideText
|
<ShowButton hideText title={t("buttons.show")} size="small" recordItemId={record.id} />
|
||||||
title={t("buttons.edit")}
|
<CloneButton hideText title={t("buttons.clone")} size="small" recordItemId={record.id} />
|
||||||
size="small"
|
|
||||||
recordItemId={record.id}
|
|
||||||
/>
|
|
||||||
<ShowButton
|
|
||||||
hideText
|
|
||||||
title={t("buttons.show")}
|
|
||||||
size="small"
|
|
||||||
recordItemId={record.id}
|
|
||||||
/>
|
|
||||||
<CloneButton
|
|
||||||
hideText
|
|
||||||
title={t("buttons.clone")}
|
|
||||||
size="small"
|
|
||||||
recordItemId={record.id}
|
|
||||||
/>
|
|
||||||
{record.archived ? (
|
{record.archived ? (
|
||||||
<Button
|
<Button
|
||||||
icon={<ToTopOutlined />}
|
icon={<ToTopOutlined />}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import { IResourceComponentsProps, useShow, useTranslate } from "@refinedev/core";
|
||||||
IResourceComponentsProps,
|
|
||||||
useShow,
|
|
||||||
useTranslate,
|
|
||||||
} from "@refinedev/core";
|
|
||||||
import { Show, NumberField, DateField, TextField } from "@refinedev/antd";
|
import { Show, NumberField, DateField, TextField } from "@refinedev/antd";
|
||||||
import { Typography } from "antd";
|
import { Typography } from "antd";
|
||||||
import { NumberFieldUnit } from "../../components/numberField";
|
import { NumberFieldUnit } from "../../components/numberField";
|
||||||
|
|||||||
10
client/src/pages/vendors/create.tsx
vendored
10
client/src/pages/vendors/create.tsx
vendored
@@ -9,20 +9,14 @@ interface CreateOrCloneProps {
|
|||||||
mode: "create" | "clone";
|
mode: "create" | "clone";
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VendorCreate: React.FC<
|
export const VendorCreate: React.FC<IResourceComponentsProps & CreateOrCloneProps> = (props) => {
|
||||||
IResourceComponentsProps & CreateOrCloneProps
|
|
||||||
> = (props) => {
|
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
|
|
||||||
const { formProps, saveButtonProps, formLoading } = useForm<IVendor>();
|
const { formProps, saveButtonProps, formLoading } = useForm<IVendor>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Create
|
<Create
|
||||||
title={
|
title={props.mode === "create" ? t("vendor.titles.create") : t("vendor.titles.clone")}
|
||||||
props.mode === "create"
|
|
||||||
? t("vendor.titles.create")
|
|
||||||
: t("vendor.titles.clone")
|
|
||||||
}
|
|
||||||
isLoading={formLoading}
|
isLoading={formLoading}
|
||||||
saveButtonProps={saveButtonProps}
|
saveButtonProps={saveButtonProps}
|
||||||
>
|
>
|
||||||
|
|||||||
95
client/src/pages/vendors/list.tsx
vendored
95
client/src/pages/vendors/list.tsx
vendored
@@ -1,27 +1,13 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import { IResourceComponentsProps, BaseRecord, useTranslate } from "@refinedev/core";
|
||||||
IResourceComponentsProps,
|
import { useTable, List, EditButton, ShowButton, CloneButton } from "@refinedev/antd";
|
||||||
BaseRecord,
|
|
||||||
useTranslate,
|
|
||||||
} from "@refinedev/core";
|
|
||||||
import {
|
|
||||||
useTable,
|
|
||||||
List,
|
|
||||||
EditButton,
|
|
||||||
ShowButton,
|
|
||||||
CloneButton,
|
|
||||||
} from "@refinedev/antd";
|
|
||||||
import { Table, Space, Button, Dropdown } from "antd";
|
import { Table, Space, Button, Dropdown } from "antd";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
import { genericSorter, typeSorters } from "../../utils/sorting";
|
import { genericSorter, typeSorters } from "../../utils/sorting";
|
||||||
import { genericFilterer, typeFilters } from "../../utils/filtering";
|
import { genericFilterer, typeFilters } from "../../utils/filtering";
|
||||||
import { IVendor } from "./model";
|
import { IVendor } from "./model";
|
||||||
import {
|
import { TableState, useInitialTableState, useStoreInitialState } from "../../utils/saveload";
|
||||||
TableState,
|
|
||||||
useInitialTableState,
|
|
||||||
useStoreInitialState,
|
|
||||||
} from "../../utils/saveload";
|
|
||||||
import { EditOutlined, FilterOutlined } from "@ant-design/icons";
|
import { EditOutlined, FilterOutlined } from "@ant-design/icons";
|
||||||
import { DateColumn, SortedColumn } from "../../components/column";
|
import { DateColumn, SortedColumn } from "../../components/column";
|
||||||
|
|
||||||
@@ -34,43 +20,27 @@ export const VendorList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
const initialState = useInitialTableState("vendorList");
|
const initialState = useInitialTableState("vendorList");
|
||||||
|
|
||||||
// Fetch data from the API
|
// Fetch data from the API
|
||||||
const {
|
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent, setPageSize } =
|
||||||
tableProps,
|
useTable<IVendor>({
|
||||||
sorters,
|
syncWithLocation: false,
|
||||||
setSorters,
|
pagination: {
|
||||||
filters,
|
mode: "off", // Perform pagination in antd's Table instead. Otherwise client-side sorting/filtering doesn't work.
|
||||||
setFilters,
|
current: initialState.pagination.current,
|
||||||
current,
|
pageSize: initialState.pagination.pageSize,
|
||||||
pageSize,
|
},
|
||||||
setCurrent,
|
sorters: {
|
||||||
setPageSize,
|
mode: "off", // Disable server-side sorting
|
||||||
} = useTable<IVendor>({
|
initial: initialState.sorters,
|
||||||
syncWithLocation: false,
|
},
|
||||||
pagination: {
|
filters: {
|
||||||
mode: "off", // Perform pagination in antd's Table instead. Otherwise client-side sorting/filtering doesn't work.
|
mode: "off", // Disable server-side filtering
|
||||||
current: initialState.pagination.current,
|
initial: initialState.filters,
|
||||||
pageSize: initialState.pagination.pageSize,
|
},
|
||||||
},
|
});
|
||||||
sorters: {
|
|
||||||
mode: "off", // Disable server-side sorting
|
|
||||||
initial: initialState.sorters,
|
|
||||||
},
|
|
||||||
filters: {
|
|
||||||
mode: "off", // Disable server-side filtering
|
|
||||||
initial: initialState.filters,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create state for the columns to show
|
// Create state for the columns to show
|
||||||
const allColumns: (keyof IVendor & string)[] = [
|
const allColumns: (keyof IVendor & string)[] = ["id", "name", "registered", "comment"];
|
||||||
"id",
|
const [showColumns, setShowColumns] = React.useState<string[]>(initialState.showColumns ?? allColumns);
|
||||||
"name",
|
|
||||||
"registered",
|
|
||||||
"comment",
|
|
||||||
];
|
|
||||||
const [showColumns, setShowColumns] = React.useState<string[]>(
|
|
||||||
initialState.showColumns ?? allColumns
|
|
||||||
);
|
|
||||||
|
|
||||||
// Type the sorters and filters
|
// Type the sorters and filters
|
||||||
const typedSorters = typeSorters<IVendor>(sorters);
|
const typedSorters = typeSorters<IVendor>(sorters);
|
||||||
@@ -181,24 +151,9 @@ export const VendorList: React.FC<IResourceComponentsProps> = () => {
|
|||||||
title={t("table.actions")}
|
title={t("table.actions")}
|
||||||
render={(_, record: BaseRecord) => (
|
render={(_, record: BaseRecord) => (
|
||||||
<Space>
|
<Space>
|
||||||
<EditButton
|
<EditButton hideText title={t("buttons.edit")} size="small" recordItemId={record.id} />
|
||||||
hideText
|
<ShowButton hideText title={t("buttons.show")} size="small" recordItemId={record.id} />
|
||||||
title={t("buttons.edit")}
|
<CloneButton hideText title={t("buttons.clone")} size="small" recordItemId={record.id} />
|
||||||
size="small"
|
|
||||||
recordItemId={record.id}
|
|
||||||
/>
|
|
||||||
<ShowButton
|
|
||||||
hideText
|
|
||||||
title={t("buttons.show")}
|
|
||||||
size="small"
|
|
||||||
recordItemId={record.id}
|
|
||||||
/>
|
|
||||||
<CloneButton
|
|
||||||
hideText
|
|
||||||
title={t("buttons.clone")}
|
|
||||||
size="small"
|
|
||||||
recordItemId={record.id}
|
|
||||||
/>
|
|
||||||
</Space>
|
</Space>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
6
client/src/pages/vendors/show.tsx
vendored
6
client/src/pages/vendors/show.tsx
vendored
@@ -1,9 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import { IResourceComponentsProps, useShow, useTranslate } from "@refinedev/core";
|
||||||
IResourceComponentsProps,
|
|
||||||
useShow,
|
|
||||||
useTranslate,
|
|
||||||
} from "@refinedev/core";
|
|
||||||
import { Show, NumberField, DateField, TextField } from "@refinedev/antd";
|
import { Show, NumberField, DateField, TextField } from "@refinedev/antd";
|
||||||
import { Typography } from "antd";
|
import { Typography } from "antd";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|||||||
Reference in New Issue
Block a user