fix(icons): render FA glyphs in the SPA picker grid and harden item clicks
The server catalog ships bare glyph names, but the SPA grid preview composed "fas home" instead of "fas fa-home" — every FA icon rendered blank (the old curated lists carried the fa- prefix, so the regression appeared with the catalog switch). Item clicks move from per-element @click to a delegated panel handler reading data-icon (immunity to DOM-replacing extensions/userscripts, matching the PHP picker's pattern), and selecting now closes the popover so the choice is visible in the field immediately.
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
import t from"./SchemaPage._RXlmOMl.js";import{a2 as o,W as m}from"./vendor-vue.BxZIRU0_.js";import"./shared-api.DsnKC5vk.js";import"./FaIcon.NZ6TDkNu.js";import"./index.js";import"./vendor-naive.CKYCZmXD.js";import"./vendor-misc.bELTaXdf.js";import"./FaIconPicker.DuahAn6_.js";import"./shared-api.DnsQ5cxS.js";import"./level.E3ANSDAX.js";import"./badge.CKTsmH1z.js";const h={__name:"CommentSettings",setup(r){return(p,e)=>(m(),o(t,{domain:"post_list",section:"comment"}))}};export{h as default};
|
||||
import t from"./SchemaPage.DUnjy3YN.js";import{a2 as o,W as m}from"./vendor-vue.BxZIRU0_.js";import"./shared-api.DieGsdVx.js";import"./FaIcon.NZ6TDkNu.js";import"./index.js";import"./vendor-naive.CKYCZmXD.js";import"./vendor-misc.bELTaXdf.js";import"./FaIconPicker.C_p6xA0k.js";import"./shared-api.DnsQ5cxS.js";import"./level.E3ANSDAX.js";import"./badge.CKTsmH1z.js";const h={__name:"CommentSettings",setup(r){return(p,e)=>(m(),o(t,{domain:"post_list",section:"comment"}))}};export{h as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
.aksrt-icon-value__svg[data-v-127de8f8]{display:inline-flex}.aksrt-icon-value__svg[data-v-127de8f8] svg,.aksrt-icon-value__svg svg[data-v-127de8f8]{width:1em;height:1em;fill:currentColor}.aksrt-icon-picker__panel[data-v-b3172250]{padding:12px}.aksrt-icon-picker__search[data-v-b3172250],.aksrt-icon-picker__tabs[data-v-b3172250]{margin-bottom:10px}.aksrt-icon-picker__tabs[data-v-b3172250] .n-radio-group{flex-wrap:wrap}.aksrt-icon-picker__grid[data-v-b3172250]{display:grid;grid-template-columns:repeat(8,1fr);gap:4px;max-height:260px;overflow-y:auto}.aksrt-icon-picker__item[data-v-b3172250]{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:6px;cursor:pointer;font-size:16px;color:var(--aksrt-color-text-secondary);transition:all .15s}.aksrt-icon-picker__item[data-v-b3172250]:hover{background:var(--aksrt-color-primary-soft);color:var(--aksrt-color-primary)}.aksrt-icon-picker__item.is-active[data-v-b3172250]{background:var(--aksrt-color-primary);color:#fff}.aksrt-icon-picker__item[data-v-b3172250] svg,.aksrt-icon-picker__preview-svg[data-v-b3172250] svg,.aksrt-icon-picker__preview-svg svg[data-v-b3172250]{width:18px;height:18px;fill:currentColor}.aksrt-icon-picker__preview-svg[data-v-b3172250]{display:inline-flex}.aksrt-icon-picker__empty[data-v-b3172250]{grid-column:1 / -1;text-align:center;padding:20px;color:var(--aksrt-color-muted);font-size:13px}.aksrt-icon-picker__custom-actions[data-v-b3172250]{display:flex;align-items:center;gap:10px;margin-top:8px}.aksrt-icon-picker__custom-preview[data-v-b3172250]{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px dashed var(--aksrt-color-muted);border-radius:4px}.aksrt-icon-picker__grid--session[data-v-b3172250]{margin-top:10px;padding-top:8px;border-top:1px solid var(--aksrt-color-muted)}
|
||||
.aksrt-icon-value__svg[data-v-127de8f8]{display:inline-flex}.aksrt-icon-value__svg[data-v-127de8f8] svg,.aksrt-icon-value__svg svg[data-v-127de8f8]{width:1em;height:1em;fill:currentColor}.aksrt-icon-picker__panel[data-v-ff0f92a9]{padding:12px}.aksrt-icon-picker__search[data-v-ff0f92a9],.aksrt-icon-picker__tabs[data-v-ff0f92a9]{margin-bottom:10px}.aksrt-icon-picker__tabs[data-v-ff0f92a9] .n-radio-group{flex-wrap:wrap}.aksrt-icon-picker__grid[data-v-ff0f92a9]{display:grid;grid-template-columns:repeat(8,1fr);gap:4px;max-height:260px;overflow-y:auto}.aksrt-icon-picker__item[data-v-ff0f92a9]{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:6px;cursor:pointer;font-size:16px;color:var(--aksrt-color-text-secondary);transition:all .15s}.aksrt-icon-picker__item[data-v-ff0f92a9]:hover{background:var(--aksrt-color-primary-soft);color:var(--aksrt-color-primary)}.aksrt-icon-picker__item.is-active[data-v-ff0f92a9]{background:var(--aksrt-color-primary);color:#fff}.aksrt-icon-picker__item[data-v-ff0f92a9] svg,.aksrt-icon-picker__preview-svg[data-v-ff0f92a9] svg,.aksrt-icon-picker__preview-svg svg[data-v-ff0f92a9]{width:18px;height:18px;fill:currentColor}.aksrt-icon-picker__preview-svg[data-v-ff0f92a9]{display:inline-flex}.aksrt-icon-picker__empty[data-v-ff0f92a9]{grid-column:1 / -1;text-align:center;padding:20px;color:var(--aksrt-color-muted);font-size:13px}.aksrt-icon-picker__custom-actions[data-v-ff0f92a9]{display:flex;align-items:center;gap:10px;margin-top:8px}.aksrt-icon-picker__custom-preview[data-v-ff0f92a9]{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px dashed var(--aksrt-color-muted);border-radius:4px}.aksrt-icon-picker__grid--session[data-v-ff0f92a9]{margin-top:10px;padding-top:8px;border-top:1px solid var(--aksrt-color-muted)}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as H,a1 as s,W as r,X as q,a4 as p,a3 as t,a2 as m,F as A,R as D,f as B,Z as y,a5 as C,l as I,N as P,c as V,o as O,r as N,Y as f,L as $}from"./vendor-vue.BxZIRU0_.js";import{a as E}from"./shared-api.DnsQ5cxS.js";import{P as R}from"./PageHeader.CtT29f8Y.js";import{u as T,A as U,g as W}from"./shared-api.DsnKC5vk.js";import{u as L}from"./vendor-naive.CKYCZmXD.js";import{_ as X}from"./index.js";import"./FaIcon.NZ6TDkNu.js";import"./FaIconPicker.DuahAn6_.js";import"./vendor-misc.bELTaXdf.js";import"./level.E3ANSDAX.js";import"./badge.CKTsmH1z.js";const Y={class:"aksrt-page-container"},Z={__name:"PaymentSectionPage",props:{section:{type:String,required:!0},title:{type:String,required:!0},desc:{type:String,default:""},note:{type:String,default:""},links:{type:Array,default:()=>[]}},setup(c){const g=c,h=H(),l=L(),u=V(()=>W("payment",g.section)||{groups:[]}),F=V(()=>{const n={};return(u.value.groups||[]).forEach(x=>{(x.fields||[]).forEach(S=>{S.default!==void 0&&(n[S.key]=S.default)})}),n}),{formData:e,loading:v,saving:_,loadError:i,dirty:a,save:k,reload:d}=T({fetch:()=>E.getSchemaPage("payment",g.section),submit:n=>E.saveSchemaPage("payment",g.section,n),defaults:F.value,onSaved:()=>{l.success("设置已保存")}});function w(n){h.push(n)}async function o(){try{await k()}catch(n){l.error(n.message||"保存失败")}}function M(){d(),l.info("已放弃更改")}return(n,x)=>{const S=s("n-button"),z=s("n-space"),G=s("n-alert"),j=s("n-card");return r(),q("div",Y,[p(R,{title:c.title,desc:c.desc},{actions:t(()=>[c.links.length?(r(),m(z,{key:0},{default:t(()=>[(r(!0),q(A,null,D(c.links,b=>(r(),m(S,{key:b.path,quaternary:"",onClick:ee=>w(b.path)},{default:t(()=>[B(y(b.label),1)]),_:2},1032,["onClick"]))),128))]),_:1})):C("",!0)]),_:1},8,["title","desc"]),c.note?(r(),m(j,{key:0,class:"aksrt-section-card"},{default:t(()=>[p(G,{type:"info","show-icon":!1},{default:t(()=>[B(y(c.note),1)]),_:1})]),_:1})):C("",!0),I(n.$slots,"before-form"),p(U,{schema:u.value.groups,"form-data":P(e),dirty:P(a),loading:P(v),saving:P(_),"load-error":P(i),"show-search":!1,"onUpdate:formData":x[0]||(x[0]=b=>e.value=b),onSave:o,onReload:M},null,8,["schema","form-data","dirty","loading","saving","load-error"])])}}},J={class:"aksrt-gateway__card"},K={class:"aksrt-gateway__help"},Q={__name:"PaymentGateway",setup(c){const g=L(),h=N([]),l=N({}),u=N(!1);function F(e){return e==="balance"||e==="alipay"||e==="epay_alipay"?"fa fas fa-credit-card":e==="wechatpay"||e==="epay_wxpay"?"fa fab fa-weixin":e==="paypal"?"fa fab fa-paypal":e==="stripe"?"fa fab fa-cc-stripe":"fa fas fa-credit-card"}return O(async()=>{var e,v,_;u.value=!0;try{const[i,a]=await Promise.all([E.request("/payment/overview").catch(()=>null)]);if((v=(e=i==null?void 0:i.data)==null?void 0:e.gateway)!=null&&v.gateways){const k=Object.entries(i.data.gateway.gateways).map(([d,w])=>({id:d,name:d,configured:!!w}));h.value=k}(_=a==null?void 0:a.data)!=null&&_.gateway?l.value=a.data.gateway:a!=null&&a.data&&(l.value=a.data)}catch{g.warning("部分支付接口暂不可用")}finally{u.value=!1}}),(e,v)=>{const _=s("n-tag"),i=s("n-grid-item"),a=s("n-grid"),k=s("n-empty"),d=s("n-card"),w=s("n-spin");return r(),m(Z,{section:"gateway",title:"收款接口",desc:"管理余额、支付宝、微信、PayPal、Stripe、易支付与卡密兑换通道。",note:"以渠道开关与凭据是否齐全为准;异步回调由各网关验签。卡密为兑换入口,不进入收银台。",links:[{label:"余额充值",path:"/payment/recharge"},{label:"充值卡",path:"/payment/card-pass"}]},{"before-form":t(()=>[p(w,{show:u.value},{default:t(()=>[p(d,{class:"aksrt-section-card",title:"网关状态"},{default:t(()=>[p(a,{cols:3,"x-gap":12,"y-gap":12},{default:t(()=>[(r(!0),q(A,null,D(h.value,o=>(r(),m(i,{key:o.id},{default:t(()=>[f("div",J,[f("div",{class:$(["aksrt-gateway__icon",o.configured?"aksrt-gateway__icon--active":""])},[f("i",{class:$(F(o.id))},null,2)],2),f("div",null,[f("strong",null,y(o.name),1),f("p",null,y(o.configured?"已配置":"未配置"),1)]),p(_,{type:o.configured?"success":"default",size:"small",round:""},{default:t(()=>[B(y(o.configured?"可用":"不可用"),1)]),_:2},1032,["type"])])]),_:2},1024))),128))]),_:1}),!u.value&&h.value.length===0?(r(),m(k,{key:0,description:"暂无已注册的支付网关"})):C("",!0)]),_:1}),l.value.help_text?(r(),m(d,{key:0,class:"aksrt-section-card",title:"运行说明"},{default:t(()=>[f("p",K,y(l.value.help_text),1)]),_:1})):C("",!0)]),_:1},8,["show"])]),_:1})}}},fe=X(Q,[["__scopeId","data-v-37b55ac6"]]);export{fe as default};
|
||||
import{_ as H,a1 as s,W as r,X as q,a4 as p,a3 as t,a2 as m,F as A,R as D,f as B,Z as y,a5 as C,l as I,N as P,c as V,o as O,r as N,Y as f,L as $}from"./vendor-vue.BxZIRU0_.js";import{a as E}from"./shared-api.DnsQ5cxS.js";import{P as R}from"./PageHeader.CtT29f8Y.js";import{u as T,A as U,g as W}from"./shared-api.DieGsdVx.js";import{u as L}from"./vendor-naive.CKYCZmXD.js";import{_ as X}from"./index.js";import"./FaIcon.NZ6TDkNu.js";import"./FaIconPicker.C_p6xA0k.js";import"./vendor-misc.bELTaXdf.js";import"./level.E3ANSDAX.js";import"./badge.CKTsmH1z.js";const Y={class:"aksrt-page-container"},Z={__name:"PaymentSectionPage",props:{section:{type:String,required:!0},title:{type:String,required:!0},desc:{type:String,default:""},note:{type:String,default:""},links:{type:Array,default:()=>[]}},setup(c){const g=c,h=H(),l=L(),u=V(()=>W("payment",g.section)||{groups:[]}),F=V(()=>{const n={};return(u.value.groups||[]).forEach(x=>{(x.fields||[]).forEach(S=>{S.default!==void 0&&(n[S.key]=S.default)})}),n}),{formData:e,loading:v,saving:_,loadError:i,dirty:a,save:k,reload:d}=T({fetch:()=>E.getSchemaPage("payment",g.section),submit:n=>E.saveSchemaPage("payment",g.section,n),defaults:F.value,onSaved:()=>{l.success("设置已保存")}});function w(n){h.push(n)}async function o(){try{await k()}catch(n){l.error(n.message||"保存失败")}}function M(){d(),l.info("已放弃更改")}return(n,x)=>{const S=s("n-button"),z=s("n-space"),G=s("n-alert"),j=s("n-card");return r(),q("div",Y,[p(R,{title:c.title,desc:c.desc},{actions:t(()=>[c.links.length?(r(),m(z,{key:0},{default:t(()=>[(r(!0),q(A,null,D(c.links,b=>(r(),m(S,{key:b.path,quaternary:"",onClick:ee=>w(b.path)},{default:t(()=>[B(y(b.label),1)]),_:2},1032,["onClick"]))),128))]),_:1})):C("",!0)]),_:1},8,["title","desc"]),c.note?(r(),m(j,{key:0,class:"aksrt-section-card"},{default:t(()=>[p(G,{type:"info","show-icon":!1},{default:t(()=>[B(y(c.note),1)]),_:1})]),_:1})):C("",!0),I(n.$slots,"before-form"),p(U,{schema:u.value.groups,"form-data":P(e),dirty:P(a),loading:P(v),saving:P(_),"load-error":P(i),"show-search":!1,"onUpdate:formData":x[0]||(x[0]=b=>e.value=b),onSave:o,onReload:M},null,8,["schema","form-data","dirty","loading","saving","load-error"])])}}},J={class:"aksrt-gateway__card"},K={class:"aksrt-gateway__help"},Q={__name:"PaymentGateway",setup(c){const g=L(),h=N([]),l=N({}),u=N(!1);function F(e){return e==="balance"||e==="alipay"||e==="epay_alipay"?"fa fas fa-credit-card":e==="wechatpay"||e==="epay_wxpay"?"fa fab fa-weixin":e==="paypal"?"fa fab fa-paypal":e==="stripe"?"fa fab fa-cc-stripe":"fa fas fa-credit-card"}return O(async()=>{var e,v,_;u.value=!0;try{const[i,a]=await Promise.all([E.request("/payment/overview").catch(()=>null)]);if((v=(e=i==null?void 0:i.data)==null?void 0:e.gateway)!=null&&v.gateways){const k=Object.entries(i.data.gateway.gateways).map(([d,w])=>({id:d,name:d,configured:!!w}));h.value=k}(_=a==null?void 0:a.data)!=null&&_.gateway?l.value=a.data.gateway:a!=null&&a.data&&(l.value=a.data)}catch{g.warning("部分支付接口暂不可用")}finally{u.value=!1}}),(e,v)=>{const _=s("n-tag"),i=s("n-grid-item"),a=s("n-grid"),k=s("n-empty"),d=s("n-card"),w=s("n-spin");return r(),m(Z,{section:"gateway",title:"收款接口",desc:"管理余额、支付宝、微信、PayPal、Stripe、易支付与卡密兑换通道。",note:"以渠道开关与凭据是否齐全为准;异步回调由各网关验签。卡密为兑换入口,不进入收银台。",links:[{label:"余额充值",path:"/payment/recharge"},{label:"充值卡",path:"/payment/card-pass"}]},{"before-form":t(()=>[p(w,{show:u.value},{default:t(()=>[p(d,{class:"aksrt-section-card",title:"网关状态"},{default:t(()=>[p(a,{cols:3,"x-gap":12,"y-gap":12},{default:t(()=>[(r(!0),q(A,null,D(h.value,o=>(r(),m(i,{key:o.id},{default:t(()=>[f("div",J,[f("div",{class:$(["aksrt-gateway__icon",o.configured?"aksrt-gateway__icon--active":""])},[f("i",{class:$(F(o.id))},null,2)],2),f("div",null,[f("strong",null,y(o.name),1),f("p",null,y(o.configured?"已配置":"未配置"),1)]),p(_,{type:o.configured?"success":"default",size:"small",round:""},{default:t(()=>[B(y(o.configured?"可用":"不可用"),1)]),_:2},1032,["type"])])]),_:2},1024))),128))]),_:1}),!u.value&&h.value.length===0?(r(),m(k,{key:0,description:"暂无已注册的支付网关"})):C("",!0)]),_:1}),l.value.help_text?(r(),m(d,{key:0,class:"aksrt-section-card",title:"运行说明"},{default:t(()=>[f("p",K,y(l.value.help_text),1)]),_:1})):C("",!0)]),_:1},8,["show"])]),_:1})}}},fe=X(Q,[["__scopeId","data-v-37b55ac6"]]);export{fe as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import t from"./SchemaPage._RXlmOMl.js";import{a2 as o,W as r}from"./vendor-vue.BxZIRU0_.js";import"./shared-api.DsnKC5vk.js";import"./FaIcon.NZ6TDkNu.js";import"./index.js";import"./vendor-naive.CKYCZmXD.js";import"./vendor-misc.bELTaXdf.js";import"./FaIconPicker.DuahAn6_.js";import"./shared-api.DnsQ5cxS.js";import"./level.E3ANSDAX.js";import"./badge.CKTsmH1z.js";const d={__name:"PostPageSettings",setup(p){return(m,e)=>(r(),o(t,{domain:"post_list",section:"page"}))}};export{d as default};
|
||||
import t from"./SchemaPage.DUnjy3YN.js";import{a2 as o,W as r}from"./vendor-vue.BxZIRU0_.js";import"./shared-api.DieGsdVx.js";import"./FaIcon.NZ6TDkNu.js";import"./index.js";import"./vendor-naive.CKYCZmXD.js";import"./vendor-misc.bELTaXdf.js";import"./FaIconPicker.C_p6xA0k.js";import"./shared-api.DnsQ5cxS.js";import"./level.E3ANSDAX.js";import"./badge.CKTsmH1z.js";const d={__name:"PostPageSettings",setup(p){return(m,e)=>(r(),o(t,{domain:"post_list",section:"page"}))}};export{d as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="aksrt-fa-icon-picker">
|
||||
<n-popover trigger="click" placement="bottom-start" :width="460" :style="{ padding: 0 }">
|
||||
<n-popover v-model:show="popoverShow" trigger="click" placement="bottom-start" :width="460" :style="{ padding: 0 }">
|
||||
<template #trigger>
|
||||
<n-input
|
||||
:value="modelValue"
|
||||
@@ -19,7 +19,7 @@
|
||||
</n-input>
|
||||
</template>
|
||||
|
||||
<div class="aksrt-icon-picker__panel">
|
||||
<div class="aksrt-icon-picker__panel" @click="onPanelClick">
|
||||
<div class="aksrt-icon-picker__search">
|
||||
<n-input v-model:value="search" placeholder="搜索图标..." size="small" clearable>
|
||||
<template #prefix>
|
||||
@@ -45,30 +45,34 @@
|
||||
确认插入
|
||||
</n-button>
|
||||
</div>
|
||||
<div v-if="sessionCustom.length" class="aksrt-icon-picker__grid aksrt-icon-picker__grid--session">
|
||||
<div
|
||||
v-if="sessionCustom.length"
|
||||
class="aksrt-icon-picker__grid aksrt-icon-picker__grid--session"
|
||||
data-aksrt-icon-grid="custom"
|
||||
>
|
||||
<div
|
||||
v-for="(svg, i) in sessionCustom"
|
||||
:key="i"
|
||||
class="aksrt-icon-picker__item"
|
||||
:class="{ 'is-active': modelValue === `customsvg-${svg}` }"
|
||||
title="customsvg"
|
||||
@click="$emit('update:modelValue', `customsvg-${svg}`)"
|
||||
:data-icon="`customsvg-${svg}`"
|
||||
v-html="cleanSvg(svg)"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Catalog tab -->
|
||||
<div v-else class="aksrt-icon-picker__grid" ref="gridRef">
|
||||
<div v-else class="aksrt-icon-picker__grid" data-aksrt-icon-grid="catalog">
|
||||
<div
|
||||
v-for="icon in filteredIcons"
|
||||
:key="icon"
|
||||
class="aksrt-icon-picker__item"
|
||||
:class="{ 'is-active': modelValue === composeIconValue(activeGroup, icon) }"
|
||||
:title="icon"
|
||||
@click="selectIcon(icon)"
|
||||
:data-icon="composeIconValue(activeGroup, icon)"
|
||||
>
|
||||
<i v-if="activeGroup.type === 'fa'" :class="[activeTab, icon]"></i>
|
||||
<i v-if="activeGroup.type === 'fa'" :class="[activeTab, 'fa-' + icon]"></i>
|
||||
<span
|
||||
v-else
|
||||
class="aksrt-icon-picker__preview-svg"
|
||||
@@ -120,6 +124,7 @@ const search = ref('')
|
||||
const activeTab = ref('fas')
|
||||
const customCode = ref('')
|
||||
const sessionCustom = ref([])
|
||||
const popoverShow = ref(false)
|
||||
|
||||
const activeGroup = computed(() => tabs.value.find(t => t.id === activeTab.value) || tabs.value[0])
|
||||
|
||||
@@ -133,8 +138,16 @@ const filteredIcons = computed(() => {
|
||||
|
||||
const customPreview = computed(() => cleanSvg(customCode.value))
|
||||
|
||||
function selectIcon(icon) {
|
||||
emit('update:modelValue', composeIconValue(activeGroup.value, icon))
|
||||
function selectIcon(value) {
|
||||
emit('update:modelValue', value)
|
||||
popoverShow.value = false
|
||||
}
|
||||
|
||||
// Delegated on the panel: survives any DOM replacement inside the grids and
|
||||
// works for both the catalog and session grids.
|
||||
function onPanelClick(event) {
|
||||
const item = event.target.closest('[data-icon]')
|
||||
if (item) selectIcon(item.dataset.icon)
|
||||
}
|
||||
|
||||
function insertCustom() {
|
||||
|
||||
Reference in New Issue
Block a user