Skip to content

Commit 7049e58

Browse files
author
FolderView Plus Test
committed
Move theme workspace into dedicated Appearance tab
1 parent 1968d26 commit 7049e58

8 files changed

Lines changed: 23 additions & 6 deletions

archive/folderview.plus-2026.04.12.01.txz.sha256

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
75b34c1de9f07fac20cc10e67364b2598f1d1e04302bbcea664ae549538b5428 folderview.plus-2026.04.15.03.txz

folderview.plus.plg

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@
66
<!ENTITY launch "Settings/FolderViewPlus">
77
<!ENTITY plugdir "/usr/local/emhttp/plugins/&name;">
88
<!ENTITY pluginURL "https://raw.githubusercontent.com/&github;/dev/folderview.plus.plg">
9-
<!ENTITY version "2026.04.15.02">
10-
<!ENTITY md5 "1ceddf3e9c607e9b80deefa768bafabb">
9+
<!ENTITY version "2026.04.15.03">
10+
<!ENTITY md5 "bc8b75aff9dcb40180ac80bc5eb10874">
1111
]>
1212

1313
<PLUGIN name="&name;" author="&author;" version="&version;" launch="&launch;" pluginURL="&pluginURL;" icon="folder-icon.png" support="https://forums.unraid.net/topic/197631-plugin-folderview-plus/" min="7.0.0">
1414
<CHANGES>
1515

16+
###2026.04.15.03
17+
- UX: Settings workspace layout, section flows, and table behavior.
18+
19+
1620
###2026.04.15.02
1721
- Fix: Fixed concurrent JSON writes during first-load settings normalization so VM and Docker prefs no longer race on the same temporary file.
1822
- Fix: Updated atomic JSON writes to use a unique temp file per request before rename, which prevents intermittent `Failed to replace JSON payload` errors during settings bootstrap and diagnostics reads.

src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/FolderViewPlus.page

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ if (!empty($fvplusRuntimeConflicts)) {
7979
<span id="update-check-status" class="status-line"></span>
8080
<span id="rollback-status" class="status-line"></span>
8181

82+
<h2 data-fv-section="theme-workspace" data-fv-advanced="1" data-fv-advanced-group="appearance">Theme workspace</h2>
8283
<div id="fv-theme-workspace-panel" class="fv-theme-workspace-panel">
8384
<div class="rules-panel fv-theme-workspace-shell">
8485
<div class="rules-header">
85-
<h3>Theme Workspace</h3>
8686
<span class="rules-help">Import GitHub CSS themes, activate one managed theme at a time, and layer FolderView Plus token overrides and custom CSS on top.</span>
8787
</div>
8888
<div class="fv-theme-workspace-body">

src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/scripts/folderviewplus.settings-sections.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const LEGACY_ADVANCED_SECTION_KEYS = [
1616
'conflict-inspector'
1717
];
1818
const ADVANCED_SECTION_KEYS = new Set([
19+
'theme-workspace',
1920
'auto-assignment',
2021
'bulk-assignment',
2122
'runtime-actions',
@@ -25,18 +26,20 @@ const ADVANCED_SECTION_KEYS = new Set([
2526
'diagnostics',
2627
'conflict-inspector'
2728
]);
28-
const ADVANCED_GROUPS = ['automation', 'rules', 'recovery', 'operations', 'diagnostics'];
29+
const ADVANCED_GROUPS = ['automation', 'rules', 'recovery', 'operations', 'appearance', 'diagnostics'];
2930
const ADVANCED_GROUP_LABELS = {
3031
automation: 'Automation',
3132
rules: 'Rules',
3233
recovery: 'Recovery',
3334
operations: 'Operations',
35+
appearance: 'Appearance',
3436
diagnostics: 'Diagnostics'
3537
};
3638
const SECTION_APPLY_BEHAVIOR = Object.freeze({
3739
customizations: 'instant',
3840
docker: 'instant',
3941
vms: 'instant',
42+
'theme-workspace': 'instant',
4043
'auto-assignment': 'instant',
4144
'conflict-inspector': 'instant',
4245
'bulk-assignment': 'instant',
@@ -47,6 +50,7 @@ const SECTION_APPLY_BEHAVIOR = Object.freeze({
4750
diagnostics: 'instant'
4851
});
4952
const ADVANCED_GROUP_BY_SECTION = {
53+
'theme-workspace': 'appearance',
5054
'auto-assignment': 'rules',
5155
'bulk-assignment': 'automation',
5256
'conflict-inspector': 'rules',
@@ -69,6 +73,7 @@ const ADVANCED_MODULE_KEYS_BY_TAB = Object.freeze({
6973
rules: Object.freeze([]),
7074
recovery: Object.freeze(['docker_backups', 'vm_backups', 'change_history']),
7175
operations: Object.freeze(['docker_templates', 'vm_templates']),
76+
appearance: Object.freeze([]),
7277
diagnostics: Object.freeze(['change_history'])
7378
});
7479
const BASIC_WORKSPACE_SECTION_KEYS = new Set(['docker', 'vms']);

tests/settings-bindings.test.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ test('settings page loads extracted settings metadata before the main runtime',
9696
});
9797

9898
test('settings page exposes theme workspace and saved folder defaults controls', () => {
99+
assert.match(page, /<h2 data-fv-section="theme-workspace" data-fv-advanced="1" data-fv-advanced-group="appearance">Theme workspace<\/h2>/);
99100
assert.match(page, /id="fv-theme-workspace-panel"/);
100101
assert.match(page, /id="fv-theme-github-source"/);
101102
assert.match(page, /id="fv-theme-workspace-list"/);

tests/settings-surface-regression.test.mjs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ test('advanced settings split auto-assignment rules into a dedicated Rules tab',
206206
assert.match(settingsPage, /<h2 data-fv-section="auto-assignment" data-fv-advanced="1" data-fv-advanced-group="rules">Auto-assignment rules<\/h2>/);
207207
assert.match(settingsPage, /<h2 data-fv-section="conflict-inspector" data-fv-advanced="1" data-fv-advanced-group="rules">Rule testing and troubleshooting<\/h2>/);
208208
assert.match(settingsPage, /<h2 data-fv-section="bulk-assignment" data-fv-advanced="1" data-fv-advanced-group="automation">Bulk assignment<\/h2>/);
209-
assert.match(settingsSectionsJs, /const ADVANCED_GROUPS = \['automation', 'rules', 'recovery', 'operations', 'diagnostics'\];/);
209+
assert.match(settingsSectionsJs, /const ADVANCED_GROUPS = \['automation', 'rules', 'recovery', 'operations', 'appearance', 'diagnostics'\];/);
210210
assert.match(settingsSectionsJs, /rules:\s*'Rules'/);
211211
assert.match(settingsSectionsJs, /'auto-assignment':\s*'rules'/);
212212
assert.match(settingsSectionsJs, /'conflict-inspector':\s*'rules'/);
@@ -219,6 +219,13 @@ test('advanced settings split auto-assignment rules into a dedicated Rules tab',
219219
assert.ok(bulkAssignmentIndex > conflictInspectorIndex, 'bulk assignment should remain after the Rules sections');
220220
});
221221

222+
test('theme workspace lives in its own Appearance advanced tab', () => {
223+
assert.match(settingsPage, /<h2 data-fv-section="theme-workspace" data-fv-advanced="1" data-fv-advanced-group="appearance">Theme workspace<\/h2>/);
224+
assert.match(settingsSectionsJs, /appearance:\s*'Appearance'/);
225+
assert.match(settingsSectionsJs, /'theme-workspace':\s*'appearance'/);
226+
assert.match(settingsSectionsJs, /appearance:\s*Object\.freeze\(\[\]\)/);
227+
});
228+
222229
test('rules tab uses a source-switched workspace and bulk assignment keeps the two-column desktop layout', () => {
223230
assert.match(settingsPage, /class="fv-rules-source-switch"[\s\S]*setRulesWorkspaceType\('docker'\)[\s\S]*setRulesWorkspaceType\('vm'\)/);
224231
assert.match(settingsPage, /class="rules-panel fv-rules-workspace" data-fv-rules-type="docker"[\s\S]*id="docker-rules-status"[\s\S]*id="docker-rules-selection-summary"[\s\S]*id="docker-rules"/);

0 commit comments

Comments
 (0)