Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

### Added

- System Summary can read its figures from a host running Glances or Beszel, or

Check warning on line 12 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / test

entry is 178 characters; keep it to one line: "System Summary can read its figures from a host running G..."

Check warning on line 12 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / test

writes to the reader; state the fact about the software: "System Summary can read its figures from a host running G..."
from the Unraid API. The network row's throughput follows the same source, on
an interface you pick.

Expand All @@ -20,6 +20,9 @@

### Fixed

- A widget's settings no longer open filled in from the last widget of the same
type you edited.

Check warning on line 25 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / test

writes to the reader; state the fact about the software: "A widget's settings no longer open filled in from the las..."
- A tile with only a fixed label set now shows that badge.

- Saving settings no longer warns about deleting the stored password when
Expand Down
2 changes: 1 addition & 1 deletion ui/admin/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,6 @@ <h1 class="sec-title" id="ev-title">General</h1>
</div></div>
</div>

<script type="module" src="/js/admin.js?v=e8364642"></script>
<script type="module" src="/js/admin.js?v=22c45dff"></script>
</body>
</html>
8 changes: 4 additions & 4 deletions ui/js/admin-app-form.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { clr as rc, el, inp as inpById, q as qSel, qa, qi, tgt } from '/js/utils.js?v=b18c93ed';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { loadLocalIcons, resolveIcon, iconChain, cdnIconName } from '/js/icons.js?v=69c2b9bd';
import { state } from '/js/admin-state.js?v=42393ee1';
import { isDockBlocked, DOCK_MAX, clearsStoredSecret } from '/js/admin-logic.js?v=80a4637d';
import { state } from '/js/admin-state.js?v=b7731aa4';
import { isDockBlocked, DOCK_MAX, clearsStoredSecret } from '/js/admin-logic.js?v=f3f87abf';
import { t } from '/js/i18n.js?v=d056c9c5';
import {
toast,
Expand All @@ -13,8 +13,8 @@ import {
initInlineEdit,
setTogDisabled,
wireChecklist,
} from '/js/admin-shared.js?v=9c6bb360';
import { renderColorControl, BADGE_SWATCHES } from '/js/admin-color-control.js?v=c853fe21';
} from '/js/admin-shared.js?v=3d2627a9';
import { renderColorControl, BADGE_SWATCHES } from '/js/admin-color-control.js?v=3a3a1bad';
import { badgeErrorAdvice, TONE } from '/js/admin-error.js?v=10f3cdb1';

export function buildFolderForm(body, item) {
Expand Down
2 changes: 1 addition & 1 deletion ui/js/admin-auth.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ag, ap } from '/js/admin-shared.js?v=9c6bb360';
import { ag, ap } from '/js/admin-shared.js?v=3d2627a9';
import { t } from '/js/i18n.js?v=d056c9c5';
import { pwStrength } from '/js/password-strength.js?v=42f45ac7';
import { el, inp as inpById, qa } from '/js/utils.js?v=b18c93ed';
Expand Down
2 changes: 1 addition & 1 deletion ui/js/admin-color-control.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PE_SVG, initInlineEdit } from '/js/admin-shared.js?v=9c6bb360';
import { PE_SVG, initInlineEdit } from '/js/admin-shared.js?v=3d2627a9';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { qa, q } from '/js/utils.js?v=b18c93ed';

Expand Down
9 changes: 9 additions & 0 deletions ui/js/admin-logic.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
// @ts-check
/* Keep this module free of the DOM and of imports. Tests load it directly. */

/* Values typed into a widget's config form survive a re-render of that same
form, and nothing else. Opening the editor again is a new session, so the
saved config wins, or one widget's form would fill in from the last widget of
the same type that was open. */
export function carriesTypedValues(cached, wtype, session) {
if (!cached || !cached.form) return false;
return cached.type === wtype && cached.session === session;
}

export function seedCarried(config, carryKeys) {
const out = Object.create(null);
for (const k of carryKeys || []) if (config && config[k] !== undefined) out[k] = config[k];
Expand Down
4 changes: 2 additions & 2 deletions ui/js/admin-settings.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { toast, ag, ap } from '/js/admin-shared.js?v=9c6bb360';
import { toast, ag, ap } from '/js/admin-shared.js?v=3d2627a9';
import { pwStrength } from '/js/password-strength.js?v=42f45ac7';
import { t } from '/js/i18n.js?v=d056c9c5';
import { shouldWritePassword, settingsSaveBlocker, clearsStoredPassword, BLOCK } from '/js/admin-logic.js?v=80a4637d';
import { shouldWritePassword, settingsSaveBlocker, clearsStoredPassword, BLOCK } from '/js/admin-logic.js?v=f3f87abf';
import { el, inp, q, qa, setUserText } from '/js/utils.js?v=b18c93ed';

/* Mirrors the server's rule: auth cannot be switched on with no password. */
Expand Down
2 changes: 1 addition & 1 deletion ui/js/admin-shared.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Stateless helpers shared by the admin modules. Mutable state stays out. */
import { nextActiveIndex, recoversSession, toastMs } from '/js/admin-logic.js?v=80a4637d';
import { nextActiveIndex, recoversSession, toastMs } from '/js/admin-logic.js?v=f3f87abf';
import { el, qa, q } from '/js/utils.js?v=b18c93ed';
import { t } from '/js/i18n.js?v=d056c9c5';

Expand Down
2 changes: 2 additions & 0 deletions ui/js/admin-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ export const state = {
_wAutoCfg: {},
_autoForm: null,
_autoFormType: null,
_autoFormSession: null,
_evSession: 0,
};
25 changes: 19 additions & 6 deletions ui/js/admin-widget-form.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { state } from '/js/admin-state.js?v=42393ee1';
import { PE_SVG, CHEV_SVG, initInlineEdit } from '/js/admin-shared.js?v=9c6bb360';
import { renderWidgetConfigForm } from '/js/widget-config-form.js?v=e2dfacc3';
import { state } from '/js/admin-state.js?v=b7731aa4';
import { PE_SVG, CHEV_SVG, initInlineEdit } from '/js/admin-shared.js?v=3d2627a9';
import { renderWidgetConfigForm } from '/js/widget-config-form.js?v=bf180b36';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { sizesForView, widgetConfigMode, rejectionLines, refusedNoticeKey } from '/js/admin-logic.js?v=80a4637d';
import {
sizesForView,
widgetConfigMode,
rejectionLines,
refusedNoticeKey,
carriesTypedValues,
} from '/js/admin-logic.js?v=f3f87abf';
import { t } from '/js/i18n.js?v=d056c9c5';
import { q, qi, qa } from '/js/utils.js?v=b18c93ed';

Expand Down Expand Up @@ -35,8 +41,14 @@ export function buildWidgetForm(body, item) {
}

function _renderWidgetForm(body) {
/* Re-render of the same registry widget: keep typed values. */
if (state._autoForm && state._autoFormType === state._wtype) {
/* Re-render of the same form in the same editing session: keep typed values. */
if (
carriesTypedValues(
{ form: state._autoForm, type: state._autoFormType, session: state._autoFormSession },
state._wtype,
state._evSession,
)
) {
state._wAutoCfg = Object.assign({}, state._wAutoCfg, state._autoForm.getValues());
}
state._autoForm = null;
Expand Down Expand Up @@ -120,6 +132,7 @@ function _renderWidgetForm(body) {
},
});
state._autoFormType = state._wtype;
state._autoFormSession = state._evSession;
} else if (_mode === 'unavailable') _renderUnavailableConfig(body);
else _renderCustomConfig(body);
}
Expand Down
15 changes: 8 additions & 7 deletions ui/js/admin.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { buildAppForm, buildFolderForm, serializeKvRows } from '/js/admin-app-form.js?v=70e2d15b';
import { checkAuth, requireLogin, wirePasswordStrength } from '/js/admin-auth.js?v=cb00465f';
import { buildAppForm, buildFolderForm, serializeKvRows } from '/js/admin-app-form.js?v=f8fda76d';
import { checkAuth, requireLogin, wirePasswordStrength } from '/js/admin-auth.js?v=76be763e';
import { applyDrop, canJoinFolder } from '/js/admin-drag-logic.js?v=8fcf583a';
import { reorderItems, resolveAdminSection } from '/js/admin-logic.js?v=80a4637d';
import { reorderItems, resolveAdminSection } from '/js/admin-logic.js?v=f3f87abf';
import {
buildAppItem,
claimFolderChildren,
Expand All @@ -10,10 +10,10 @@ import {
snapshotItems,
upsertItem,
} from '/js/admin-save-logic.js?v=52a970d3';
import { loadSettings, showBgFields } from '/js/admin-settings.js?v=263d3422';
import { ag, ap, initInlineEdit, setReauthHandler, toast } from '/js/admin-shared.js?v=9c6bb360';
import { state } from '/js/admin-state.js?v=42393ee1';
import { buildWidgetForm } from '/js/admin-widget-form.js?v=04ee8ab3';
import { loadSettings, showBgFields } from '/js/admin-settings.js?v=e9bec962';
import { ag, ap, initInlineEdit, setReauthHandler, toast } from '/js/admin-shared.js?v=3d2627a9';
import { state } from '/js/admin-state.js?v=b7731aa4';
import { buildWidgetForm } from '/js/admin-widget-form.js?v=5292c6a0';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { initI18n, LANGUAGES, t } from '/js/i18n.js?v=d056c9c5';
import { iconChain, loadLocalIcons, resolveIcon } from '/js/icons.js?v=69c2b9bd';
Expand Down Expand Up @@ -695,6 +695,7 @@ function openModal(idx) {

state._evItem = item;
state._evIsEdit = isEdit;
state._evSession += 1;
_renderEditBody();

showEditView();
Expand Down
6 changes: 3 additions & 3 deletions ui/js/widget-config-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@

import { t } from '/js/i18n.js?v=d056c9c5';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { wireChecklist } from '/js/admin-shared.js?v=9c6bb360';
import { renderColorControl } from '/js/admin-color-control.js?v=c853fe21';
import { wireChecklist } from '/js/admin-shared.js?v=3d2627a9';
import { renderColorControl } from '/js/admin-color-control.js?v=3a3a1bad';
import {
seedCarried,
applyOptionSet,
collectFieldValues,
requiredFieldMissing,
groupBounds,
visibleFieldFlags,
} from '/js/admin-logic.js?v=80a4637d';
} from '/js/admin-logic.js?v=f3f87abf';
import { optionsErrorAdvice, TONE } from '/js/admin-error.js?v=10f3cdb1';
import { qi } from '/js/utils.js?v=b18c93ed';

Expand Down
15 changes: 15 additions & 0 deletions ui/test/admin-logic.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
nextActiveIndex,
groupBounds,
visibleFieldKeys,
carriesTypedValues,
visibleFieldFlags,
collectFieldValues,
clearsStoredSecret,
Expand Down Expand Up @@ -176,6 +177,20 @@ test('visibleFieldKeys does not leak a field across a hidden branch default', ()
assert.deepEqual([...shown], ['source']);
});

/* Two tiles of one widget type each open the same form. Carrying values by type
alone filled the second tile's form from the first, so a Beszel tile opened
after a Glances one showed Glances as its source. */
test('typed values are carried within one editing session, never into the next', () => {
const form = { getValues: () => ({}) };
const opened = { form, type: 'system-summary', session: 4 };

assert.equal(carriesTypedValues(opened, 'system-summary', 4), true, 'a re-render of the same open form');
assert.equal(carriesTypedValues(opened, 'system-summary', 5), false, 'another widget of the same type');
assert.equal(carriesTypedValues(opened, 'dns', 4), false, 'a different widget type');
assert.equal(carriesTypedValues({ form: null, type: 'system-summary', session: 4 }, 'system-summary', 4), false);
assert.equal(carriesTypedValues(null, 'system-summary', 4), false);
});

test('only the visible copy of a repeated key is saved', () => {
/* The system summary declares its slot list once per source. Both are built,
one is on screen, and the saved config must carry that one alone. */
Expand Down