/** @jsx jsx */ /** @jsxFrag React.Fragment */ import update from 'immutability-helper'; import React from 'react'; import { jsx, css } from '@emotion/react'; import { Checkbox, ControlGroup, ControlGroupProps, InputGroup } from '@blueprintjs/core'; import { PropertyDetailView } from '@riboseinc/paneron-registry-kit/views/util'; import type { ItemClassConfiguration, ItemListView } from '@riboseinc/paneron-registry-kit/types'; import { type CommonGRItemData, COMMON_PROPERTIES, DEFAULTS as SHARED_DEFAULTS, EditView as CommonEditView, ListItemView as CommonListItemView, RelatedItem, } from './common'; export interface EllipsoidData extends CommonGRItemData { inverseFlattening: number | null inverseFlatteningUoM: string | null semiMajorAxis: number | null semiMajorAxisUoM: string | null isSphere: boolean // Ellipsoid only (isSphere == false): semiMinorAxis: number | null semiMinorAxisUoM: string | null } export const ellipsoid: ItemClassConfiguration = { ...COMMON_PROPERTIES, meta: { title: "Ellipsoid", description: "Ellipsoid", id: 'ellipsoid', alternativeNames: [] as const, }, defaults: { ...SHARED_DEFAULTS, }, views: { listItemView: CommonListItemView as ItemListView, editView: ({ itemData, onChange, itemRef, ...props }) => ( { onChange?.({ ...itemData, ...newData }); } : undefined}> onChange!(update(itemData, { isSphere: { $set: e.currentTarget.checked } }))} /> onChange!(update(itemData, { semiMajorAxis: { $set: num }, semiMajorAxisUoM: { $set: uom }, })) : undefined} /> {!itemData.isSphere || itemData.semiMinorAxis || itemData.semiMinorAxisUoM || itemData.inverseFlattening || itemData.inverseFlatteningUoM ? <> onChange!(update(itemData, { inverseFlattening: { $set: num }, inverseFlatteningUoM: { $set: uom }, })) : undefined} val={[ itemData.inverseFlattening, itemData.inverseFlatteningUoM, ]} /> onChange!(update(itemData, { semiMinorAxis: { $set: num }, semiMinorAxisUoM: { $set: uom }, })) : undefined} /> : null} ), }, validatePayload: async () => true, sanitizePayload: async (t) => t, }; /** * Shows a float value with an accompanying unit of measurement related item * as a control group. */ const FloatWithUoM: React.FC<{ val: [num: number | null, uom: string | null], showUoM: boolean, onChange?: (newVal: [number | null, string | null]) => void, fill?: ControlGroupProps["fill"], controlGroupProps?: ControlGroupProps, className?: string, }> = function ({ val, showUoM, onChange, fill, controlGroupProps, className }) { const [invalidValue, setInvalidValue] = React.useState(null); const handleRawValueChange = React.useCallback(function handleRawValueChange(rawVal: string) { if (!onChange) { return; } if (['.', ','].map(char => rawVal.trim().endsWith(char)).find(c => c === true)) { //console.debug("Cannot parse float", rawVal); setInvalidValue(rawVal); } else { try { const parsed = parseFloat(rawVal); //console.debug("Parsed float", rawVal, parsed); onChange!([parsed, val[1]]); setInvalidValue(null); } catch (e) { //console.debug("Cannot parse float", rawVal); setInvalidValue(rawVal); } } }, [onChange, setInvalidValue]); return ( { handleRawValueChange(evt.currentTarget.value); }} value={invalidValue !== null ? invalidValue : val[0]?.toString() || ''} /> {showUoM ? onChange([null, null]))} onSet={onChange ? ((spec) => onChange(update(val, { 1: spec } ))) : undefined} mode="id" classIDs={['unit-of-measurement']} /> : null} ); };