Data Model

This a an example of a data model definition. It is used both by the backend and frontend.

@validity
class Asset: DataRecord {
  @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.

@edgeSpaces([
  EdgeSpace(Asset)
])
class AssetsDashboard: Page {
  state date = QueryState<String>(valuesQuery: Query(
    paths: [\._validFrom],
    orderPaths: [\._validFrom],
    limit: 1000,
    isDistinct: true
  ))
  state assetCount = QueryState<Int>(Query(
    paths: [\._orgCode..count],
    filters: [
      '_validFrom==\'\(date)\'',
      "status=='In use'"
    ]
  ))
  state os = QueryState<[String]>(valuesQuery: Query(
    paths: [\.os],
    orderPaths: [\.os],
    limit: 100,
    isDistinct: true
  ))
  state status = QueryState<[String]>(valuesQuery: Query(
    paths: [\.status],
    orderPaths: [\.status],
    limit: 100,
    isDistinct: true
  ))
  state environment = QueryState<[String]>(valuesQuery: Query(
    paths: [\.environment],
    orderPaths: [\.environment],
    limit: 100,
    isDistinct: true
  ))
  state compareDate = QueryState<Date>(valuesQuery: Query(
    paths: [\._validFrom],
    orderPaths: [\._validFrom],
    limit: 1000,
    isDistinct: true
  ))
  @edgeSpaces([
    EdgeSpace(Asset, name: 'comp', filters: ['comp._validFrom=="\(compareDate)"'])
  ])
  init() {
    super(
      VStack(
        HStack(
          StateSelector(\.date, title: 'Date', titlePath: \._validFrom, defaultSelectionIndex: 0, css: 'col-md-2'),
          StateSelector(\.os, title: 'OS', titlePath: \.os, css: 'col-md-3'),
          StateSelector(\.status, title: 'Status', titlePath: \.status, css: 'col-md-2'),
          StateSelector(\.environment, title: 'Environment', titlePath: \.environment, css: 'col-md-3'),
          StateSelector(\.compareDate, title: 'Compare Date', titlePath: \._validFrom, css: 'col-md-2')
        ),
        HStack(
          TextView(
            title: 'Assets in use',
            mdText: '\(assetCount .% \'%d\')',
            mdFontId: 'assetCount',
            css: 'col-md-3'
          ),
          BarChart(
            title: 'Operating System',
            barPath: \.os,
            splitPath: \.status,
            statePath: \.os,
            valuePath: \._orgCode..count,
            query: Query(
              filters: ['_validFrom==\'\(date)\''],
              orderPaths: [\.os]
            ),
            emHeight: 16,
            css: 'col-md-3'
          ),
          PieChart(
            title: 'Status',
            piePath: \.status,
            statePath: \.status,
            valuePath: \._orgCode..count,
            query: Query(
              filters: ['_validFrom==\'\(date)\''],
              orderPaths: [\.status]
            ),
            emHeight: 16,
            css: 'col-md-3'
          ),
          PieChart(
            title: 'Environment',
            piePath: \.environment,
            statePath: \.environment,
            valuePath: \._orgCode..count,
            query: Query(
              filters: ['_validFrom==\'\(date)\''],
              orderPaths: [\.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: Query(
            paths: [\._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)")'],
            orderPaths: [\.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: