Keep profile editor page access complete
- reuse the create-form page controls when rendering edit forms - preserve existing home_page and allowed_pages IDs that the old whitelist hid - keep mandatory pages checked so saves do not drop them
This commit is contained in:
parent
f5d70768c1
commit
3be028f97b
1 changed files with 102 additions and 29 deletions
|
|
@ -1482,6 +1482,93 @@ function _invalidateListenBrainzCache() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PROFILE_PAGE_LABELS = {
|
||||||
|
dashboard: 'Dashboard',
|
||||||
|
sync: 'Sync',
|
||||||
|
search: 'Search',
|
||||||
|
discover: 'Discover',
|
||||||
|
watchlist: 'Watchlist',
|
||||||
|
wishlist: 'Wishlist',
|
||||||
|
automations: 'Automations',
|
||||||
|
'active-downloads': 'Downloads',
|
||||||
|
library: 'Library',
|
||||||
|
stats: 'Listening Stats',
|
||||||
|
'playlist-explorer': 'Playlist Explorer',
|
||||||
|
import: 'Import',
|
||||||
|
tools: 'Tools',
|
||||||
|
hydrabase: 'Hydrabase',
|
||||||
|
issues: 'Issues',
|
||||||
|
help: 'Help & Docs',
|
||||||
|
settings: 'Settings',
|
||||||
|
'artist-detail': 'Artist Detail',
|
||||||
|
};
|
||||||
|
|
||||||
|
function getProfilePageLabel(pageId) {
|
||||||
|
return PROFILE_PAGE_LABELS[pageId] || pageId.split('-').map(part => part ? part[0].toUpperCase() + part.slice(1) : part).join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProfilePageSelectOptions(profileSettings = {}) {
|
||||||
|
const options = [];
|
||||||
|
const seen = new Set();
|
||||||
|
const homeSelect = document.getElementById('new-profile-home-page');
|
||||||
|
|
||||||
|
if (homeSelect) {
|
||||||
|
homeSelect.querySelectorAll('option').forEach(option => {
|
||||||
|
if (!option.value || seen.has(option.value)) return;
|
||||||
|
options.push({
|
||||||
|
value: option.value,
|
||||||
|
label: option.textContent?.trim() || getProfilePageLabel(option.value),
|
||||||
|
});
|
||||||
|
seen.add(option.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profileSettings.home_page && !seen.has(profileSettings.home_page)) {
|
||||||
|
options.push({
|
||||||
|
value: profileSettings.home_page,
|
||||||
|
label: getProfilePageLabel(profileSettings.home_page),
|
||||||
|
});
|
||||||
|
seen.add(profileSettings.home_page);
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProfilePageAccessOptions(profileSettings = {}) {
|
||||||
|
const options = [];
|
||||||
|
const seen = new Set();
|
||||||
|
const allowedSet = Array.isArray(profileSettings.allowed_pages) ? new Set(profileSettings.allowed_pages) : null;
|
||||||
|
const accessContainer = document.getElementById('new-profile-allowed-pages');
|
||||||
|
|
||||||
|
if (accessContainer) {
|
||||||
|
accessContainer.querySelectorAll('input[type="checkbox"]').forEach(cb => {
|
||||||
|
if (seen.has(cb.value)) return;
|
||||||
|
options.push({
|
||||||
|
value: cb.value,
|
||||||
|
label: cb.parentElement?.textContent?.trim() || getProfilePageLabel(cb.value),
|
||||||
|
checked: cb.disabled ? true : (allowedSet ? allowedSet.has(cb.value) : true),
|
||||||
|
disabled: cb.disabled,
|
||||||
|
});
|
||||||
|
seen.add(cb.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowedSet) {
|
||||||
|
allowedSet.forEach(pageId => {
|
||||||
|
if (seen.has(pageId)) return;
|
||||||
|
options.push({
|
||||||
|
value: pageId,
|
||||||
|
label: getProfilePageLabel(pageId),
|
||||||
|
checked: true,
|
||||||
|
disabled: false,
|
||||||
|
});
|
||||||
|
seen.add(pageId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
function initProfileManagement() {
|
function initProfileManagement() {
|
||||||
const manageBtn = document.getElementById('manage-profiles-btn');
|
const manageBtn = document.getElementById('manage-profiles-btn');
|
||||||
const closeBtn = document.getElementById('profile-manage-close');
|
const closeBtn = document.getElementById('profile-manage-close');
|
||||||
|
|
@ -1698,11 +1785,8 @@ function showProfileEditForm(profileId, currentName, currentColor, currentAvatar
|
||||||
const isAdmin = currentProfile && currentProfile.is_admin;
|
const isAdmin = currentProfile && currentProfile.is_admin;
|
||||||
const isEditingAdmin = profileSettings.is_admin;
|
const isEditingAdmin = profileSettings.is_admin;
|
||||||
const editColors = ['#6366f1', '#ec4899', '#10b981', '#f59e0b', '#3b82f6', '#ef4444', '#8b5cf6', '#14b8a6'];
|
const editColors = ['#6366f1', '#ec4899', '#10b981', '#f59e0b', '#3b82f6', '#ef4444', '#8b5cf6', '#14b8a6'];
|
||||||
const pageLabels = {
|
const pageSelectOptions = getProfilePageSelectOptions(profileSettings);
|
||||||
dashboard: 'Dashboard', sync: 'Sync', search: 'Search', discover: 'Discover',
|
const pageAccessOptions = getProfilePageAccessOptions(profileSettings);
|
||||||
automations: 'Automations', library: 'Library', stats: 'Listening Stats',
|
|
||||||
'playlist-explorer': 'Playlist Explorer', import: 'Import', help: 'Help & Docs'
|
|
||||||
};
|
|
||||||
|
|
||||||
const form = document.createElement('div');
|
const form = document.createElement('div');
|
||||||
form.id = 'profile-edit-form';
|
form.id = 'profile-edit-form';
|
||||||
|
|
@ -1752,14 +1836,12 @@ function showProfileEditForm(profileId, currentName, currentColor, currentAvatar
|
||||||
defaultOpt.value = '';
|
defaultOpt.value = '';
|
||||||
defaultOpt.textContent = isEditingAdmin ? 'Default (Dashboard)' : 'Default (Discover)';
|
defaultOpt.textContent = isEditingAdmin ? 'Default (Dashboard)' : 'Default (Discover)';
|
||||||
homeSelect.appendChild(defaultOpt);
|
homeSelect.appendChild(defaultOpt);
|
||||||
const allowedSet = profileSettings.allowed_pages;
|
|
||||||
const normalizedHome = profileSettings.home_page;
|
const normalizedHome = profileSettings.home_page;
|
||||||
Object.entries(pageLabels).forEach(([id, label]) => {
|
pageSelectOptions.forEach(({ value, label }) => {
|
||||||
if (allowedSet && !allowedSet.includes(id)) return; // Skip non-permitted
|
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
opt.value = id;
|
opt.value = value;
|
||||||
opt.textContent = label;
|
opt.textContent = label;
|
||||||
if (id === normalizedHome) opt.selected = true;
|
if (value === normalizedHome) opt.selected = true;
|
||||||
homeSelect.appendChild(opt);
|
homeSelect.appendChild(opt);
|
||||||
});
|
});
|
||||||
form.appendChild(homeSelect);
|
form.appendChild(homeSelect);
|
||||||
|
|
@ -1775,26 +1857,18 @@ function showProfileEditForm(profileId, currentName, currentColor, currentAvatar
|
||||||
|
|
||||||
const apContainer = document.createElement('div');
|
const apContainer = document.createElement('div');
|
||||||
apContainer.className = 'profile-page-checkboxes';
|
apContainer.className = 'profile-page-checkboxes';
|
||||||
Object.entries(pageLabels).forEach(([id, label]) => {
|
pageAccessOptions.forEach(({ value, label, checked, disabled }) => {
|
||||||
const lbl = document.createElement('label');
|
const lbl = document.createElement('label');
|
||||||
const cb = document.createElement('input');
|
const cb = document.createElement('input');
|
||||||
cb.type = 'checkbox';
|
cb.type = 'checkbox';
|
||||||
cb.value = id;
|
cb.value = value;
|
||||||
cb.checked = !allowedSet || allowedSet.includes(id);
|
cb.checked = checked;
|
||||||
|
cb.disabled = disabled;
|
||||||
lbl.appendChild(cb);
|
lbl.appendChild(cb);
|
||||||
lbl.appendChild(document.createTextNode(' ' + label));
|
lbl.appendChild(document.createTextNode(' ' + label));
|
||||||
apContainer.appendChild(lbl);
|
apContainer.appendChild(lbl);
|
||||||
pageCheckboxes.push(cb);
|
pageCheckboxes.push(cb);
|
||||||
});
|
});
|
||||||
// Always-on help
|
|
||||||
const helpLbl = document.createElement('label');
|
|
||||||
const helpCb = document.createElement('input');
|
|
||||||
helpCb.type = 'checkbox';
|
|
||||||
helpCb.checked = true;
|
|
||||||
helpCb.disabled = true;
|
|
||||||
helpLbl.appendChild(helpCb);
|
|
||||||
helpLbl.appendChild(document.createTextNode(' Help & Docs'));
|
|
||||||
apContainer.appendChild(helpLbl);
|
|
||||||
form.appendChild(apContainer);
|
form.appendChild(apContainer);
|
||||||
|
|
||||||
const dlLabel = document.createElement('label');
|
const dlLabel = document.createElement('label');
|
||||||
|
|
@ -1824,8 +1898,9 @@ function showProfileEditForm(profileId, currentName, currentColor, currentAvatar
|
||||||
|
|
||||||
// Admin-only fields
|
// Admin-only fields
|
||||||
if (isAdmin && !isEditingAdmin && pageCheckboxes.length) {
|
if (isAdmin && !isEditingAdmin && pageCheckboxes.length) {
|
||||||
const allChecked = pageCheckboxes.every(cb => cb.checked);
|
const editablePageCheckboxes = pageCheckboxes.filter(cb => !cb.disabled);
|
||||||
payload.allowed_pages = allChecked ? null : pageCheckboxes.filter(cb => cb.checked).map(cb => cb.value);
|
const allChecked = editablePageCheckboxes.every(cb => cb.checked);
|
||||||
|
payload.allowed_pages = allChecked ? null : editablePageCheckboxes.filter(cb => cb.checked).map(cb => cb.value);
|
||||||
payload.can_download = canDlCheckbox ? canDlCheckbox.checked : true;
|
payload.can_download = canDlCheckbox ? canDlCheckbox.checked : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1921,14 +1996,12 @@ function showSelfEditForm() {
|
||||||
defaultOpt.value = '';
|
defaultOpt.value = '';
|
||||||
defaultOpt.textContent = 'Default (Discover)';
|
defaultOpt.textContent = 'Default (Discover)';
|
||||||
homeSelect.appendChild(defaultOpt);
|
homeSelect.appendChild(defaultOpt);
|
||||||
const ap = currentProfile.allowed_pages;
|
|
||||||
const normalizedHome = currentProfile.home_page;
|
const normalizedHome = currentProfile.home_page;
|
||||||
Object.entries(pageLabels).forEach(([id, label]) => {
|
getProfilePageSelectOptions({ home_page: normalizedHome }).forEach(({ value, label }) => {
|
||||||
if (ap && !ap.includes(id)) return;
|
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
opt.value = id;
|
opt.value = value;
|
||||||
opt.textContent = label;
|
opt.textContent = label;
|
||||||
if (id === normalizedHome) opt.selected = true;
|
if (value === normalizedHome) opt.selected = true;
|
||||||
homeSelect.appendChild(opt);
|
homeSelect.appendChild(opt);
|
||||||
});
|
});
|
||||||
form.appendChild(homeSelect);
|
form.appendChild(homeSelect);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue