From 5bf1039a0ec97aab4236f6c96e1e96dc0caf5e78 Mon Sep 17 00:00:00 2001 From: "bozo.kopic" Date: Sat, 18 Dec 2021 21:31:37 +0100 Subject: frontend update --- VERSION | 2 +- src_js/common.js | 3 +++ src_js/states.js | 1 + src_js/vt.js | 53 +++++++++++++++++++++++++++++++++++++++++++---------- src_scss/_grid.scss | 53 ----------------------------------------------------- src_scss/main.scss | 15 ++++++++++----- 6 files changed, 58 insertions(+), 69 deletions(-) delete mode 100644 src_scss/_grid.scss diff --git a/VERSION b/VERSION index 0d91a54..9e11b32 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.0 +0.3.1 diff --git a/src_js/common.js b/src_js/common.js index 6e164f9..bf1327a 100644 --- a/src_js/common.js +++ b/src_js/common.js @@ -17,6 +17,7 @@ let itemCounter = 0; export async function calculate() { + r.set('calculating', true); try { const method = r.get('form', 'method'); const params = createCalculateParams(); @@ -35,6 +36,8 @@ export async function calculate() { showNotification('success', 'New calculation available'); } catch (e) { showNotification('error', e); + } finally { + r.set('calculating', false); } } diff --git a/src_js/states.js b/src_js/states.js index f55716f..a696007 100644 --- a/src_js/states.js +++ b/src_js/states.js @@ -11,6 +11,7 @@ export const main = { panel: null, item: null }, + calculating: false }; diff --git a/src_js/vt.js b/src_js/vt.js index 1dc467e..8320f75 100644 --- a/src_js/vt.js +++ b/src_js/vt.js @@ -59,15 +59,15 @@ function leftPanel() { ['span.fa.fa-github'] ] ], - ['div.group', + ['div.form', ['label', 'Method'], selectInput(r.get('form', 'method'), - ['forward_greedy', 'greedy'], - val => r.set(['form', 'method'], val)) - ], - ['div.group', + [['forward_greedy', 'Forward greedy'], + ['greedy', 'Greedy']], + val => r.set(['form', 'method'], val)), ['label', 'Cut width'], numberInput(r.get('form', 'cut_width'), + u.isNumber, val => r.set(['form', 'cut_width'], val)) ], ['div.content', @@ -75,6 +75,9 @@ function leftPanel() { leftPanelItems() ], ['button.calculate', { + props: { + disabled: r.get('calculating') + }, on: { click: common.calculate }}, @@ -87,6 +90,13 @@ function leftPanel() { function leftPanelPanels() { const panelsPath = ['form', 'panels']; + const panelNames = new Set(); + const nameValidator = name => { + const valid = !panelNames.has(name); + panelNames.add(name); + return valid; + } + return ['div', ['table', ['thead', @@ -103,24 +113,28 @@ function leftPanelPanels() { ['td.col-name', ['div', textInput(panel.name, + nameValidator, val => r.set([panelsPath, index, 'name'], val)) ] ], ['td.col-quantity', ['div', numberInput(panel.quantity, + u.isInteger, val => r.set([panelsPath, index, 'quantity'], val)) ] ], ['td.col-height', ['div', numberInput(panel.height, + u.isNumber, val => r.set([panelsPath, index, 'height'], val)) ] ], ['td.col-width', ['div', numberInput(panel.width, + u.isNumber, val => r.set([panelsPath, index, 'width'], val)) ] ], @@ -175,6 +189,13 @@ function leftPanelPanels() { function leftPanelItems() { const itemsPath = ['form', 'items']; + const itemNames = new Set(); + const nameValidator = name => { + const valid = !itemNames.has(name); + itemNames.add(name); + return valid; + } + return ['div', ['table', ['thead', @@ -192,24 +213,28 @@ function leftPanelItems() { ['td.col-name', ['div', textInput(item.name, + nameValidator, val => r.set([itemsPath, index, 'name'], val)) ] ], ['td.col-quantity', ['div', numberInput(item.quantity, + u.isInteger, val => r.set([itemsPath, index, 'quantity'], val)) ] ], ['td.col-height', ['div', numberInput(item.height, + u.isNumber, val => r.set([itemsPath, index, 'height'], val)) ] ], ['td.col-width', ['div', numberInput(item.width, + u.isNumber, val => r.set([itemsPath, index, 'width'], val)) ] ], @@ -415,12 +440,15 @@ function centerPanel() { } -function textInput(value, onChange) { +function textInput(value, validator, onChange) { return ['input', { props: { type: 'text', value: value }, + class: { + invalid: validator && !validator(value) + }, on: { change: evt => onChange(evt.target.value) } @@ -428,12 +456,16 @@ function textInput(value, onChange) { } -function numberInput(value, onChange) { +function numberInput(value, validator, onChange) { + return ['input', { props: { type: 'number', value: value }, + class: { + invalid: validator && !validator(value) + }, on: { change: evt => onChange(evt.target.valueAsNumber) } @@ -459,11 +491,12 @@ function selectInput(selected, values, onChange) { on: { change: evt => onChange(evt.target.value) }}, - values.map(i => ['option', { + values.map(([value, label]) => ['option', { props: { - selected: i == selected + selected: value == selected, + value: value }}, - i + label ]) ]; } diff --git a/src_scss/_grid.scss b/src_scss/_grid.scss deleted file mode 100644 index 68c9cb9..0000000 --- a/src_scss/_grid.scss +++ /dev/null @@ -1,53 +0,0 @@ -@import 'color'; - - -table.grid { - table-layout: fixed; - border-spacing: 0px; - border: 1px solid $color-grey-400; - - td:not(:last-child) { - border-right: 1px solid $color-grey-300; - } - - thead tr, tfoot tr { - background-color: $color-grey-200; - } - - td, th { - padding: 4px; - overflow: hidden; - text-overflow: ellipsis; - } - - tbody td { - background-color: white; - } - - tbody td, tfoot td { - border-top: 1px solid $color-grey-400; - } - - input { - width: 100%; - } - - input[type=text] { - position: relative; - border: 1px; - font-size: 10pt; - font-family: 'Roboto'; - } - - tfoot td > div { - display: flex; - - & > .spacer { - flex-grow: 1; - } - } - - .invalid { - background-color: rgba(red, 0.2); - } -} diff --git a/src_scss/main.scss b/src_scss/main.scss index 80cb0ab..ed40ab2 100644 --- a/src_scss/main.scss +++ b/src_scss/main.scss @@ -36,6 +36,10 @@ body { background-color: $color-grey-100; overflow: auto; + .invalid { + background-color: rgba(red, 0.3); + } + & > .header { flex-shrink: 0; margin: 1rem; @@ -63,12 +67,13 @@ body { } } - & > .group { - flex-shrink: 0; - display: flex; - flex-direction: column; + & > .form { + display: grid; + grid-template-columns: auto 1fr; + grid-column-gap: 0.5rem; + grid-row-gap: 0.3rem; + align-items: center; margin: 1rem; - margin-bottom: 0; } & > .content { -- cgit v1.2.3-70-g09d2