Skip to content

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:

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:

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:

WidgetFactory.ts
import Timeline from "./Timeline";

Inside the setWidgetClass method, we add:

WidgetFactory.ts
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:

Terminal window
npm run build

And 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:

Terminal window
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:

Timeline.tsx
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:

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:

Terminal window
npm run build

And then tell the global npm to use this module as a link in other projects:

Terminal window
npm link

Then, change to the webclient project root, and link the module:

Terminal window
npm link "@gisce/react-ooui"

And then you can start the bundler normally:

Terminal window
npm start