{"id":21430068,"url":"https://github.com/cuba-platform/frontend","last_synced_at":"2025-08-24T09:16:25.878Z","repository":{"id":36571406,"uuid":"227807575","full_name":"cuba-platform/frontend","owner":"cuba-platform","description":"Monorepo for CUBA Platform Frontend Tools and Libraries","archived":false,"fork":false,"pushed_at":"2023-04-19T10:08:50.000Z","size":18528,"stargazers_count":24,"open_issues_count":155,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-07T14:16:46.721Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cuba-platform.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-13T09:50:40.000Z","updated_at":"2024-09-10T14:59:03.000Z","dependencies_parsed_at":"2024-06-18T21:41:03.520Z","dependency_job_id":null,"html_url":"https://github.com/cuba-platform/frontend","commit_stats":{"total_commits":796,"total_committers":16,"mean_commits":49.75,"dds":0.620603015075377,"last_synced_commit":"bbe4f3d5d944b20fd077341770401a0f6dddc8ce"},"previous_names":[],"tags_count":74,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cuba-platform%2Ffrontend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cuba-platform%2Ffrontend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cuba-platform%2Ffrontend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cuba-platform%2Ffrontend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cuba-platform","download_url":"https://codeload.github.com/cuba-platform/frontend/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225972009,"owners_count":17553574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-22T22:20:30.165Z","updated_at":"2024-11-22T22:20:30.856Z","avatar_url":"https://github.com/cuba-platform.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CUBA Platform Frontend Tools and Libraries\n\n[![Build Status](https://travis-ci.org/cuba-platform/frontend.svg?branch=master)](https://travis-ci.org/cuba-platform/frontend)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n\n# Frontend UI\n\nFrontend UI is an alternative to the [Generic UI](https://doc.cuba-platform.com/manual-latest/gui_framework.html) that provides frontend-oriented development experience, more flexibility in terms of layout customization and easy integration of UI libraries and components from vast JavaScript ecosystem.\n\n## Documentation\n\nActual [documentation](https://doc.cuba-platform.com/frontend) is available on the website.\n\n## Old Documentation\n\nThe documentation below is actual for previously released versions:\n\n| Package                        | Version |\n| ------------------------------ | --------|\n| @cuba-platform/front-generator | 2.4.x   |\n| @cuba-platform/rest            | 0.7.x   |\n| @cuba-platform/react           | 0.4.x   |\n\n### Table of Contents\n\n[comment]: \u003c\u003e (Run `npm run doc:toc` to update the table of contents. Do not alter comments around it.)\n[comment]: \u003c\u003e (TOC-start)\n- [Overview](#overview)\n- [Getting Started](#getting-started)\n    - [Getting Started Using CUBA Studio](#getting-started-studio)\n    - [Getting Started Using CLI](#getting-started-cli)\n- [Generator CLI](#generator)\n    - [Commands Description](#generator-commands-description)\n- [React Client](#react-client)\n    - [Overview of React Client](#react-client-overview)\n    - [Creating React Components](#react-client-creating-components)\n    - [Observable State with MobX](#react-client-mobx)\n    - [CUBA React Components](#react-client-cuba-react)\n    - [Routing and Menu](#react-client-routing)\n    - [Forms](#react-client-forms)\n    - [I18n](#react-client-i18n)\n    - [Customizing Theme](#react-client-theme)\n    - [Backend Model](#react-client-backend-model)\n    - [Synchronizing Project Model](#react-client-sync)\n    - [Security](#react-client-security)\n    - [Building the Client](#react-client-build)\n    - [Configuration](#react-client-configuration)\n- [Polymer-based Client (Deprecated)](#polymer-client)\n- [TypeScript SDK](#typescript-sdk)\n    - [Entities](#react-client-entities)\n    - [Enums](#react-client-enums)\n- [REST API](#rest-api)\n\n[comment]: \u003c\u003e (TOC-end)\n\n\u003ca name=\"overview\"/\u003e\n\n## Overview\n\nThis tool can be used to generate:\n- a front-end client for a CUBA Platform based application. The client can be powered by one of the following frameworks:\n  - React\n  - Polymer\n- a framework-agnostic [TypeScript SDK](#typescript-sdk)\n\n\u003e NOTE: Polymer client is deprecated and is not supported anymore\n\nThe front-end client is an alternative to the [Generic UI](https://doc.cuba-platform.com/manual-latest/gui_framework.html)\nproviding front-end oriented development experience. \nIt's more flexible in terms of layout customization and allows easy integration of\nUI libraries and components from vast JavaScript ecosystem. \nHowever, it requires better knowledge of modern front-end stack.\n\nThe generator is used by [CUBA Studio](https://doc.cuba-platform.com/studio/) for [front module](https://doc.cuba-platform.com/manual-latest/front_ui.html) creation.\nAlternatively it can be used as a standalone CLI tool.\n\n##### Supported Browsers\n\nThe client supports all modern (evergreen) browsers. \nIn order to support IE 9,10,11 [additional configuration](https://facebook.github.io/create-react-app/docs/supported-browsers-features) \nrequired.\n\n\u003ca name=\"getting-started\"/\u003e\n\n## Getting Started\n\nWe recommend using an IDE with [TypeScript](http://www.typescriptlang.org/) support: [VSCode](https://code.visualstudio.com/),\nWebStorm or [IntelliJ IDEA](https://www.jetbrains.com/idea/) Ultimate Edition.\n\nSteps will vary depending on whether you are using the generator from CUBA Studio or as a standalone CLI tool. \n\n\u003ca name=\"getting-started-studio\"/\u003e\n\n### Getting Started Using CUBA Studio\n\n#### Installation\n\nInstall [CUBA Studio](https://doc.cuba-platform.com/studio/#installation).\n\n#### Generating a Client from Studio\n\nYou can generate a client as [a module of CUBA application](https://doc.cuba-platform.com/studio/#modules). \nYou will be able to create CRUD screens using CUBA Studio UI.\n\n\u003ca name=\"getting-started-cli\"/\u003e\n\n### Getting Started Using CLI\n\n#### Installation\n\nInstall [Node.js](https://nodejs.org/en/download/) 10.15+ and npm 6+ (usually comes with node).\n\nInstall the generator using npm package manager: \n\n```bash\nnpm install -g @cuba-platform/front-generator\n```\n\nUse the generator by running the following command in command line:\n\n```bash\ngen-cuba-front\n```\n\nAlternatively, you can run the generator without installation using [npx](https://www.npmjs.com/package/npx):\n\n```bash\nnpx @cuba-platform/front-generator\n```\n\n#### Generating a Client Using CLI\n\nIn order to generate a starter app, we need to feed the generator with project metadata (what entities do we have, etc.). \nThere are two ways of doing that.\n\n##### Passing Project Metadata from CUBA Studio\n\n- Open your project in CUBA Studio. \n- Open settings (`File \u003e Settings`), then open `Languages \u0026 Frameworks \u003e CUBA`. \n- Tick the `Old Studio integration` checkbox:\n                                  \n![Enabling Studio integration](packages/front-generator/etc/studio-integration.png)\n\nNow generator will be able to automatically detect CUBA projects opened in Studio.\n\nGenerate a starter React app by running the following command:\n\n```bash\ngen-cuba-front react-typescript:app\n```\n\nGenerator will prompt you to select one of the currently opened CUBA projects.\n\n![Interactive project selection](packages/front-generator/etc/interactive-projects.png)\n\n##### Passing Project Metadata Manually\n\nYou can export the project model manually. Select `CUBA \u003e Advanced \u003e Export project model` in the main menu. Studio will generate `projectModel.json` file.\n\nUse `--model` command line option to specify location of the project model file:\n\n```bash\ngen-cuba-front react-typescript:app --model /work/cuba-samples/sample-sales/projectModel.json\n```\n\n\u003ca name=\"generator\"/\u003e\n\n## Generator CLI\n\nRun `gen-cuba-front` (or `npx @cuba-platform/front-generator`) without arguments to see usage info.\n\n```\nUsage: gen-cuba-front [command] [options]\n\n  Options:\n\n    -v, --version  output the version number\n    -h, --help     output usage information\n\n  Commands:\n\n    list [options]                                   List all available clients and their clients\n    polymer2:app [options]                           Generates polymer2 app\n    polymer2:blank-component [options]               Generates polymer2 blank-component\n    polymer2:entity-cards [options]                  Generates polymer2 entity-cards\n    polymer2:entity-edit [options]                   Generates polymer2 entity-edit\n    polymer2:entity-list [options]                   Generates polymer2 entity-list\n    polymer2:entity-management [options]             Generates polymer2 entity-management\n    polymer2:query-results [options]                 Generates polymer2 query-results\n    polymer2:service-data [options]                  Generates polymer2 service-data\n    polymer2:service-form [options]                  Generates polymer2 service-form\n    polymer2-typescript:app [options]                Generates polymer2-typescript app\n    polymer2-typescript:blank-component [options]    Generates polymer2-typescript blank-component\n    polymer2-typescript:entity-cards [options]       Generates polymer2-typescript entity-cards\n    polymer2-typescript:entity-edit [options]        Generates polymer2-typescript entity-edit\n    polymer2-typescript:entity-list [options]        Generates polymer2-typescript entity-list\n    polymer2-typescript:entity-management [options]  Generates polymer2-typescript entity-management\n    react-typescript:app [options]                   Generates react-typescript app\n    react-typescript:blank-component [options]       Generates react-typescript blank-component\n    react-typescript:entity-cards [options]          Generates react-typescript entity-cards\n    react-typescript:entity-management [options]     Generates react-typescript entity-management\n    sdk:all [options]                                Generates sdk all\n    sdk:model [options]                              Generates sdk model\n```\n\n\u003e NOTE: Polymer client is deprecated\n\nRun `gen-cuba-front \u003ccommand\u003e --help` to see the list of available options.\n\nMost commands use interactive prompts to capture necessary inputs such as which entity you want to use,\nwhich [view](https://doc.cuba-platform.com/manual-latest/views.html), etc.\nAlternatively, `answers` command line parameter can be used to provide these inputs. You may want to use it if you want to automate the generation. `answers` is a base64-encoded JSON string. See [descriptions of individual commands](#generator-commands-description) for details on what shall be put inside this JSON.   \n\nExample of using `answers`:\n\n```\ngen-cuba-front react-typescript:entity-management \\\n  --dest ../model-playground/modules/front/src/app/car \\\n  --model /home/myusername/model-playground/projectModel.json \\\n  --dirShift ../../ \\\n  --answers eyJlZGl0VmlldyI6eyJuYW1lIjoiY2FyLXZpZXciLCJlbnRpdHlOYW1lIjoibXBnJENhciJ9LCJlZGl0Q29tcG9uZW50TmFtZSI6Im1wZy1jYXItZWRpdCIsImxpc3RWaWV3Ijp7Im5hbWUiOiJjYXItdmlldyIsImVudGl0eU5hbWUiOiJtcGckQ2FyIn0sImxpc3RDb21wb25lbnROYW1lIjoibXBnLWNhci1saXN0IiwibGlzdFR5cGUiOiJsaXN0IiwiZW50aXR5Ijp7Im5hbWUiOiJtcGckQ2FyIn0sIm1hbmFnZW1lbnRDb21wb25lbnROYW1lIjoibXBnLWNhci1tYW5hZ2VtZW50In0=\n```\n\n\u003ca name=\"generator-commands-description\"/\u003e\n\n### Commands Description\n\n##### react-typescript:app\n\nGenerates a React starter app. See [Getting started](#getting-started).\n\n```\n  Options:\n\n    -d, --dest [dest]    destination directory\n    -m, --model [model]  specify path to project model, if given no interactive prompt will be invoked\n    -h, --help           output usage information\n```\n\n\u003ca name=\"react-typescript-entity-management\"/\u003e\n\n##### react-typescript:entity-management\n\nGenerates:\n- Route / main menu item\n- Editor screen to create or edit an entity\n- Browser screen to view the list of entities and/or perform CRUD operations.\n\n```\n  Options:\n\n    -d, --dest [dest]           destination directory\n    -m, --model [model]         specify path to project model, if given no interactive prompt will be invoked\n    -ds, --dirShift [dirShift]  directory shift for html imports e.g ../../\n    -a, --answers [answers]     fulfilled params for generator to avoid interactive input in serialized JSON string\n    -h, --help                  output usage information\n```\n\nBrowser screen is available in one of the following flavors (we call it list types):\n- list\n\n![List browser example](packages/front-generator/etc/react/browser-list.png)\n\n- cards\n\n![Cards browser example](packages/front-generator/etc/react/browser-cards.png)\n\n- table\n\n![Data table showcase](packages/front-generator/etc/react/data-table-demo.gif)\n\n`answers` format:\n\n```\n{\n    \"editView\": {\n      \"name\": \"car-edit\", // Name of view that will be used in Editor screen\n      \"entityName\": \"mpg$Car\" // Entity name\n    },\n    \"editComponentName\": \"CarEdit\", // Editor component class name \n    \"listView\": {\n      \"name\": \"car-edit\", // Name of view that will be used in Browser screen\n      \"entityName\": \"mpg$Car\" // Entity name\n    },\n    \"listComponentName\": \"CarCards\", // Browser component class name\n    \"listType\": \"cards\", // List type: list, cards or table\n    \"entity\": {\n      \"name\": \"mpg$Car\" // Entity name\n    },\n    \"managementComponentName\": \"CarManagement\" // Management component class name (renders either Editor or Browser depending on current route) \n    }\n}\n```   \n\n##### react-typescript:entity-cards\n\nGenerates a list of entities where each entity is represented by a card\n(similar to a Browser component with `\"listType\": \"cards\"`, see [react-typescript:entity-management](#react-typescript-entity-management))\n\n```\n  Options:\n\n    -d, --dest [dest]           destination directory\n    -m, --model [model]         specify path to project model, if given no interactive prompt will be invoked\n    -ds, --dirShift [dirShift]  directory shift for html imports e.g ../../\n    -a, --answers [answers]     fulfilled params for generator to avoid interactive input in serialized JSON string\n    -h, --help                  output usage information\n\n```\n\n`answers` format:\n\n```\n{\n    \"entityView\": {\n      \"name\": \"favoriteCar-view\", // View name\n      \"entityName\": \"mpg$FavoriteCar\" // Entity name \n    },\n    \"componentName\": \"FavoriteCarCards\", // Component class name\n    \"entity\": {\n      \"name\": \"mpg$FavoriteCar\" // Entity name \n    }\n}\n```\n\n##### react-typescript:blank-component\n\nGenerates a blank component.\n\n```\n  Options:\n\n    -d, --dest [dest]           destination directory\n    -m, --model [model]         specify path to project model, if given no interactive prompt will be invoked\n    -ds, --dirShift [dirShift]  directory shift for html imports e.g ../../\n    -a, --answers [answers]     fulfilled params for generator to avoid interactive input in serialized JSON string\n    -h, --help                  output usage information\n\n```\n\n`answers` format:\n\n```\n{\n    \"componentName\": \"BlankComponent\" // Component class name\n}\n```\n\n##### sdk:all\n\nGenerates framework-agnostic [TypeScript SDK](#typescript-sdk).\nIt is also generated when executing `react-typescript:app` command.\n\n```\n  Options:\n\n    -d, --dest [dest]    destination directory\n    -m, --model [model]  specify path to project model, if given no interactive prompt will be invoked\n    -h, --help           output usage information\n```\n\n##### sdk:model\n\nGenerates SDK model only.\n\n```\n  Options:\n\n    -d, --dest [dest]    destination directory\n    -m, --model [model]  specify path to project model, if given no interactive prompt will be invoked\n    -h, --help           output usage information\n```\n\n\u003ca name=\"react-client\"/\u003e\n\n## React Client\n\n\u003ca name=\"react-client-overview\"/\u003e\n\n### Overview of React Client\n\n#### Running the Client\n\nYou can run the client by executing the following command:\n\n```bash\nnpm run start\n```\n\nThis will launch a dev server and allow you to access your app at `localhost:3000`.\n\nIf the client was generated via CUBA Studio (as a module of CUBA application) you can use Gradle in order\nto run npm tooling:\n\n```bash\n./gradlew npm_run_start\n``` \n\u003e There is a known [bug](https://github.com/srs/gradle-node-plugin/issues/339) in Gradle node plugin which does not\n\u003e kill JS development server on task interruption. \n\nYou can also run your CUBA application normally (e.g. via `CUBA -\u003e Start Application Server`) and front-end client will\nbe accessible at `localhost:8080/app-front` (context root can be [configured](react-client-configuration)). However, in this case hot deploy will not be available.\nWe recommend using one of the above methods during development.    \n\n#### Technologies\n\nThe client is based on the following frameworks and libraries: \n\n* [React](https://reactjs.org/) - UI rendering;\n* [MobX](https://mobx.js.org/) - reactive state management;\n* [Ant Design](https://ant.design/docs/react/introduce) - UI components;\n* [React Router](https://reacttraining.com/react-router/) - routing;\n* [CUBA React](packages/cuba-react) - CUBA React components and utilities;\n* [CUBA REST JS](packages/cuba-rest-js) - interaction with СUBA generic REST API;\n* [Create React App](https://facebook.github.io/create-react-app/) - build scripts and configuration;\n\n#### Project Structure\n\nHere is the structure of the newly generated project:\n\n```\napp-name/\n  package.json\n  package-lock.json\n  node_modules/\n  public/\n    index.html\n    favicon.ico\n  src/\n    index.css\n    index.tsx          \u003c- App entry point. Do not move/rename this file\n    routing.ts         \u003c- Routing configuration\n    app/\n      App.css\n      App.tsx          \u003c- App shell. Switches between Login form and internal application\n    cuba/              \u003c- CUBA Model. See [Backend model]\n      entitites/       \u003c- Project entities\n        base/          \u003c- Entities from addons and framework\n      enums/           \u003c- Project enums\n```\n\nIf the client was generated using Studio it's placed in `modules/front` directory of main project. \n\n\u003ca name=\"react-client-creating-components\"/\u003e\n\n### Creating React Components\n\nIt is highly recommended to read full [React documentation](https://reactjs.org/docs/getting-started.html).\nIn React, like in many modern frameworks everything is a component. \nWe use components to create reusable blocks of our application as well as particular pages and screens. \n\nLet's create our first component: place file `Button.tsx` in `src` directory: \n\n```typescript jsx\nimport React, { Component } from 'react';\n\nexport class Button extends Component {\n  render() {\n    \u003cbutton\u003eClick me\u003c/button\u003e;\n  }\n}\n```\n\nAlternatively, you can create the component using a function:\n\n```typescript jsx\nexport function Button(props) {\n  return \u003cbutton\u003e{props.name}\u003c/button\u003e;\n}\n```\n\n\u003ca name=\"react-client-mobx\"/\u003e\n\n### Observable State with MobX\n\n[MobX](https://mobx.js.org/intro/overview.html) is a library for reactive state management which enables to work with \nstate in a convenient and concise way. \n\nConsider the following example:\n\n```typescript jsx\n@observer \nclass Counter extends React.Component {\n\n  @observable\n  count = 0;\n  \n  render() {\n    return (\n      \u003cdiv\u003e\n        Counter: {this.count} \u003cbr /\u003e\n        \u003cbutton onClick={this.handleInc}\u003e + \u003c/button\u003e\n        \u003cbutton onClick={this.handleDec}\u003e - \u003c/button\u003e\n      \u003c/div\u003e\n    )\n  }\n\n  handleInc = () =\u003e {\n    this.count++;\n  }\n\n  handleDec = () =\u003e {\n    this.count--;\n  }\n}\n```\n\nAs soon as we decorate a class or a function component as [observer](https://mobx.js.org/refguide/observer-component.html), it automatically subscribes to changes on any [observable](https://mobx.js.org/refguide/observable.html) value or object i.e. in the example above changing `count` property will result in automatic re-render of the component.\n\n\u003ca name=\"react-client-cuba-react\"/\u003e\n\n### CUBA React Components\n\n##### MainStore\n\n`MainStore` contains common application data. It's being initialized using `\u003cCubaAppProvider\u003e`:\n\n```typescript\n\u003cCubaAppProvider cubaREST={cubaREST}\u003e\n   // App component tree\n\u003c/CubaAppProvider\u003e\n```\n\nYou can inject it in any component using `@injectMainStore` decorator:\n\n```typescript\n@injectMainStore\n@observer\nexport class AppInfo extends React.Component\u003cMainStoreInjected\u003e {\n  render() {\n    if (!this.props.mainStore) {\n      return null;\n    }\n    const {\n      initialized,\n      authenticated,\n      userName,\n      metadata,\n      messages,\n      enums\n    } = this.props.mainStore;\n    return (\n      \u003cul\u003e\n        \u003cli\u003eApp initialized: {initialized ? 'yes' : 'no'}\u003c/li\u003e\n        \u003cli\u003eUser authenticated: {authenticated ? 'yes' : 'no'}\u003c/li\u003e\n        \u003cli\u003eUser name: {userName}\u003c/li\u003e\n        \u003cli\u003eMetadata: {JSON.stringify(metadata)}\u003c/li\u003e\n        \u003cli\u003eMessages: {JSON.stringify(messages)}\u003c/li\u003e\n        \u003cli\u003eEnums: {JSON.stringify(enums)}\u003c/li\u003e\n      \u003c/ul\u003e\n    )\n  }\n}\n```\n##### DataCollectionStore\n`DataCollectionStore` is a MobX based store for loading entity collections. It can be created via `collection()` initializer function:\n```typescript\ndataCollection = collection\u003cPet\u003e(Pet.NAME, {\n    view: 'pet-with-owner-and-type',\n    sort: 'identificationNumber',\n    filter: {conditions: [{property: 'name', operator: \"contains\", value: 'Ro'}]},\n    limit: 10,\n    offset: 0,\n    loadImmediately: true, // true by default\n  }\n);\n```\nTypically it's being used to display list of entities. Since it's reactive, any changes in `items` and `status` will trigger re-render of `@observer` components:\n```typescript\n@observer\nclass CarList extends React.Component {\n  carsData = collection\u003cCar\u003e(Car.NAME, {view: 'car-view', sort: '-updateTs'});\n  render() {\n    if (this.carsData.status === \"LOADING\") return 'Loading...';\n    return (\n      \u003cul\u003e\n        {this.carsData.items.map(car =\u003e\n           \u003cli\u003e{car._instanceName}\u003c/li\u003e\n        )}\n      \u003c/ul\u003e\n    )\n  }\n}\n``` \n\n##### DataInstanceStore\n`DataInstanceStore` is used to work with a single instance of some Entity. It can be created via `instance()` initializer function:\n```typescript\ndataInstance = instance\u003cPet\u003e(Pet.NAME, {view: 'pet-with-owner-and-type', loadImmediately: false});\n```\nUse `dataInstance.commit()` method to perform entity update:\n```typescript\ndataInstance.item.name = 'New Name';\ndataInstance.commit()\n```\n\n##### EntityProperty\n`\u003cEntityProperty\u003e` component is aimed to display a value of some Entity's property. It automatically applies formatting according to the type of property and adds a corresponding label from global message pack (defined on the backend)\n```typescript\n\u003cEntityProperty entityName={Pet.NAME}\n                propertyName='birthDate'\n                value={pet.birthDate}/\u003e\n```\n\n##### FormField\n\n`\u003cFormField\u003e` component automatically creates correct Form UI component based on entity and property names:\n\n```typescript\n\u003cFormField entityName={Pet.NAME} propertyName='birthDate'/\u003e\n```\nFor the attributes with relationship it's possible to provide an instance of DataCollectionStore via `optionsContainer` prop to render options list\n```typescript\npetTypesDc = collection\u003cPetType\u003e(PetType.NAME, {view: '_minimal', sort: 'name'});\n...\n\u003cFormField entityName={Pet.NAME}\n           propertyName='type'\n           optionsContainer={this.petTypesDc}/\u003e\n```\n\n##### DataTable\n\n`\u003cDataTable\u003e` is used to present data in tabular form.\n\n![Data table showcase](packages/front-generator/etc/react/data-table-demo.gif)\n\nIt uses Ant Design's [Table](https://ant.design/components/table/) under the hood and provides the following additional\nbenefits:\n\n- out-of-the-box integration with `DataCollectionStore`\n- powerful filters   \n- support for action buttons (e.g. for CRUD operations)\n \nAt the same time `\u003cDataTable\u003e` provides developer with a full access to underlying `Table` via its `tableProps` and `columnProps`\nproperties (see below). \n\nExample of using `\u003cDataTable\u003e`'s API:\n\n```html\n\u003cDataTable dataCollection={this.dataCollection}\n           fields={this.fields}\n           onSelectedRowChange={this.onSelectedRowChange}\n           buttons={buttons}\n           tableProps={{\n             bordered: true\n           }}\n           columnProps={{\n             align: 'right'\n           }}\n/\u003e\n```\n\n- `dataCollection` - instance of `DataCollectionStore`\n- `fields` - array of entity property names\n- `onSelectedRowChange` - callback that takes the id of selected row, can be used together with `buttons` e.g. to facilitate CRUD operations\n- `buttons` - array of React elements representing controls that will be rendered above the table\n- `tableProps` - can be used to override any of the underlying [Table properties](https://ant.design/components/table/#Table)\n- `columnProps` - can be used to override any of the underlying [Column properties](https://ant.design/components/table/#Column).\nIt shall be used instead of redefining `columns` in `tableProps` if the goal is to extend rather that fully replace the existing\ncustom column-related functionality.\n\n##### API Reference\n\nAPI reference for CUBA React components can be found [here](http://cuba-platform.github.io/frontend/docs/cuba-react).\n\n\u003ca name=\"react-client-routing\"/\u003e\n\n### Routing and Menu\n\nRouting is based on well-known [React Router](https://reacttraining.com/react-router/web/guides/quick-start) library.\nThe generated app has a single point (`src/routing.ts`) to define screens which will be automatically placed\nin the main menu:\n\n```typescript jsx\nmenuItems.push({\n  pathPattern: '/pets', // pattern may be used to consume some parameters, e.g.: /pets/:petId?\n  menuLink: '/pets',\n  component: PetBrowser, // component to be rendered, should be imported in `routes.ts`\n  caption: 'Pets' // Menu item caption\n});\n```\n\nThe `src/App.tsx` contains `Switch` component which renders screen depending on the URL path: \n\n```typescript jsx\n  \u003cSwitch\u003e\n    \u003cRoute exact={true} path=\"/\" component={HomePage}/\u003e\n  {collectRouteItems(menuItems).map(route =\u003e (  // get all routes from main and sub menus\n  \u003cRoute key={route.pathPattern} path={route.pathPattern} component={route.component}/\u003e\n    )}\n  \u003c/Switch\u003e\n```\n\nYou can manually add `Route` to `Switch` component or customize the structure used in `routes.ts` for example in order to create \nhierarchical menu.\n\n#### Sub Menus\n\nTo create hierarchical menu you need to create `SubMenu` instance  in `routes.ts` and add it to `menuItems`\n```typescript jsx\n// This is RouteItem object that we want to see in User Settings sub menu\nconst userProfileRouteItem = {\n  pathPattern: \"/profile\",\n  menuLink: \"/profile\",\n  component: UserProfile,\n  caption: \"UserProfile\"\n};\n\n// SubMenu \nconst userSettingsSubMenu = {\n  caption: 'UserSettings', // add router.UserSettings key to src/i18n/en.json for valid caption\n  items: [userProfileRouteItem]};\n\n// Add sub menu to menu config\nmenuItems.push(userSettingsSubMenu);\n```\n\nSub menus can have unlimited nesting. One sub menu could be used as item of another.\n\n\u003ca name=\"react-client-forms\"/\u003e\n\n### Forms\n\nIn order to facilitate data binding, Ant Design's [Form](https://ant.design/components/form/) component and utilities\nare used in the app. \n\n`getFieldDecorator` is a useful higher order function which allows you to set up validation and binding. See the following example:\n\n```typescript jsx\n  \u003cForm.Item label='name'\u003e\n     getFieldDecorator('model', {\n       normalize: (value) =\u003e {\n         return value === '' ? null : value; // Normalize value so that empty string is converted to null\n       },\n       rules: [ // Allows you to setup front-end validation rules\n         {required: true} \n       ]\n     })(\n        \u003cFormField entityName={Entity.NAME}\n                   propertyName='model'/\u003e\n     )}\n  \u003c/Form.Item\u003e\n```\n\n\u003ca name=\"react-client-i18n\"/\u003e\n\n### I18n\n\ni18n is powered by [react-intl](https://github.com/formatjs/react-intl) library.\n\nOut of the box React client supports `en` and `ru` locales.\n\n##### Adding New Localized Content\n\n- Add new messages to `src/i18n/{locale}.json` files\n- Refer to them from your code using standard `react-intl` components or API (see [documentation](https://github.com/formatjs/react-intl/blob/master/docs/README.md))\n \n##### Overriding Existing Messages\n\nSimply replace existing messages in `src/i18n/{locale}.json` files.\nThis way you can override messages in client app, `cuba-react` components and some of the messages in `antd` components. \n\n##### Adding Support for New Locales\n\n- Add a corresponding `{locale}.json` message pack. \nNote that it shall contain messages for `cuba-react` components (keys starting with `cuba-react`)\nand `antd` `Form` validation messages (keys starting with `antd.form.validation`)\n- Create a mapping between locale and message pack by modifying `messagesMapping` in `src/i18n/i18nMappings.ts`\n- Create a mapping between locale and `antd/es/locale-provider/Locale` object by modifying `antdLocaleMapping` in `src/i18n/i18nMappings.ts`.\n\u003e This is required because most of the messages in `antd` components are translated by telling `antd` to use one of the predefined locales.\n\u003e An extensive list of locales supported by `antd` can be found [here](https://ant.design/docs/react/i18n).\n- Add import of corresponding [moment](https://github.com/moment/moment) locale to `index.tsx`, e.g. `import 'moment/locale/ru';`\n\u003e This is required because some of `antd` components use localized messages from `moment`.\n- Add a means of switching to the new locale. E.g. if you are using the default `LanguageSwitcher` - add a locale option into it.\n\n\u003ca name=\"react-client-theme\"/\u003e\n\n### Customizing Theme\n\nAnt Design provides a possibility to [customize theme](https://ant.design/docs/react/customize-theme) using `less` and\noverriding built-in variables. You can also use these variables in your own code.\n\nIn order to do so, you will need to make some modifications to the generated app.\n\n\u003e NOTE: you will have to enable deprecated inline Javascript in `less` as `antd` makes heavy use of it.\n\u003e [Reasons for deprecation.](http://lesscss.org/usage/#less-options-strict-units)\n- Install the required dependencies. Note that we are using [react-app-rewired](https://github.com/timarney/react-app-rewired) to modify the webpack config without having to `eject`.  \n```shell script\nnpm i react-app-rewired less less-loader customize-cra babel-plugin-import --save-dev\n```\n- Create `config-overrides.js` file in the app root. The file shall look like this. \n```typescript\nconst {addLessLoader, override, fixBabelImports} = require(\"customize-cra\");\nconst path = require('path');\nmodule.exports = override(\n  fixBabelImports('import', {\n      libraryName: 'antd',\n      libraryDirectory: 'es',\n      style: true,\n  }),\n  addLessLoader({\n    javascriptEnabled: true,\n    modifyVars: {\n      'overrideTheme': `true; @import \"${path.resolve(__dirname, './src/theme.less')}\";`,\n    },\n  }),\n);\n```\nNow you can place your overrides in `src/theme.less`:\n```less\n@primary-color: #1DA57A;\n``` \n\nYou can use `antd` variables in your code like this:\n```less\n@import \"~antd/es/style/themes/default\";\nbody {\n  background: @list-header-background;\n}\n```\n\nReferences:\n - detailed [documentation](https://ant.design/docs/react/use-with-create-react-app#Customize-Theme) on Ant Design\nwebsite\n\n##### CSS Methodology\n\nBoth client and CUBA React follow [RSCSS methodology](http://rscss.io).\nAdditionally, we adopt Base Rules from [SMACSS methodology](http://smacss.com/book/type-base).\n\n\u003ca name=\"react-client-backend-model\"/\u003e\n\n### Backend Model\n\n`src/cuba` directory contains TypeScript representation of project's entities, views and facades to access REST services.\nSee more details in [TypeScript SDK](#typescript-sdk) section.\nHere is the layout of the directory:\n\n* `entities` - project entities and views;\n* `entities/base` - framework and addons entities;\n* `enums` - project enums;\n* `services.ts` - middleware services exposed to REST;\n* `queries.ts` - REST queries.\n\nConsider the `Role` entity class of CUBA Framework generated in typescript:\n\n`src/cuba/entities/base/sec$Role.ts`\n```typescript\nexport class Role extends StandardEntity {\n    static NAME = \"sec$Role\";\n    name?: string | null;\n    locName?: string | null;\n    description?: string | null;\n    type?: any | null;\n    defaultRole?: boolean | null;\n    permissions?: Permission[] | null;\n}\n```\n\n* You can easily access entity name by static `NAME` property: `Role.NAME`,\n* The class contains all properties of the domain model entity including ones from class hierarchy.\nReference fields have corresponding types as well so that you can work with them in a type-safe manner:  \n\n```typescript\nfunction changeRole(role: Role) {\n  role.defaultRole = true;   // ok\n  role.defaultRole = 'foo';  // compilation fails  \n}\n```\n\n\u003ca name=\"react-client-sync\"/\u003e\n\n### Synchronizing Project Model\n\nIn order to regenerate project model to conform changes in the backend you can use the following command:\n \n```bash\n$ npm run `update-model`\n```\n\n\u003ca name=\"react-client-security\"/\u003e\n\n### Security\n\nSince React client works via Generic REST API endpoints, the backend (CUBA) application should have properly configured Security \nRoles and Access groups. See the [corresponding chapter](https://doc.cuba-platform.com/restapi-7.1/#security) in REST API documentation.\n\n\u003ca name=\"react-client-build\"/\u003e\n\n### Building the Client\n\n`$ npm run build` command builds your app for production use. See `build` folder.\n\nSee [available scripts](https://facebook.github.io/create-react-app/docs/available-scripts) in Create React App documentation.\n\n\u003ca name=\"react-client-configuration\"/\u003e\n\n### Configuration\n\nBy default, client deployed to Tomcat is built with production preset and aimed to be served under \n`app-front` context. Use `PUBLIC_URL` env variable to change this behavior (see `.env.production.local`).\n\nThe client served from development server has absolute URL of REST API specified in `REACT_APP_CUBA_URL` \n(see `.env.development.local`).\n\nSee the [list of all available environment variables](https://facebook.github.io/create-react-app/docs/advanced-configuration).\n\nSee `src/config.ts` for full list of common application settings used in runtime.\n\n\u003ca name=\"polymer-client\"/\u003e\n\n## Polymer-based Client (Deprecated)\n\nDocumentation can be found [here](https://doc.cuba-platform.com/manual-latest/polymer_ui.html).\n\n\u003ca name=\"typescript-sdk\"/\u003e\n\n## TypeScript SDK\n\nTypeScript SDK contains CUBA data model\n([entities and enums](https://doc.cuba-platform.com/manual-latest/data_model.html)), \nrest [services](https://doc.cuba-platform.com/restapi-7.1/#rest_api_v2_services_config) \nand [queries](https://doc.cuba-platform.com/restapi-7.1/#rest_api_v2_queries_config) \nas TypeScript classes.\n\nThe SDK is framework-agnostic, meaning that in addition to using it with our React client, you can use it with any\nTypeScript-compatible framework such as Angular of Vue.  \n\nIt's possible to generate the following configurations of SDK depending on your needs (see [usage instruction](#getting-started-cli)):\n\n- ```gen-cuba-front sdk:model``` - generates entities and enums\u003cbr\u003e\n- ```gen-cuba-front sdk:all``` - generates all toolkit - entities, enums, queries and services\u003cbr\u003e\n\nSDK can be used for front-end clients and Node.js-based BFF (Backend for Frontend) development.\n\n\u003ca name=\"react-client-entities\"/\u003e\n\n### Entities\n\n##### Persistent Entities\n\nConsider the `Role` entity class of CUBA Framework generated in TypeScript:\n\n`src/cuba/entities/base/sec$Role.ts`\n```typescript\nexport class Role extends StandardEntity {\n    static NAME = \"sec$Role\";\n    name?: string | null;\n    locName?: string | null;\n    description?: string | null;\n    type?: any | null;\n    defaultRole?: boolean | null;\n    permissions?: Permission[] | null;\n}\n```\n\n* you can easily access entity name by static `NAME` property: `Role.NAME`,\n* class contains all properties of domain model entity including from class hierarchy,\nreference fields have corresponding types as well so that you can work with them in a type-safe manner:  \n\n```typescript\nfunction changeRole(role: Role) {\n  role.defaultRole = true;   // ok\n  role.defaultRole = 'foo';  // compilation fails  \n}\n```\n\n##### Non-persistent Entities\nCUBA Platform supports non-persistent entities in model.  Entity class should be annotated with ```com.haulmont.chile.core.annotations.MetaClass```, \nand extended from ```com.haulmont.cuba.core.entity.BaseUuidEntity```. Class properties\nannotated with ```com.haulmont.chile.core.annotations.MetaProperty``` will be included in generated model.\n\n##### Source\n```java\npackage com.company;\n\nimport com.haulmont.chile.core.annotations.MetaClass;\nimport com.haulmont.chile.core.annotations.MetaProperty;\nimport com.haulmont.cuba.core.entity.BaseUuidEntity;\n\n@MetaClass(name = \"SampleUserInfo\")\npublic class SampleUserInfo extends BaseUuidEntity {\n\n    @MetaProperty\n    public String firstName;\n\n    @MetaProperty\n    public String lastName;\n    \n    }\n``` \n\n##### Generated \n```typescript\nexport class SampleUserInfo {\n    static NAME = \"SampleUserInfo\";\n    firstName?: string | null;\n    lastName?: string | null;\n}\n```\n\n\u003ca name=\"react-client-enums\"/\u003e\n\n### Enums\nCUBA REST API module uses enum’s constant name in client-server communication. SDK contains generated string\nenums e.g.: \n```typescript\nexport enum CarType {\n    SEDAN = \"SEDAN\",\n    HATCHBACK = \"HATCHBACK\"\n}\n```\n\nIn order to get enum id and localized caption, you can query full information about enums in runtime using `loadEnums` method\nof cuba-rest-js: \n\n```typescript\nimport {EnumInfo, initializeApp} from \"@cuba-platform/rest\";\n\nconst cubaREST = initializeApp();\ncubaREST.loadEnums()\n    .then(((enums: EnumInfo[]) =\u003e {\n        console.log('enums', enums)\n    }));\n\n```\n\nResponse example:\n\n```json\n[{\n    \"name\": \"com.company.mpg.entity.CarType\",\n    \"values\": [\n      {\n        \"name\": \"SEDAN\",\n        \"id\": \"SEDAN\",\n        \"caption\": \"Sedan\"\n      },\n      {\n        \"name\": \"HATCHBACK\",\n        \"id\": \"HATCHBACK\",\n        \"caption\": \"Hatchback\"\n      }\n    ]\n  }]\n```\n\n\u003ca name=\"rest-api\"/\u003e\n\n## REST API\n\nGenerated front-end clients use [Generic REST API](https://doc.cuba-platform.com/restapi-7.1/). The detailed documentation on the API endpoints is published at [http://files.cuba-platform.com/swagger/7.1](http://files.cuba-platform.com/swagger/7.1).\n\n[CUBA REST JS](packages/cuba-rest-js) library is used to communicate with Generic REST API.\nDocumentation and API reference can be found [here](https://cuba-platform.github.io/frontend/docs/cuba-rest-js).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcuba-platform%2Ffrontend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcuba-platform%2Ffrontend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcuba-platform%2Ffrontend/lists"}