Updated client packages

This commit is contained in:
Donkie
2026-01-06 01:40:59 +01:00
parent 848f5dcc94
commit b627e151a8
27 changed files with 2603 additions and 1840 deletions

View File

@@ -7,9 +7,6 @@
<meta name="description" content="Spoolman - Keep track of your inventory of 3D-printer filament spools." /> <meta name="description" content="Spoolman - Keep track of your inventory of 3D-printer filament spools." />
<meta name="robots" content="noindex,nofollow" /> <meta name="robots" content="noindex,nofollow" />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="icon" href="/favicon.ico" sizes="48x48" />
<link rel="icon" href="/favicon.svg" sizes="any" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon-180x180.png" />
<script type="text/javascript" src="./config.js"></script> <script type="text/javascript" src="./config.js"></script>
<title>Spoolman</title> <title>Spoolman</title>
</head> </head>

4073
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,53 +7,51 @@
"private": true, "private": true,
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@ant-design/icons": "^5.6.1",
"@ant-design/v5-patch-for-react-19": "^1.0.3", "@ant-design/v5-patch-for-react-19": "^1.0.3",
"@loadable/component": "^5.16.7", "@loadable/component": "^5.16.7",
"@refinedev/antd": "^5.46.1", "@refinedev/antd": "^6.0.3",
"@refinedev/core": "^4.57.9", "@refinedev/core": "^5.0.7",
"@refinedev/kbar": "^1.3.16", "@refinedev/kbar": "^2.0.1",
"@refinedev/react-router": "^1.0.1", "@refinedev/react-router": "^2.0.3",
"@refinedev/simple-rest": "^5.0.10", "@refinedev/simple-rest": "^6.0.1",
"@tanstack/react-query": "^4.36.1", "@tanstack/react-query": "^5.90.16",
"@tanstack/react-query-devtools": "^4.36.1", "@tanstack/react-query-devtools": "^5.91.2",
"@types/loadable__component": "^5.13.9", "@types/loadable__component": "^5.13.10",
"@types/lodash": "^4.17.17", "@types/lodash": "^4.17.21",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@yudiel/react-qr-scanner": "^1.2.10", "@yudiel/react-qr-scanner": "^1.2.10",
"antd": "^5.25.4", "axios": "^1.13.2",
"axios": "^1.12.2",
"html-to-image": "^1.11.13", "html-to-image": "^1.11.13",
"i18next": "^25.2.1", "i18next": "^25.7.3",
"i18next-browser-languagedetector": "^8.1.0", "i18next-browser-languagedetector": "^8.2.0",
"i18next-http-backend": "^3.0.2", "i18next-http-backend": "^3.0.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"react": "^19.1.0", "react": "^19.2.3",
"react-dnd": "^16.0.1", "react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1", "react-dnd-html5-backend": "^16.0.1",
"react-dom": "^19.1.0", "react-dom": "^19.2.3",
"react-i18next": "^15.5.2", "react-i18next": "^16.5.1",
"react-router": "^7.6.2", "react-router": "^7.11.0",
"react-to-print": "^3.1.0", "react-to-print": "^3.2.0",
"uuid": "^11.1.0", "uuid": "^13.0.0",
"vite-plugin-svgr": "^4.3.0", "vite-plugin-svgr": "^4.5.0",
"zustand": "^5.0.5" "zustand": "^5.0.9"
}, },
"devDependencies": { "devDependencies": {
"@refinedev/cli": "^2.16.46", "@refinedev/cli": "^2.16.50",
"@simbathesailor/use-what-changed": "^2.0.0", "@simbathesailor/use-what-changed": "^2.0.0",
"@types/node": "^22.15.30", "@types/node": "^25.0.3",
"@types/react": "^19.1.6", "@types/react": "^19.2.7",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^19.2.3",
"@typescript-eslint/eslint-plugin": "^8.33.1", "@typescript-eslint/eslint-plugin": "^8.52.0",
"@typescript-eslint/parser": "^8.33.1", "@typescript-eslint/parser": "^8.52.0",
"@vitejs/plugin-react": "^4.5.1", "@vitejs/plugin-react": "^5.1.2",
"eslint": "^9.28.0", "eslint": "^9.39.2",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-react-refresh": "^0.4.26",
"typescript": "^5.8.3", "typescript": "^5.9.3",
"vite": "^6.4.1", "vite": "^7.3.0",
"vite-plugin-mkcert": "^1.17.8", "vite-plugin-mkcert": "^1.17.9",
"vite-plugin-pwa": "^1.2.0" "vite-plugin-pwa": "^1.2.0"
}, },
"scripts": { "scripts": {

View File

@@ -90,14 +90,7 @@ function App() {
<BrowserRouter basename={getBasePath() + "/"}> <BrowserRouter basename={getBasePath() + "/"}>
<RefineKbarProvider> <RefineKbarProvider>
<ColorModeContextProvider> <ColorModeContextProvider>
<ConfigProvider <ConfigProvider locale={antdLocale}>
locale={antdLocale}
theme={{
token: {
colorPrimary: "#dc7734",
},
}}
>
<Refine <Refine
dataProvider={dataProvider(getAPIURL())} dataProvider={dataProvider(getAPIURL())}
notificationProvider={SpoolmanNotificationProvider} notificationProvider={SpoolmanNotificationProvider}

View File

@@ -116,8 +116,8 @@ function Column<Obj extends Entity>(
if (open && props.onFilterDropdownOpen) { if (open && props.onFilterDropdownOpen) {
props.onFilterDropdownOpen(); props.onFilterDropdownOpen();
} }
} },
} };
if (props.dataId) { if (props.dataId) {
columnProps.key = props.dataId; columnProps.key = props.dataId;
} }
@@ -186,7 +186,7 @@ export function RichColumn<Obj extends Entity>(
} }
interface FilteredQueryColumnProps<Obj extends Entity> extends BaseColumnProps<Obj> { interface FilteredQueryColumnProps<Obj extends Entity> extends BaseColumnProps<Obj> {
filterValueQuery: UseQueryResult<string[] | ColumnFilterItem[]>; filterValueQuery: UseQueryResult<string[] | ColumnFilterItem[], unknown>;
allowMultipleFilters?: boolean; allowMultipleFilters?: boolean;
} }

View File

@@ -19,7 +19,7 @@ const dataProvider = (
if (pagination && pagination.mode == "server") { if (pagination && pagination.mode == "server") {
const pageSize = pagination.pageSize ?? 10; const pageSize = pagination.pageSize ?? 10;
const offset = ((pagination.current ?? 1) - 1) * pageSize; const offset = ((pagination.currentPage ?? 1) - 1) * pageSize;
queryParams["limit"] = pageSize; queryParams["limit"] = pageSize;
queryParams["offset"] = offset; queryParams["offset"] = offset;
} }

View File

@@ -1,5 +1,5 @@
import { DownOutlined } from "@ant-design/icons"; import { DownOutlined } from "@ant-design/icons";
import type { RefineThemedLayoutV2HeaderProps } from "@refinedev/antd"; import type { RefineThemedLayoutHeaderProps } from "@refinedev/antd";
import { useGetLocale, useSetLocale } from "@refinedev/core"; import { useGetLocale, useSetLocale } from "@refinedev/core";
import { Layout as AntdLayout, Button, Dropdown, MenuProps, Space, Switch, theme } from "antd"; import { Layout as AntdLayout, Button, Dropdown, MenuProps, Space, Switch, theme } from "antd";
import React, { useContext } from "react"; import React, { useContext } from "react";
@@ -10,7 +10,7 @@ import QRCodeScannerModal from "../qrCodeScanner";
const { useToken } = theme; const { useToken } = theme;
export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({ sticky }) => { export const Header: React.FC<RefineThemedLayoutHeaderProps> = ({ sticky }) => {
const { token } = useToken(); const { token } = useToken();
const locale = useGetLocale(); const locale = useGetLocale();
const changeLanguage = useSetLocale(); const changeLanguage = useSetLocale();

View File

@@ -1,4 +1,4 @@
import { ThemedLayoutV2, ThemedSiderV2, ThemedTitleV2 } from "@refinedev/antd"; import { ThemedLayout, ThemedSider, ThemedTitle } from "@refinedev/antd";
import { useTranslate } from "@refinedev/core"; import { useTranslate } from "@refinedev/core";
import { Button } from "antd"; import { Button } from "antd";
import { Footer } from "antd/es/layout/layout"; import { Footer } from "antd/es/layout/layout";
@@ -51,16 +51,16 @@ interface SpoolmanLayoutProps {
} }
export const SpoolmanLayout: React.FC<SpoolmanLayoutProps> = ({ children }) => ( export const SpoolmanLayout: React.FC<SpoolmanLayoutProps> = ({ children }) => (
<ThemedLayoutV2 <ThemedLayout
Header={() => <Header sticky />} Header={() => <Header sticky />}
Sider={() => ( Sider={() => (
<ThemedSiderV2 <ThemedSider
fixed fixed
Title={({ collapsed }) => <ThemedTitleV2 collapsed={collapsed} text="Spoolman" icon={<Logo />} />} Title={({ collapsed }) => <ThemedTitle collapsed={collapsed} text="Spoolman" icon={<Logo />} />}
/> />
)} )}
Footer={() => <SpoolmanFooter />} Footer={() => <SpoolmanFooter />}
> >
{children} {children}
</ThemedLayoutV2> </ThemedLayout>
); );

View File

@@ -17,12 +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> = ({ value, locale, options, ...rest }) => { export const NumberFieldUnit: React.FC<Props> = ({ value, locale, options, unit }) => {
const number = Number(value); const number = Number(value);
return ( return (
<Text {...rest}> <Text>
{toLocaleStringSupportsOptions() ? number.toLocaleString(locale, options) : number} {rest.unit} {toLocaleStringSupportsOptions() ? number.toLocaleString(locale, options) : number} {unit}
</Text> </Text>
); );
}; };

View File

@@ -31,7 +31,7 @@ export const Version: React.FC = () => {
return <Spin />; return <Spin />;
} }
if (infoResult.isError) { if (infoResult.isError || !infoResult.data) {
return <span>Unknown</span>; return <span>Unknown</span>;
} }

View File

@@ -1,4 +1,3 @@
import { RefineThemes } from "@refinedev/antd";
import { ConfigProvider, theme } from "antd"; import { ConfigProvider, theme } from "antd";
import { createContext, PropsWithChildren, useEffect, useState } from "react"; import { createContext, PropsWithChildren, useEffect, useState } from "react";
@@ -40,8 +39,10 @@ export const ColorModeContextProvider: React.FC<PropsWithChildren> = ({ children
<ConfigProvider <ConfigProvider
// you can change the theme colors here. example: ...RefineThemes.Magenta, // you can change the theme colors here. example: ...RefineThemes.Magenta,
theme={{ theme={{
...RefineThemes.Yellow,
algorithm: mode === "light" ? defaultAlgorithm : darkAlgorithm, algorithm: mode === "light" ? defaultAlgorithm : darkAlgorithm,
token: {
colorPrimary: "#dc7734",
},
}} }}
> >
{children} {children}

View File

@@ -1,4 +1,4 @@
import '@ant-design/v5-patch-for-react-19'; import "@ant-design/v5-patch-for-react-19";
import React from "react"; import React from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";

View File

@@ -88,12 +88,12 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
// To provide the live updates, we use a custom solution (useLiveify) instead of the built-in refine "liveMode" feature. // To provide the live updates, we use a custom solution (useLiveify) instead of the built-in refine "liveMode" feature.
// This is because the built-in feature does not call the liveProvider subscriber with a list of IDs, but instead // This is because the built-in feature does not call the liveProvider subscriber with a list of IDs, but instead
// calls it with a list of filters, sorters, etc. This means the server-side has to support this, which is quite hard. // calls it with a list of filters, sorters, etc. This means the server-side has to support this, which is quite hard.
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent } = const { tableProps, sorters, setSorters, filters, setFilters, currentPage, pageSize, setCurrentPage } =
useTable<IFilamentCollapsed>({ useTable<IFilamentCollapsed>({
syncWithLocation: false, syncWithLocation: false,
pagination: { pagination: {
mode: "server", mode: "server",
current: initialState.pagination.current, currentPage: initialState.pagination.currentPage,
pageSize: initialState.pagination.pageSize, pageSize: initialState.pagination.pageSize,
}, },
sorters: { sorters: {
@@ -131,7 +131,7 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
const tableState: TableState = { const tableState: TableState = {
sorters, sorters,
filters, filters,
pagination: { current, pageSize }, pagination: { currentPage: currentPage, pageSize },
showColumns, showColumns,
}; };
useStoreInitialState(namespace, tableState); useStoreInitialState(namespace, tableState);
@@ -175,7 +175,7 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
onClick={() => { onClick={() => {
setFilters([], "replace"); setFilters([], "replace");
setSorters([{ field: "id", order: "asc" }]); setSorters([{ field: "id", order: "asc" }]);
setCurrent(1); setCurrentPage(1);
}} }}
> >
{t("buttons.clearFilters")} {t("buttons.clearFilters")}

View File

@@ -21,10 +21,10 @@ export const FilamentShow: React.FC<IResourceComponentsProps> = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const extraFields = useGetFields(EntityType.filament); const extraFields = useGetFields(EntityType.filament);
const currencyFormatter = useCurrencyFormatter(); const currencyFormatter = useCurrencyFormatter();
const { queryResult } = useShow<IFilament>({ const { query } = useShow<IFilament>({
liveMode: "auto", liveMode: "auto",
}); });
const { data, isLoading } = queryResult; const { data, isLoading } = query;
const record = data?.data; const record = data?.data;

View File

@@ -6,8 +6,8 @@ import Title from "antd/es/typography/Title";
import dayjs from "dayjs"; import dayjs from "dayjs";
import utc from "dayjs/plugin/utc"; import utc from "dayjs/plugin/utc";
import React, { ReactNode } from "react"; import React, { ReactNode } from "react";
import { Link } from "react-router";
import { Trans } from "react-i18next"; import { Trans } from "react-i18next";
import { Link } from "react-router";
import Logo from "../../icon.svg?react"; import Logo from "../../icon.svg?react";
import { ISpool } from "../spools/model"; import { ISpool } from "../spools/model";
@@ -32,7 +32,7 @@ export const Home: React.FC<IResourceComponentsProps> = () => {
pagination: { pageSize: 1 }, pagination: { pageSize: 1 },
}); });
const hasSpools = !spools.data || spools.data.data.length > 0; const hasSpools = !spools.result || spools.result.data.length > 0;
const ResourceStatsCard = (props: { loading: boolean; value: number; resource: string; icon: ReactNode }) => ( const ResourceStatsCard = (props: { loading: boolean; value: number; resource: string; icon: ReactNode }) => (
<Col xs={12} md={6}> <Col xs={12} md={6}>
@@ -89,20 +89,20 @@ export const Home: React.FC<IResourceComponentsProps> = () => {
<Row justify="center" gutter={[16, 16]} style={{ marginTop: "3em" }}> <Row justify="center" gutter={[16, 16]} style={{ marginTop: "3em" }}>
<ResourceStatsCard <ResourceStatsCard
resource="spool" resource="spool"
value={spools.data?.total || 0} value={spools.result?.total || 0}
loading={spools.isLoading} loading={spools.query.isLoading}
icon={<FileOutlined />} icon={<FileOutlined />}
/> />
<ResourceStatsCard <ResourceStatsCard
resource="filament" resource="filament"
value={filaments.data?.total || 0} value={filaments.result?.total || 0}
loading={filaments.isLoading} loading={filaments.query.isLoading}
icon={<HighlightOutlined />} icon={<HighlightOutlined />}
/> />
<ResourceStatsCard <ResourceStatsCard
resource="vendor" resource="vendor"
value={vendors.data?.total || 0} value={vendors.result?.total || 0}
loading={vendors.isLoading} loading={vendors.query.isLoading}
icon={<UserOutlined />} icon={<UserOutlined />}
/> />
</Row> </Row>

View File

@@ -17,11 +17,7 @@ export function LocationContainer() {
const locationsSpoolOrders = useLocationsSpoolOrders(); const locationsSpoolOrders = useLocationsSpoolOrders();
const setLocationsSpoolOrders = useSetSetting<Record<string, number[]>>("locations_spoolorders"); const setLocationsSpoolOrders = useSetSetting<Record<string, number[]>>("locations_spoolorders");
const { const { result: spoolData, query } = useList<ISpool>({
data: spoolData,
isLoading,
isError,
} = useList<ISpool>({
resource: "spool", resource: "spool",
meta: { meta: {
queryParams: { queryParams: {
@@ -32,6 +28,8 @@ export function LocationContainer() {
mode: "off", mode: "off",
}, },
}); });
const isLoading = query.isLoading;
const isError = query.isError;
// Group spools by location // Group spools by location
const spoolLocations = (() => { const spoolLocations = (() => {

View File

@@ -34,7 +34,9 @@ export function useRenameSpoolLocation() {
return await response.text(); return await response.text();
}, },
onMutate: async (value) => { onMutate: async (value) => {
await queryClient.cancelQueries(queryKeyList); await queryClient.cancelQueries({
queryKey: queryKeyList
});
// Optimistically update all spools with matching location to the new one // Optimistically update all spools with matching location to the new one
queryClient.setQueriesData<GetListResponse<ISpool>>({ queryKey: queryKeyList }, (old) => { queryClient.setQueriesData<GetListResponse<ISpool>>({ queryKey: queryKeyList }, (old) => {
@@ -71,7 +73,9 @@ export function useRenameSpoolLocation() {
}, },
onSuccess: (_data, _value) => { onSuccess: (_data, _value) => {
// Mutation succeeded, refetch // Mutation succeeded, refetch
queryClient.invalidateQueries(queryKey); queryClient.invalidateQueries({
queryKey: queryKey
});
}, },
}); });
} }

View File

@@ -42,7 +42,7 @@ const SpoolSelectModal: React.FC<Props> = ({ description, onContinue }) => {
const [messageApi, contextHolder] = message.useMessage(); const [messageApi, contextHolder] = message.useMessage();
const navigate = useNavigate(); const navigate = useNavigate();
const { tableProps, sorters, filters, current, pageSize } = useTable<ISpoolCollapsed>({ const { tableProps, sorters, filters, currentPage, pageSize } = useTable<ISpoolCollapsed>({
resource: "spool", resource: "spool",
meta: { meta: {
queryParams: { queryParams: {
@@ -52,7 +52,7 @@ const SpoolSelectModal: React.FC<Props> = ({ description, onContinue }) => {
syncWithLocation: false, syncWithLocation: false,
pagination: { pagination: {
mode: "off", mode: "off",
current: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
}, },
sorters: { sorters: {
@@ -75,7 +75,7 @@ const SpoolSelectModal: React.FC<Props> = ({ description, onContinue }) => {
const tableState: TableState = { const tableState: TableState = {
sorters, sorters,
filters, filters,
pagination: { current, pageSize }, pagination: { currentPage: currentPage, pageSize },
}; };
// Collapse the dataSource to a mutable list and add a filament_name field // Collapse the dataSource to a mutable list and add a filament_name field

View File

@@ -105,7 +105,7 @@ export function GeneralSettings() {
</Form.Item> </Form.Item>
<Form.Item wrapperCol={{ offset: 8, span: 16 }}> <Form.Item wrapperCol={{ offset: 8, span: 16 }}>
<Button type="primary" htmlType="submit" loading={settings.isFetching || setCurrency.isLoading}> <Button type="primary" htmlType="submit" loading={settings.isFetching || setCurrency.isPending}>
{t("buttons.save")} {t("buttons.save")}
</Button> </Button>
</Form.Item> </Form.Item>

View File

@@ -2,6 +2,7 @@ import { useSelect, useTranslate } from "@refinedev/core";
import { useQueries } from "@tanstack/react-query"; import { useQueries } from "@tanstack/react-query";
import { Form, InputNumber, Modal, Radio } from "antd"; import { Form, InputNumber, Modal, Radio } from "antd";
import { useForm } from "antd/es/form/Form"; import { useForm } from "antd/es/form/Form";
import type { InputNumberRef } from "rc-input-number";
import { useCallback, useMemo, useRef, useState } from "react"; import { useCallback, useMemo, useRef, useState } from "react";
import { formatLength, formatWeight } from "../../utils/parsing"; import { formatLength, formatWeight } from "../../utils/parsing";
import { SpoolType, useGetExternalDBFilaments } from "../../utils/queryExternalDB"; import { SpoolType, useGetExternalDBFilaments } from "../../utils/queryExternalDB";
@@ -63,7 +64,6 @@ export async function useSpoolFilamentMeasure(spool: ISpool, weight: number) {
await fetch(request, init); await fetch(request, init);
} }
/** /**
* Returns an array of queries using the useQueries hook from @tanstack/react-query. * Returns an array of queries using the useQueries hook from @tanstack/react-query.
* Each query fetches a spool by its ID from the server. * Each query fetches a spool by its ID from the server.
@@ -126,7 +126,7 @@ interface SelectOption {
export function useGetFilamentSelectOptions() { export function useGetFilamentSelectOptions() {
// Setup hooks // Setup hooks
const t = useTranslate(); const t = useTranslate();
const { queryResult: internalFilaments } = useSelect<IFilament>({ const { query: internalFilaments } = useSelect<IFilament>({
resource: "filament", resource: "filament",
}); });
const externalFilaments = useGetExternalDBFilaments(); const externalFilaments = useGetExternalDBFilaments();
@@ -201,7 +201,7 @@ export function useSpoolAdjustModal() {
const [curSpool, setCurSpool] = useState<ISpool | null>(null); const [curSpool, setCurSpool] = useState<ISpool | null>(null);
const [measurementType, setMeasurementType] = useState<MeasurementType>("length"); const [measurementType, setMeasurementType] = useState<MeasurementType>("length");
const inputNumberRef = useRef<HTMLInputElement | null>(null); const inputNumberRef = useRef<InputNumberRef | null>(null);
const openSpoolAdjustModal = useCallback((spool: ISpool) => { const openSpoolAdjustModal = useCallback((spool: ISpool) => {
setCurSpool(spool); setCurSpool(spool);

View File

@@ -117,7 +117,7 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
// To provide the live updates, we use a custom solution (useLiveify) instead of the built-in refine "liveMode" feature. // To provide the live updates, we use a custom solution (useLiveify) instead of the built-in refine "liveMode" feature.
// This is because the built-in feature does not call the liveProvider subscriber with a list of IDs, but instead // This is because the built-in feature does not call the liveProvider subscriber with a list of IDs, but instead
// calls it with a list of filters, sorters, etc. This means the server-side has to support this, which is quite hard. // calls it with a list of filters, sorters, etc. This means the server-side has to support this, which is quite hard.
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent } = const { tableProps, sorters, setSorters, filters, setFilters, currentPage, pageSize, setCurrentPage } =
useTable<ISpoolCollapsed>({ useTable<ISpoolCollapsed>({
meta: { meta: {
queryParams: { queryParams: {
@@ -127,7 +127,7 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
syncWithLocation: false, syncWithLocation: false,
pagination: { pagination: {
mode: "server", mode: "server",
current: initialState.pagination.current, currentPage: initialState.pagination.currentPage,
pageSize: initialState.pagination.pageSize, pageSize: initialState.pagination.pageSize,
}, },
sorters: { sorters: {
@@ -165,7 +165,7 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
const tableState: TableState = { const tableState: TableState = {
sorters, sorters,
filters, filters,
pagination: { current, pageSize }, pagination: { currentPage: currentPage, pageSize },
showColumns, showColumns,
}; };
useStoreInitialState(namespace, tableState); useStoreInitialState(namespace, tableState);
@@ -284,7 +284,7 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
onClick={() => { onClick={() => {
setFilters([], "replace"); setFilters([], "replace");
setSorters([{ field: "id", order: "asc" }]); setSorters([{ field: "id", order: "asc" }]);
setCurrent(1); setCurrentPage(1);
}} }}
> >
{t("buttons.clearFilters")} {t("buttons.clearFilters")}

View File

@@ -1,4 +1,3 @@
import { getBasePath } from "../../utils/url";
import { InboxOutlined, PrinterOutlined, ToTopOutlined, ToolOutlined } from "@ant-design/icons"; import { InboxOutlined, PrinterOutlined, ToTopOutlined, ToolOutlined } from "@ant-design/icons";
import { DateField, NumberField, Show, TextField } from "@refinedev/antd"; import { DateField, NumberField, Show, TextField } from "@refinedev/antd";
import { IResourceComponentsProps, useInvalidate, useShow, useTranslate } from "@refinedev/core"; import { IResourceComponentsProps, useInvalidate, useShow, useTranslate } from "@refinedev/core";
@@ -12,6 +11,7 @@ import SpoolIcon from "../../components/spoolIcon";
import { enrichText } from "../../utils/parsing"; import { enrichText } from "../../utils/parsing";
import { EntityType, useGetFields } from "../../utils/queryFields"; import { EntityType, useGetFields } from "../../utils/queryFields";
import { useCurrencyFormatter } from "../../utils/settings"; import { useCurrencyFormatter } from "../../utils/settings";
import { getBasePath } from "../../utils/url";
import { IFilament } from "../filaments/model"; import { IFilament } from "../filaments/model";
import { setSpoolArchived, useSpoolAdjustModal } from "./functions"; import { setSpoolArchived, useSpoolAdjustModal } from "./functions";
import { ISpool } from "./model"; import { ISpool } from "./model";
@@ -27,10 +27,10 @@ export const SpoolShow: React.FC<IResourceComponentsProps> = () => {
const currencyFormatter = useCurrencyFormatter(); const currencyFormatter = useCurrencyFormatter();
const invalidate = useInvalidate(); const invalidate = useInvalidate();
const { queryResult } = useShow<ISpool>({ const { query } = useShow<ISpool>({
liveMode: "auto", liveMode: "auto",
}); });
const { data, isLoading } = queryResult; const { data, isLoading } = query;
const record = data?.data; const record = data?.data;
@@ -118,17 +118,19 @@ export const SpoolShow: React.FC<IResourceComponentsProps> = () => {
title={record ? formatTitle(record) : ""} title={record ? formatTitle(record) : ""}
headerButtons={({ defaultButtons }) => ( headerButtons={({ defaultButtons }) => (
<> <>
<Button <Button type="primary" icon={<ToolOutlined />} onClick={() => record && openSpoolAdjustModal(record)}>
type="primary"
icon={<ToolOutlined />}
onClick={() => record && openSpoolAdjustModal(record)}
>
{t("spool.titles.adjust")} {t("spool.titles.adjust")}
</Button> </Button>
<Button <Button
type="primary" type="primary"
icon={<PrinterOutlined />} icon={<PrinterOutlined />}
href={getBasePath() + "/spool/print?spools=" + record?.id + "&return=" + encodeURIComponent(window.location.pathname)} href={
getBasePath() +
"/spool/print?spools=" +
record?.id +
"&return=" +
encodeURIComponent(window.location.pathname)
}
> >
{t("printing.qrcode.button")} {t("printing.qrcode.button")}
</Button> </Button>

View File

@@ -38,11 +38,12 @@ export const VendorList: React.FC<IResourceComponentsProps> = () => {
const initialState = useInitialTableState(namespace); const initialState = useInitialTableState(namespace);
// Fetch data from the API // Fetch data from the API
const { tableProps, sorters, setSorters, filters, setFilters, current, pageSize, setCurrent } = useTable<IVendor>({ const { tableProps, sorters, setSorters, filters, setFilters, currentPage, pageSize, setCurrentPage } =
useTable<IVendor>({
syncWithLocation: false, syncWithLocation: false,
pagination: { pagination: {
mode: "server", mode: "server",
current: initialState.pagination.current, currentPage: initialState.pagination.currentPage,
pageSize: initialState.pagination.pageSize, pageSize: initialState.pagination.pageSize,
}, },
sorters: { sorters: {
@@ -72,7 +73,7 @@ export const VendorList: React.FC<IResourceComponentsProps> = () => {
const tableState: TableState = { const tableState: TableState = {
sorters, sorters,
filters, filters,
pagination: { current, pageSize }, pagination: { currentPage, pageSize },
showColumns, showColumns,
}; };
useStoreInitialState(namespace, tableState); useStoreInitialState(namespace, tableState);
@@ -117,7 +118,7 @@ export const VendorList: React.FC<IResourceComponentsProps> = () => {
onClick={() => { onClick={() => {
setFilters([], "replace"); setFilters([], "replace");
setSorters([{ field: "id", order: "asc" }]); setSorters([{ field: "id", order: "asc" }]);
setCurrent(1); setCurrentPage(1);
}} }}
> >
{t("buttons.clearFilters")} {t("buttons.clearFilters")}

View File

@@ -17,10 +17,10 @@ export const VendorShow: React.FC<IResourceComponentsProps> = () => {
const t = useTranslate(); const t = useTranslate();
const extraFields = useGetFields(EntityType.vendor); const extraFields = useGetFields(EntityType.vendor);
const { queryResult } = useShow<IVendor>({ const { query } = useShow<IVendor>({
liveMode: "auto", liveMode: "auto",
}); });
const { data, isLoading } = queryResult; const { data, isLoading } = query;
const record = data?.data; const record = data?.data;

View File

@@ -66,7 +66,9 @@ export function useSetField(entity_type: EntityType) {
}, },
onMutate: async ({ key, params }) => { onMutate: async ({ key, params }) => {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update) // Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries(["fields", entity_type]); await queryClient.cancelQueries({
queryKey: ["fields", entity_type]
});
// Snapshot the previous value // Snapshot the previous value
const previousFields = queryClient.getQueryData<Field[]>(["fields", entity_type]); const previousFields = queryClient.getQueryData<Field[]>(["fields", entity_type]);
@@ -101,7 +103,9 @@ export function useSetField(entity_type: EntityType) {
}, },
onSettled: () => { onSettled: () => {
// Invalidate and refetch // Invalidate and refetch
queryClient.invalidateQueries(["fields", entity_type]); queryClient.invalidateQueries({
queryKey: ["fields", entity_type]
});
}, },
}); });
} }
@@ -124,7 +128,9 @@ export function useDeleteField(entity_type: EntityType) {
}, },
onSuccess: () => { onSuccess: () => {
// Invalidate and refetch // Invalidate and refetch
queryClient.invalidateQueries(["fields", entity_type]); queryClient.invalidateQueries({
queryKey: ["fields", entity_type]
});
}, },
}); });
} }

View File

@@ -52,7 +52,9 @@ export function useSetSetting<T>(key: string) {
return response.json(); return response.json();
}, },
onMutate: async (value) => { onMutate: async (value) => {
await queryClient.cancelQueries(["settings", key]); await queryClient.cancelQueries({
queryKey: ["settings", key]
});
const previousValue = queryClient.getQueryData<SettingResponseValue>(["settings", key]); const previousValue = queryClient.getQueryData<SettingResponseValue>(["settings", key]);
queryClient.setQueryData<SettingResponseValue>(["settings", key], (old) => queryClient.setQueryData<SettingResponseValue>(["settings", key], (old) =>
old ? { ...old, value: JSON.stringify(value) } : undefined old ? { ...old, value: JSON.stringify(value) } : undefined
@@ -64,7 +66,9 @@ export function useSetSetting<T>(key: string) {
}, },
onSuccess: (_data, _value) => { onSuccess: (_data, _value) => {
// Invalidate and refetch // Invalidate and refetch
queryClient.invalidateQueries(["settings", key]); queryClient.invalidateQueries({
queryKey: ["settings", key]
});
}, },
}); });
} }

View File

@@ -2,7 +2,7 @@ import { CrudFilter, CrudSort } from "@refinedev/core";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { isLocalStorageAvailable } from "./support"; import { isLocalStorageAvailable } from "./support";
interface Pagination { interface Pagination {
current: number; currentPage: number;
pageSize: number; pageSize: number;
} }