Sunday, July 27, 2014

Development Environment

I took this project as an opportunity to learn recent web development techniques. This is the list of buzz words I've used:

First, I used Bower to download Durandal and Bootstrap and prepared some basic Grunt configuration (run web server for development). Then, I dived into Durandal and learned how to structure the application. I tried to scaffold the app structure with existing Durandal's Grunt configuration but eventually, I created everything from scratch using the scaffolding structure as a tutorial. One learns more with this approach.

Having basic app structure (2 pages wired together) and grunt configuration, I created my first Jasmine test. I wanted to practice TDD for development but I found out that it does not work well for me. I did not have any clear vision how things would work and I did a lot of changes during the development. That's why I have just classic unit tests. Once I am satisfied with a feature, I create unit tests for it to make sure I won't break it in future.

Although Durandal uses AMD, I worried about referencing source files from tests. The research, experimentation and creating Grunt configuration took me some time. But it works nicely in the end. Grunt's Jasmine task references two require.config.js files. The first one is the main application require.config.js file and the second one is Jasmine's one with baseUrl pointing to application's folder. All unit tests run when any of my JavaScript files change.

The last thing to figure out was how to test SQL queries. I set it up only later when I was developing the report and it was obvious that with manual testing I would not be able to cover all the corner cases properly. I use T.S.T. and I set it up like unit tests. I have special query file which contains just the SQL query. Using simple script, this query is inserted into production and testing JavaScript template files. If any of these files change, tests are triggered. Of course, there is a Grunt task for firing it up.

Note at the end: web technologies change rapidly. Today, instead of Durandal, I might use just Knockout 3 based on Steve Sanderson NDC presentation:  Architecting large Single Page Applications with Knockout.js.

Saturday, July 26, 2014

POS for Ice-cream Kiosks

I have a neighbor who sells ice cream. He owns several kiosks in various towns around the country.  Two years ago we talked and he asked how hard would be to develop a simple POS (Point Of Sale) for him. He was very unsatisfied with his solution. He had a general cash register from which he had to download all transactions every day otherwise they would disappear. It had functionality he did not need but also lacked some functionality he needed. And it was expensive.

I worked for Radiant Systems so I know a thing or two about POS systems. This one is very simple. All it has to do is to send transactions to the server. The items and prices are fixed during the year which means there is no inventory management. The only changing variables are cashiers but their management is simple - we need to track just name, pin and kiosk where the cashier work. Reporting consists of one report with sold items and shift durations. Overall, quite simple functionality, right?

Then I started thinking about the server requirements which is a grey area for me. I don't know enough about it, especially about operations. I played with Node in Azure VM a little bit but I was not sure enough. The project went to sleep at the end of the year 2012…

To be resumed a year later. My neighbor was more angry about the cash registers. And there was a new feature in Azure - the Mobile Services. I don't need to deal with the server details any more. Exactly what I wanted. So in the autumn 2013, we agreed on an attempt to implement it and I started to work on a proof of concept.

Following the KISS principle, the initial design was as follows:
  • Android tablet in each kiosk connected to the Internet via 3G modem
  • HTML SPA (Single Page Application) as client POS application running in the browser on the tablet
  • JavaScript Azure Mobile Services with SQL database as server

I prototyped an initial solution during the rest of the year 2013. Three screens (sign in, cash box, report), all in one big awful HTML page. But that is what prototypes are for - to see whether it can work, then throw it away and do it properly. Here is the main screen from the prototype:


We tested it on a tablet and it looked good - a green light for my little, fun, real, side project. I had three months to properly develop it during my spare time. Yes, it was optimistic :-)

Sunday, November 13, 2011

Sharing .xaml in WPF and Silverlight

Sharing code between WPF and Silverlight is not difficult. Good how-to is in the Prism guide. However sharing more complex .xaml is not so easy. You have to handle different namespaces and properties.

Handling different namespaces

Silverlight toolkit components are accessible via special namespace. So if you want to use a WrapPanel in Silverlight, you write something like this:

<UserControl x:Class="UnifiedXaml.TestControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">
    <toolkit:WrapPanel></toolkit:WrapPanel>
</UserControl>

WPF world is easier:

<UserControl x:Class="UnifiedXaml.TestControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <WrapPanel></WrapPanel>
</UserControl>

It's clear those two .xaml files are so similar that they should be just one file. Here is one tiny line that makes it possible:

namespace UnifiedXaml
{
    public class MyWrapPanel: WrapPanel { }
}

From now on, you can share the .xaml file:

<UserControl x:Class="UnifiedXaml.TestControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:ux="clr-namespace:UnifiedXaml">
    <ux:MyWrapPanel></ux:MyWrapPanel>
</UserControl>

Handling different properties

When you follow Prism guidelines, you have separate projects for WPF and Silverlight parts. That means the WPF/SL application resources dictionaries are also separate. So the easiest way to handle different properties is to use styles. Shared .xaml file specifies just the control and its style. All necessary properties for WPF are defined in the style stored in the WPF application resources dictionary and the same is done for Silverlight.