Hardware Components
Hardware components are loaded by the Hardware Object component. The type
from the REST response tells the UI which component to load using the objMap
lookup table. To add a new component import your component and extend this object.
import MyComponent from 'components/hardware/MyComponent';
export const objMap = {
...
mycomponent: MyComponent
}
Building a New Hardware Component
Components should be placed into src/components/hardware
and export a single default component. New components should be built as React functional component using typescript.
To be consistent with other hardware objects components should make use of <HardwareTemplate>
, <HardwareState>
, and <TypeIcon>
.
options
should extend HardwareTypes.HardwareWidgetOptions
and document its properties using jsdoc notation.
import {
TypeIcon,
HardwareTemplate,
HardwareState,
HardwareTypes,
} from '@esrf/daiquiri-lib';
// Define the interface of the properties recieved from the REST API
export interface ComponentSchema extends HardwareTypes.Hardware {
properties: {
property: string;
property2: number;
};
}
// Define the interface of the component options
export interface ComponentOptions extends HardwareTypes.HardwareWidgetOptions {
/** Make the arrows large */
large?: number;
}
export function Component(
props: HardwareTypes.HardwareWidgetProps<ComponentSchema, ComponentOptions>
) {
const { hardware, options = {}, disabled } = props;
const { state } = hardware.properties;
return (
<HardwareTemplate
hardware={hardware}
widgetIcon={
<TypeIcon name="Component" icon="fa-cog" online={hardware.online} />
}
widgetState={
<HardwareState.HardwareState
state={state}
minWidth={6}
variant={state === 'READY' ? 'success' : 'warning'}
/>
}
widgetContent={
...
}
/>
);
}
Will render:
Props
Components will be passed a series of props:
HardwareTypes.EditableHardware<HWComponentSchema>
HWComponentSchema
Schemas are defined by the server for properties
and callables
, both in standard
JSONSchema format. These can be used for validation and
automatic form creation with react-jsonschema-form
Options
An example layout yaml from the server may look like:
- type: component
component: hardware
title: Diffractometer3
ids:
- id: omega
variant: small
step: 90
- id: robz
variant: small
precision: 3
variant
, step
, and precision
will be passed as options
into the specific hardware component.
TypeIcon
The <TypeIcon>
component takes a few props
Updating Components
The hardware.actions
prop can be used to update the hardware object on the server. This function can be called in two ways, one to modify a property and the other to make a function call.
To update a property:
onClick = () => {
hardware.actions.setProperty('exposure', 0.5);
};
To call a function:
onClick = () => {
hardware.actions.call('move', 10);
};
Variants
For some components it is useful to specify different variants. For example a normal motor widget and a small one. Daiquiri UI provides some helper classes to implement this functionality easily.
For example the motor variant class:
import { HardwareVariant } from '@esrf/daiquiri-lib';
import MotorDefault from 'components/hardware/motor/MotorDefault';
import MotorSmall from 'components/hardware/motor/MotorSmall';
export default class Motor extends HardwareVariant {
variants = {
default: MotorDefault,
small: MotorSmall,
};
}
The HardwareVariant
class responds to the variant
option from the yaml config. If a variant is not found the component will use the default
.
- type: component
component: hardware
title: Diffractometer3
options:
ids:
- id: omega
variant: small
step: 90
Documentation
Make sure to provide a component mockup, this should be placed into docusaurus/docs/ui-components/hardware/MyComponent.mdx
and the json
markup for the mock response should go in src/components/mocks/hardware/MyComponent.json
.
The component should be wrapped in <DaiquiriHardwareObject>
in the markdown documentation file and will be transformed into a component mockup, for example:
import DaiquiriHardwareObject from '@site/src/DaiquiriHardwareObject';
import Shutter from 'daiquiri-ui/src/components/hardware/shutter';
import shutter from 'daiquiri-ui/src/components/mocks/shutter/BeamShutter.json';
<DaiquiriHardwareObject>
<Shutter hardware={shutter} options={{ extended: true }} />;
</DaiquiriHardwareObject>;
Will render:
Options Documentation
A dummy component can be created using only the options
interface as its props. This can then be automatically used to generate a props
table for the object. This component should be placed in the docusaurus/src/options
folder as it serves no purpose in the application code base.
For example:
export function HWComponentOptions(props: HWComponentOptions) {
return null;
}
Will generate a prop types definition for the options which can be loaded via:
import PropTable from '@site/src/PropTable';
<PropTable component="HWComponentOptions" />;
Which will render: