Skip to content

Commit af306d6

Browse files
committed
Refactor fleth.js to improve loading and rendering of MAP-E fields, streamline status handling, and enhance error management.
1 parent f57475c commit af306d6

File tree

1 file changed

+73
-137
lines changed
  • htdocs/luci-static/resources/view

1 file changed

+73
-137
lines changed

htdocs/luci-static/resources/view/fleth.js

Lines changed: 73 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -11,111 +11,24 @@ fleth_style.innerHTML = `.cbi-value-field { padding-top: 6px;}</style>`;
1111
document.head.appendChild(fleth_style);
1212

1313
return view.extend({
14-
// ¿
15-
load: async function () {
16-
// Return empty data immediately to allow page to render
17-
return {
18-
status: [_("Loading..."), _("Loading...")],
19-
mape_status: [_("Loading...")],
20-
};
21-
},
22-
23-
// Function to execute command with timeout
24-
execWithTimeout: function(cmd, args, timeout) {
25-
return Promise.race([
26-
fs.exec(cmd, args),
27-
new Promise((_, reject) =>
28-
setTimeout(() => reject(new Error('Command timeout')), timeout)
29-
)
30-
]).catch(err => {
31-
console.warn(`Command failed: ${cmd} ${args.join(' ')}`, err);
32-
return { stdout: "" };
14+
load: function () {
15+
return Promise.all([
16+
L.resolveDefault(fs.exec("/usr/sbin/fleth", ["get_area"]), { stdout: "" }),
17+
L.resolveDefault(fs.exec("/usr/sbin/fleth", ["get_dslite_provider"]), { stdout: "" }),
18+
L.resolveDefault(fs.exec("/usr/sbin/fleth", ["mape_status"]), { stdout: "" }),
19+
]).then(function (results) {
20+
const area = (results[0].stdout || "").trim();
21+
const dslite_provider = (results[1].stdout || "").trim();
22+
const mape_status = (results[2].stdout || "").split("\n");
23+
24+
return {
25+
area: area || "UNKNOWN",
26+
dslite_provider: dslite_provider || "UNKNOWN",
27+
mape_status: mape_status,
28+
};
3329
});
3430
},
3531

36-
// Load status data asynchronously after page render
37-
loadStatusAsync: async function() {
38-
try {
39-
// Execute both commands in parallel with timeout
40-
const [statusResult, mapeResult] = await Promise.all([
41-
this.execWithTimeout("/usr/sbin/fleth", ["status"], 5000),
42-
this.execWithTimeout("/usr/sbin/fleth", ["mape_status"], 5000)
43-
]);
44-
45-
const status = (statusResult.stdout || "").split("\n");
46-
const mape_status = (mapeResult.stdout || "").split("\n");
47-
48-
// Update area field
49-
const areaElem = document.querySelector('[data-name="area"] .cbi-value-field');
50-
let areaValue = status[0] || "UNKNOWN";
51-
if (areaElem && status[0]) {
52-
areaElem.textContent = _(status[0] || "UNKNOWN");
53-
}
54-
55-
// Update DS-Lite provider field
56-
const dsliteElem = document.querySelector('[data-name="dslite_privider"] .cbi-value-field');
57-
let dsliteValue = status[1] || "UNKNOWN";
58-
if (dsliteElem && status[1]) {
59-
dsliteElem.textContent = _(status[1] || "UNKNOWN");
60-
}
61-
62-
// Update MAP-E fields
63-
let mapeIsUnknown = true;
64-
if (mape_status.length > 1 && mape_status[0] !== "UNKNOWN") {
65-
mapeIsUnknown = false;
66-
const mapeFields = [
67-
"mape_provider", "mape_ipaddr", "mape_peeraddr",
68-
"mape_ip4prefix", "mape_ip4prefixlen", "mape_ip6prefix",
69-
"mape_ip6prefixlen", "mape_ealen", "mape_psidlen",
70-
"mape_offset", "mape_map_ports"
71-
];
72-
73-
mapeFields.forEach((field, i) => {
74-
const elem = document.querySelector(`[data-name="${field}"] .cbi-value-field`);
75-
if (elem && mape_status[i]) {
76-
elem.textContent = mape_status[i];
77-
}
78-
});
79-
} else {
80-
// Update MAP-E Provider to UNKNOWN when not available
81-
const mapeProviderElem = document.querySelector('[data-name="mape_provider"] .cbi-value-field');
82-
if (mapeProviderElem) {
83-
mapeProviderElem.textContent = _("UNKNOWN");
84-
}
85-
}
86-
87-
// Check pending status when area is not UNKNOWN but both DSLite and MAP-E are UNKNOWN
88-
if (areaValue !== "UNKNOWN" && dsliteValue === "UNKNOWN" && mapeIsUnknown) {
89-
try {
90-
const pendingResult = await this.execWithTimeout("/usr/sbin/fleth", ["pending_status"], 5000);
91-
const pendingStatus = (pendingResult.stdout || "").trim();
92-
93-
if (pendingStatus === "_pending") {
94-
// Update area field to show pending status
95-
if (areaElem) {
96-
areaElem.textContent = _(areaValue) + " " + _("(Service Pending)");
97-
}
98-
}
99-
} catch (error) {
100-
console.warn("Failed to check pending status:", error);
101-
}
102-
}
103-
} catch (error) {
104-
console.error("Failed to load status data:", error);
105-
106-
// Set error state for fields
107-
const areaElem = document.querySelector('[data-name="area"] .cbi-value-field');
108-
if (areaElem) {
109-
areaElem.textContent = _("Failed to load");
110-
}
111-
112-
const dsliteElem = document.querySelector('[data-name="dslite_privider"] .cbi-value-field');
113-
if (dsliteElem) {
114-
dsliteElem.textContent = _("Failed to load");
115-
}
116-
}
117-
},
118-
11932
render: async function (data) {
12033
let m, s, o;
12134

@@ -133,7 +46,7 @@ return view.extend({
13346

13447
o = s.taboption("info", form.DummyValue, "area", _("Area"));
13548
o.cfgvalue = function () {
136-
return _(data.status[0]);
49+
return data.area;
13750
};
13851

13952
o = s.taboption(
@@ -143,39 +56,47 @@ return view.extend({
14356
_("DS-Lite Provider")
14457
);
14558
o.cfgvalue = function () {
146-
return _(data.status[1]);
59+
return data.dslite_provider;
14760
};
148-
if (data.mape_status.length > 1 && data.mape_status[0] !== "UNKNOWN" && data.mape_status[0] !== _("Loading...")) {
149-
const mapeFields = [
150-
["mape_provider", "MAP-E Provider"],
151-
["mape_ipaddr", "IP Address"],
152-
["mape_peeraddr", "Peer Address"],
153-
["mape_ip4prefix", "IPv4 prefix"],
154-
["mape_ip4prefixlen", "IPv4 Prefix Length"],
155-
["mape_ip6prefix", "IPv6 Prefix"],
156-
["mape_ip6prefixlen", "IPv6 Prefix Length"],
157-
["mape_ealen", "EA Length"],
158-
["mape_psidlen", "PSID Length"],
159-
["mape_offset", "Offset"],
160-
["mape_map_ports", "Available ports"],
161-
];
162-
mapeFields.forEach((field, i) => {
163-
let o = s.taboption("info", form.DummyValue, field[0], _(field[1]));
164-
o.cfgvalue = function () {
165-
return data.mape_status[i];
166-
};
167-
});
168-
} else {
169-
o = s.taboption(
170-
"info",
171-
form.DummyValue,
172-
"mape_provider",
173-
_("MAP-E Provider")
174-
);
61+
62+
// Create all MAP-E fields
63+
const mapeFields = [
64+
["mape_provider", "MAP-E Provider"],
65+
["mape_ipaddr", "IP Address"],
66+
["mape_peeraddr", "Peer Address"],
67+
["mape_ip4prefix", "IPv4 prefix"],
68+
["mape_ip4prefixlen", "IPv4 Prefix Length"],
69+
["mape_ip6prefix", "IPv6 Prefix"],
70+
["mape_ip6prefixlen", "IPv6 Prefix Length"],
71+
["mape_ealen", "EA Length"],
72+
["mape_psidlen", "PSID Length"],
73+
["mape_offset", "Offset"],
74+
["mape_map_ports", "Available ports"],
75+
];
76+
77+
// Check if we should hide MAP-E details initially
78+
const shouldHideMapeDetails = data.mape_status[0] === "UNKNOWN" ||
79+
data.mape_status.length <= 1;
80+
81+
// Create all MAP-E fields
82+
mapeFields.forEach((field, i) => {
83+
const [fieldName, fieldLabel] = field;
84+
o = s.taboption("info", form.DummyValue, fieldName, _(fieldLabel));
17585
o.cfgvalue = function () {
176-
return data.mape_status[0] === _("Loading...") ? _("Loading...") : _("UNKNOWN");
86+
if (i === 0) { // MAP-E Provider field
87+
return data.mape_status[0] || _("UNKNOWN");
88+
}
89+
return data.mape_status[i] || "";
17790
};
178-
}
91+
// Add a class to identify MAP-E detail fields for hiding
92+
if (i > 0 && shouldHideMapeDetails) {
93+
o.rmempty = false;
94+
o.editable = false;
95+
// We'll hide these with CSS after render
96+
o.modalonly = false;
97+
o.optional = true;
98+
}
99+
});
179100

180101
// o = s.taboption('general', form.Button, '_hook_luci-firewall-port-forward');
181102
// o.title = '&#160;';
@@ -261,10 +182,25 @@ return view.extend({
261182
);
262183
o.nocreate = true;
263184
o.default = "wan";
264-
265-
// Start async loading of status data after render
266-
setTimeout(() => this.loadStatusAsync(), 100);
185+
186+
// Hide MAP-E detail fields initially if no valid data
187+
setTimeout(() => {
188+
if (data.mape_status[0] === "UNKNOWN" ||
189+
data.mape_status.length <= 1) {
190+
const mapeDetailFields = [
191+
"mape_ipaddr", "mape_peeraddr", "mape_ip4prefix", "mape_ip4prefixlen",
192+
"mape_ip6prefix", "mape_ip6prefixlen", "mape_ealen", "mape_psidlen",
193+
"mape_offset", "mape_map_ports"
194+
];
195+
mapeDetailFields.forEach(field => {
196+
const fieldContainer = document.querySelector(`[data-name="${field}"]`);
197+
if (fieldContainer) {
198+
fieldContainer.style.display = 'none';
199+
}
200+
});
201+
}
202+
}, 100);
267203

268204
return m.render();
269205
},
270-
});
206+
});

0 commit comments

Comments
 (0)