[FIX] 修復帳號管理角色下拉選單消失問題並優化初始化防護 & [STYLE] 新增個人檔案選單圖標
All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 58s
All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 58s
This commit is contained in:
@@ -10,22 +10,12 @@ $roleSelectConfig = [
|
|||||||
"hasSearch" => true,
|
"hasSearch" => true,
|
||||||
"searchPlaceholder" => __('Search Role...'),
|
"searchPlaceholder" => __('Search Role...'),
|
||||||
"isHidePlaceholder" => false,
|
"isHidePlaceholder" => false,
|
||||||
"searchClasses" => "block w-[calc(100%-16px)] mx-2 py-2 px-3 text-sm border-slate-200 dark:border-white/10 rounded-lg
|
"searchClasses" => "block w-[calc(100%-16px)] mx-2 py-2 px-3 text-sm border-slate-200 dark:border-white/10 rounded-lg focus:border-cyan-500 focus:ring-cyan-500 bg-slate-50 dark:bg-slate-900/50 dark:text-slate-200 placeholder:text-slate-400 dark:placeholder:text-slate-500",
|
||||||
focus:border-cyan-500 focus:ring-cyan-500 bg-slate-50 dark:bg-slate-900/50 dark:text-slate-200
|
|
||||||
placeholder:text-slate-400 dark:placeholder:text-slate-500",
|
|
||||||
"searchWrapperClasses" => "sticky top-0 bg-white/95 dark:bg-slate-900/95 backdrop-blur-md p-2 z-10",
|
"searchWrapperClasses" => "sticky top-0 bg-white/95 dark:bg-slate-900/95 backdrop-blur-md p-2 z-10",
|
||||||
"toggleClasses" => "hs-select-toggle luxury-select-toggle",
|
"toggleClasses" => "hs-select-toggle luxury-select-toggle",
|
||||||
"dropdownClasses" => "hs-select-menu w-full bg-white/95 dark:bg-slate-900/95 backdrop-blur-xl border border-slate-200
|
"dropdownClasses" => "hs-select-menu w-full bg-white/95 dark:bg-slate-900/95 backdrop-blur-xl border border-slate-200 dark:border-white/10 rounded-xl shadow-[0_20px_50px_rgba(0,0,0,0.3)] mt-2 z-[100] animate-luxury-in",
|
||||||
dark:border-white/10 rounded-xl shadow-[0_20px_50px_rgba(0,0,0,0.3)] mt-2 z-[100] animate-luxury-in",
|
"optionClasses" => "hs-select-option py-2.5 px-3 mb-0.5 text-sm text-slate-800 dark:text-slate-300 cursor-pointer hover:bg-slate-100 dark:hover:bg-cyan-500/10 dark:hover:text-cyan-400 rounded-lg flex items-center justify-between transition-all duration-300",
|
||||||
"optionClasses" => "hs-select-option py-2.5 px-3 mb-0.5 text-sm text-slate-800 dark:text-slate-300 cursor-pointer
|
"optionTemplate" => '<div class="flex items-center justify-between w-full"><span data-title></span><span class="hs-select-active-indicator hidden text-cyan-500"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg></span></div>'
|
||||||
hover:bg-slate-100 dark:hover:bg-cyan-500/10 dark:hover:text-cyan-400 rounded-lg flex items-center justify-between
|
|
||||||
transition-all duration-300",
|
|
||||||
"optionTemplate" => '<div class="flex items-center justify-between w-full"><span data-title></span><span
|
|
||||||
class="hs-select-active-indicator hidden text-cyan-500"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"
|
|
||||||
stroke-linecap="round" stroke-linejoin="round">
|
|
||||||
<polyline points="20 6 9 17 4 12"></polyline>
|
|
||||||
</svg></span></div>'
|
|
||||||
];
|
];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@@ -728,12 +718,17 @@ transition-all duration-300",
|
|||||||
this.editing = false;
|
this.editing = false;
|
||||||
const initialCompanyId = initData.oldValues.company_id;
|
const initialCompanyId = initData.oldValues.company_id;
|
||||||
let initialRole = '';
|
let initialRole = '';
|
||||||
const roles = this.filteredRoles;
|
|
||||||
|
let roles = [];
|
||||||
|
if (!initialCompanyId || initialCompanyId.toString().trim() === '') {
|
||||||
|
roles = this.allRoles.filter(r => !r.company_id || r.company_id.toString().trim() === '');
|
||||||
|
} else {
|
||||||
|
let companyRoles = this.allRoles.filter(r => r.company_id == initialCompanyId);
|
||||||
|
roles = companyRoles.length > 0 ? companyRoles : this.allRoles.filter(r => !r.company_id || r.company_id.toString().trim() === '');
|
||||||
|
}
|
||||||
|
|
||||||
if (roles.length > 0) {
|
if (roles.length > 0) {
|
||||||
initialRole = roles[0].name;
|
initialRole = roles[0].name;
|
||||||
} else if (this.allRoles.length > 0) {
|
|
||||||
const systemRoles = this.allRoles.filter(r => !r.company_id || r.company_id.toString().trim() === '');
|
|
||||||
if (systemRoles.length > 0) initialRole = systemRoles[0].name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentUser = {
|
this.currentUser = {
|
||||||
@@ -785,7 +780,11 @@ transition-all duration-300",
|
|||||||
const wrapper = document.getElementById('role-select-wrapper');
|
const wrapper = document.getElementById('role-select-wrapper');
|
||||||
if (!wrapper) return;
|
if (!wrapper) return;
|
||||||
|
|
||||||
const configStr = JSON.stringify(this.roleSelectConfig);
|
// 🛡️ 終極防護:自動過濾配置中的換行符號,防止自動排版工具折行導致 Preline 崩潰
|
||||||
|
const cleanConfig = JSON.parse(JSON.stringify(this.roleSelectConfig), (key, value) => {
|
||||||
|
return typeof value === 'string' ? value.replace(/\r?\n|\r/g, ' ').trim() : value;
|
||||||
|
});
|
||||||
|
const configStr = JSON.stringify(cleanConfig);
|
||||||
const roles = this.filteredRoles;
|
const roles = this.filteredRoles;
|
||||||
|
|
||||||
if (roles.length > 0 && !roles.find(r => r.name === this.currentUser.role)) {
|
if (roles.length > 0 && !roles.find(r => r.name === this.currentUser.role)) {
|
||||||
@@ -794,18 +793,29 @@ transition-all duration-300",
|
|||||||
this.currentUser.role = '';
|
this.currentUser.role = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldSelect = document.getElementById('modal-account-role');
|
const oldSelects = wrapper.querySelectorAll('select');
|
||||||
if (oldSelect && window.HSSelect && window.HSSelect.getInstance(oldSelect)) {
|
oldSelects.forEach(oldSelect => {
|
||||||
window.HSSelect.getInstance(oldSelect).destroy();
|
if (window.HSSelect && window.HSSelect.getInstance(oldSelect)) {
|
||||||
|
try { window.HSSelect.getInstance(oldSelect).destroy(); } catch (e) { console.warn('HSSelect destroy warning:', e); }
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
wrapper.innerHTML = '';
|
wrapper.innerHTML = '';
|
||||||
const selectEl = document.createElement('select');
|
const selectEl = document.createElement('select');
|
||||||
selectEl.name = 'role';
|
selectEl.name = 'role';
|
||||||
selectEl.id = 'modal-account-role';
|
const uniqueSelectId = 'modal-account-role-' + Date.now() + '-' + Math.round(Math.random() * 1000);
|
||||||
|
selectEl.id = uniqueSelectId;
|
||||||
selectEl.className = 'hidden';
|
selectEl.className = 'hidden';
|
||||||
selectEl.setAttribute('data-hs-select', configStr);
|
selectEl.setAttribute('data-hs-select', configStr);
|
||||||
|
|
||||||
|
if (roles.length === 0) {
|
||||||
|
const opt = document.createElement('option');
|
||||||
|
opt.value = '';
|
||||||
|
opt.textContent = '{{ __("No roles available") }}';
|
||||||
|
opt.disabled = true;
|
||||||
|
opt.selected = true;
|
||||||
|
selectEl.appendChild(opt);
|
||||||
|
} else {
|
||||||
roles.forEach(r => {
|
roles.forEach(r => {
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
opt.value = r.name;
|
opt.value = r.name;
|
||||||
@@ -814,11 +824,9 @@ transition-all duration-300",
|
|||||||
if (r.name === this.currentUser.role) opt.selected = true;
|
if (r.name === this.currentUser.role) opt.selected = true;
|
||||||
selectEl.appendChild(opt);
|
selectEl.appendChild(opt);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
wrapper.appendChild(selectEl);
|
wrapper.appendChild(selectEl);
|
||||||
if (window.HSStaticMethods && window.HSStaticMethods.autoInit) {
|
|
||||||
window.HSStaticMethods.autoInit(['select']);
|
|
||||||
}
|
|
||||||
|
|
||||||
selectEl.addEventListener('change', (e) => {
|
selectEl.addEventListener('change', (e) => {
|
||||||
this.currentUser.role = e.target.value;
|
this.currentUser.role = e.target.value;
|
||||||
@@ -832,12 +840,28 @@ transition-all duration-300",
|
|||||||
|
|
||||||
const select = window.HSSelect ? window.HSSelect.getInstance(selectEl) : null;
|
const select = window.HSSelect ? window.HSSelect.getInstance(selectEl) : null;
|
||||||
if (select) {
|
if (select) {
|
||||||
select.setValue(this.currentUser.role);
|
select.setValue(this.currentUser.role || '');
|
||||||
} else if (attempts < 20) {
|
} else if (attempts < 20) {
|
||||||
setTimeout(() => waitForHSSelect(attempts + 1), 50);
|
setTimeout(() => waitForHSSelect(attempts + 1), 50);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const initPreline = (attempts = 0) => {
|
||||||
|
if (currentGen !== this._roleGeneration) return;
|
||||||
|
|
||||||
|
if (window.HSStaticMethods && window.HSStaticMethods.autoInit) {
|
||||||
|
try {
|
||||||
|
window.HSStaticMethods.autoInit(['select']);
|
||||||
waitForHSSelect();
|
waitForHSSelect();
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('HSStaticMethods autoInit warning:', e);
|
||||||
|
}
|
||||||
|
} else if (attempts < 50) {
|
||||||
|
setTimeout(() => initPreline(attempts + 1), 50);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
initPreline();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
init() {
|
init() {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
<ul class="luxury-submenu" data-sidebar-sub>
|
<ul class="luxury-submenu" data-sidebar-sub>
|
||||||
<li>
|
<li>
|
||||||
<a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('profile.edit') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('profile.edit') }}">
|
<a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('profile.edit') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('profile.edit') }}">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 shrink-0 transition-colors" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>
|
||||||
{{ __('Profile') }}
|
{{ __('Profile') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
Reference in New Issue
Block a user