02.-Metadata-Framework

Metadata is the heart of Narik. With metadata, you can control all parts of your application. For example list and properties of your entities, how a component should be displayed, where and when your data should be cached, the business for visibility of a component or command, how your data must be taken from a remote server, properties of all UI component and etc.

Metadata format in Narik is JSON And every module in Narik can have its own metadata. You can load module metadata from static JSON file or dynamic JSON from a remote API.

Metadata Features

Inheritance

A metadata JSON can extend another metadata JSON. this feature can be useful when you have multiple modules and these modules' metadata seems to be similar with a few differences. In this case, you create parent metadata and every module extends from this metadata and applies its own.

This can be in this way

{
"extends":"relative path to parent"
}

Imports

With Imports feature, you can use all or a specific part of another JSON in your JSON. for example, you define all UiDefaults in one JSON and use it in another JSON files.

Imports:

"imports": {
    "$$dataInfo": "data-info.json",
    "$$toolbar": "tool-bars.json",
    "$$uiDefaults": "ui-default-options.json"
  }

Using Imported File:

"UiDefaultOptions": ["$$uiDefaults.select", "$$uiDefaults.data-table"]

In the above sample, you add "select" and "data-table" attributes value from "ui-default-options.json" to your UiDefaultOptions' array.

Another sample:

"dataInfo": "$$dataInfo.dataInfo"

in this sample, you set your dataInfo with "dataInfo" attribute value from "data-info.json"

Variable

You can define variables and use them inside your JSON. event if variables are used in the parent.

Define a variable:

"variables": {
    "@moduleHomePath": "../main-admin"
  }

Using a variable:

"menuItems": [{
        "title": "MainPage",
        "icon": "nb-e-commerce",
        "link": "@moduleHomePath",
        "home": true
      }]

Metadata Items

Narik metadata contains many predefined sections, also you can add your custom sections and access them with MetaDataService.

translateItems

In this section, you specify localization files related to this module. These localization files will be downloaded whenever your module loaded. If your module is a lazily loaded module, their localization files also will be loaded lazily.

for example:

"translateItems": ["staff-admin", "admin-share"]

You can find more information about Narik localization service Narik Localization Service.

dataInfo

In this section, you specify the way that QueryService must communicate with remote servers.

"dataInfo": {
    "dataUrlInfo": {
      "defaultRemoteDataProvider": "odata",
      "dataPathTemplate": "odata/{moduleKey}/{dataKey}/Default.{dataUrlMethod}",
      "getPathTemplate": "odata/{moduleKey}/{dataKey}",
      "listPathTemplate": "odata/{moduleKey}/{dataKey}/{dataUrlMethod}",
      "postPathTemplate": "odata/{moduleKey}/{dataKey}",
      "updatePathTemplate": "odata/{moduleKey}/{dataKey}",
      "deletePathTemplate": "odata/{moduleKey}/{dataKey}/Default.Delete",
      "completePathTemplate": "odata/{moduleKey}/{dataKey}/Default.Complete",
      "parameterPrefix": "?",
      "defaultDataUrlMethod": "GetForSelector"
    },
    "defaultDataProvider": "remote",
    "defaultOriginDataProvider": "remote"
  }

dataItems

In this section, you specify the attributes of data items inside the module. for example, if you add this hear

 {
    "key": "fonts",
    "dataProviderKey":"localStorage",
    "originDataProviderKey":"remote"
  }

it means that everywhere someone asks data with key "fonts", dataProvider should retrieve data from "static" dataProvider and if request option is loadFromOrigin(for example in refresh) it retrieves data from "remote" data provider.

More Information about Data Framework

entities

In this section, you define module entities and their attributes. for example:

{
  "key": "userAccount",
  "fields": [{
      "name": "userName",
      "required": true,
      "fieldType": "text"
    },
    {
      "name": "title",
      "required": true,
      "fieldType": "text"
    },
    {
      "name": "password",
      "title": "login.password",
      "required": true,
      "showInList": false,
      "fieldType": "password"
    },
    {
      "name": "isActive",
      "required": true,
      "fieldType": "boolean"
    }
  ],
  "defaultEntity": {
    "isActive": true
  }
}

or another example:

{
  "key": "account",
  "fields": [{
      "name": "openDate",
      "required": true,
      "fieldType": "date"
    },
    {
      "name": "availBalance",
      "required": false,
      "order": 1,
      "fieldType": "number"
    },
    {
      "name": "closeDate",
      "required": false,
      "fieldType": "date"
    },
    {
      "name": "lastActivityDate",
      "required": false,
      "fieldType": "date"
    },
    {
      "name": "pendingBalance",
      "required": false,
      "fieldType": "number"
    },
    {
      "name": "status",
      "required": false,
      "fieldType": "text"
    },
    {
      "name": "customerTitle",
      "showInDetail": false,
      "title": "customer",
      "fieldType": "text"
    },
    {
      "name": "custId",
      "title": "customer",
      "required": false,
      "showInList": false,
      "dataInfo": {
        "dataKey": "customer",
        "dataProviderKey": "remote"
      },
      "fieldType": "select"
    },
    {
      "name": "branchTitle",
      "showInDetail": false,
      "title": "branch",
      "fieldType": "text"
    },
    {
      "name": "openBranchId",
      "title": "openBranch",
      "required": true,
      "showInList": false,
      "dataInfo": {
        "dataKey": "branch",
        "dataProviderKey": "remote"
      },
      "fieldType": "select"
    },
    {
      "name": "employeeTitle",
      "showInDetail": false,
      "title": "employee",
      "fieldType": "text"
    },
    {
      "name": "openEmpId",
      "title": "openEmp",
      "required": true,
      "showInList": false,
      "dataInfo": {
        "dataKey": "employee",
        "dataProviderKey": "remote"
      },
      "fieldType": "select"
    },
    {
      "name": "productTitle",
      "showInDetail": false,
      "title": "product",
      "fieldType": "text"
    },
    {
      "name": "productCd",
      "title": "product",
      "required": true,
      "showInList": false,
      "dataInfo": {
        "dataKey": "product",
        "dataProviderKey": "remote"
      },
      "fieldType": "select"
    }
  ],
  "defaultEntity": {}
}

views

In this section, you define module views and their attributes. Then you can navigate to these views. Some views have a related component in Angular application, but many views will be created dynamically(with information that you define here).

for example:

{
  "key": "product",
  "viewType": "Detail",
  "entity": "product",
  "options": {
    "columnsCount": 2,
    "groupFields": true
  }
}

another example:

{
  "key": "product-list",
  "viewType": "List",
  "entity": "product"
}

and another:

{
  "key": "userAccount",
  "viewType": "Detail",
  "entity": "userAccount",
  "toolbarKey": "userDetailToolBar"
}

uiDefaultOptions

In this section, you can define default options for your UI components. for example, you want to display SearchPanel in all dataTables inside your application. you can do this:

{
  "key": "data-table",
  "value": {
    "showSearchPanel": true
  }
}

Another example of default options of "select":

{
  "key": "select",
  "value": {
    "toolbarKey": "selectRefreshToolbar",
    "toolbarModuleKey": "narik",
    "showSearchBox": true,
    "showToolbar": true
  }
}

toolbars

Commands play a major role in Narik. With them, you can manage actions in your forms, easily. You do that with a toolbar. You can define many toolbars in your metadata and assign them to your forms and manage their actions.

Here are some examples:

{
  "key": "detailToolBar",
  "items": [{
      "key": "new",
      "icon": "add"
    },
    {
      "key": "save",
      "disableExpr": "host.config.readOnly"
    },
    {
      "key": "delete",
      "disableExpr": "host.config.readOnly || !host.currentEntity || !host.currentEntity.viewModelId"
    },
    {
      "key": "close",
      "hideExpr": "!host.isInDialog"
    }
  ]
}

Another example:

{
  "key": "userDetailToolBar",
  "items": [
    "&&detailToolBar",
    "-",
    {
      "key": "role",
      "icon": "perm_identity",
      "disableExpr": "!host.currentEntity || !host.currentEntity.viewModelId"
    }
  ]
}

In the above example, you create a new toolbar with inheriting "detailToolBar" and add a separator and other command to the toolbar.

staticData

One of the Narik dataProviders is staticDataProvider. It provides data from static data. for example for your enums or some other static data. You can define them here and easily use them in your UI components and your code.

for example:

{
  "key": "taskStatuses",
  "ignoreTranslate": false,
  "convertToDto": false,
  "data": [
    {
      "id": "1",
      "title": "new"
    },
    {
      "id": "2",
      "title": "inProgress"
    },
    {
      "id": "3",
      "title": "Done"
    }
  ]
}

More Information about Data Framework

events

This part is related to Narik EventAggregator Service. Whereas Narik is a module framework, you sometimes need to handle events from one module in another module. In this selection you define attributes of this events.

for example:

"events": [{
      "key": "MODULE_LOAD_COMPLETELY",
      "info": {
        "subjectType": "ReplaySubject",
        "subjectParam": 10
      }
    }]

More Information about Event Aggregator

You can see more complete Metadata example in these Narik samples and starters

narik-material-starter narik-material-demo narik-devextreme-demo narik-devextreme-starter narik-ng-bootstrap-demo narik-primeng-demo narik-nebular-demo

Last updated