Galite Applications are

simple

  • Get started
  •   Github
  •   Maven

WHAT IS GALITE

Opensource framework that allows users to build business applications
made of forms, reports and charts using a simple and creative syntax
based on a domain specific language.

STRENGHTS & ADVANTAGES

Generic

Make it easy to build a full-fledged application based on business requirement without the need of creating tailor components.

Extendible

Provides a collections of component that can be combined in order to build application in a timely manner.

Developer friendly

Provides a domain specific language that is easy to use in combination with the Koltin programming language.

Productive

Takes into consideration the time to market, you can create your application and run it in a few hours.

GREAT UX / UI

Good UX (User Experience) for business.
Great UI (User interface) focusing on keeping interactions simple and easy.

DSL BASED FRAMEWORK

Galite provides a DSL layer for developer to use. It make creating application from model very easy. Using few lines of code, Galite creates a nice user interface with backend fully managed.

Screenshots for the Galite UI
                          
class ClientForm : Form(title = "Clients", locale = Locale.UK) {
  val action = menu("Action")

  val quit = actor(
    menu = action,
    label = "Quit",
    help = "Quit",
  ) {
    key = Key.ESCAPE
    icon = Icon.QUIT
  }

  val list = actor(
          menu = action,
          label = "list",
          help = "Display List",
  ) {
    key = Key.F10
    icon = Icon.LIST
  }

  val interSave = actor(
          menu = action,
          label = "Save and load",
          help = " Save and load",
  ) {
    key = Key.F11
    icon = Icon.SAVE
  }

  val dynamicReport = actor(
          menu = action,
          label = "DynamicReport",
          help = " Create Dynamic Report",
  ) {
    key = Key.F6
    icon = Icon.REPORT
  }

  val quitCmd = command(item = quit) {
    model.close()
  }

  val clientsPage= page("Clients")

  val clientsBlock = clientsPage.insertBlock(Clients())
  val salesBlock = clientsPage.insertBlock(Sales())


  inner class Clients : Block("Clients", 1, 100) {
    val c = table(Client)

    val idClt = visit(domain = INT(30), position = at(1, 1..2)) {
      label = "ID"
      help = "The client id"
      columns(c.idClt)
      value = 1
    }
    val fstnameClt = visit(domain = STRING(25), position = at(2, 1)) {
      label = "First Name"
      help = "The client first name"
      columns(c.firstNameClt) {
        priority = 1
      }
    }
    val nameClt = visit(domain = STRING(25), position = at(2, 2)) {
      label = "Last name"
      help = "The client last name"
      columns(c.lastNameClt) {
        priority = 2
      }
    }
    val ageClt = visit(domain = INT(3), position = at(2, 3)) {
      label = "Age"
      help = "The client age"
      columns(c.ageClt) {
        priority = 3
      }
    }
    val email = visit(domain = STRING(25), position = at(3, 1)) {
      label = "Email"
      help = "The mail adress"
      columns(c.mail) {
        priority = 4
      }
    }
    val addressClt = visit(domain = STRING(20), position = at(3, 2)) {
      label = "Address"
      help = "The client address"
      columns(c.addressClt)
    }
    val countryClt = visit(domain = STRING(12), position = at(4, 1)) {
      label = "Country"
      help = "The client country"
      columns(c.countryClt)
    }
    val cityClt = visit(domain = STRING(12), position = at(4, 2)) {
      label = "City"
      help = "The client city"
      columns(c.cityClt)
    }
    val zipCodeClt = visit(domain = INT(12), position = follow(cityClt)) {
      label = "Zip code"
      help = "The client zip code"
      columns(c.zipCodeClt)
    }
    val active = visit(domain = BOOL, position = at(5, 1)) {
      label = "Active ?"
      help = "Is the user active?"
      columns(c.activeClt)
    }

    val PostqryTrigger = trigger(POSTQRY) {
      salesBlock.idClt[0] = idClt.value
      salesBlock.load()
    }

    init {
      command(item = report) {
        createReport {
          ClientR()
        }
      }
      command(item = dynamicReport) {
        createDynamicReport()
      }
      command(item = list) {
        recursiveQuery()
      }
    }
  }

  inner class Sales : Block("Sales", 10, 10) {
    val C = table(Client)
    val S = table(Purchase)
    val P = table(Product)

    val idClt = hidden(domain = INT(5)) {
      label = "ID"
      help = "The client id"
      columns(C.idClt, S.idClt)
    }

    val idPdt = hidden(domain = INT(5)) {
      label = "ID"
      help = "The product id"
      columns(P.idPdt, S.idPdt)
    }

    val id = visit(domain = INT(5), position = at(1, 1..2)) {
      label = "ID"
      help = "The item id"
      columns(S.id)
      options(FieldOption.SORTABLE)
    }
    val description = visit(domain = STRING(25), position = at(2, 1)) {
      label = "Description"
      help = "The item description"
      columns(P.description)
      options(FieldOption.SORTABLE)
    }
    val quantity = visit(domain = INT(7), position = at(2, 2)) {
      label = "Quantity"
      help = "The number of items"
      columns(S.quantity)
    }
    val price = visit(domain = DECIMAL(10, 5), position = at(2, 2)) {
      label = "Price"
      help = "The item price"
      columns(P.price)
    }

    init {
      border = Border.LINE

      command(item = showHideFilter) {
        showHideFilter()
      }

      command(item = report) {
        createReport {
          ClientR()
        }
      }
      command(item = dynamicReport) {
        createDynamicReport()
      }
      command(item = list) {
        recursiveQuery()
      }
      command(item = interSave) {
        val b = salesBlock.block
        val rec: Int = b.activeRecord

        b.validate()

        if (!b.isFilled()) {
          b.currentRecord = 0
          throw VExecFailedException()
        }

        transaction {
          b.save()
        }

        gotoBlock(b)
        b.gotoRecord(if (b.isRecordFilled(rec)) rec + 1 else rec)
      }
    }
  }
}
                          
                        
Screenshots for the Galite UI
                          
class ClientR : Report(title = "Clients_Report", locale = Locale.UK) {
  val action = menu("Action")

  val csv = actor(
          menu = action,
          label = "CSV",
          help = "CSV Format",
  ) {
    key = Key.F8           // key is optional here
    icon = Icon.EXPORT_CSV // icon is optional here
  }

  val xls = actor(
          menu = action,
          label = "XLS",
          help = "Excel (XLS) Format",
  ) {
    key = Key.SHIFT_F8
    icon = Icon.EXPORT_XLSX
  }

  val xlsx = actor(
          menu = action,
          label = "XLSX",
          help = "Excel (XLSX) Format",
  ) {
    key = Key.SHIFT_F8
    icon = Icon.EXPORT_XLSX
  }

  val pdf = actor(
          menu = action,
          label = "PDF",
          help = "PDF Format",
  ) {
    key = Key.F9
    icon = Icon.EXPORT_PDF
  }

  val editColumnData = actor(
    menu = action,
    label = "Edit Column Data",
    help = "Edit Column Data",
  ) {
    key = Key.F8
    icon = Icon.FORMULA
  }

  val helpForm = actor(
          menu = action,
          label = "Help",
          help = " Help"
  ) {
    key = Key.F1
    icon = Icon.HELP
  }

  val cmdCSV = command(item = csv) {
    model.export(VReport.TYP_CSV)
  }

  val cmdPDF = command(item = pdf) {
    model.export(VReport.TYP_PDF)
  }

  val cmdXLS = command(item = xls) {
    model.export(VReport.TYP_XLS)
  }

  val cmdXLSX = command(item = xlsx) {
    model.export(VReport.TYP_XLSX)
  }

  val helpCmd = command(item = helpForm) {
    model.showHelp()
  }

  val editColumn = command(item = editColumnData) {
    if ((model.getDisplay() as UReport).getSelectedColumn() != -1) {
      val formula  = org.kopi.galite.demo.product.ProductForm()
      WindowController.windowController.doModal(formula)
    }
  }

  val firstName = field(STRING(25)) {
    label = "First Name"
    help = "The client first name"
    align = FieldAlignment.LEFT
    group = ageClt
    format { value ->
      value.toUpperCase()
    }
  }

  val lastName = field(STRING(25)) {
    label = "Last Name"
    help = "The client last name"
    align = FieldAlignment.LEFT
    format { value ->
      value.toUpperCase()
    }
  }

  val addressClt = field(STRING(50)) {
    label = "Address"
    help = "The client address"
    align = FieldAlignment.LEFT
    format { value ->
      value.toLowerCase()
    }
  }

  val ageClt = field(INT(2)) {
    label = "Age"
    help = "The client age"
    align = FieldAlignment.LEFT
  }

  val countryClt = field(STRING(50)) {
    label = "Country"
    help = "The client country"
    align = FieldAlignment.LEFT
  }

  val cityClt = field(STRING(50)) {
    label = "City"
    help = "The client city"
    align = FieldAlignment.LEFT
  }

  val zipCodeClt = field(INT(2)) {
    label = "Zip code"
    help = "The client zip code"
    align = FieldAlignment.LEFT
  }

  val activeClt = field(BOOL) {
    label = "Status"
    help = "Is the client active?"
  }

  val clients = Client.selectAll()

  init {
    transaction {
      clients.forEach { result ->
        add {
          this[firstName] = result[Client.firstNameClt]
          this[lastName] = result[Client.lastNameClt]
          this[addressClt] = result[Client.addressClt]
          this[ageClt] = result[Client.ageClt]
          this[countryClt] = result[Client.countryClt]
          this[cityClt] = result[Client.cityClt]
          this[zipCodeClt] = result[Client.zipCodeClt]
          this[activeClt] = result[Client.activeClt]
        }
      }
    }
  }
}
                          
                        
Screenshots for the Galite UI
                          
class ChartSample : Chart(
  locale = Locale.UK,
  title = "Area/population per city",
  help = "This chart presents the area/population per city"
) {

  val action = menu("Action")

  val area = measure(DECIMAL(width = 10, scale = 5)) {
    label = "area (ha)"

    color {
      VColor.GREEN
    }
  }

  val population = measure(INT(10)) {
    label = "population"
  }

  val city = dimension(STRING(10)) {
    label = "dimension"

    format { value ->
      value?.toUpperCase()
    }
  }

  val type = trigger(CHARTTYPE) {
    VChartType.BAR
  }

  init {
    city.add("Tunis") {
      this[area] = BigDecimal("34600")
      this[population] = 1056247
    }

    city.add("Kasserine") {
      this[area] = BigDecimal("806600")
      this[population] = 439243
    }

    city.add("Bizerte") {
      this[area] = BigDecimal("568219")
      this[population] = 368500
    }
  }
}