MO2.2.5 Install openIMIS frontend

MO2.2.5 Install openIMIS frontend

To start working in openIMIS as a (module) developer:

When programming for openIMIS frontend, the shared (with openimis-fe_js) dependencies (react,...) must be declared as *peerDependencies* in your package.json file. You are also highly encouraged to used the features provided in the openimis-fe-core module. This includes (but is not limited to) main menu entries, date handling, user info,... Another important point is NOT TO HAVE in backend db table user_Core (managed by Django) user called 'admin' or 'Admin'. This could case defects while running frontend via command `yarn start`. This issue is related to the link between userCore and tblUser tables.

  • clone this repo (creates the openimis-fe_js directory)

  • install node (node V16.x)

  • install yarn

  • within openimis-fe_js directory

    • generate the openIMIS modules dependencies and locales (from openimis.json config): yarn load-config or yarn load-config openimis.json

    • install openIMIS technical dependencies: yarn install

    • start openIMIS frontend (in development mode): yarn start

Frontend Development Setup with CRACO and API Proxy

This frontend project uses CRACO to customize Create React App configurations without ejecting. It also sets up a flexible proxy system for API routing during development.

🔧 Requirements

  • Node.js (v16+ recommended)

  • Yarn

📦 Setup

  • Install dependencies:

    yarn install

Create .env file (if it doesn't exist):

API_PROXY_TARGET=http://localhost:8000
  • Use http://backend:8000 if you're running the backend as a Docker container.

  • Start the dev server:

    yarn start
  1. This will start the frontend on http://localhost:3000/front and proxy all API requests from /api to the API_PROXY_TARGET defined above.

🌐 Proxy Configuration

The proxy logic is handled in src/setupProxy.js. It reads API_PROXY_TARGET from the environment to dynamically redirect API calls to the appropriate backend:

  • /api$API_PROXY_TARGET

  • Additional proxies (e.g. /opensearch) are configured statically in package.json:

"proxies": { "opensearch": { "base": "/opensearch", "target": "http://opensearch:5410" } }

⚙️ CRACO Configuration

craco.config.js sets:

  • output.publicPath to /front/ to support deployment under sub-paths.

  • DefinePlugin to inject environment variables.

  • Dev server historyApiFallback and proxy behavior.

webpackConfig.output.publicPath = '/front/';

📁 Folder Structure

  • src/setupProxy.js: Middleware proxy setup

  • craco.config.js: Webpack and dev server overrides

  • .env: Environment-specific overrides

✅ Tips

  • Make sure the backend server is running and accessible from your frontend environment.

  • Use Docker network names like http://backend:8000 when both frontend and backend are running in Docker.

  • Set PUBLIC_URL=/front if needed to ensure assets load correctly.

To start working in openIMIS as a (module) for production with git / shh / urls for dependencies:

  • within openimis-fe_js directory

    • generate the openIMIS modules dependencies and locales (from openimis.json config): yarn load-config or yarn load-config openimis.json

    • clean yarn cache in case local directory / git /link are used: yarn cache clean

    • install openIMIS technical dependencies: yarn install

    • build openIMIS frontend (in development mode): yarn build

    • copy the build folder on the webserver

using npm

```{ "name": "CoreModule", // If name is not provided, it will assume the module is exported as the `default` module "npm": "@openimis/fe-core@1.2.0-rc15" }```

At this stage, your browser opened on localhost:3000 with current openIMIS frontend. In developement mode, the frontend connects to the backend via a proxy configuration, expecting to reach the backend on localhost:8000 (cfr. /package.json file, "proxy" entry).

To edit (modify) an existing openIMIS module (e.g. @openimis/fe-claim)

  • checkout the module's git repo NEXT TO (not within!) openimis-fe_js directory and create a git branch for your changes

  • from openimis-fe-claim_js

    • install module dependencies: yarn install

    • build current (dev) version of the module: yarn build

    • prepare a linkable version of your local package: yarn link

  • from openimis-fe_js

    • uninstall the packaged module you want to work on (example @openimis/fe-claim): yarn remove @openimis/fe-claim

    • link the local version of the module: yarn link "@openimis/fe-claim"

Note:

  • It is not necessary to register a linked module in the package.json file

  • To unlink a previously linked package: yarn unlink "@openimis/fe-claim"

  • [OPTIONAL] To enable live reload of the module, from openimis-fe-claim_js, activate the watch: yarn start (if configured into the package.json of the module)

To create a new openIMIS module (e.g. @openimis/fe-mymodule)

  • create a (git-enabled) directory next to the other modules: /openimis-fe-mymodule_js. Note: the module name can be different from the directory/github repo. The npm repo has an @openimis scope to group all openIMIS modules

  • to be integrated in openIMIS ecosystem, you module should provide an entry entity (e.g. MyModule) with its contributions (MainMenu entries,...).

  • prepare a linkable version of your local package: yarn link (from within /openimis-fe-mymodule_js)

  • from /openimis-fe_js:

    • install the linkable version of your package: yarn link @openimis/fe-mymodule

    • add your module (name and entry entiry) in openimis.json and regenerate the modules import script: node module-requirements.js Note: to ease development lifecycle, please consider using the 'rollup' mechanism (see @openimis/fe-core for an example)

Managing translations/localization

To add new translation/localisations:

  • create separate new module based on frontend template module.

  • this module should be named like: openimis-fe-language_{lang}_js for example openimis-fe-language_es_js (Spanish language)

  • add to this module such files as: .babelrc, .gitignore, .estlintrc

  • within src/translation add {lang}.json file for example es.json

  • in index.js within src modified (for example we want to have 'es' Spanish language):

import messages_es from "./translations/es.json"; const DEFAULT_CONFIG = { "translations": [{ key: "es", messages: messages_es }], } export const LanguageEsModule = (cfg) => { return { ...DEFAULT_CONFIG, ...cfg }; }
  • build your new module with translations by typing within this module yarn build, yarn install and yarn link commands.

  • in tblLanguages on database level add new language for example 'es' (Spanish language)

  • within assembly frontend module openimis-fe_js in openimis.json add language key for new language/localization for example:

... "locales": [ { "languages": [ "es", "es-ES" ], "intl": "es-ES", "fileNames": "es" }, { "languages": [ "en", "en-GB" ], "intl": "en-GB", "fileNames": "en" }, { "languages": [ "fr", "fr-FR" ], "intl": "fr-FR", "fileNames": "fr" } ], ...
  • in openimis.json add also this newly created module with translations

  • within openimis-fe_js/src in locales.js add new language like below:

export const locales = ["es-ES","en-GB","fr-FR"] export const fileNamesByLang = {"es":"es", "es-ES":"es","en":"en","en-GB":"en","fr":"fr","fr-FR":"fr"} export default {"es":"es-ES", "es-ES": "es-ES","en":"en-GB","en-GB":"en-GB","fr":"fr-FR","fr-FR":"fr-FR"}
  • type yarn build and if success - type yarn start and you should see this translation in your app (go to 'users' page, select user, change language into the newly provided, refresh page and you should see texts in changed language)

  • if you encounter any problems by that point, run yarn load-config in the main module

  • there is also possibility to overwrite particular language for example 'English' into 'Gambian English' (without changes on database level). In your new translation module in index.js (for example new module called openimis-fe-language_en_gm_js):

import messages_en from "./translations/en.json"; const DEFAULT_CONFIG = { "translations": [{ key: "en", messages: messages_en }], } export const LanguageEnGmModule = (cfg) => { return { ...DEFAULT_CONFIG, ...cfg }; }
  • this approach overwrites default en language translations into en-gm (Gambian English) translations without adding new language on database level and without changing 'locales' in 'openimis.json' and 'locales.js' file both on assembly frontend module (openimis-fe_js).

🎨 Theme & Logo Configuration

To customize the appearance of your openIMIS frontend, you can define a theme and optionally a logo configuration in your module settings either on database level or django admin panel (table moduleConfiguration).

🧹 JSON Configuration Structure

Theme Configuration (theme)

To override the default theme colors, provide a theme object under the fe-core module configuration. Below is the full structure with all supported properties:

{ "theme": { "name": "defaultBlue", "primaryColor": "#004E96", "errorColor": "#801a00", "whiteColor": "#ffffff", "backgroundColor": "#e4f2ff", "headerColor": "#BCD4E6", "greyColor": "grey", "selectedTableRowColor": "rgba(0, 0, 0, 0.08)", "hoveredTableRowColor": "rgba(0, 0, 0, 0.12)", "toggledButtonColor": "#999999", "lockedBackgroundPattern": "repeating-linear-gradient(45deg, #D3D3D3 1px, #D3D3D3 1px, #fff 10px, #fff 10px)" } }
Description of Properties:

Property

Description

Property

Description

name

Optional name identifier for the theme

primaryColor

Main brand color used in headers, buttons, text, etc.

errorColor

Used to highlight errors or critical UI elements

whiteColor

Used for contrasting text and background elements

backgroundColor

General background color for the app

headerColor

Header background color

greyColor

Used for subdued UI elements (e.g., disabled text)

selectedTableRowColor

Background for selected table rows

hoveredTableRowColor

Background for hovered table rows

toggledButtonColor

Background for toggled/active state buttons

lockedBackgroundPattern

Background pattern used for locked (readonly) UI elements

Note: If theme is not provided, the default openIMIS theme will be used instead.


🖼️ Logo Configuration (logo)

Add additional property under fe-core configuration in moduleConfiguration. Logos can also be configured via base64-encoded images. This allows the UI to show custom branding without bundling new static files.

{ "logo": { "value": "data:image/png;base64,iVBORw0KGgoAAAANSUhEU...", "disableTextLogo": true } }

Note: Supported formats: svg+xml, jpeg, png

Logo Fields:

Property

Description

Property

Description

value

Base64-encoded string of the main logo

disableTextLogo

(Optional) Do not show openIMIS text next to logo: true or false. By default false

Note: If logo.value is not provided, the default openIMIS logo will be used instead.

Role Right Translation Management

This section outlines where translations for Role Rights (permissions) are managed within the openIMIS frontend modules. Understanding this structure is crucial for adding or modifying permission display names.

Standard Location:

  • By default, translations for Role Rights belonging to a specific module reside within the en.json localization file of that module's corresponding frontend package.

  • The path typically follows this pattern: openimis-fe-<module_name>/src/translations/en.json.

  • Example: Translations for rights under the insuree module (e.g., insuree.gql_query_insurees_perms) are located in openimis-fe-insuree/src/translations/en.json.

Centralized Location for Specific Modules:

  • Certain backend modules provide Role Rights but do not have their own dedicated frontend package (openimis-fe-*).

  • Translations for rights originating from these specific modules are centralized within the core frontend module's localization file: openimis-fe-core/src/translations/en.json.

  • The modules whose Role Right translations are currently managed in openimis-fe-core are:

    • api_fhir_r4

    • report

    • api_etl

  • Example: The translation for report.gql_reports_user_activity_perms ("Report | User Activity") must be defined in openimis-fe-core/src/translations/en.json.

Translation Key and Value Format:

  • Key: module_key.original_permission_string (e.g., core.gql_query_users_perms)

  • Value: "ModuleNameInTitleCase | ReadablePermissionNameInTitleCase" (e.g., "Core | Query Users")

Fallback for Missing Translations:

  • The system requires a translation entry for every Role Right presented in the UI.

  • If a translation cannot be found for a specific right (either because the module providing the translation is not deployed/included, or the specific key is missing from the relevant en.json file), the UI will display the right name prefixed with [No Translation].

  • Example: If the translation for core.gql_query_users_perms is missing, it might be displayed as: [No Translation] Core | Query Users.

Advanced Filters Translation Management

All advanced filters translations live under the core.advancedFilters namespace, so the UI picks up the right labels from your locale files.

Default Translations:

In your locale file (e.g. translations/en.json), you’ll find entries like:

{ "core.advancedFilters.exact": "Exact", "core.advancedFilters.iexact": "Exact", "core.advancedFilters.istartswith": "Starts with", "core.advancedFilters.icontains": "Contains", "core.advancedFilters.lt": "Less than", "core.advancedFilters.lte": "Less than or equal to", "core.advancedFilters.gt": "Greater than", "core.advancedFilters.gte": "Greater than or equal to", "core.advancedFilters.email": "Email", "core.advancedFilters.able_bodied": "Able bodied", "core.advancedFilters.national_id": "National ID", "core.advancedFilters.educated_level": "Educated level", "core.advancedFilters.chronic_illness": "Chronic illness", "core.advancedFilters.national_id_type": "National ID type", "core.advancedFilters.number_of_elderly": "Number of elderly", "core.advancedFilters.number_of_children": "Number of children", "core.advancedFilters.beneficiary_data_source": "Beneficiary data source" }

These keys power two reusable React components:

  • CustomFilterFieldStatusPicker
    Renders a dropdown of available filter fields, using
    formatMessage('advancedFilters.<field>').

  • CustomFilterTypeStatusPicker
    After you pick a field, shows matching filter types, also via
    formatMessage('advancedFilters.<type>').

How to Add or Update Translations:

Whenever the individual global schema changes (you add or remove a filter field/type), update your locale files:

  1. Identify the new key(s):

    • Field → core.advancedFilters.<new_field>

    • Type → core.advancedFilters.<new_type>

  2. Open your locale file, e.g.:

    translations/en.json

Add the translation entry:

{ "core.advancedFilters.example_field": "Example field" }

Main Menu and Submenu Configuration

Overview

This document provides guidance on how to configure the Main Menu and its Submenus within the OpenIMIS application. It outlines the structure of menu entries, explains key concepts, and lists all possible configurations extracted from the system.

Key Concepts

  1. Main Menu and Submenu Structure:

    • Each menu is uniquely identified by an id.

    • Submenus are associated with specific Main Menu entries and cannot currently be added dynamically unless linked to predefined frontend logic.

  2. Attributes of Menu Entries:

    • text: Label displayed for the menu entry.

    • icon: Icon displayed alongside the label.

    • route: Path to navigate when the menu is clicked.

    • filter: Logic to determine visibility based on user permissions.

  3. Positioning:

    • The position attribute determines the order of menus and submenus in the interface.

  4. Dynamic Linking:

    • New menus can be created dynamically, but submenus must be linked to existing application logic.

  5. Keeping old approach:

    • If you want to keep old approach, just leave 'menus' as empty array or do not put this key into configuration file. In that case menu will be populated in a deault, old way based on the order of modules in openimis.json.

Additional Notes

  • Dynamic Menu Creation: New menus can be added dynamically by defining them in the configuration.

  • Submenu Restrictions: Submenus must be linked to predefined frontend logic and cannot currently be added dynamically.

  • Configuration Management: Use the id field to map menus and submenus to their frontend counterparts for consistent functionality.

Useful links (openIMIS wiki page on Confluence)

Did you encounter a problem or do you have a suggestion?

Please contact our Service Desk



This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. https://creativecommons.org/licenses/by-sa/4.0/