aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--src_js/common.js3
-rw-r--r--src_js/states.js1
-rw-r--r--src_js/vt.js53
-rw-r--r--src_scss/_grid.scss53
-rw-r--r--src_scss/main.scss15
6 files changed, 58 insertions, 69 deletions
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 {