New widgets
In order to add new custom widgets you should follow these steps:
Create the logic model in ooui.js
You must add the new widget logic data implementation in the ooui.js module.
In this example we will be adding a new widget called Timeline which will be a different representation of the current widget One2many.
We create the main widget file in src/Timeline.ts:
import One2many from "./One2many";
class Timeline extends One2many {}
export default Timeline;Since the main logic will be the same than One2many, we just extend it.
Then, we export the widget in src/index.ts:
import Timeline from "./Timeline";
export { // ... Timeline,}And the last step in this part is to add the new widget in the WidgetFactory.ts.
We add the import:
import Timeline from "./Timeline";Inside the setWidgetClass method, we add:
case "timeline": this._widgetClass = Timeline; break;Note that the string “timeline”, will be the string used in the arch XML definition to indicate that we want to use this kind of widget.
Then, we build the library:
npm run buildAnd if we link it with npm link in order to use this local module in our other dependencies.
Create the UI widget implementation in react-ooui
In order to use the local linked module for our previous changes in ooui.js, we run this in our react-ooui root:
npm link "@gisce/ooui"Then, we create our first version of the Timeline.tsx widget, inside src/widgets/custom. This is a first basic implementation for learning purposes:
import React from "react";import { Timeline as TimelineOoui } from "@gisce/ooui";import Field from "@/common/Field";import { One2manyItem } from "../base/one2many/One2manyInput";
type TimelineProps = { ooui: TimelineOoui;};
type TimelineInputProps = TimelineProps & { value?: Array<One2manyItem>; onChange?: (value: any[]) => void;};
export const Timeline = (props: TimelineProps) => { const { ooui } = props;
return ( <Field type={"array"} {...props}> <TimelineInput ooui={ooui} /> </Field> );};
export const TimelineInput = (props: TimelineInputProps) => { const { value } = props;
return <>{JSON.stringify(value, null, 2)}</>;};This will result in a widget that shows an string of the current value.
Once this is done, we must add the new widget in our WidgetFactory.tsx:
import { Timeline } from "./custom/Timeline";
const getWidgetType = (type: string) => { switch (type) { //... case "timeline": return Timeline; }}In order to test the component, we can change a view in the ERP Server adding the widget attribute:
<field colspan="4" name="category_id" nolabel="1" select="2" widget="timeline"/>Now if you run npm run storybook in the react-ooui project, and navigate to Widgets / Forms / Partners you’ll see the new widget in action.
Using the new widget in the webclient app.
Before using the modified react-ooui library in your local project, you should build the library:
npm run buildAnd then tell the global npm to use this module as a link in other projects:
npm linkThen, change to the webclient project root, and link the module:
npm link "@gisce/react-ooui"And then you can start the bundler normally:
npm start