Skip to content

Repository files navigation

aras-react-example – embedding a React app in Aras Innovator

An example of hosting a React app inside Aras Innovator (Release 35) as a form body. The worked case replaces the Part form with four React fields; the integration layer (src/aras/) is generic and reusable for any ItemType.

The app is injected as an iframe by an html field (or an onload Form Event Method) of a custom Form, is served from the Innovator client origin (<Client>/customer/part-react/) and therefore talks to Innovator through top.aras.IomInnovator / parent.aras with the logged-in user's session – permissions, lock/edit state, validation and the standard Save/Done toolbar keep working unchanged.

Start with WALKTHROUGH.md – how Innovator renders forms, what the bridge hooks into, step-by-step setup, dev loops and the gotchas. PLAN.md has the original investigation notes.

Fields in v1

item_number, name, description, classification – bound by property name; labels, required/readonly flags, data types and the class structure come from the Part ItemType metadata, edit/view mode from the item window. Adding a field is one line in src/features/part/PartForm.tsx (<TextField name="…" />, <TextAreaField …/>, <ClassificationField …/>); adding a whole form for another ItemType is a component plus one registry line – see WALKTHROUGH.md §7.

Aras side (done in Innovator, not in this repo)

  1. New Form (e.g. Part React); Body CSS html, body { margin: 0; overflow: hidden; }; Form height = desired height of the form area (stock Part form: 300).
  2. An html field on the Form whose HTML is the contents of aras-package/html-field-snippet.html – a full-size iframe hosting this app; its position:fixed style escapes the field wrapper, so it fills the form area cleanly. (Alternative: no fields, and a JavaScript Method with the code in aras-package/form-onload-method.js attached as a Form Event with event onload – same result.)
  3. New View on the Part ItemType → that Form, type = default, client = js, display_priority = 0, role = pilot identity (later World). The stock Part view stays.
  4. Deploy this app to <Client>\customer\part-react\ (below).

Quick check without any configuration: open a Part in Innovator, in DevTools pick the form frame (instance) as the console context and paste the Method code – the React form appears over the stock form and is fully wired (Edit/Save work).

Repo layout

src/aras/        bridge to Innovator
  types.ts         minimal typings for aras / Form window / IOM
  resolve.ts       find the Form window + aras (tabbed client and tear-off windows)
  bridge.ts        reads from document.item, writes via handleItemChange, change notifications
  metadata.ts      ItemType properties + class structure from the client metadata cache
  dialogs.ts       Innovator ClassStructureDialog wrapper
  ArasProvider.tsx React context + hooks (useProperty, useItemSnapshot, useEditMode, …)
  mock/            in-memory stand-in for standalone dev & tests
src/fields/      Field, TextField, TextAreaField, ClassificationField (+ useDraft)
src/features/part/PartForm.tsx   the Part form layout
src/registry.ts  itemTypeName → lazy form component (one app serves all registered ItemTypes)
dev/index.html   Vite "backend integration" shell for HMR inside Innovator
scripts/deploy.ps1   copy build / dev shell into the Aras client folder (self-elevates)
aras-package/    snippets for the Aras-side configuration

Commands

Command What it does
npm install once
npm run dev Vite dev server on http://localhost:5173 (standalone = mock mode)
npm run deploy:dev copies dev/index.html to <Client>\customer\part-react\index.html (UAC prompt)
npm run build type-check + production build to dist/
npm run deploy build + copy dist/ to <Client>\customer\part-react\ (UAC prompt)
npm test vitest (bridge / metadata / resolve)
npm run typecheck tsc -b

ARAS_CLIENT_ROOT (or -ClientRoot) overrides the default C:\Program Files (x86)\Aras\Innovator\Innovator\Client.

Development loops

Inside Innovator with HMRnpm run deploy:dev once, then npm run dev and open a Part. The page served by Innovator is only a shell; modules, CSS and hot reload come from the Vite dev server (the document stays same-origin with Innovator, so parent.aras works). If the dev server is down the shell says so.

Standalone / mocknpm run dev and open http://localhost:5173/ (or any URL with ?mock=1). A yellow toolbar simulates Edit/Done, Save, Reset; the mock implements the same contracts the real bridge uses (document.item, handleItemChange, observersHash, onformpopulated, registerEventHandler, the classification dialog via window.prompt). Good for layout/UI work and it is what the unit tests run against.

Productionnpm run deploy, then bump the version in the field/Method snippet (or hard-refresh) so the browser re-fetches index.html; assets are content-hashed.

How the integration works (short version)

main window (top)  aras, aras.IomInnovator, ArasModules, OAuth token
 └ item tab        window.item, setEditMode/setViewMode, toolbar (Edit/Save/Done/…)
    └ Form iframe  document.item, document.isEditMode, handleItemChange, observersHash, onformpopulated
       └ this app  reads document.item, writes via handleItemChange, re-renders on onformpopulated /
                   observer events / ItemLock|ItemSave|ItemVersion|ItemRefresh
  • Readsaras.getItemProperty(document.item, name) (neutral format).
  • WritesvalidateFieldValueByPropEvent (ItemType property rules) then handleItemChange(name, value, dataType): sets isDirty, action="update", enables Save. Refused when not in edit mode. Saving is the standard toolbar → same server events, permissions, required-property checks as the stock form.
  • Permissions – enforced by the server on every call made with the user's session; the UI additionally honours edit mode (lock), property readonly/is_required, and can ask aras.getPermissions('can_update' | …) where it needs to show/hide actions.
  • Classification – opens Innovator's own ClassStructureDialog.html through ArasModules.Dialog.show, exactly like the stock field.

Known limits / next steps

  • Fixed form height (Form height) – the app scrolls internally if it needs more room.
  • v1 fields only; lists, dates, item pickers, thumbnails, class-specific fields are the next components (the binding layer already exposes dataType, dataSourceId, pattern).
  • Ctrl+S inside the iframe is not forwarded to the item window yet.

About

Example of embedding a React app inside Aras Innovator (Release 35): a React Part form injected via a Form onload Method iframe, using top.aras / IomInnovator with the logged-in session

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages