diff --git a/package.json b/package.json index 06abc75ff..b15f7b470 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "private": true, "dependencies": { "@codecov/vite-plugin": "^1.9.0", + "@dagrejs/dagre": "^1.1.4", "@date-io/date-fns": "^3.2.1", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", @@ -29,6 +30,7 @@ "@uppy/react": "^4.0.2", "@uppy/xhr-upload": "^4.3.3", "@vitejs/plugin-react": "^5.0.0", + "@xyflow/react": "^12.4.2", "axios": "^1.7.2", "blob-polyfill": "^9.0.20240710", "browserslist": "^4.23.0", diff --git a/src/App.tsx b/src/App.tsx index 0b6381957..8e36247a3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -67,6 +67,7 @@ import SystemsLayout, { SystemsLayoutErrorComponent, systemsLayoutLoader, } from './systems/systemsLayout.component'; +import SystemsTree from './systems/systemsTree.component'; import ViewTabs from './view/viewTabs.component'; export const queryClient = new QueryClient({ @@ -202,6 +203,15 @@ const routeObject: RouteObject[] = [ Component: Systems, loader: systemsLayoutLoader(queryClient), }, + { + path: paths.systemRootTree, + Component: SystemsTree, + }, + { + path: paths.systemTree, + Component: SystemsTree, + loader: systemsLayoutLoader(queryClient), + }, { path: '*', Component: SystemsErrorComponent, diff --git a/src/api/__snapshots__/systems.test.tsx.snap b/src/api/__snapshots__/systems.test.tsx.snap new file mode 100644 index 000000000..c29757531 --- /dev/null +++ b/src/api/__snapshots__/systems.test.tsx.snap @@ -0,0 +1,4140 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`System api functions > useGetSystemsTree > fetches root-level systems and items with depth of 1 successfully 1`] = ` +[ + { + "catalogueItems": [], + "code": "root", + "created_time": "", + "description": null, + "id": "root", + "importance": "low", + "location": null, + "modified_time": "", + "name": "Root", + "owner": null, + "parent_id": null, + "subsystems": [ + { + "catalogueItems": [ + { + "catalogue_category_id": "9", + "cost_gbp": 1100, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 90, + "days_to_rework": null, + "description": "Motorized actuators for controlled motion. 32", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 647, + "id": "11", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Motorized Actuators 32", + "notes": null, + "number_of_spares": 1, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": "10", + "properties": [ + { + "id": "13", + "name": "Travel Range", + "unit": "millimeters", + "unit_id": "5", + "value": 100, + }, + { + "id": "14", + "name": "Load Capacity", + "unit": "kilograms", + "unit_id": "6", + "value": 10, + }, + ], + }, + ], + "code": "storage", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Storage system for various items.", + "id": "657f8c3b2a1b4e5d8f9b3c4e5", + "importance": "medium", + "location": "Warehouse 42 +Sector 7 +Galactic Core", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Storage", + "owner": "Prof Peter Jackson", + "parent_id": null, + "subsystems": [], + "type_id": "1", + }, + { + "catalogueItems": [ + { + "catalogue_category_id": "4", + "cost_gbp": 500, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 1", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2070, + "id": "1", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 1", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 12, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 30, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": null, + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 600, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 2", + "drawing_link": "http://example-drawing-link.com", + "drawing_number": null, + "expected_lifetime_days": 400, + "id": "2", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 4, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 2", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 16, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 60, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Sony", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 700, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 3", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 322, + "id": "3", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 3", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 20, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 120, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Canon", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 800, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 4", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1609, + "id": "90", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 4", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 24, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 240, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Nikon", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 900, + "cost_to_rework_gbp": 0, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": 0, + "description": "High-resolution cameras for beam characterization. 5", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3501, + "id": "24", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 4, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 5", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 28, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 120, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Panasonic", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1000, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 6", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 936, + "id": "25", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 6", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 32, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 240, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Olympus", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1100, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 7", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1029, + "id": "26", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 4, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 7", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 36, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 360, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Fujifilm", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1200, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 8", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1309, + "id": "27", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 8", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 40, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 480, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Leica", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "13", + "cost_gbp": 250, + "cost_to_rework_gbp": 60, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 2, + "days_to_rework": 3, + "description": "Turbomolecular pumps for high-speed vacuum applications. 42", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1709, + "id": "21", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Turbomolecular Pumps 42", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "20", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 700, + }, + { + "id": "21", + "name": "Compression Ratio", + "unit": null, + "unit_id": null, + "value": 100, + }, + ], + }, + ], + "code": "giant-laser", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Take Democrat early money some. +Tree meet fly her likely.", + "id": "65328f34a40ff5301575a4e3", + "importance": "high", + "location": "80371 Alvarado Drive Apt. 272, Heatherhaven, MP 33307", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Giant laser", + "owner": "Juan Horton", + "parent_id": null, + "subsystems": [], + "type_id": "2", + }, + { + "catalogueItems": [ + { + "catalogue_category_id": "4", + "cost_gbp": 1200, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 8", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1309, + "id": "27", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 8", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 40, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 480, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Leica", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1300, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 9", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": null, + "id": "28", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 9", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 48, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 600, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Pentax", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1400, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 10", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3335, + "id": "29", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 4, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 10", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 52, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 720, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Sigma", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1500, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 11", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1387, + "id": "30", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 11", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 56, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 840, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Hasselblad", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1600, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 12", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2857, + "id": "31", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 12", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 60, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 960, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Red", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1700, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 13", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1050, + "id": "32", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 4, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 13", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 64, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 1080, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Phase One", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1800, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 14", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1080, + "id": "33", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "4", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 14", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 68, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 1440, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Hasselblad", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1900, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 15", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1647, + "id": "34", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 15", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 72, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 1800, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Mamiya", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 2000, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 16", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1685, + "id": "35", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 4, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 16", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 76, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 2160, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Phase One", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 2100, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 17", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2738, + "id": "36", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 17", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 80, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 2520, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Leica", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 2200, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 18", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3056, + "id": "37", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 18", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 84, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 2880, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Hasselblad", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 2300, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 19", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": null, + "id": "38", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 19", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 88, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 3240, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Mamiya", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 2400, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 20", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3613, + "id": "39", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 20", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 92, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 3600, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Phase One", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 2700, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 23", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 613, + "id": "42", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 23", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 104, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 4680, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Mamiya", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "6", + "cost_gbp": 900, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "Wavefront sensors for precise optical measurements. 30", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": null, + "id": "9", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Wavefront Sensors 30", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "11", + "name": "Wavefront Measurement Range", + "unit": null, + "unit_id": null, + "value": "0-10 micrometers", + }, + { + "id": "12", + "name": "Spatial Resolution", + "unit": "micrometers", + "unit_id": "1", + "value": 5, + }, + ], + }, + { + "catalogue_category_id": "6", + "cost_gbp": 1000, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "Wavefront sensors for precise optical measurements. 31", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2677, + "id": "10", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Wavefront Sensors 31", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "11", + "name": "Wavefront Measurement Range", + "unit": null, + "unit_id": null, + "value": "0-20 micrometers", + }, + { + "id": "12", + "name": "Spatial Resolution", + "unit": "micrometers", + "unit_id": "1", + "value": 10, + }, + ], + }, + { + "catalogue_category_id": "9", + "cost_gbp": 1100, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 90, + "days_to_rework": null, + "description": "Motorized actuators for controlled motion. 32", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 647, + "id": "11", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Motorized Actuators 32", + "notes": null, + "number_of_spares": 1, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": "10", + "properties": [ + { + "id": "13", + "name": "Travel Range", + "unit": "millimeters", + "unit_id": "5", + "value": 100, + }, + { + "id": "14", + "name": "Load Capacity", + "unit": "kilograms", + "unit_id": "6", + "value": 10, + }, + ], + }, + { + "catalogue_category_id": "9", + "cost_gbp": 1200, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "Motorized actuators for controlled motion. 33", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2778, + "id": "12", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Motorized Actuators 33", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "13", + "name": "Travel Range", + "unit": "millimeters", + "unit_id": "5", + "value": 200, + }, + { + "id": "14", + "name": "Load Capacity", + "unit": "kilograms", + "unit_id": "6", + "value": 20, + }, + ], + }, + { + "catalogue_category_id": "9", + "cost_gbp": 1300, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "Motorized actuators for controlled motion. 34", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1862, + "id": "13", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Motorized Actuators 34", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "13", + "name": "Travel Range", + "unit": "millimeters", + "unit_id": "5", + "value": 300, + }, + { + "id": "14", + "name": "Load Capacity", + "unit": "kilograms", + "unit_id": "6", + "value": 30, + }, + ], + }, + { + "catalogue_category_id": "9", + "cost_gbp": 200, + "cost_to_rework_gbp": 50, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 3, + "days_to_rework": 2, + "description": "Motorized actuators for controlled motion. 35", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1735, + "id": "14", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Motorized Actuators 35", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "13", + "name": "Travel Range", + "unit": "millimeters", + "unit_id": "5", + "value": 400, + }, + { + "id": "14", + "name": "Load Capacity", + "unit": "kilograms", + "unit_id": "6", + "value": 40, + }, + ], + }, + { + "catalogue_category_id": "11", + "cost_gbp": 150, + "cost_to_rework_gbp": 40, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 4, + "days_to_rework": 1, + "description": "Cryo pumps for maintaining low temperatures. 36", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3566, + "id": "15", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cryo Pumps 36", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "15", + "name": "Cooldown Time", + "unit": null, + "unit_id": null, + "value": "2 hours", + }, + { + "id": "16", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 50, + }, + ], + }, + { + "catalogue_category_id": "11", + "cost_gbp": 180, + "cost_to_rework_gbp": 45, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 2, + "days_to_rework": 3, + "description": "Cryo pumps for maintaining low temperatures. 37", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1875, + "id": "16", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cryo Pumps 37", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "15", + "name": "Cooldown Time", + "unit": null, + "unit_id": null, + "value": "3 hours", + }, + { + "id": "16", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 60, + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 260, + "cost_to_rework_gbp": 65, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 2, + "days_to_rework": 1, + "description": "Dry vacuum pumps for creating vacuum environments. 40", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 967, + "id": "19", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 40", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 500, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.01, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "x", + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 220, + "cost_to_rework_gbp": 55, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 1, + "days_to_rework": 4, + "description": "Dry vacuum pumps for creating vacuum environments. 41", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2903, + "id": "20", + "is_obsolete": true, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 41", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": "The item is no longer being manufactured", + "obsolete_replacement_catalogue_item_id": "19", + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 300, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.1, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "z", + }, + ], + }, + ], + "code": "pulse-laser", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Ullam fuga neque fugiat dolores laborum.", + "id": "656da8ef9cba7a76c6f81a5d", + "importance": "high", + "location": "Studio 80s +O'Sullivan trail +Victoriaville +NP1R 4QP", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Pulse Laser", + "owner": "Antony Yates", + "parent_id": null, + "subsystems": [], + "type_id": "2", + }, + { + "catalogueItems": [ + { + "catalogue_category_id": "4", + "cost_gbp": 500, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 1", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2070, + "id": "1", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 1", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 12, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 30, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": null, + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1300, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 9", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": null, + "id": "28", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 9", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 48, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 600, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Pentax", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1500, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 11", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1387, + "id": "30", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 11", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 56, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 840, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Hasselblad", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 2400, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 20", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3613, + "id": "39", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 20", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 92, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 3600, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Phase One", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "5", + "cost_gbp": 600, + "cost_to_rework_gbp": 89, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": 60, + "description": "Precision energy meters for accurate measurements. 27", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3635, + "id": "6", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Energy Meters 27", + "notes": "Need to find new manufacturer. 27", + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "7", + "name": "Measurement Range", + "unit": "Joules", + "unit_id": "3", + "value": 2000, + }, + { + "id": "8", + "name": "Accuracy", + "unit": null, + "unit_id": null, + "value": null, + }, + ], + }, + { + "catalogue_category_id": "9", + "cost_gbp": 1200, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "Motorized actuators for controlled motion. 33", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2778, + "id": "12", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Motorized Actuators 33", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "13", + "name": "Travel Range", + "unit": "millimeters", + "unit_id": "5", + "value": 200, + }, + { + "id": "14", + "name": "Load Capacity", + "unit": "kilograms", + "unit_id": "6", + "value": 20, + }, + ], + }, + { + "catalogue_category_id": "9", + "cost_gbp": 1300, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "Motorized actuators for controlled motion. 34", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1862, + "id": "13", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Motorized Actuators 34", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "13", + "name": "Travel Range", + "unit": "millimeters", + "unit_id": "5", + "value": 300, + }, + { + "id": "14", + "name": "Load Capacity", + "unit": "kilograms", + "unit_id": "6", + "value": 30, + }, + ], + }, + { + "catalogue_category_id": "11", + "cost_gbp": 150, + "cost_to_rework_gbp": 40, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 4, + "days_to_rework": 1, + "description": "Cryo pumps for maintaining low temperatures. 36", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3566, + "id": "15", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cryo Pumps 36", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "15", + "name": "Cooldown Time", + "unit": null, + "unit_id": null, + "value": "2 hours", + }, + { + "id": "16", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 50, + }, + ], + }, + { + "catalogue_category_id": "11", + "cost_gbp": 180, + "cost_to_rework_gbp": 45, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 2, + "days_to_rework": 3, + "description": "Cryo pumps for maintaining low temperatures. 37", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1875, + "id": "16", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cryo Pumps 37", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "15", + "name": "Cooldown Time", + "unit": null, + "unit_id": null, + "value": "3 hours", + }, + { + "id": "16", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 60, + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 220, + "cost_to_rework_gbp": 55, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 1, + "days_to_rework": 4, + "description": "Dry vacuum pumps for creating vacuum environments. 38", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": null, + "id": "17", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 38", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 300, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.1, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "x", + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 240, + "cost_to_rework_gbp": 60, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 3, + "days_to_rework": 2, + "description": "Dry vacuum pumps for creating vacuum environments. 39", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2378, + "id": "18", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 39", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 400, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.05, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "y", + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 260, + "cost_to_rework_gbp": 65, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 2, + "days_to_rework": 1, + "description": "Dry vacuum pumps for creating vacuum environments. 40", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 967, + "id": "19", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 40", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 500, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.01, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "x", + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 220, + "cost_to_rework_gbp": 55, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 1, + "days_to_rework": 4, + "description": "Dry vacuum pumps for creating vacuum environments. 41", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2903, + "id": "20", + "is_obsolete": true, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 41", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": "The item is no longer being manufactured", + "obsolete_replacement_catalogue_item_id": "19", + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 300, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.1, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "z", + }, + ], + }, + { + "catalogue_category_id": "13", + "cost_gbp": 250, + "cost_to_rework_gbp": 60, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 2, + "days_to_rework": 3, + "description": "Turbomolecular pumps for high-speed vacuum applications. 42", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1709, + "id": "21", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Turbomolecular Pumps 42", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "20", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 700, + }, + { + "id": "21", + "name": "Compression Ratio", + "unit": null, + "unit_id": null, + "value": 100, + }, + ], + }, + { + "catalogue_category_id": "13", + "cost_gbp": 270, + "cost_to_rework_gbp": 70, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 3, + "days_to_rework": 2, + "description": "Turbomolecular pumps for high-speed vacuum applications. 43", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 707, + "id": "22", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Turbomolecular Pumps 43", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "20", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 800, + }, + { + "id": "21", + "name": "Compression Ratio", + "unit": null, + "unit_id": null, + "value": 120, + }, + ], + }, + { + "catalogue_category_id": "14", + "cost_gbp": 300, + "cost_to_rework_gbp": 80, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 4, + "days_to_rework": 1, + "description": "Turbo pumps for efficient vacuum pumping. 44", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 291, + "id": "23", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 3, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Turbo Pumps 44", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "22", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 500, + }, + { + "id": "23", + "name": "Backing Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.2, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 900, + "cost_to_rework_gbp": 0, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": 0, + "description": "High-resolution cameras for beam characterization. 5", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3501, + "id": "24", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 2, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 5", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 28, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 120, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Panasonic", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + ], + "code": "pico-laser", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Totam maxime est.", + "id": "656ef565ed0773f82e44bc6d", + "importance": "low", + "location": "Flat 90w +Watson inlet +New Eric +G05 6SZ", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Pico Laser", + "owner": "Dr Stacey Ward", + "parent_id": null, + "subsystems": [], + "type_id": "2", + }, + { + "catalogueItems": [], + "code": "scrapped", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Scrapped system for various items.", + "id": "657f8c3b2a1b4e5d8f9b3c4e8", + "importance": "medium", + "location": "Warehouse 42 +Sector 7 +Galactic Core", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Scrapped", + "owner": "Mrs Jasmine Jackson", + "parent_id": null, + "subsystems": [], + "type_id": "3", + }, + ], + "type_id": "", + }, +] +`; + +exports[`System api functions > useGetSystemsTree > fetches systems and items for a specific system ID successfully 1`] = ` +[ + { + "catalogueItems": [ + { + "catalogue_category_id": "4", + "cost_gbp": 700, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 3", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 322, + "id": "3", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "1", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 3", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 20, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 120, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Canon", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 1900, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 15", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1647, + "id": "34", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 15", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 72, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 1800, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Mamiya", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 2100, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 17", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2738, + "id": "36", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 17", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 80, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 2520, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CCD", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Leica", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 2800, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 24", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 449, + "id": "43", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 24", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 108, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 5040, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Phase One", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "6", + "cost_gbp": 1000, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "Wavefront sensors for precise optical measurements. 31", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2677, + "id": "10", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Wavefront Sensors 31", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "11", + "name": "Wavefront Measurement Range", + "unit": null, + "unit_id": null, + "value": "0-20 micrometers", + }, + { + "id": "12", + "name": "Spatial Resolution", + "unit": "micrometers", + "unit_id": "1", + "value": 10, + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 240, + "cost_to_rework_gbp": 60, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 3, + "days_to_rework": 2, + "description": "Dry vacuum pumps for creating vacuum environments. 39", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2378, + "id": "18", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 39", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 400, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.05, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "y", + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 900, + "cost_to_rework_gbp": 0, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": 0, + "description": "High-resolution cameras for beam characterization. 5", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3501, + "id": "24", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 5", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 28, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 120, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Panasonic", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + ], + "code": "laser-star", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Might green few thank current.", + "id": "65328f34a40ff5301575a4e7", + "importance": "high", + "location": "USS Smith +FPO AE 71714", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Laser Star", + "owner": "Kelli Scott", + "parent_id": "65328f34a40ff5301575a4e6", + "subsystems": [ + { + "catalogueItems": [ + { + "catalogue_category_id": "4", + "cost_gbp": 2600, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 22", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1269, + "id": "41", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 22", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 100, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 4320, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Hasselblad", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 220, + "cost_to_rework_gbp": 55, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 1, + "days_to_rework": 4, + "description": "Dry vacuum pumps for creating vacuum environments. 38", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": null, + "id": "17", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 38", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 300, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.1, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "x", + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 240, + "cost_to_rework_gbp": 60, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 3, + "days_to_rework": 2, + "description": "Dry vacuum pumps for creating vacuum environments. 39", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2378, + "id": "18", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 39", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 400, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.05, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "y", + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 900, + "cost_to_rework_gbp": 0, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": 0, + "description": "High-resolution cameras for beam characterization. 5", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3501, + "id": "24", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 5", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 28, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 120, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Panasonic", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + ], + "code": "laser-xpress", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Left money allow begin garden. Method time single none.", + "id": "65328f34a40ff5301575a4e8", + "importance": "high", + "location": "375 Wilson Ranch Suite 965 +Lake Alisonville, KS 63575", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Laser Xpress", + "owner": "Mrs. Susan Barnes", + "parent_id": "65328f34a40ff5301575a4e7", + "subsystems": [ + { + "catalogueItems": [ + { + "catalogue_category_id": "4", + "cost_gbp": 2600, + "cost_to_rework_gbp": null, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": null, + "description": "High-resolution cameras for beam characterization. 22", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 1269, + "id": "41", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 22", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 100, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 4320, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Hasselblad", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": false, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": true, + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 220, + "cost_to_rework_gbp": 55, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 1, + "days_to_rework": 4, + "description": "Dry vacuum pumps for creating vacuum environments. 38", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": null, + "id": "17", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 38", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 300, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.1, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "x", + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 240, + "cost_to_rework_gbp": 60, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 3, + "days_to_rework": 2, + "description": "Dry vacuum pumps for creating vacuum environments. 39", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2378, + "id": "18", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 39", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 400, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.05, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "y", + }, + ], + }, + { + "catalogue_category_id": "4", + "cost_gbp": 900, + "cost_to_rework_gbp": 0, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 7, + "days_to_rework": 0, + "description": "High-resolution cameras for beam characterization. 5", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 3501, + "id": "24", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "2", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Cameras 5", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "1", + "name": "Resolution", + "unit": "megapixels", + "unit_id": "1", + "value": 28, + }, + { + "id": "2", + "name": "Frame Rate", + "unit": "fps", + "unit_id": "2", + "value": 120, + }, + { + "id": "3", + "name": "Sensor Type", + "unit": null, + "unit_id": null, + "value": "CMOS", + }, + { + "id": "4", + "name": "Sensor brand", + "unit": null, + "unit_id": null, + "value": "Panasonic", + }, + { + "id": "5", + "name": "Broken", + "unit": null, + "unit_id": null, + "value": true, + }, + { + "id": "6", + "name": "Older than five years", + "unit": null, + "unit_id": null, + "value": false, + }, + ], + }, + ], + "code": "laser-xpress", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Left money allow begin garden. Method time single none.", + "id": "65328f34a40ff5301575a4e8", + "importance": "high", + "location": "375 Wilson Ranch Suite 965 +Lake Alisonville, KS 63575", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Laser Xpress", + "owner": "Mrs. Susan Barnes", + "parent_id": "65328f34a40ff5301575a4e7", + "subsystems": [ + { + "catalogueItems": [ + { + "catalogue_category_id": "12", + "cost_gbp": 220, + "cost_to_rework_gbp": 55, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 1, + "days_to_rework": 4, + "description": "Dry vacuum pumps for creating vacuum environments. 38", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": null, + "id": "17", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 38", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 300, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.1, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "x", + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 240, + "cost_to_rework_gbp": 60, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 3, + "days_to_rework": 2, + "description": "Dry vacuum pumps for creating vacuum environments. 39", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2378, + "id": "18", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 39", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 400, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.05, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "y", + }, + ], + }, + ], + "code": "plasma-beam", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Test believe performance behind staff. When pick figure suffer responsibility.", + "id": "65328f34a40ff5301575a4e9", + "importance": "high", + "location": "205 Jeffrey Mountains +Jessicaside, ND 78734", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Plasma Beam", + "owner": "Adam Adams", + "parent_id": "65328f34a40ff5301575a4e8", + "subsystems": [ + { + "catalogueItems": [ + { + "catalogue_category_id": "12", + "cost_gbp": 220, + "cost_to_rework_gbp": 55, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 1, + "days_to_rework": 4, + "description": "Dry vacuum pumps for creating vacuum environments. 38", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": null, + "id": "17", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 38", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 300, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.1, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "x", + }, + ], + }, + { + "catalogue_category_id": "12", + "cost_gbp": 240, + "cost_to_rework_gbp": 60, + "created_time": "2024-01-01T12:00:00.000+00:00", + "days_to_replace": 3, + "days_to_rework": 2, + "description": "Dry vacuum pumps for creating vacuum environments. 39", + "drawing_link": null, + "drawing_number": null, + "expected_lifetime_days": 2378, + "id": "18", + "is_obsolete": false, + "item_model_number": null, + "itemsQuantity": 1, + "manufacturer_id": "3", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Dry Vacuum Pumps 39", + "notes": null, + "number_of_spares": 0, + "obsolete_reason": null, + "obsolete_replacement_catalogue_item_id": null, + "properties": [ + { + "id": "17", + "name": "Pumping Speed", + "unit": "liters per second", + "unit_id": "7", + "value": 400, + }, + { + "id": "18", + "name": "Ultimate Pressure", + "unit": "millibar", + "unit_id": "8", + "value": 0.05, + }, + { + "id": "19", + "name": "Axis", + "unit": null, + "unit_id": null, + "value": "y", + }, + ], + }, + ], + "code": "plasma-beam", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Test believe performance behind staff. When pick figure suffer responsibility.", + "id": "65328f34a40ff5301575a4e9", + "importance": "high", + "location": "205 Jeffrey Mountains +Jessicaside, ND 78734", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Plasma Beam", + "owner": "Adam Adams", + "parent_id": "65328f34a40ff5301575a4e8", + "subsystems": [], + "type_id": "2", + }, + ], + "type_id": "2", + }, + ], + "type_id": "2", + }, + ], + "type_id": "2", + }, + ], + "type_id": "2", + }, +] +`; + +exports[`System api functions > useGetSystemsTree > fetches systems and items with default depth and subsystemsCutOffPoint successfully 1`] = ` +[ + { + "catalogueItems": [], + "code": "storage", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Storage system for various items.", + "id": "657f8c3b2a1b4e5d8f9b3c4e5", + "importance": "medium", + "location": "Warehouse 42 +Sector 7 +Galactic Core", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Storage", + "owner": "Prof Peter Jackson", + "parent_id": null, + "subsystems": [], + "type_id": "1", + }, + { + "catalogueItems": [], + "code": "giant-laser", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Take Democrat early money some. +Tree meet fly her likely.", + "id": "65328f34a40ff5301575a4e3", + "importance": "high", + "location": "80371 Alvarado Drive Apt. 272, Heatherhaven, MP 33307", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Giant laser", + "owner": "Juan Horton", + "parent_id": null, + "subsystems": [], + "type_id": "2", + }, + { + "catalogueItems": [], + "code": "pulse-laser", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Ullam fuga neque fugiat dolores laborum.", + "id": "656da8ef9cba7a76c6f81a5d", + "importance": "high", + "location": "Studio 80s +O'Sullivan trail +Victoriaville +NP1R 4QP", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Pulse Laser", + "owner": "Antony Yates", + "parent_id": null, + "subsystems": [], + "type_id": "2", + }, + { + "catalogueItems": [], + "code": "pico-laser", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Totam maxime est.", + "id": "656ef565ed0773f82e44bc6d", + "importance": "low", + "location": "Flat 90w +Watson inlet +New Eric +G05 6SZ", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Pico Laser", + "owner": "Dr Stacey Ward", + "parent_id": null, + "subsystems": [], + "type_id": "2", + }, + { + "catalogueItems": [], + "code": "scrapped", + "created_time": "2024-01-01T12:00:00.000+00:00", + "description": "Scrapped system for various items.", + "id": "657f8c3b2a1b4e5d8f9b3c4e8", + "importance": "medium", + "location": "Warehouse 42 +Sector 7 +Galactic Core", + "modified_time": "2024-01-02T13:10:10.000+00:00", + "name": "Scrapped", + "owner": "Mrs Jasmine Jackson", + "parent_id": null, + "subsystems": [], + "type_id": "3", + }, +] +`; diff --git a/src/api/catalogueCategories.tsx b/src/api/catalogueCategories.tsx index be099495e..e18618f4a 100644 --- a/src/api/catalogueCategories.tsx +++ b/src/api/catalogueCategories.tsx @@ -11,6 +11,7 @@ import { CopyToCatalogueCategory, MoveToCatalogueCategory, TransferState, + type GetQueryOptionsType, } from '../app.types'; import handleTransferState from '../handleTransferState'; @@ -475,7 +476,7 @@ const getCatalogueCategory = async ( export const getCatalogueCategoryQuery = ( id?: string | null, - loader?: boolean + extraOptions?: GetQueryOptionsType ) => queryOptions({ queryKey: ['CatalogueCategory', id], @@ -483,7 +484,7 @@ export const getCatalogueCategoryQuery = ( return getCatalogueCategory(id ?? ''); }, enabled: !!id, - retry: loader ? false : undefined, + ...extraOptions, }); export const useGetCatalogueCategory = ( diff --git a/src/api/catalogueItems.tsx b/src/api/catalogueItems.tsx index 4912acbe3..e6a4d12a3 100644 --- a/src/api/catalogueItems.tsx +++ b/src/api/catalogueItems.tsx @@ -8,7 +8,11 @@ import { useQueryClient, } from '@tanstack/react-query'; import { AxiosError } from 'axios'; -import { TransferState, TransferToCatalogueItem } from '../app.types'; +import { + TransferState, + TransferToCatalogueItem, + type GetQueryOptionsType, +} from '../app.types'; import { imsApi } from './api'; import { APIError, @@ -84,7 +88,7 @@ const getCatalogueItem = async ( export const getCatalogueItemQuery = ( catalogueCategoryId: string | undefined, - loader?: boolean + extraOptions?: GetQueryOptionsType ) => queryOptions({ queryKey: ['CatalogueItem', catalogueCategoryId], @@ -92,7 +96,7 @@ export const getCatalogueItemQuery = ( return getCatalogueItem(catalogueCategoryId); }, enabled: catalogueCategoryId !== undefined, - retry: loader ? false : undefined, + ...extraOptions, }); export const useGetCatalogueItem = ( diff --git a/src/api/items.tsx b/src/api/items.tsx index a4e26111c..48736f00b 100644 --- a/src/api/items.tsx +++ b/src/api/items.tsx @@ -7,7 +7,12 @@ import { UseQueryResult, } from '@tanstack/react-query'; import { AxiosError } from 'axios'; -import { MoveItemsToSystem, PostItems, TransferState } from '../app.types'; +import { + MoveItemsToSystem, + PostItems, + TransferState, + type GetQueryOptionsType, +} from '../app.types'; import { imsApi } from './api'; import { APIError, Item, ItemPatch, ItemPost } from './api.types'; @@ -107,17 +112,25 @@ const getItems = async ( }); }; -export const useGetItems = ( +export const getItemsQuery = ( system_id?: string, - catalogue_item_id?: string -): UseQueryResult => { - return useQuery({ + catalogue_item_id?: string, + extraOptions?: GetQueryOptionsType +) => + queryOptions({ queryKey: ['Items', system_id, catalogue_item_id], queryFn: () => { return getItems(system_id, catalogue_item_id); }, enabled: system_id !== undefined || catalogue_item_id !== undefined, + ...extraOptions, }); + +export const useGetItems = ( + system_id?: string, + catalogue_item_id?: string +): UseQueryResult => { + return useQuery(getItemsQuery(system_id, catalogue_item_id)); }; const getItem = async (id: string): Promise => { @@ -132,14 +145,17 @@ const getItem = async (id: string): Promise => { }); }; -export const getItemQuery = (id?: string | null, loader?: boolean) => +export const getItemQuery = ( + id?: string | null, + extraOptions?: GetQueryOptionsType +) => queryOptions({ queryKey: ['Item', id], queryFn: () => { return getItem(id ?? ''); }, enabled: !!id, - retry: loader ? false : undefined, + ...extraOptions, }); export const useGetItem = ( diff --git a/src/api/manufacturers.tsx b/src/api/manufacturers.tsx index b862826bc..8765146b2 100644 --- a/src/api/manufacturers.tsx +++ b/src/api/manufacturers.tsx @@ -9,6 +9,7 @@ import { } from '@tanstack/react-query'; import { AxiosError } from 'axios'; +import type { GetQueryOptionsType } from '../app.types'; import { imsApi } from './api'; import { Manufacturer, ManufacturerPatch, ManufacturerPost } from './api.types'; @@ -76,12 +77,15 @@ const getManufacturer = async (id: string): Promise => { .get(`/v1/manufacturers/${id}`) .then((response) => response.data); }; -export const getManufacturerQuery = (id?: string | null, retry?: boolean) => +export const getManufacturerQuery = ( + id?: string | null, + extraOptions?: GetQueryOptionsType +) => queryOptions({ queryKey: ['Manufacturer', id], queryFn: () => getManufacturer(id ?? ''), enabled: !!id, - retry: retry ? false : undefined, + ...extraOptions, }); export const useGetManufacturer = ( diff --git a/src/api/systems.test.tsx b/src/api/systems.test.tsx index e87353725..5446357f2 100644 --- a/src/api/systems.test.tsx +++ b/src/api/systems.test.tsx @@ -19,6 +19,7 @@ import { useGetSystemIds, useGetSystems, useGetSystemsBreadcrumbs, + useGetSystemsTree, useGetSystemTypes, useMoveToSystem, usePatchSystem, @@ -88,11 +89,71 @@ describe('System api functions', () => { await waitFor(() => { expect(result.current.isSuccess).toBeTruthy(); }); - expect(result.current.data).toEqual(SystemTypesJSON); }); }); + describe('useGetSystemsTree', () => { + it('fetches root-level systems and items with depth of 1 successfully', async () => { + const { result } = renderHook(() => useGetSystemsTree(null, 1), { + wrapper: hooksWrapperWithProviders(), + }); + + await waitFor(() => { + expect(result.current.isSuccess).toBeTruthy(); + }); + + expect(result.current.data).toMatchSnapshot(); + }); + + it('fetches systems and items for a specific system ID successfully', async () => { + const { result } = renderHook( + () => useGetSystemsTree('65328f34a40ff5301575a4e7'), + { + wrapper: hooksWrapperWithProviders(), + } + ); + + await waitFor(() => { + expect(result.current.isSuccess).toBeTruthy(); + }); + + expect(result.current.data).toMatchSnapshot(); + }); + + it('throws an error when total subsystems exceed the maxSubsystems limit', async () => { + const { result } = renderHook( + () => useGetSystemsTree(null, undefined, 2, 0), + { + wrapper: hooksWrapperWithProviders(), + } + ); + + await waitFor(() => { + expect(result.current.isError).toBeTruthy(); + }); + + expect(result.current.error?.message).toEqual( + 'Total subsystems exceeded the maximum allowed limit of 0. Current count: 3' + ); + }); + + it('fetches systems and items with default depth and subsystemsCutOffPoint successfully', async () => { + const { result } = renderHook( + () => useGetSystemsTree(null, undefined, 1), + { + wrapper: hooksWrapperWithProviders(), + } + ); + + await waitFor(() => { + expect(result.current.isSuccess).toBeTruthy(); + }); + + expect(result.current.data).toMatchSnapshot(); + }); + }); + describe('useGetSystem', () => { it('does not send a request when given an id of null', async () => { const { result } = renderHook(() => useGetSystem(null), { diff --git a/src/api/systems.tsx b/src/api/systems.tsx index 002ccbfc0..40c449da2 100644 --- a/src/api/systems.tsx +++ b/src/api/systems.tsx @@ -6,9 +6,15 @@ import { useQueries, useQuery, useQueryClient, + type QueryClient, } from '@tanstack/react-query'; import { AxiosError } from 'axios'; -import { CopyToSystem, MoveToSystem, TransferState } from '../app.types'; +import { + CopyToSystem, + MoveToSystem, + TransferState, + type GetQueryOptionsType, +} from '../app.types'; import { generateUniqueNameUsingCode } from '../utils'; import { imsApi } from './api'; import { @@ -19,7 +25,10 @@ import { SystemPatch, SystemPost, SystemType, + type CatalogueItem, } from './api.types'; +import { getCatalogueItemQuery } from './catalogueItems'; +import { getItemsQuery } from './items'; /** Utility for turning an importance into an MUI palette colour to display */ export const getSystemImportanceColour = ( @@ -70,15 +79,22 @@ export const useGetSystemIds = (ids: string[]): UseQueryResult[] => { }); }; -export const useGetSystems = ( - parent_id?: string -): UseQueryResult => { - return useQuery({ - queryKey: ['Systems', parent_id], +export const getSystemsQuery = ( + id?: string, + extraOptions?: GetQueryOptionsType +) => + queryOptions({ + queryKey: ['Systems', id], queryFn: () => { - return getSystems(parent_id); + return getSystems(id); }, + ...extraOptions, }); + +export const useGetSystems = ( + parent_id?: string +): UseQueryResult => { + return useQuery(getSystemsQuery(parent_id)); }; const getSystem = async (id: string): Promise => { @@ -87,14 +103,17 @@ const getSystem = async (id: string): Promise => { }); }; -export const getSystemQuery = (id?: string | null, loader?: boolean) => +export const getSystemQuery = ( + id?: string | null, + extraOptions?: GetQueryOptionsType +) => queryOptions({ queryKey: ['System', id], queryFn: () => { return getSystem(id ?? ''); }, enabled: !!id, - retry: loader ? false : undefined, + ...extraOptions, }); // Allows a value of undefined or null to disable @@ -104,6 +123,185 @@ export const useGetSystem = ( return useQuery(getSystemQuery(id)); }; +export interface SystemTree extends Partial { + catalogueItems: (CatalogueItem & { itemsQuantity: number })[]; + subsystems?: SystemTree[]; +} + +const GET_SYSTEM_TREE_QUERY_OPTIONS = { + staleTime: 1000 * 60 * 5, +}; + +const getSystemTree = async ( + queryClient: QueryClient, + parent_id: string, + maxSubsystems: number, + maxDepth?: number, + currentDepth: number = 0, + subsystemsCutOffPoint?: number, + totalSubsystems: { count: number } = { count: 0 }, + catalogueItemCache: Map = new Map(), + systemsCache: Map = new Map() // Cache for systems +): Promise => { + if (maxDepth !== undefined && currentDepth >= maxDepth) return []; + + // Determine the root system from cache + let rootSystem: System; + + if (parent_id === 'null') { + rootSystem = { + name: 'Root', + code: 'root', + id: 'root', + created_time: '', + type_id: '', + modified_time: '', + description: null, + location: null, + owner: null, + importance: SystemImportanceType.LOW, + parent_id: null, + }; + } else { + // Check cache for the parent system + if (!systemsCache.has(parent_id)) { + const fetchedSystem = await queryClient.fetchQuery( + getSystemQuery(parent_id, GET_SYSTEM_TREE_QUERY_OPTIONS) + ); + systemsCache.set(parent_id, fetchedSystem); // Cache only the parent system + } + rootSystem = systemsCache.get(parent_id)!; + } + + // Fetch systems at the current level + const systems = await queryClient.fetchQuery( + getSystemsQuery(parent_id, GET_SYSTEM_TREE_QUERY_OPTIONS) + ); + + // Store all fetched systems in cache + systems.forEach((system) => { + if (!systemsCache.has(system.id)) { + systemsCache.set(system.id, system); + } + }); + + totalSubsystems.count += systems.length; + if (maxSubsystems !== undefined && totalSubsystems.count > maxSubsystems) { + throw new Error( + `Total subsystems exceeded the maximum allowed limit of ${maxSubsystems}. Current count: ${totalSubsystems.count}` + ); + } + + if ( + subsystemsCutOffPoint !== undefined && + totalSubsystems.count > subsystemsCutOffPoint + ) { + return systems.map((system) => ({ + ...system, + subsystems: [], + catalogueItems: [], + })); + } + + // Fetch subsystems recursively + const systemsWithTree = await Promise.all( + systems.map(async (system) => ({ + ...system, + subsystems: await getSystemTree( + queryClient, + system.id, + maxSubsystems, + maxDepth, + currentDepth + 1, + subsystemsCutOffPoint, + totalSubsystems, + catalogueItemCache, + systemsCache + ), + catalogueItems: await fetchCatalogueItems( + queryClient, + system.id, + catalogueItemCache + ), + })) + ); + + return [ + { + ...rootSystem, + catalogueItems: await fetchCatalogueItems( + queryClient, + parent_id, + catalogueItemCache + ), + subsystems: systemsWithTree, + }, + ]; +}; + +// Helper function for fetching and caching catalogue items +const fetchCatalogueItems = async ( + queryClient: QueryClient, + systemId: string, + catalogueItemCache: Map +): Promise => { + const items = await queryClient.fetchQuery( + getItemsQuery(systemId, undefined, GET_SYSTEM_TREE_QUERY_OPTIONS) + ); + + const catalogueItems: SystemTree['catalogueItems'] = []; + const catalogueItemIdSet = new Set( + items.map((item) => item.catalogue_item_id) + ); + + for (const id of Array.from(catalogueItemIdSet)) { + catalogueItemCache.set( + id, + catalogueItemCache.get(id) || + (await queryClient.fetchQuery( + getCatalogueItemQuery(id, GET_SYSTEM_TREE_QUERY_OPTIONS) + )) + ); + catalogueItems.push({ + ...catalogueItemCache.get(id)!, + itemsQuantity: items.filter((item) => item.catalogue_item_id === id) + .length, + }); + } + + return catalogueItems; +}; + +export const useGetSystemsTree = ( + parent_id?: string | null, + maxDepth?: number, + subsystemsCutOffPoint?: number, // Add cutoff point as a parameter + maxSubsystems?: number +): UseQueryResult => { + const queryClient = useQueryClient(); + + return useQuery({ + // eslint-disable-next-line @tanstack/query/exhaustive-deps + queryKey: [ + 'SystemsTree', + parent_id, + maxSubsystems, + maxDepth, + subsystemsCutOffPoint, + ], + queryFn: () => + getSystemTree( + queryClient, + parent_id ?? 'null', + maxSubsystems ?? 150, + maxDepth, + 0, + subsystemsCutOffPoint + ), + ...GET_SYSTEM_TREE_QUERY_OPTIONS, + }); +}; + const getSystemsBreadcrumbs = async (id: string): Promise => { return imsApi.get(`/v1/systems/${id}/breadcrumbs`, {}).then((response) => { return response.data; diff --git a/src/app.types.tsx b/src/app.types.tsx index a119b890f..2f44347db 100644 --- a/src/app.types.tsx +++ b/src/app.types.tsx @@ -1,4 +1,6 @@ +import type { UndefinedInitialDataOptions } from '@tanstack/react-query'; import type { Body, Meta } from '@uppy/core'; +import type { AxiosError } from 'axios'; import { MRT_ColumnFiltersState } from 'material-react-table'; import { CatalogueCategory, @@ -47,6 +49,15 @@ export interface AllowedValuesList { }; } +export type GetQueryOptionsType = Omit< + UndefinedInitialDataOptions< + T, + AxiosError, + T, + readonly unknown[] + >, + 'queryKey' +>; // ------------------------------------ CATALOGUE CATEGORIES ------------------------------------ export type AllowedValues = AllowedValuesList; diff --git a/src/catalogue/__snapshots__/catalogueLayout.component.test.tsx.snap b/src/catalogue/__snapshots__/catalogueLayout.component.test.tsx.snap index d9a13d21f..c0562cfb4 100644 --- a/src/catalogue/__snapshots__/catalogueLayout.component.test.tsx.snap +++ b/src/catalogue/__snapshots__/catalogueLayout.component.test.tsx.snap @@ -1090,7 +1090,7 @@ exports[`Catalogue Layout Error Component > renders catalogue error page correct > diff --git a/src/catalogue/catalogueLayout.component.tsx b/src/catalogue/catalogueLayout.component.tsx index 1717ab73b..2535cd843 100644 --- a/src/catalogue/catalogueLayout.component.tsx +++ b/src/catalogue/catalogueLayout.component.tsx @@ -43,12 +43,12 @@ export const catalogueLayoutLoader = if (catalogueCategoryId) { await queryClient.ensureQueryData( - getCatalogueCategoryQuery(catalogueCategoryId, true) + getCatalogueCategoryQuery(catalogueCategoryId, { retry: false }) ); } if (catalogueItemId && catalogueCategoryId) { const catalogueItem = await queryClient.ensureQueryData( - getCatalogueItemQuery(catalogueItemId, true) + getCatalogueItemQuery(catalogueItemId, { retry: false }) ); if (catalogueItem.catalogue_category_id !== catalogueCategoryId) { @@ -59,7 +59,7 @@ export const catalogueLayoutLoader = } if (catalogueItemId && catalogueCategoryId && itemId) { const item = await queryClient.ensureQueryData( - getItemQuery(itemId, true) + getItemQuery(itemId, { retry: false }) ); if (item.catalogue_item_id !== catalogueItemId) { throw new Error( diff --git a/src/catalogue/items/__snapshots__/catalogueItemsDetailsPanel.component.test.tsx.snap b/src/catalogue/items/__snapshots__/catalogueItemsDetailsPanel.component.test.tsx.snap index 7a52daca9..353e4e57e 100644 --- a/src/catalogue/items/__snapshots__/catalogueItemsDetailsPanel.component.test.tsx.snap +++ b/src/catalogue/items/__snapshots__/catalogueItemsDetailsPanel.component.test.tsx.snap @@ -2820,7 +2820,7 @@ exports[`Catalogue Items details panel > renders manufacturer panel correctly 1` @@ -3939,7 +3923,7 @@ exports[`Catalogue Items details panel > renders properties panel correctly (emp @@ -3669,7 +3653,7 @@ exports[`Items details panel > renders properties panel correctly (empty propert +
+ + + + + + +
@@ -203,6 +261,64 @@ exports[`Systems Layout > renders units breadcrumbs correctly 1`] = ` +
+ + + + + + +
@@ -262,7 +378,7 @@ exports[`Systems Layout Error Component > renders system error page correctly 1` >