IBM Maximo Application Suite · Manage · Maximo Mobile · Application Configuration

Maximo Application Framework, piece by piece: Graphite, role-based apps, bundles, Maximo Mobile and where React fits

Open any modern Maximo screen and you are told five names at once: Maximo Application Framework, Graphite, role-based applications, Maximo Mobile, React. They sound like five products. They are one thing seen from five sides. This guide puts the pieces on one map, shows where each one lives on a running system, and then follows a single small customization from the first click to the moment every user sees it. Every screenshot was taken on a live Maximo Application Suite 9.2 system.

What you will learn

Reading time: about 25 minutes. Doing the exercise: one hour.

Part 1The names, untangled

Start with one sentence that holds them all. A role-based application, such as Technician, is described in an XML file; the Maximo Application Framework turns that description into a React web application drawn with IBM's Carbon components; the result is packed into a bundle and stored in Manage; a browser runs it directly, and the Maximo Mobile app on a phone downloads the same bundle and runs it offline. Graphite is the engineering name of the framework, and it is the word you meet in addresses, pod names and package names.

NameWhat it isWhere you see it
Maximo Application Framework (MAF)The framework and tools for building and configuring the modern Maximo applications.IBM documentation, release notes, the name of the practice.
GraphiteThe same framework, under its engineering name.The address /maximo/oslc/graphite/<app>, the container image graphite-configuration, the documentation topic "Basic Graphite concepts".
Role-based applicationAn application designed around what one kind of person does, not around one database table.Technician, Inspections, Service Requests, Inventory Counting, Work Orders.
app.xmlThe description of one application: its pages, data and behaviour, in a tag language.The Code editor of the Application Configuration tool.
ReactThe open-source library that draws the screen and redraws it when data changes.Inside the bundle. You do not write React; the framework generates it.
CarbonIBM's open-source design system: buttons, lists, colours, spacing.The look of every screen in this guide.
BundleOne zip file holding a built application and its own source.The table MAFAPPDATA in the Manage database.
Maximo MobileThe app from the app stores. A container that downloads bundles and their data and runs them without a network.The technician's phone or tablet.
Application ConfigurationThe browser tool where you change an application and publish the change.Its own address in the suite, appconfig.<your MAS domain>.
Sourceapp.xmlcontrollers (.js) BuildXML becomes React,then one web app Bundleone zip per app,source included Managetable MAFAPPDATA,version and revision Browser/maximo/oslc/graphite/<app>online, straight from Manage Maximo Mobiledownloads bundle and data,works offline, syncs later
The one idea to keep

You describe, the framework builds. An application is data (an XML description and a few JavaScript files), not a program you compile by hand. That is why the same Technician app can be changed in a browser tool, runs on a desktop and on a phone, and survives an upgrade better than screen customizations used to.

Part 2Role-based applications: what is installed

The quickest way to see what "role-based application" means on your own system is the first page of the Application Configuration tool. On the system used here the list has 44 entries.

The Application list. Each row is one application with its version, its revision, and whether Maximo Mobile may download it.

The columns say more than they seem to:

ColumnMeaning
App nameThe application's ID. It is also the last part of its address in a browser.
VersionWhat IBM shipped. It changes when the product is updated.
RevisionHow many times you have published a change on top of that version. Zero means untouched.
Publish date, Published byWhen the current bundle was stored. Published by was empty on this system, even after a publish done by hand.
Mobile downloadtrue means the Maximo Mobile app offers it. false means browser only.
CategoryWhich part of the suite owns it. Here every row says manage.

Sixteen of the 44 are mobile. The rest are the desktop side of the same framework: dashboards, administration pages, and the shell that hosts them.

Mobile download = trueFor whom
TECHMOBILE (Technician)The person doing the work order.
INSPECTION, VISUALINSPECTIONMOBILEThe inspector with a form or a camera.
SRMOBILE (Service Requests), INCMOBILE (Incident Reporter)Anyone reporting a problem.
ICMOBILE, IRMOBILE, ITMOBILE, MATERIALREQUESTThe storeroom: counting, receiving, issues and transfers, requesting material.
ASSETMOBILE, LOCATIONMOBILEWhoever maintains the asset and location registers in the field.
CREWMOBILE, TIMESHEETCrew leads and labour reporting.
PTWREQMOBILE (Permit to Work), DASHBOARDMOBILESafety and a mobile dashboard.
NAVIGATORNot a role: the home screen of Maximo Mobile that lists the other apps.
Mobile download = false (examples)What it is
WOSUMMARY (Work Orders), TICKETS, WFASSIGN (Workflow Assignments)Desktop work lists.
OPDASHBOARD, PLANNINGDASHBOARD, SCHEDULINGDASHBOARD, DISPATCHINGDASHBOARDRole dashboards.
MASUSER, MASGROUP, APIKEY, MOBADMINAdministration pages: users, security groups, API keys, mobile configuration.
MANAGE-SHELLThe frame around all of them: header, navigation, sign-out.

Any of them opens in a browser at https://<manage host>/maximo/oslc/graphite/<app name in lower case>/index.html.

Part 3Anatomy of an application

Open Technician in the tool, search the Navigator for one page, and the structure of every Graphite application is on the screen at once.

The Work order page of Technician. Left, the Navigator: the application, its pages, and inside the page its states, data sources, dialogs and layout. Top right, the same thing as XML. Bottom right, the Canvas drawing the page.
Building blockTagWhat it is
Applicationmaximo-applicationThe root. It names the app, its version and its application controller.
PagepageOne screen with its own address. IBM's guide describes it as the container that coordinates the components, data sources and logic of one view.
Statestates, stateA named value the screen reacts to: a flag, a selection, a counter. A state belongs to a page or to the whole application.
Data sourcemaximo-datasource, json-datasourceThe link between data and the components that show it. It loads, caches, filters, pages and saves, and the screen redraws when it changes.
Schemaschema, attributeThe list of fields the data source asks Maximo for. A field that is not in the schema does not exist for the app.
Controllerthe attribute controller="..."A JavaScript class with the page's behaviour: what happens on load, on a click, on a change.
Dialogsdialogs with dialog, lookup, lookup-with-filter, sliding-drawerEverything that opens on top of a page. They must be declared inside a dialogs container.
Componentsbutton, field, label, data-list, card-group, box and many moreWhat the user sees and touches.
Bindingcurly braces: {page.state.x}An expression in place of a fixed value. When the thing it names changes, the component follows.

Three lines from the screenshot show the pieces working together. They are the start of the Work order page:

XML<page id="workOrderDetails" title="Work order" controller="WorkOrderDetailsController">
  <states id="x947_">
    <state name="canLoadWoDetailResource" value="true" type="boolean" id="xdv7y"/>
  </states>
  <maximo-datasource id="woDetailResource" default="true"
      can-load="{page.state.canLoadWoDetailResource}"
      object-structure="mxapiwodetail"
      where="wonum=&quot;{page.params.wonum}&quot; and siteid=&quot;{page.params.siteid}&quot;"
      controller="WorkOrderDataController" item-url="{page.params.href}" page-size="1">

Read it slowly. The page has an ID, a title and a controller class. It owns a state called canLoadWoDetailResource. Its data source reads the object structure mxapiwodetail, which is the same integration object the REST API uses, and it loads only when that state is true. The work order number and site come from the page's address. So one screen is three things tied together by names: a state, a data source and a controller.

The data source is the bridge to everything you already know

A maximo-datasource points at an object structure. Security on that object structure, the fields it exposes, its saved queries and its relationships are all defined in Manage, in the places an integration developer already works. A Graphite app is, in the end, a well-dressed client of the Maximo REST API.

IBM documents these ideas in Basic Graphite concepts and the topics linked from it: data sources, the page component, dialog components, applying configurations, the mobile master schema and the preloaded database. That page also shows a detail worth knowing early: the required attribute works both on an input component and on a schema attribute.

XML<text-input value="{page.state.name}" required="true"
    invalid="{page.state.nameInvalid}" invalid-text="{page.state.nameInvalidText}"/>

Part 4Where React and Carbon come in

Nobody writes React by hand for a Maximo app, yet every Maximo app is a React app. The build step reads app.xml and writes one React component for each page, dialog, drawer and list. The proof is in any built workspace. This is the top of a generated file from a Permit to Work app on the same system:

JavaScript// Generated File - Do not edit
import React, { Component, useEffect, useState } from 'react';
import { observer, Provider, inject } from 'mobx-react';
import { Datasource, JSONDataAdapter, Application, Page, Dialog } from '@maximo/maximo-js-api';
import { Button, Box, Label, Field, SmartInput, Tabs, Tab, Tag, BorderLayout } from '@maximo/react-components';
import AppController from './AppController';
import PagePtwList from './PagePtwList';
import PagePtwDetails from './PagePtwDetails';
import PTWDetailsController from './PTWDetailsController';
import DialogChgStatusDialog from './DialogChgStatusDialog';
import SlidingDrawerAssetLookup from './SlidingDrawerAssetLookup';

(The import lines are grouped here for reading; the generated file has one per line.) The names tell the story:

In app.xmlGenerated React file
<page id="ptwDetails">PagePtwDetails.jsx
<dialog id="chgStatusDialog">DialogChgStatusDialog.jsx
<sliding-drawer id="assetLookup">SlidingDrawerAssetLookup.jsx
<card-group id="ptwHazards_cg">CardGroupPtwHazards_cg.jsx and ...Item.jsx
controller="PTWDetailsController"Your own PTWDetailsController.js, copied in unchanged
PackageRole
@maximo/react-componentsThe component library. Each tag you can write in app.xml is one of these React components, built on Carbon.
@maximo/maximo-js-apiThe engine without a face: Application, Page, Datasource, Dialog, the adapters that talk to Maximo or to the device database.
@maximo/app-processor, @maximo/maxdev-cliThe build tools that turn XML into the React files.
react, react-domReact itself (18.3 in the 9.2 toolchain).
mobx, mobx-reactThe reactivity: when a state or a data source changes, MobX tells React exactly which components to redraw. This is what makes a binding "live".

Carbon is the open-source IBM design system underneath the components: github.com/carbon-design-system/carbon. It matters to an administrator for one practical reason. A design system is software with versions, and its security policy states which major versions receive fixes (at the time of writing, 11.x and 10.x) and how to report a vulnerability privately. When a security scanner flags a front-end package inside a Maximo bundle, that policy and IBM's own fix packs are where the answer comes from. You do not patch Carbon inside a bundle yourself.

Trap: "it is React, so I will add my own React component"

The generated files say "Do not edit" for a reason: the next build overwrites them. Your code goes in controllers and in the customization file, and your screen changes go in app.xml. Knowing that React is underneath is for reading stack traces and understanding behaviour, not for editing the output.

Part 5The bundle

A bundle is what the build produces and what the system stores: one zip per application. This is the inside of the Technician bundle taken from this system, 10.6 MB:

Listingtechmobile bundle (145 entries)
  index.html          the page a browser loads
  assets/             104 files: the built JavaScript and styles, split into chunks
  js/                 2 files
  i18n/               29 files: the labels, one per language
  data/               4 files
  build.json          version 9.2.110, application ID, title, and the routes
  manifest.json       name, icon and "standalone" display, as for any installable web app
  loader.css, favicon.svg
  app-source.zip      the source this bundle was built from

The last line is the one people miss. Every bundle carries its own source. Unzip app-source.zip and you have a complete project:

Listingapp-source.zip (368 entries)
  package.json        dependencies and build scripts
  src/app.xml         the application description
  src/*Controller.js  about 37 controllers: WorkOrderDetailsController, SchedulePageController, ...
  src/assets/
  public/i18n/        29 label files
  ibm-config/         63 files: IBM's original, kept for comparison
QuestionAnswer
Where is the bundle stored?In the Manage database, table MAFAPPDATA, one row per application with the zip in a binary column.
How does a browser get it?Manage unpacks it and serves it at /maximo/oslc/graphite/<app>/.
How does a phone get it?Maximo Mobile asks the suite's mobile service for its packages and downloads those marked for mobile.
What does "Download app src" in the tool give me?That same source project, as a file.
What does a publish do?Builds a new bundle from the edited source, writes it to MAFAPPDATA, and raises the revision.

Part 6The Application Configuration tool

Click an application in the list and the editor opens. It takes half a minute, because the tool is unpacking that application's source into its own workspace.

The editor for TECHMOBILE. The file being edited is chosen at the top right, next to Save.
AreaWhat it is for
NavigatorThe application as a tree. The search box takes a component type or an ID, which is the fastest way to find anything in a file of several thousand lines.
PropertiesEvery attribute of the selected component as a form. Changing a value here rewrites the XML for you.
Code editorThe XML itself. Selecting something in the Navigator jumps to its line.
CanvasA drawing of the selected page, recompiled after each change. It uses no real data, so labels bound to data show as "undefined".
File selectorWhich file of the project the Code editor shows. It opens on app.xml.

The arrow next to Save opens the actions that move a change through its life:

The actions menu before anything has been built.
ActionWhat it does
Start PreviewBuilds the application as it is now in the tool, for you alone. When the build ends the entry becomes Open Preview.
PublishBuilds it and stores it as the application everyone gets.
Migrate prior configurationsAfter a product update, carries the changes you made on the previous version onto the new one. Greyed out here, because there is nothing to migrate.
Upload filePuts a file from your computer into the project, for example an image or a controller edited elsewhere.
Download app srcGives you the whole source project.
Download logsThe build log of the last preview or publish. Available once something has been built.

The question mark at the top right of the tool links to the reference material you will need once you go beyond changing a label: Component Documentation, Developer Documentation and JS API Documentation.

Part 7Life of a customization, with an exercise

1 EditProperties orCode editor 2 Savekept in the tool,nobody else sees it 3 Previewa private build,real data 4 Publishbuild, then uploadto the database 5 Revision +1in theApplication list 6a Browser usersget it at their next load 6b Maximo Mobile usersget it at the next update check Steps 1 to 3 are private and can be repeated as often as you like. Step 4 changes the application for everyone. After a product update, "Migrate prior configurations" replays your changes on the new version.

The exercise changes one word in Technician and follows it through all six steps. The change is deliberately tiny, so that everything you see is the process and not the change.

Before: use the application

Open Technician. A user needs something to look at, so create a work order with the + button. This is the page woCreateEdit: a form whose fields are components bound to a data source.

Create work order in Technician. Description, priority, dates and duration are each one component in app.xml.

After Save, the app goes to the work order's detail page, and the list Work created by me now has one record.

The work list. The selector at the top left switches between saved queries such as Assigned work, Work created by me and Work order history.
The detail page as shipped. Its header reads "Work order". That word is the title of the page workOrderDetails, and it is what the exercise will change.
Trap: an empty work list is usually not a bug

The first time Technician opened here, every list said "No results found". The lists are saved queries about your work, and the administrator account had no labor record and no assignments. Before you debug the app, check that the person signed in is someone the query can find work for.

Step 1: edit

In the Application Configuration tool, open TECHMOBILE. Type workOrderDetails in the Navigator search and click page Work order. Switch to the Properties tab. Every attribute of the page is there. Change title from Work order to Work order details and press Tab.

Properties of the page. The moment the title field loses focus, line 1651 of app.xml changes to match, Save turns blue, and the Canvas says "Compiling...".

Look at the other properties while you are there, because they are the vocabulary of every page: controller names the JavaScript class, sigoption ties the page to a Maximo security option, hidden can take a binding, and license and feature let a page appear only when the right product is installed.

Step 2: save

Click Save. The tool answers "File was updated" and, if a preview was running, starts rebuilding it.

Saved. The change is stored in the tool's copy of the project and the preview build starts again by itself.

At this point nothing has changed for any user. Close the browser and come back tomorrow: the edit is still in the tool, and still private.

Step 3: preview

Open the actions menu and choose Start Preview. The status line reads "Preview: Building the application artifacts". When it finishes, the same menu offers Open Preview, which opens the application in a new tab under the tool's own address, /preview/. It is the real application with the real data of the signed-in user. Open the work order again:

The preview. The header now reads "Work order details". Only the person previewing sees this.

Step 4: publish

Choose Publish. A notice warns that publishing can take some time, and the status line walks through three stages.

Stage one: "Publish: Starting publish...".
Stage three: "Publish: Uploading the application to the DB". Between the two the line read "Publish: Building the application".
The end: "TECHMOBILE Published Successfully". On this system the three stages took about two and a half minutes.
Status lineWhat is happening
Publish: Starting publish...The tool collects the project files.
Publish: Building the applicationXML to React, then React to the final web application. This is the slow part.
Publish: Uploading the application to the DBThe new bundle is written to MAFAPPDATA in Manage.
Published SuccessfullyManage now serves the new bundle.

Step 5: the revision

Go back to the Application list. TECHMOBILE has moved to the top.

After publishing. Same version, 9.2.110.0, because IBM's code did not change. Revision went from 0 to 1, and the publish date is today.

Version and revision together answer the question every support call starts with: "is this IBM's application or yours?" Version 9.2.110.0 revision 0 is exactly what IBM shipped. Revision 1 or more means somebody on your side published a change.

Step 6: delivery

Open the application at its normal address on Manage, not the preview:

The published application at /maximo/oslc/graphite/techmobile on the Manage host. Every browser user now gets "Work order details".

Browser users receive the new bundle the next time the application loads. Maximo Mobile users receive it when the app next checks for updates and downloads the newer revision; a device that stays offline keeps working with the bundle it already has. That last behaviour was not exercised on a phone for this guide.

Trap: publish is for everyone, at once

There is no "publish to a few users". The moment the upload ends, the bundle in the database is the application. Do the edit, save and preview steps on a test system, and move the result to production deliberately: download the source there, upload it here, or rebuild from source control. And publish when field users can afford an update, not at the start of a shift.

Part 8Life of a running application

The second lifecycle is the one that runs every time somebody opens the app. Knowing its order tells you where a problem is and where your own code may step in. These are the calls Technician made, in order, when the preview started:

Listing/maximo/oslc/login                           who is this session
/maximo/oslc/whoami                          user, person, default site and organization
/maximo/oslc/systeminfo                      version of the server
/maximo/oslc/permission/allowedappoptions    which security options this user holds
/maximo/oslc/licenseinfo                     which products are licensed
/maximo/oslc/messages                        text of system messages
/maximo/oslc/os/mxapiwodetail                the first data source loads
/maximo/oslc/os/mxapimaxapp, mxapiorganization, ...   supporting data

Identity first, then permissions and licence, then data. If an app stays blank, the first of these calls that fails tells you which layer to look at.

Application startssign-in, permissions,licence, labelsapplicationInitialized Page opensstates get theirstarting valuespageInitialized Data source loadsonBeforeLoadDatarequest to Maximo or deviceonAfterLoadData User worksclicks call handlers,edits fireonValueChanged Page left, returned topagePausedpageResumed The names in the last line of each box are methods you may write in a controller or in the customization file.
HookFiresTypical use
applicationInitialized(app)Once, when the app has started.Read a system property, set an application state.
pageInitialized(page, app)The first time a page is created.Prepare page states.
pageResumed(page, app)Every time the page becomes the visible one, including coming back to it.Refresh what may have changed elsewhere.
onDatasourceInitialized(ds, owner, app)When a data source object exists, before it has data.Keep a reference to it.
onBeforeLoadData(datasource, query)Just before a data source asks for data.Add a filter to the query.
onAfterLoadData(datasource, items, query)When the rows have arrived.Compute something from them, set a state.
onValueChanged({datasource, field, newValue})When any field of any data source changes.React to an edit. Always test which data source and which field first.

A customization file using two of them looks like this. It is a pattern, not part of the exercise above:

JavaScript// AppCustomizations.js: your code, kept apart from IBM's controllers
class AppCustomizations {
  applicationInitialized(app) {
    this.app = app;
  }

  // show only work orders of my own organization, whatever list is chosen
  onBeforeLoadData(datasource, query) {
    if (datasource.name !== 'todaywoassignedDS') return;
    const mine = datasource.parseQBE({ orgid: '=' + this.app.client.userInfo.defaultOrg });
    query.qbe = { ...query.qbe, ...mine };
  }

  // warn when the estimated duration is cleared
  onValueChanged({ datasource, field, newValue }) {
    if (datasource.name === 'dsCreateWo' && field === 'estdur' && !newValue) {
      this.app.toast('Estimated duration is empty', 'warning');
    }
  }
}
export default AppCustomizations;

The data source names in it are examples, and the helper calls should be checked against the JS API Documentation linked from the tool. Use the Navigator search to find the real IDs in the app you are changing.

Part 9Three ways to customize, and when to use each

IBM's guidance on applying configurations is short: use the customization file for most changes, extend a controller class for the complex ones, and never edit IBM's base controller files. In practice there are three levels.

LevelYou changeGood forCost at upgrade
1. Configurationapp.xml, through Properties or the Code editorLabels, titles, hiding a field, adding a field that the object structure already has, reordering.Lowest. "Migrate prior configurations" is made for this.
2. Customization fileAppCustomizations.jsFiltering data, defaults, validation, reacting to a change, small calculations.Low. Your code is in its own file and hooks in by name.
3. Extended controllerA class that extends one of IBM's controllersChanging how an existing action behaves; new pages with real logic.Higher. You depend on the insides of a class that IBM may change.

The patterns below come up in almost every project. They are written in the app.xml tag language.

NeedHow
Show one more fieldAdd <attribute name="supervisor"/> to the data source's schema, then a <field label="Supervisor" value="{woDetailResource.item.supervisor}"/> on the page. Schema first, or the field is always empty.
A field from a related recordDot notation in the schema, serviceaddress.streetaddress, for one-to-one. For a list of children, rel.failurelist{failurecode,description}.
Hide a button from people without the permissionsigoption="MXAPIWODETAIL.CREATEWO" on the control. The framework checks it against the options returned at start-up.
Filter a list on the devicemobile-qbe-filter on the data source. See the trap below.
A pick listA lookup inside dialogs, bound to its own data source, opened from the field.
A required valuerequired="true" on the input, or on the schema attribute so it applies everywhere the field is used.
Trap: where= filters on the server, not on the phone

A where clause on a data source decides which records are sent to the device. Once they are on the device, the offline database does not apply it again. To filter what an offline user sees, use mobile-qbe-filter or a hook in code. A filter that works perfectly in the browser and not at all on the tablet is nearly always this.

Trap: a handler name that does not match does nothing

A button says on-click="saveHazards", the controller has saveHazard. Nothing happens and nothing is logged. When a click does nothing, compare the two spellings before anything else. The same silence follows from two components sharing one id.

Part 10Maximo Mobile: the same apps, offline

Maximo Mobile is one app from the app store that contains no Maximo screens of its own. After sign-in it downloads the Navigator and every application marked Mobile download = true that the user may open, then the data those applications need, and from then on it works without a network.

PieceWhat it does
Server addressWhat the user types at first start: the suite's workspace home address, https://<workspace>.home.<your MAS domain>. Not the Manage address.
NavigatorThe home screen: the tiles of the applications this user has.
BundlesThe same zips a browser gets, downloaded once and kept.
Mobile master schemaOne combined definition of every object and field that all the active mobile apps use. The server builds it from their schemas, so adding an attribute to a schema changes what devices store.
Preloaded databaseSlow-changing reference data (domains, classifications and the like) prepared on the server in advance and downloaded in one piece before the work data, so a first sync does not take all morning.
TransactionsWhat the user does offline is queued on the device and sent when a connection returns.
In a browserIn Maximo Mobile
BundleFetched from Manage at each visit.Stored on the device, replaced when a newer revision is found.
DataEvery screen asks Manage.Read from the device database; synchronised in the background.
where on a data sourceApplied to each request.Applied to what is downloaded.
After you publishNext load.Next update check.
Trap: two addresses and one account that never works

Typing the Manage address into Maximo Mobile ends in "The app does not exist". The app wants the workspace home address. And the suite's built-in superuser can sign in to the suite but not to Maximo Mobile, because Manage has no user record for it. Test with a real user who has been given access to Manage.

Part 11Working outside the tool

The browser tool is enough for configuration. For larger work, developers take the project out with Download app src and use the same build the tool runs. The project's package.json shows it plainly:

JSON{
  "dependencies": {
    "@maximo/maximo-js-api": "3.2.803",
    "@maximo/react-components": "3.2.803",
    "mobx": "6.15.4",
    "react": "18.3.1"
  },
  "scripts": {
    "build": "npx @maximo/maxdev-cli build --in ./src/app.xml --out ./build/app/src/ --update-ids --copy",
    "build:production": "yarn build && yarn labels && cd build/app && react-scripts build",
    "labels": "npx @maximo/maxdev-cli localize -i ./src/app.xml -o ./src/i18n/labels.json --format json"
  }
}

Two steps, as in Part 1: maxdev-cli build turns app.xml into React files, then the bundler turns those into the web application. Three facts save time here:

Part 12When it does not work

SymptomLook at
The Application list stays grey for a long timeIt is slow to load, half a minute and more here. Wait before you assume it is broken.
Every work list says "No results found"The signed-in person: labor record, assignments, default site. The lists are saved queries about that person.
The Canvas shows "undefined" in labelsNothing. The Canvas has no data. Use Start Preview to see real values.
A new field is always emptyIs the attribute in the data source's schema? Does the object structure expose it?
A click does nothingThe handler name in app.xml against the method name in the controller; duplicate IDs.
Publish failsDownload logs in the actions menu. A build error names the line of app.xml.
Browser shows the change, device does notHas the device checked for updates since the publish? Is "Mobile download" true for the app?
A filter works online, not offlinewhere against mobile-qbe-filter, Part 9.
Maximo Mobile says "The app does not exist"The server address. It must be the workspace home address.
After a product update the app looks original againMigrate prior configurations, then preview and publish.

ValueWho gains what

Everything above is about how the applications are built. This is why an organisation cares.

WhoWhat changes for themHow you would measure it
Technicians in the fieldScreens shaped around the job, usable without a network. Work is recorded at the asset, not at a desk at the end of the shift.Time between finishing a job and it being recorded; share of work orders completed on a device.
Supervisors and plannersStatus, labour and failure data arrive the same day, so tomorrow's plan uses today's facts.Age of the newest data in the morning planning meeting; work orders closed without actuals.
Maximo administratorsA label, a field or a filter changes in a browser tool in minutes and is previewed before anyone sees it.Lead time from a change request to it being live; changes rolled back.
IT and the upgrade budgetChanges are configuration kept apart from IBM's code, with a tool to carry them onto a new version.Effort spent re-applying customizations at each update.
The business as a wholeOne application serves desktop and mobile, so there is one thing to train, secure and support.Training hours per new user; number of separate mobile tools retired.

No figures are promised here. Record your own baseline for each measure before the change, and compare after one quarter.

GlossaryThe words, once more

WordIn one line
MAFMaximo Application Framework: how the modern Maximo applications are built and changed.
GraphiteThe framework's engineering name; the word in addresses and package names.
Role-based applicationAn app shaped around one job, such as Technician.
app.xmlThe description of an application in tags.
Page, state, data source, controllerA screen; a value the screen reacts to; the link to data; the code behind.
Object structureThe Maximo integration object a data source reads and writes.
React, MobXThe library that draws the screen; the one that tells it what changed.
CarbonIBM's open-source design system behind the components.
BundleThe built application as one zip, with its source inside.
MAFAPPDATAThe Manage table where bundles are stored.
Version, revisionWhat IBM shipped; how many times you published on top of it.
Preview, publishA private build to check; the build everyone gets.
Maximo MobileThe container app that runs the bundles offline.
Mobile master schema, preloaded databaseThe combined data definition for devices; reference data prepared in advance.

Run on IBM Maximo Application Suite 9.2 with Manage 9.2.4 on Red Hat OpenShift. Technician was at version 9.2.110.0; the exercise published revision 1. The Maximo Mobile behaviour in Part 10 is described from the product's design and from other systems, and was not exercised on a device for this guide.