diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OdoSpeedField.java b/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OdoSpeedField.java index b1e38f2..b1b84fa 100644 --- a/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OdoSpeedField.java +++ b/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OdoSpeedField.java @@ -12,7 +12,7 @@ public class OdoSpeedField { private String id; - private int shift; + private Integer shift; private String mask; diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OdsDirField.java b/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OdsDirField.java index 177a6f0..b0e6439 100644 --- a/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OdsDirField.java +++ b/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OdsDirField.java @@ -13,7 +13,7 @@ public class OdsDirField { private String id; - private int shift; + private Integer shift; private String mask; diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index 2dff5fc..3972cb8 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -54,12 +54,97 @@ details.nav { background: #d9d9d9; display: flex; align-items: center; + justify-content: space-between; padding: 0 32px; font-size: 28px; font-weight: 500; box-shadow: 0 2px 4px rgba(0, 0, 0, .15) inset } +.topbar-actions { + display: flex; + align-items: center; + gap: 12px; +} + +.topbar-file-actions { + display: flex; + align-items: center; + gap: 12px; +} + +.topbar-actions .file-upload-wrapper-device { + display: flex; + align-items: center; +} + +.topbar-actions .file-upload-wrapper-protocol { + display: flex; + align-items: center; +} + +.topbar-actions button { + min-width: 140px; + height: 40px; + padding: 10px 18px; + line-height: 1; + font-size: 16px; + border: 1px solid #bbb; + border-radius: 4px; + cursor: pointer; +} + +.topbar-actions .select-file-btn-device, +.topbar-actions .download-device-file { + background: #2f6fdf; + border-color: #245cc0; + color: #fff; +} + +.topbar-actions .select-file-btn-device:hover, +.topbar-actions .download-device-file:hover { + background-color: #245cc0; +} + +.topbar-actions .select-file-btn-device:active, +.topbar-actions .download-device-file:active { + background-color: #1d4da3; + transform: scale(0.97); +} + +.topbar-actions .select-file-btn-protocol, +.topbar-actions .download-protocol-file { + background: #d97706; + border-color: #b85f00; + color: #fff; +} + +.topbar-actions .select-file-btn-protocol:hover, +.topbar-actions .download-protocol-file:hover { + background-color: #b85f00; +} + +.topbar-actions .select-file-btn-protocol:active, +.topbar-actions .download-protocol-file:active { + background-color: #924b00; + transform: scale(0.97); +} + +.topbar-actions .save-file { + background-color: #4caf50; + border-color: #3f9a43; + color: #fff; +} + +.topbar-actions .save-file:hover { + background-color: #45a049; +} + +.topbar-actions .save-file:active { + background-color: #3e8e41; + transform: scale(0.97); +} + /* ───── Main Board ───── */ .content { flex: 1; diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 31ac8cc..2f17783 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -26,7 +26,7 @@ - + @@ -35,7 +35,31 @@
SSID - +
+
+
+ + +
+ +
+ + +
@@ -63,20 +87,9 @@
- 2-letter code such as KR, EU, JP, US + 2-letter code such as KR, DE, JP, US
-
-
- - -
- -
@@ -115,17 +128,6 @@
LTE Server
-
-
- - -
- -
@@ -215,17 +217,6 @@ -
-
- - -
- -
@@ -245,22 +236,11 @@ -
-
- - -
- -
diff --git a/src/main/resources/static/js/navigation.js b/src/main/resources/static/js/navigation.js index 882f0aa..b830fca 100644 --- a/src/main/resources/static/js/navigation.js +++ b/src/main/resources/static/js/navigation.js @@ -15,6 +15,8 @@ export function createNavigation() { const titleElement = byId('page-title'); const sidebarButtons = queryAll('.nav-items button'); + const topbarDeviceActions = document.querySelector('.topbar-device-actions'); + const topbarProtocolActions = document.querySelector('.topbar-protocol-actions'); const protocolSelect = byId('reg_protocol'); const canInputSelect = byId('reg_can_input'); const odometerSelect = byId('OdoMeter'); @@ -32,6 +34,15 @@ export function createNavigation() { const sourceButton = document.querySelector(`.nav-items button[data-page="${pageName}"]`); titleElement.textContent = sourceButton?.textContent ?? pageName; + + const isProtocolPage = ['reg', 'modbus', 'opcua', 'can', 'odometer'].includes(pageName); + if (topbarDeviceActions) { + topbarDeviceActions.style.display = isProtocolPage ? 'none' : 'flex'; + } + + if (topbarProtocolActions) { + topbarProtocolActions.style.display = isProtocolPage ? 'flex' : 'none'; + } } function toggleProtocolMenus(protocolValue, canInputValue, odometerValue) { diff --git a/src/main/resources/static/js/protocol/odometer.js b/src/main/resources/static/js/protocol/odometer.js index fa7e603..4686476 100644 --- a/src/main/resources/static/js/protocol/odometer.js +++ b/src/main/resources/static/js/protocol/odometer.js @@ -56,6 +56,25 @@ export function createOdometerController() { function initialize() { renderRows(); + + listElement?.addEventListener('change', (event) => { + if (!event.target.classList.contains('odometer-source-input')) { + return; + } + + const row = event.target.closest('tr'); + if (!row) { + return; + } + + ['.odometer-id-input', '.odometer-shift-input', '.odometer-expr-input', '.odometer-mask-input'] + .forEach((selector) => { + const input = row.querySelector(selector); + if (input) { + input.value = ''; + } + }); + }); } return { diff --git a/src/main/resources/static/js/protocol/protocolValidation.js b/src/main/resources/static/js/protocol/protocolValidation.js index 3670552..5119403 100644 --- a/src/main/resources/static/js/protocol/protocolValidation.js +++ b/src/main/resources/static/js/protocol/protocolValidation.js @@ -86,9 +86,16 @@ export function getRegisterConfigValidationError(data) { continue; } - for (const key of ['odo_speed_source', 'id', 'shift']) { - if (String(item[key] ?? '').trim() === '') { - return `${label} missing '${key}'.`; + const source = String(item?.odo_speed_source ?? '').trim().toLowerCase(); + if (!source) { + return `${label} missing 'odo_speed_source'.`; + } + + if (source === 'can') { + for (const key of ['id', 'shift']) { + if (String(item[key] ?? '').trim() === '') { + return `${label} missing '${key}'.`; + } } } }