Sunday, October 3, 2021

Dummy DS

For as many testing modules as possible I needed a really quick way to set them up. In the past I had a “Builder”, allowing me to easily define components in a WYSIWYG manner.

Now with the simple REST API what I was looking for was actually more simple approach just to define a schema, with automatic GUI generator. Nothing fancy. My favorite tool for this job is HeidiSQL and I wanted to create something similar.


HeidiSQL

So I made a Schema Creator (“Schemator”), where you define some basic attribute properties, like name, label, data type, mode and whether you want it as a column in the main table, or just in the form. Then it generates appropriate schema, or even the whole model. Cool.

According to my experience, in most cases you wouldn't create the schema from scratch or top of your head. You either have a specs, data model or old version of the system. So the next logical step was to create a parser for QElem names pasted from a Clipboard.

To work even better I implemented a guessing of a proper data type, so elem with "is_" prefix probably is a boolean, if it has "date" in the name, it's often a date (duh!) and so on. This worked nice, but it wasn't impressive. And I had an idea for a long time, that would fit nicely in here.

The idea was to have a DataStore for mocking or prototyping, with dummy data, that would actually make some sense. Like for "Date of birth" it wouldn't just generate a random date, but it will be at least some 20 years old to represent an adult employee or user.

Or an e-mail address wouldn't be some random string with @, but if the entry contains name, it would be derived from that in a random format. Some of them will contain last name and a number, some first name and last name in lower case or not, with dot, underscore or nothing in between.


Qedy Schema Creator with auto-generated values. Any resemblance to real persons, living or dead, is purely coincidental.

Similarly for address fields, phone numbers, genders, identifiers and such, not to mention region-specific data sets (for the screenshot above I used my local Czech). The possibilities here are nearly endless.

There are also a simple editor for enumeration options, with paste support and file import.

Impressive, huh? But wait, it doesn't end there. The preview isn't some dumb table, it's actually a real app. In the background it generates a working model for Qedy, that is parsed and rendered into the preview DIV.

And as in a real app, by clicking on the table row you will go to a form for the chosen record, where you can edit values with proper validations, and these changes, after saving, will propagate back to the table.


Basically a working app, only without persistent data. I have to admit I had a blast working on it and I'm proud of the result. I started with an idea to have something, that makes the app in development feel good when showing to someone, and I ended up with something, that feels good showing to someone just by itself :-)

As a cherry on top, to work nicely with HeidiSQL, I added a support for SQL DDL (CREATE TABLE) for both import and export. So now it's super fast to move back and forth between the model and the database. And with proper server-side DataStore (supporting DDL) it's possible to do it directly.

Sunday, November 1, 2020

Autumn cleanup

I noticed some concepts in Qedy ain't right. For instance, I always perceived Modal window as a separate entity, but in fact it's just bit more complicated QView. This also once again confirms, that my choice of just four component types (elem, form, list, view) is indeed sufficient.

Similar problem was with various frontend perks, like content prefetching or smooth scrolling. I added prefetch to an ordinary QList as f_prefetch feature and I created some extensions (“plugins”) for QView_Page.

Thursday, April 23, 2020

Subjects

With the team we finished a module for subjects (people and companies). We were hoping to get a shortcut, but the customer disagreed :-), so in the last months of many improvements and fixes I was forced to add a lot of technical debt to the codebase.

Another setback was the customer is still using IE11 and the original Edge, which added more complexity to the code, as various polyfills were required and also separate stylesheets, because there's no way to distinguish between the two using just media queries:

  1. IE11:
  2. @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { ... }
  3. Edge:
  4. @supports (-ms-ime-align:auto) { ... }

This was our first deployment of QedyJS, where we gathered awful lot of experience, and also the module is only a temporary solution for the customer, because he contracted another company, that are unable to provide their solution at the moment for legal reasons.

So I took the opportunity and created basically a working “demo” of what the final version of QedyJS should be capable of, only without all the hacks, tweaks and crutches. It's always easier to think of what to do differently, than what to do. This demo became a foundation for the Mk. III announced back in January and was largely enhanced since – Mk. IIIb, if you will.

There were some approaches I didn't like, some of them didn't work, some of them were sub-optimal, some of them was proven and will be kept, some of them were introduced for the first time and some of them were put aside for the time being.

I gathered all of the above and started once again with a clean plate. This time not as my primary project, but rather as a side project to pamper and enjoy. I wanted to have the time to do it really properly, to be able to elaborate on ideas, to have an incubator for them.

Sunday, April 12, 2020

Comp-Elem Modes

There are six basic modes for components:

  • *hidden*: component is not in DOM and therefore not visible to user;
  • *plain*: component (rather it's text or value) is represented by plain text;
  • *inactive*: component is read-only or disabled, but as a form control;
  • *normal*: component is an editable form control;
  • *expected*: component is marked as "expected", which is just visual distinction and overall works just as “normal”;
  • *required*: component is required to have a value before form processing.

To make things easier, if you need to set a particular mode to multitude of elements, you can simply set a mode to their parent component, instead of every element separately.

But there are cases, in which you probably don't want to override the mode: if you have an element defined as inactive, like a computed value, you don't want it to suddenly became required. And if it's hidden, it should stay that way.

From such rules emerged the following table:


Results of mode overrides by component (rows) for elem modes (columns).

I did several tests and it works as expected. If your expectations are different, you can always set mode directly to elements and omit using bulk mode assignments via parent components.

Thursday, January 30, 2020

JavaScript Framework Mk. III

If I find reengineering favorable, I usually go for it. Therefore major versions with breaking changes appear fairly quickly in the beginning of a new software product, allowing me to stabilize the API as soon as possible.

On the other hand, most changes are in QedyJS, so unfortunately almost none of the current improvements will go open source.

Scopes. Multiple modules at once, scope is passed with the component, which is no problem in most cases. But it's a little annoying, since I decided to have no cirucular references, which means a component can't contain scope object and therefore I have to pass component and scope separately in two parameters. And for the rest you must specify the scope, which is also annoying, but also necessary.

Speaking of scopes, I reimagined JavaScript scopes as well. Now module methods have direct access to the scope via this and because I decided to “trust” converters, they have now direct access to components and therefore are able to modify them. It makes a lot of things much easier and more streamlined.

I waited with a release many months, to have full functionality right from the start. Nothing was postponed (like datastores in Mk. II), because that's what bit me in the butt in the past the most.

Found even more great articles and talks about JS performance and did tremendous amount of micro optimizations in the code, especially in loops, where it makes sense the most. Some (if not most) of them are probably unnecessary, but I'm a performance freak, so it feels good to have 'em all :-)

Got rid of domLinks, now links are bundled with the component. The same applies for items and data-realted logic (e.g. sorting and filtering) were moved from components to datastores.

Some of original designs are great and in fact some of them even goes back to Mk. I. And don't let me start with the whole concept of QetriX, I must admin it makes me proud the core basics I established over a decade ago still works perfectly.

Friday, March 1, 2019

JavaScript Framework Mk. II

My next big project is a frontend for enterprise web app. My assignment was to find a JS framework and the original idea was to use Sencha Ext JS, because the other team in our joint-venture uses it, but I also looked into Angular, React and especially Vue.js, which was my personal favorite.

I quickly figured out Sencha is vast, with complete set of widgets, but hard to learn, quite expensive and even one long term user wrote he wouldn't use it for a new project, so in my eyes Sencha was out.

I tried some demos for Vue.js and because it was exactly what I was looking for, I wanted to know how it works inside. I studied some basic Vue internals and virtual DOM and it got me thinking the idea is not that different from how I implemented QetriX Components years ago in PHP.

My big mistake in Mk. I was I relied solely on DOM, so most variables were strings (because input.value returns a string) and I had to convert it to proper data type all the time, which created a messy code. Now all data would be in the model, so variables will always have a correct type.

I already had a JSON definition for layout (nested components) from PHP version of Qedy, so I used it to create a proof-of-concept and it worked quite well. There's no reactive binding magic, all changes are declarative, but this way it should perform better with smaller memory footprint, than real virtual DOM. This is the best excuse I came up with ;-)

DOM is generated by Converters and some parts of it are accessible via internal key-object register called “domLinks”. For example, in a form I can access all the inputs and other fields to get/set their values. I did it this way to simplify object model in a different languages.

Wednesday, October 17, 2018

Client-Server Web App

I'm often oldschool and even I keep an eye on contemporary approaches, I don't really pay much attention to them. I'm probably worried it's just a short term fashion or an upcoming dead end, but sometimes I miss a lot for a long time - like this time.

I prefer server side HTML rendering, because it's a single solution for both users and robots. I perceive Node.js as yet another Java, so server side JavaScript for the single solution is not appealing to me.

Years ago I participated on project, where client side was created using GWT in JavaScript, while servlet only provided data via API in a form of JSON messages. I liked the idea, but I didn't see myself doing such thing.

Few years after that I participated on a project with the same approach once again and still didn't see what it's all about, but this time I finally wanted to try it. My opportunity came in less than a year.

The project for it was perfect – transforming old intranet app, created in Microsoft Access, into a modern web app. Because of the Microsoft ecosystem, my proposal to use ASP.NET Core looked like an obvious choice.

I was little worried the Core platform may lack some features, but version 2.x was mature enough to provide everything I needed and I had QetriX up and running in just a few days.

For the client side I created standalone HTML templates, that defined a layout and components. Because nowadays the DOM is optimized enough, I opted out of virtual DOM, defined custom properties as “data” attributes and the rest as QetriX Modules.

It worked surprisingly well, but I also encountered some drawbacks. First of all, I worked with a lot of numbers, but values and data attributes are strings, so I had to convert data types all the time. Second of all...

Friday, January 13, 2017

Qedy 2

I started this year under new management and only after two weeks in I'm already going to ask my new boss to postpone the development and base the app on a reengineered Qedy, because I figured out a way how to cut my database schema to half, removing a lot of relation tables (leading to much slicker code) and making more sense of what's left.

Now the whole project is moving more towards the original simple QetriX Particle system, which I spent quite a time developing, so I know well how to do stuff that way.

Also, later I found out I can easily use Particles for object attribute/relation DB cache, which made me quite happy, because the whole concept just clicked there.

Monday, August 1, 2016

Qedy

Golfers have caddie, corporations have Qedy. Both do basically the same job – supports the star in every way possible. And there are really many ways for Qedy!

Qedy is a commercial extension of the Framework, which means most of the shared functionalities won't be open source. Qedy is purposed for rapid development of intranet and extranet information systems.

With Qedy, instead of coding, you simply create your apps in Builder, where you can see a mockup of GUI, define a data model, create label translations and more.


Qedy Logo: “ED” from rotated Q, styled as Möbius strip.

But Qedy isn't just for web apps, you can create websites with it as well! Using simple block approach you add content for the page quickly and easily. In fact, exhibit A is this blog, whose content editor uses exactly that.

With Qedy you can define component conditions, visualize them and test using defined values.