Orders
This is a business screen at the size of a real one. Orders come from the server, you search them, filter by status, sort by a column, press a row to open the detail pane, change a quantity, save, and a notice appears and clears itself.
Everything you can see is the designer's
Read the designer's index.html first and you will find nothing in it for LPScript. The ids and classes are there because CSS needs them.
The LPScript side clones those samples and fills them in.
Screen >> rowOf: o = (
r := Html clone: '#lines tr' fill: {
'.c-id' -> o id.
'.c-customer' -> o customer.
'.c-total' -> (self yen: o total).
'.c-status .badge' -> o status label }.
(r on: #click send: #select: with: o id) key: o id ).
Add a column to the page and nothing here changes, as long as the class names stay. Change a class name and the build stops. A value quietly landing nowhere does not happen.
The status is not a string
Pending, in progress and done are one of three. Held as strings, a misspelling and a forgotten comparison both wait until run time. So each one is a class, and a protocol says what any of them must answer.
Protocol subclass: #Status requires: (#label #badge #next).
Object subclass: #Pending protocols: (Status).
Pending >> label = '未処理'.
Pending >> badge = 'b-new'.
Pending >> next = Working new as: Status.
'未処理' is written once. The text on the filter chip, the match when reading JSON, the CSS class and the transition to the next status all come from those three lines. Add a phase and forget badge, and the compiler stops you.
It does not wait
The request goes out and the reply arrives as a message.
Screen >> load = (
(Http get: 'orders.json') then: [:r | me ref tell loaded: r].
self ).
The handler finishes at once, so the screen keeps answering while the request is in flight. The request cannot fail: a connection that never came back answers as a Response with status 0, so there is one place to handle it.
Money
qty is an Int and price a Decimal. The amount is multiplied and then truncated to whole yen — saying where to round is what Decimal is for.
Order >> total = (qty asDecimal * price) truncatedTo: 0.
Reading it from JSON loses no digits either. A number travels as the text it arrived as, and becomes a number when something asks for asDecimal.