[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,
|
||||
"searchPlaceholder" => __('Search Role...'),
|
||||
"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
|
||||
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",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"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>'
|
||||
"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",
|
||||
"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",
|
||||
"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
|
||||
|
||||
@@ -728,12 +718,17 @@ transition-all duration-300",
|
||||
this.editing = false;
|
||||
const initialCompanyId = initData.oldValues.company_id;
|
||||
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) {
|
||||
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 = {
|
||||
@@ -785,7 +780,11 @@ transition-all duration-300",
|
||||
const wrapper = document.getElementById('role-select-wrapper');
|
||||
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;
|
||||
|
||||
if (roles.length > 0 && !roles.find(r => r.name === this.currentUser.role)) {
|
||||
@@ -794,31 +793,40 @@ transition-all duration-300",
|
||||
this.currentUser.role = '';
|
||||
}
|
||||
|
||||
const oldSelect = document.getElementById('modal-account-role');
|
||||
if (oldSelect && window.HSSelect && window.HSSelect.getInstance(oldSelect)) {
|
||||
window.HSSelect.getInstance(oldSelect).destroy();
|
||||
}
|
||||
const oldSelects = wrapper.querySelectorAll('select');
|
||||
oldSelects.forEach(oldSelect => {
|
||||
if (window.HSSelect && window.HSSelect.getInstance(oldSelect)) {
|
||||
try { window.HSSelect.getInstance(oldSelect).destroy(); } catch (e) { console.warn('HSSelect destroy warning:', e); }
|
||||
}
|
||||
});
|
||||
|
||||
wrapper.innerHTML = '';
|
||||
const selectEl = document.createElement('select');
|
||||
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.setAttribute('data-hs-select', configStr);
|
||||
|
||||
roles.forEach(r => {
|
||||
if (roles.length === 0) {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = r.name;
|
||||
opt.textContent = r.name;
|
||||
opt.setAttribute('data-title', r.name);
|
||||
if (r.name === this.currentUser.role) opt.selected = true;
|
||||
opt.value = '';
|
||||
opt.textContent = '{{ __("No roles available") }}';
|
||||
opt.disabled = true;
|
||||
opt.selected = true;
|
||||
selectEl.appendChild(opt);
|
||||
});
|
||||
} else {
|
||||
roles.forEach(r => {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = r.name;
|
||||
opt.textContent = r.name;
|
||||
opt.setAttribute('data-title', r.name);
|
||||
if (r.name === this.currentUser.role) opt.selected = true;
|
||||
selectEl.appendChild(opt);
|
||||
});
|
||||
}
|
||||
|
||||
wrapper.appendChild(selectEl);
|
||||
if (window.HSStaticMethods && window.HSStaticMethods.autoInit) {
|
||||
window.HSStaticMethods.autoInit(['select']);
|
||||
}
|
||||
|
||||
selectEl.addEventListener('change', (e) => {
|
||||
this.currentUser.role = e.target.value;
|
||||
@@ -832,12 +840,28 @@ transition-all duration-300",
|
||||
|
||||
const select = window.HSSelect ? window.HSSelect.getInstance(selectEl) : null;
|
||||
if (select) {
|
||||
select.setValue(this.currentUser.role);
|
||||
select.setValue(this.currentUser.role || '');
|
||||
} else if (attempts < 20) {
|
||||
setTimeout(() => waitForHSSelect(attempts + 1), 50);
|
||||
}
|
||||
};
|
||||
waitForHSSelect();
|
||||
|
||||
const initPreline = (attempts = 0) => {
|
||||
if (currentGen !== this._roleGeneration) return;
|
||||
|
||||
if (window.HSStaticMethods && window.HSStaticMethods.autoInit) {
|
||||
try {
|
||||
window.HSStaticMethods.autoInit(['select']);
|
||||
waitForHSSelect();
|
||||
} catch (e) {
|
||||
console.warn('HSStaticMethods autoInit warning:', e);
|
||||
}
|
||||
} else if (attempts < 50) {
|
||||
setTimeout(() => initPreline(attempts + 1), 50);
|
||||
}
|
||||
};
|
||||
|
||||
initPreline();
|
||||
});
|
||||
},
|
||||
init() {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<ul class="luxury-submenu" data-sidebar-sub>
|
||||
<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') }}">
|
||||
<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') }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user