Models initialization using code. #

You must configure an empty project from the previous step - Getting started
For the initial configuration of the project, run the script init.cmd

Using JavaScript, create a Desktop and a menu for CityPortal

rezult_view

Create a folder _initialData in models\requests
Inside create the file 010_create_navshortcuts.js with the encoding UTF-8 (Shift + F8 in the FAR Manager).

Creating a desktop #

Reference documentation of the methods used:
lookup
insert

module.exports = session => {
  const { connection } = session
  // In the ubm_desktop table look for the desktop with the code CityReq_desktop
  let desktopID = connection.lookup('ubm_desktop', 'ID', {
    expression: 'code',
    condition: 'equal',
    values: { code: 'CityReq_desktop' }
  })

  console.info('\tFill `Common dictionary` desktop')
  if (!desktopID) { //If not found, create a new
    console.info('\t\tcreate new `City request` desktop')
    desktopID = connection.insert({
      entity: 'ubm_desktop',
      fieldList: ['ID'],
      execParams: {
        code: 'CityReq_desktop',
        caption: 'City Requests'
      }
    })
  } else { //else display a message
    console.info('\t\tuse existed desktop with code `CityReq_desktop`', desktopID)
  }
}

Create a folder for a submenu #

Create a folder Departments on your City Requests desktop.
In 010_create_navshortcuts.js file add the following code in the exports section, below the desktop creating (before the last parenthesis).

let folderID = connection.lookup('ubm_navshortcut', 'ID', {
  expression: 'code',
  condition: 'equal',
  values: { code: 'req_departments_folder' }
})
if (!folderID) {
  console.log('\t\tcreate `Departments` folder')
  folderID = connection.insert({
    entity: 'ubm_navshortcut',
    fieldList: ['ID'],
    execParams: {
      desktopID,
      code: 'req_departments_folder',
      caption: 'Departments',
      isFolder: true,
      isCollapsed: false,
      displayOrder: 10
    }
  })
} else {
  console.info('\t\tuse existed folder with code `req_departments_folder`', folderID)
}

Adding a shortcut. #

To the Departments folder add the shortcut Departments
To do this in 010_create_navshortcuts.js file below the folder creating add the following code

let lastID = connection.lookup('ubm_navshortcut', 'ID', {
  expression: 'code',
  condition: 'equal',
  values: { code: 'req_depart' }
})
if (!lastID) {
  console.log('\t\t\tcreate `Department` shortcut')
  lastID = connection.insert({
    fieldList: ['ID'],
    entity: 'ubm_navshortcut',
    execParams: {
      desktopID,
      parentID: folderID,
      code: 'req_depart',
      caption: 'Departments',
      iconCls: 'fa fa-building-o',
      displayOrder: 10,
      cmdCode: JSON.stringify({ cmdType: 'showList', cmdData: { params: [{ entity: 'req_depart', fieldList: '*' }] } })
    }
  })
} else {
  console.info('\t\tuse existed shortcut with code `req_depart`', lastID)
}

Independently create the SubDepartments menu in the Departments folder and the Request List shortcut.
The full code listing of 010_create_navshortcuts.js file could be found here.

To run the script, run the command in the root of project:

npx ubcli initialize -u admin -p admin -host http://localhost:8881 -m requests

The following message should appear in the console:

creating_shortcut_console

Import the data fields from datasets #

Let's say we have a dataset of departments of the city with their addresses and phones. In order to avoid entering this information manually, you can import it to the Departments table during the initialization. To do this, you need a .csv file that will have fields similar to the req_depart entity attributes.
Create the \models\requests\_initialData\req_depart.csv file with following code:

Departments of health;addr1;phone1
Departments of education;addr2;phone2

Specification of methods used: https://unitybase.info/api/serverNew/module-dataLoader.html

Create the javascript-file \models\requests\_initialData\020_fill_departments.js with following code:

const path = require('path')
const fs = require('fs')
const { dataLoader, csv } = require('@unitybase/base')

// to fill more tables with more csv just expand this array!
const fileData = [
  {
    csvName: "req_depart.csv",
    metaName: "req_depart",
    columns: "name;postAddr;phoneNum",
    mainField: "name"
  }
]

const fillTables = (fileData, { connection: conn }) => {
  fileData.forEach(({ csvName, metaName, columns, mainField }) => {
      const fContent = fs.readFileSync(path.join(__dirname, csvName), { encoding: 'utf8' }).trim()
      if (!fContent) {
        throw new Error(`File ${csvName} is empty or not exist`)
      }
      const csvData = csv.parse(fContent)
      const splitColumns = columns.split(';')
      const mainFieldIndex = splitColumns.findIndex(field => field === mainField)
      const notExisted = csvData.filter(row => !conn.lookup(metaName, 'ID', conn.Repository(metaName).where(mainField, '=', row[mainFieldIndex]).ubql().whereList))
      const arrColumns = splitColumns.map((_, index) => index)
      console.info(`\t\tFill ${metaName} table from ${csvName}`)
      dataLoader.loadArrayData(conn, notExisted, metaName, splitColumns, arrColumns, 1000)
    }
  )
}

module.exports = function (session) {
  fillTables(fileData, session)
}

To run the script, run the command in the root of project:

npx ubcli initialize -u admin -p admin -host http://localhost:8881 -m requests

The following message should appear in the console:

creating_shortcut_console

Using Enum in models. #

Enumerated types are described in entity ubm_enum and are intended for storing variants of state values of different data.
Ubm_enum have the next fields
"eGroup" - "Group of enumeration",
"Code" - "Value code",
"shortName" ,
"name",
"sortOrder": is used for ordering enum in combobox. Default = 100 .

Add a "status" attribute to the req_reqList.meta entity.

{
  "name":"status",
  "dataType": "Enum",
  "enumGroup": "REQUEST_STATUS",
  "caption": "Status",
  "allowNull": false
}

For updating the models database, execute the command:

npx ubcli generateDDL -u admin -p admin -host http://localhost:8881 -autorun

Create the file \models\requests\_initialData\ubm_enum-req.csv with enum of statuses that will be used in requests list.

REQUEST_STATUS;NEW;New;10
REQUEST_STATUS;PROCESSED;Processed;20
REQUEST_STATUS;REJECTED;Rejected;30
REQUEST_STATUS;CLOSED;Closed;40

Create the file \models\requests\_initialData\015_fill_enum-req.js with following code:

module.exports = function(session){
      	const path = require('path')
	const fs = require('fs')
	const {dataLoader, csv, argv} = require('@unitybase/base')
    let  conn = session.connection;
	let fn = path.join(__dirname, '/ubm_enum-req.csv')
	let fContent = fs.readFileSync(fn, {encoding: 'utf8'})
	if (!fContent) { throw new Error(`File ${fn} is empty or not exist`) }
	fContent = fContent.trim()
	let csvData = csv.parse(fContent)
	let notExisted = csvData.filter(
	  (row) => !conn.lookup('ubm_enum', 'code',
	      conn.Repository('ubm_enum').where('code', '=', row[1]).ubql().whereList
	    )
	)
	console.info('\t\tFill enumeration for requests model');
	dataLoader.loadArrayData(conn, notExisted, 'ubm_enum', 'eGroup;code;name;sortOrder'.split(';'), [0, 1, 2, 3]);
}

Execute the command:

npx ubcli initialize -u admin -p admin -host http://localhost:8881 -m requests

As a result, the following message should appear in the console:

fill_enum_console

Localization of the project #

Add the support of the Ukrainian language to the project interface.
First, you need to translate the menu items - the name of the desktop and shortcuts.
Create in \models\requests\_initialData\ the folder locale
Inside create the uk^010_req_navshortcuts.js

[+ Warning! The encoding of the file must be UTF-8 (Shift + F8 in the FAR Manager) +]
Note that encoding of all files that use cyrillic script must be UTF-8.

Reference to method specification
https://unitybase.info/api/serverNew/module-dataLoader.html#~localizeEntity

Add to file the following code.

module.exports = function(session){
var
    loader = require('@unitybase/base').dataLoader,
    localizationConfig = {
        entity: 'ubm_desktop',
        keyAttribute: 'code',
        localization: [
            {keyValue: 'CityReq_desktop',  execParams: {caption: 'Міські заявки'}}
        ]
    };

    loader.localizeEntity(session, localizationConfig, __filename);


    localizationConfig = {
        entity: 'ubm_navshortcut',
        keyAttribute: 'code',
        localization: [
            {keyValue: 'req_departments_folder',  execParams: {caption: 'Департаменти'}},
            {keyValue: 'req_depart',  execParams: {caption: 'Департаменти'}},
            {keyValue: 'req_Subdepart',  execParams: {caption: 'Підрозділи'}},
            {keyValue: 'req_reqList',  execParams: {caption: 'Заявки'}}
        ]
    };

    loader.localizeEntity(session, localizationConfig, __filename);
};

Also in the folder \models\requests add a translation of the caption and description properties for model attributes. Create the file req_depart.meta.uk for req_depart entity with following code:

{
 "caption": "Департамент", // entity name
 "description": "Департамент",  // entity description
 "attributes": {
   "name": {
     "caption": "Назва департаменту",
     "description": "Назва департаменту"
    },
   "postAddr": {
     "caption": "Адреса департаменту",
     "description": "Адреса департаменту"
    },
   "phoneNum": {
     "caption": "Телефон департаменту",
     "description": "Телефон департаменту"
     } 
 }
}

Similarly, create the files req_reqList.meta.uk and req_subDepart.meta.uk

To support the Ukrainian language in the project, add culture "uk" in the connection section of the configuration file - to the attribute supportLang.

"supportLang": [ //Array of supported locales
         "en","uk"
       ]

Execute the command:

npx ubcli initialize

and check if scripts work correctly.

change_lang

The full listing of Initial data you can see here
Next step