Data Model
This a an example of a data model definition. It is used both by the backend and frontend.
@validity class Asset { @propertyTitle('Id') let id: Int @propertyTitle('Fullname') let fullname: Char<255> @propertyTitle('Name') let name: Char<255> @propertyTitle('Operating System') let os: Char<255> @propertyTitle('Status') let status: Char<255> @propertyTitle('Company') let company: Char<255> @propertyTitle('Environment') let environment: Char<255> @propertyTitle('Install Date') let installDate: Char<255> }
Pattern
This is an example of a pattern definition that is used by a server to parse an Excel file pattern into a database.
[ RecordPattern( pattern: 'assets\/\(orgCode)_Assets_(\d+)\.xlsx', pathData: (pathData: [String]) -> { [validFrom: Date(pathData[0], options: [['yyyyMMdd']])] }, processRecord: (storage: RecordStorage, record: [String], orgCode: String, pathData: [String: Node]) -> { let asset = Asset() asset._orgCode = orgCode asset._validFrom = pathData['validFrom'] var fullname, installDate: String RecordPattern.parse(record, \.asset.id, \.fullname, \.asset.os, \.asset.status, \.asset.company, \.asset.environment, \.installDate) asset.fullname = fullname.lowercase asset.name = fullname.regexp('([^[.]]+).*') asset.installDate = installDate.parseDatetime([['yyyy-MM-dd HH:mm:ss']]) storage.store(asset) }) ]
Page
This is an example of a page definition. It is used in the Nodelab frontend to generate pages and menus.
@pathClass(Asset) class AssetsDashboard: Page { state date = QueryState<String>(valuesQuery: Query( scripts: ['\._validFrom/'], orderScripts: ['\._validFrom/'], limit: 1000, isDistinct: true ))" state assetCount = QueryState<Int>(Query( scripts: ['\._orgCode..count/'], filters: [ '\._validFrom/=="\(date)"', '\.status/=="In use"' ] )) state os = QueryState<[String]>(valuesQuery: Query( scripts: ['\.os/'], orderScripts: ['\.os/'], limit: 100, isDistinct: true )) state status = QueryState<[String]>(valuesQuery: Query( scripts: ['\.status/'], orderScripts: ['\.status/'], limit: 100, isDistinct: true )) state environment = QueryState<[String]>(valuesQuery: Query( scripts: ['\.environment/'], orderScripts: ['\.environment/'], limit: 100, isDistinct: true )) state compareDate = QueryState<Date>(valuesQuery: Query( scripts: ['\._validFrom/'], orderScripts: ['\._validFrom/'], limit: 1000, isDistinct: true )) init() { super( VStack( HStack( StateSelector(\.date, title: 'Date', titleScript: '\._validFrom/', defaultSelectionIndex: 0, css: 'col-md-2'), StateSelector(\.os, title: 'OS', titleScript: '\.os/', css: 'col-md-3'), StateSelector(\.status, title: 'Status', titleScript: '\.status/', css: 'col-md-2'), StateSelector(\.environment, title: 'Environment', titleScript: '\.environment/', css: 'col-md-3'), StateSelector(\.compareDate, title: 'Compare Date', titleScript: '\._validFrom/', css: 'col-md-2') ), HStack( TextView( title: 'Assets in use', mdText: '\(assetCount .% \'%d\')', mdFontId: 'assetCount', css: 'col-md-3' ), BarChart( title: 'Operating System', barScript: '\.os/', splitScript: '\.status/', valueScript: '\._orgCode..count/', statePath: \.os, query: Query( filters: ['\._validFrom/=="\(date)"'], orderScripts: ['\.os/'] ), emHeight: 16, css: 'col-md-3' ), PieChart( title: 'Status', pieScript: '\.status/', valueScript: '\._orgCode..count/', statePath: \.status, query: Query( filters: ['\._validFrom/=="\(date)"'], orderScripts: ['\.status/'] ), emHeight: 16, css: 'col-md-3' ), PieChart( title: 'Environment', pieScript: '\.environment/', valueScript: '\._orgCode..count/', statePath: \.environment, query: Query( filters: ['\._validFrom/=="\(date)"'], orderScripts: ['\.environment/'] ), emHeight: 16, css: 'col-md-3' ) ), Table( title: 'List of Assets', titles: ['Date', 'Server Name', 'OS', 'Environment', 'Status', '\(if compareDate "Status \(compareDate)")'], hasNumbering: true, query: @edgeSpaces([ EdgeSpace(Asset, name: 'comp', filters: ['\comp._validFrom/=="\(compareDate)"']) ]) Query( scripts: ['\._validFrom/', '\.name/', '\.os/', '\.environment/', '\.status/', '\(if compareDate "\comp.status/")'], filters: [ '\._validFrom/=="\(date)"', '\(if os "\(os).contains(\.os/)")', '\(if status "\(status).contains(\.status/)")', '\(if environment "\(environment).contains(\.environment/)")'], orderScripts: ['\.name/'], limit: 1000, maxClassCount: 2 ), emHeight: 16, css: 'col-md-12' ) ) ).withFont(Font('assetCount', size: '8em', align: 'center')) } }
The code above result in a page like this in the Nodelab product: