Merge pull request #461 from samturner3/master

Feature: Add option to use full URL in QR codes instead of web+spoolman: prefix
This commit is contained in:
Donkie
2024-08-26 20:23:25 +02:00
committed by GitHub
7 changed files with 92 additions and 3 deletions

View File

@@ -118,6 +118,15 @@
"showSpoolComment": "Poznámka k cívce", "showSpoolComment": "Poznámka k cívce",
"showFilamentComment": "Poznámka k filamentu", "showFilamentComment": "Poznámka k filamentu",
"showVendorComment": "Poznámka k výrobci", "showVendorComment": "Poznámka k výrobci",
"useHTTPUrl": {
"label": "Odkaz na QR kód",
"tooltip": "Použije proprietární odkaz, který bude fungovat pouze v případě, že bude skenován pomocí funkce skenování Spoolman (výchozí). Adresa URL používá buď základní adresu URL zadanou v nastavení, nebo adresu URL aktuální stránky, pokud není nastavena.",
"options": {
"default": "Výchozí",
"url": "URL"
},
"preview": "Náhled:"
},
"template": "Šablona štítku", "template": "Šablona štítku",
"templateHelp": "Pomocí {} vložíte hodnoty objektu cívky jako text. Například {id} bude nahrazeno ID cívky nebo {filament.material} bude nahrazeno materiálem cívky. Text uzavřete dvojitou hvězdičkou **, aby byl tučný. Kliknutím na tlačítko zobrazíte seznam všech dostupných značek.", "templateHelp": "Pomocí {} vložíte hodnoty objektu cívky jako text. Například {id} bude nahrazeno ID cívky nebo {filament.material} bude nahrazeno materiálem cívky. Text uzavřete dvojitou hvězdičkou **, aby byl tučný. Kliknutím na tlačítko zobrazíte seznam všech dostupných značek.",
"showQRCode": "Tisk QR kódu", "showQRCode": "Tisk QR kódu",
@@ -374,6 +383,10 @@
"tab": "Obecné", "tab": "Obecné",
"currency": { "currency": {
"label": "Měna" "label": "Měna"
},
"base_url": {
"label": "Základní URL",
"tooltip": "Základní adresa URL, která se má použít při generování funkcí, jako jsou QR kódy"
} }
}, },
"settings": "Nastavení" "settings": "Nastavení"

View File

@@ -109,6 +109,15 @@
"templateHelp": "Use {} to insert values of the spool object as text. For example {id} will be replaced with the spool id, or {filament.material} will be replaced with the material of the spool. Enclose text with double asterix ** to make it bold. Click the button to view a list of all available tags.", "templateHelp": "Use {} to insert values of the spool object as text. For example {id} will be replaced with the spool id, or {filament.material} will be replaced with the material of the spool. Enclose text with double asterix ** to make it bold. Click the button to view a list of all available tags.",
"textSize": "Label Text Size", "textSize": "Label Text Size",
"showContent": "Print Label", "showContent": "Print Label",
"useHTTPUrl": {
"label": "QR code link",
"tooltip": "Will use proprietary link that will work only if scanned from Spoolman's scanning feature (default). URL uses either the base URL specified in settings, or the current page URL if not set.",
"options": {
"default": "Default",
"url": "URL"
},
"preview": "Preview:"
},
"showQRCode": "Print QR Code", "showQRCode": "Print QR Code",
"showQRCodeMode": { "showQRCodeMode": {
"no": "No", "no": "No",
@@ -300,6 +309,10 @@
"tab": "General", "tab": "General",
"currency": { "currency": {
"label": "Currency" "label": "Currency"
},
"base_url": {
"label": "Base URL",
"tooltip": "The base URL to use when generating features such as QR codes."
} }
}, },
"extra_fields": { "extra_fields": {

View File

@@ -18,6 +18,11 @@ const QRCodeScannerModal: React.FC = () => {
setVisible(false); setVisible(false);
navigate(`/spool/show/${match.groups.id}`); navigate(`/spool/show/${match.groups.id}`);
} }
const fullURLmatch = result.match(/^https?:\/\/[^/]+\/spool\/show\/(?<id>[0-9]+)$/);
if (fullURLmatch && fullURLmatch.groups) {
setVisible(false);
navigate(`/spool/show/${fullURLmatch.groups.id}`);
}
}; };
return ( return (

View File

@@ -1,8 +1,10 @@
import { useTranslate } from "@refinedev/core"; import { useTranslate } from "@refinedev/core";
import { Col, Form, InputNumber, QRCode, Radio, RadioChangeEvent, Row, Slider, Switch } from "antd"; import { Col, Form, InputNumber, QRCode, Radio, RadioChangeEvent, Row, Slider, Switch, Typography } from "antd";
import { QRCodePrintSettings } from "./printing"; import { QRCodePrintSettings } from "./printing";
import PrintingDialog from "./printingDialog"; import PrintingDialog from "./printingDialog";
const { Text } = Typography;
interface QRCodeData { interface QRCodeData {
value: string; value: string;
label?: JSX.Element; label?: JSX.Element;
@@ -16,6 +18,9 @@ interface QRCodePrintingDialogProps {
extraSettings?: JSX.Element; extraSettings?: JSX.Element;
extraSettingsStart?: JSX.Element; extraSettingsStart?: JSX.Element;
extraButtons?: JSX.Element; extraButtons?: JSX.Element;
baseUrlRoot: string;
useHTTPUrl: boolean;
setUseHTTPUrl: (value: boolean) => void;
} }
const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({ const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({
@@ -25,6 +30,9 @@ const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({
extraSettings, extraSettings,
extraSettingsStart, extraSettingsStart,
extraButtons, extraButtons,
baseUrlRoot,
useHTTPUrl,
setUseHTTPUrl,
}) => { }) => {
const t = useTranslate(); const t = useTranslate();
@@ -87,6 +95,23 @@ const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({
buttonStyle="solid" buttonStyle="solid"
/> />
</Form.Item> </Form.Item>
{showQRCodeMode !== "no" && (
<>
<Form.Item
label={t("printing.qrcode.useHTTPUrl.label")}
tooltip={t("printing.qrcode.useHTTPUrl.tooltip")}
style={{ marginBottom: 0 }}
>
<Radio.Group onChange={(e) => setUseHTTPUrl(e.target.value)} value={useHTTPUrl}>
<Radio value={false}>{t("printing.qrcode.useHTTPUrl.options.default")}</Radio>
<Radio value={true}>{t("printing.qrcode.useHTTPUrl.options.url")}</Radio>
</Radio.Group>
</Form.Item>
<Form.Item label={t("printing.qrcode.useHTTPUrl.preview")}>
<Text> {useHTTPUrl ? `${baseUrlRoot}/spool/show/{id}` : `web+spoolman:s-{id}`}</Text>
</Form.Item>
</>
)}
<Form.Item label={t("printing.qrcode.showContent")}> <Form.Item label={t("printing.qrcode.showContent")}>
<Switch <Switch
checked={showContent} checked={showContent}

View File

@@ -1,4 +1,5 @@
import { CopyOutlined, DeleteOutlined, PlusOutlined, SaveOutlined } from "@ant-design/icons"; import { CopyOutlined, DeleteOutlined, PlusOutlined, SaveOutlined } from "@ant-design/icons";
import { useGetSetting } from "../../utils/querySettings";
import { useTranslate } from "@refinedev/core"; import { useTranslate } from "@refinedev/core";
import { Button, Flex, Form, Input, Modal, Popconfirm, Select, Table, Typography, message } from "antd"; import { Button, Flex, Form, Input, Modal, Popconfirm, Select, Table, Typography, message } from "antd";
import TextArea from "antd/es/input/TextArea"; import TextArea from "antd/es/input/TextArea";
@@ -24,7 +25,13 @@ interface SpoolQRCodePrintingDialog {
const SpoolQRCodePrintingDialog: React.FC<SpoolQRCodePrintingDialog> = ({ spoolIds }) => { const SpoolQRCodePrintingDialog: React.FC<SpoolQRCodePrintingDialog> = ({ spoolIds }) => {
const t = useTranslate(); const t = useTranslate();
const baseUrlSetting = useGetSetting("base_url");
const baseUrlRoot =
baseUrlSetting.data?.value !== undefined && JSON.parse(baseUrlSetting.data?.value) !== ""
? JSON.parse(baseUrlSetting.data?.value)
: window.location.origin;
const [messageApi, contextHolder] = message.useMessage(); const [messageApi, contextHolder] = message.useMessage();
const [useHTTPUrl, setUseHTTPUrl] = useSavedState("print-useHTTPUrl", false);
const itemQueries = useGetSpoolsByIds(spoolIds); const itemQueries = useGetSpoolsByIds(spoolIds);
const items = itemQueries const items = itemQueries
@@ -231,6 +238,9 @@ Lot Nr: {lot_nr}
curPreset.labelSettings = newSettings; curPreset.labelSettings = newSettings;
updateCurrentPreset(curPreset); updateCurrentPreset(curPreset);
}} }}
baseUrlRoot={baseUrlRoot}
useHTTPUrl={useHTTPUrl}
setUseHTTPUrl={setUseHTTPUrl}
extraSettingsStart={ extraSettingsStart={
<> <>
<Form.Item label={t("printing.generic.settings")}> <Form.Item label={t("printing.generic.settings")}>
@@ -290,7 +300,7 @@ Lot Nr: {lot_nr}
</> </>
} }
items={items.map((spool) => ({ items={items.map((spool) => ({
value: `web+spoolman:s-${spool.id}`, value: useHTTPUrl ? `${baseUrlRoot}/spool/show/${spool.id}` : `web+spoolman:s-${spool.id}`,
label: ( label: (
<p <p
style={{ style={{

View File

@@ -5,6 +5,7 @@ import { useGetSettings, useSetSetting } from "../../utils/querySettings";
export function GeneralSettings() { export function GeneralSettings() {
const settings = useGetSettings(); const settings = useGetSettings();
const setBaseUrl = useSetSetting("base_url");
const setCurrency = useSetSetting("currency"); const setCurrency = useSetSetting("currency");
const [form] = Form.useForm(); const [form] = Form.useForm();
const [messageApi, contextHolder] = message.useMessage(); const [messageApi, contextHolder] = message.useMessage();
@@ -15,6 +16,7 @@ export function GeneralSettings() {
if (settings.data) { if (settings.data) {
form.setFieldsValue({ form.setFieldsValue({
currency: JSON.parse(settings.data.currency.value), currency: JSON.parse(settings.data.currency.value),
base_url: JSON.parse(settings.data.base_url.value),
}); });
} }
}, [settings.data, form]); }, [settings.data, form]);
@@ -27,11 +29,15 @@ export function GeneralSettings() {
}, [setCurrency.isSuccess, messageApi, t]); }, [setCurrency.isSuccess, messageApi, t]);
// Handle form submit // Handle form submit
const onFinish = (values: { currency: string }) => { const onFinish = (values: { currency: string; base_url: string }) => {
// Check if the currency has changed // Check if the currency has changed
if (settings.data?.currency.value !== JSON.stringify(values.currency)) { if (settings.data?.currency.value !== JSON.stringify(values.currency)) {
setCurrency.mutate(values.currency); setCurrency.mutate(values.currency);
} }
// Check if the base URL has changed
if (settings.data?.base_url.value !== JSON.stringify(values.base_url)) {
setBaseUrl.mutate(values.base_url);
}
}; };
return ( return (
@@ -64,6 +70,22 @@ export function GeneralSettings() {
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item
label={t("settings.general.base_url.label")}
tooltip={t("settings.general.base_url.tooltip")}
name="base_url"
rules={[
{
required: false,
},
{
pattern: /^https?:\/\/.+(?<!\/)$/,
},
]}
>
<Input placeholder="https://example.com:8000" />
</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.isLoading}>
{t("buttons.save")} {t("buttons.save")}

View File

@@ -67,3 +67,4 @@ register_setting("print_presets", SettingType.ARRAY, json.dumps([]))
register_setting("extra_fields_vendor", SettingType.ARRAY, json.dumps([])) register_setting("extra_fields_vendor", SettingType.ARRAY, json.dumps([]))
register_setting("extra_fields_filament", SettingType.ARRAY, json.dumps([])) register_setting("extra_fields_filament", SettingType.ARRAY, json.dumps([]))
register_setting("extra_fields_spool", SettingType.ARRAY, json.dumps([])) register_setting("extra_fields_spool", SettingType.ARRAY, json.dumps([]))
register_setting("base_url", SettingType.STRING, json.dumps(""))