feat: Add 3dfilamentprofiles.com integration (Issue #7)
Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
- Backend: Added ExternalSource enum, Filament3DFP model, and transform function - Backend: Updated _sync() to fetch from both SpoolmanDB and 3dfilamentprofiles - Frontend: Added source tabs to FilamentImportModal (All/SpoolmanDB/3DFP) - Frontend: Updated ExternalFilament interface with source and temp range fields - Frontend: Updated filament import handler to use temp range fields Also includes: - Dev mode styling (teal theme, DEV badge and banner) - Translation keys for source filtering Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { useTranslate } from "@refinedev/core";
|
||||
import { Form, Modal, Select } from "antd";
|
||||
import { Form, Modal, Select, Tabs } from "antd";
|
||||
import { useMemo, useState } from "react";
|
||||
import { Trans } from "react-i18next";
|
||||
import { formatFilamentLabel } from "../pages/spools/functions";
|
||||
import { searchMatches } from "../utils/filtering";
|
||||
import { ExternalFilament, useGetExternalDBFilaments } from "../utils/queryExternalDB";
|
||||
import { ExternalFilament, ExternalSource, useGetExternalDBFilaments } from "../utils/queryExternalDB";
|
||||
|
||||
export function FilamentImportModal(props: {
|
||||
isOpen: boolean;
|
||||
@@ -12,12 +13,25 @@ export function FilamentImportModal(props: {
|
||||
}) {
|
||||
const [form] = Form.useForm();
|
||||
const t = useTranslate();
|
||||
const [selectedSource, setSelectedSource] = useState<ExternalSource | "all">("all");
|
||||
|
||||
const externalFilaments = useGetExternalDBFilaments();
|
||||
const filamentOptions =
|
||||
externalFilaments.data?.map((item) => {
|
||||
|
||||
// Filter and format filaments based on selected source
|
||||
const filamentOptions = useMemo(() => {
|
||||
const filtered = externalFilaments.data?.filter((item) => {
|
||||
if (selectedSource === "all") return true;
|
||||
return item.source === selectedSource;
|
||||
}) ?? [];
|
||||
|
||||
const options = filtered.map((item) => {
|
||||
// Add source indicator to label if showing all
|
||||
const sourceIndicator = selectedSource === "all" && item.source === ExternalSource.FILAMENT_PROFILES_3D
|
||||
? "[3DFP] "
|
||||
: "";
|
||||
|
||||
return {
|
||||
label: formatFilamentLabel(
|
||||
label: sourceIndicator + formatFilamentLabel(
|
||||
item.name,
|
||||
item.diameter,
|
||||
item.manufacturer,
|
||||
@@ -28,8 +42,23 @@ export function FilamentImportModal(props: {
|
||||
value: item.id,
|
||||
item: item,
|
||||
};
|
||||
}) ?? [];
|
||||
filamentOptions.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
|
||||
});
|
||||
|
||||
options.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
|
||||
return options;
|
||||
}, [externalFilaments.data, selectedSource]);
|
||||
|
||||
// Count filaments by source
|
||||
const counts = useMemo(() => {
|
||||
const spoolmandb = externalFilaments.data?.filter(f => f.source === ExternalSource.SPOOLMANDB || !f.source).length ?? 0;
|
||||
const threeDFP = externalFilaments.data?.filter(f => f.source === ExternalSource.FILAMENT_PROFILES_3D).length ?? 0;
|
||||
return { spoolmandb, threeDFP, total: spoolmandb + threeDFP };
|
||||
}, [externalFilaments.data]);
|
||||
|
||||
const handleSourceChange = (key: string) => {
|
||||
setSelectedSource(key as ExternalSource | "all");
|
||||
form.resetFields(["filament"]);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@@ -37,7 +66,36 @@ export function FilamentImportModal(props: {
|
||||
open={props.isOpen}
|
||||
onOk={() => form.submit()}
|
||||
onCancel={() => props.onClose()}
|
||||
width={600}
|
||||
>
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey={"filament.form.import_external_description"}
|
||||
components={{
|
||||
br: <br />,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
|
||||
<Tabs
|
||||
activeKey={selectedSource}
|
||||
onChange={handleSourceChange}
|
||||
items={[
|
||||
{
|
||||
key: "all",
|
||||
label: `${t("filament.form.all_sources")} (${counts.total})`,
|
||||
},
|
||||
{
|
||||
key: ExternalSource.SPOOLMANDB,
|
||||
label: `SpoolmanDB (${counts.spoolmandb})`,
|
||||
},
|
||||
{
|
||||
key: ExternalSource.FILAMENT_PROFILES_3D,
|
||||
label: `3D Filament Profiles (${counts.threeDFP})`,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<Form
|
||||
layout="vertical"
|
||||
form={form}
|
||||
@@ -49,21 +107,15 @@ export function FilamentImportModal(props: {
|
||||
props.onImport(filament);
|
||||
props.onClose();
|
||||
form.resetFields();
|
||||
setSelectedSource("all");
|
||||
}}
|
||||
>
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey={"filament.form.import_external_description"}
|
||||
components={{
|
||||
br: <br />,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<Form.Item name="filament" rules={[{ required: true }]}>
|
||||
<Select
|
||||
options={filamentOptions}
|
||||
showSearch
|
||||
filterOption={(input, option) => typeof option?.label === "string" && searchMatches(input, option?.label)}
|
||||
placeholder={t("filament.form.select_filament")}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
Reference in New Issue
Block a user