1import{_ as W}from"./SettingsPage.vue_vue_type_script_setup_true_lang-DVrSOfdb.js";import{bt as Z,bl as A,cu as Y,cM as q,au as P,at as J,aZ as K}from"./index-CAb_WIP4.js";import{_ as Q}from"./InlineBanner.vue_vue_type_script_setup_true_lang-D-q41_c1.js";import{_ as X}from"./SettingRow.vue_vue_type_script_setup_true_lang-DL0ljWx9.js";import{F as ee}from"./FormNumberInput-DlIeUPGl.js";import{u as R,a2 as s,m as w,av as v,l as $,s as N,o as b,af as C,n as E,r as U,a5 as y,at as V,a1 as te,p as ae,al as p,F as B,a6 as H,j as S,a4 as ie}from"./editor-CwJpQLR6.js";import{u as ne,_ as oe}from"./useUnsavedGuard-DLYDRQx-.js";const se={key:0,class:"text-fg-subtle"},le={key:0,class:"mt-0.5 text-meta text-status-rejected"},re={class:"w-24"},ce=R({__name:"SettingNumberRow",props:{id:{},label:{},description:{},modelValue:{},defaultValue:{},min:{},max:{},step:{},disabled:{type:Boolean},invalid:{type:Boolean},invalidMessage:{}},emits:["update:modelValue"],setup(a){return(t,l)=>(s(),w(X,{label:a.label,"html-for":a.id,align:"start"},{description:v(()=>[U(C(a.description)+" ",1),a.defaultValue!=null?(s(),b("span",se,"Default "+C(a.defaultValue)+".",1)):E("",!0)]),below:v(()=>[a.invalid&&a.invalidMessage?(s(),b("p",le,C(a.invalidMessage),1)):E("",!0)]),control:v(()=>[$("div",re,[N(ee,{id:a.id,dense:"","model-value":a.modelValue,min:a.min,max:a.max,step:a.step,disabled:a.disabled,invalid:a.invalid,"onUpdate:modelValue":l[0]||(l[0]=d=>t.$emit("update:modelValue",d))},null,8,["id","model-value","min","max","step","disabled","invalid"])])]),_:1},8,["label","html-for"]))}}),L={max_total_priority:200,max_customer_weight:100,max_company_weight:50,max_vote_volume:1e3,max_comments:200,max_subscribers:500,w_total_priority:.2,w_average_priority:.15,w_customer_weight:.2,w_company_weight:.1,w_vote_score:.15,w_engagement:.1,w_user_happiness:.05,w_recency:.05,recency_window_days:365},D=[{key:"max_total_priority",label:"Max total priority",description:"Expected maximum of combined priority votes. Used to normalize total priority to 0â1.",kind:"count"},{key:"max_customer_weight",label:"Max customer weight",description:"Expected combined weight of all participating users.",kind:"count"},{key:"max_company_weight",label:"Max company weight",description:"Expected combined weight of all participating companies (each counted once).",kind:"count"},{key:"max_vote_volume",label:"Max vote volume",description:"Caps up/down vote volume so very popular items donât dominate.",kind:"count"},{key:"max_comments",label:"Max comments",description:"Normalization limit for comment count.",kind:"count"},{key:"max_subscribers",label:"Max subscribers",description:"Normalization cap for the number of followers on an item.",kind:"count"}],z=[{key:"w_total_priority",label:"Total priority",description:"How much the number of priority votes counts.",kind:"weight"},{key:"w_average_priority",label:"Average priority",description:"How much the average priority score per user counts.",kind:"weight"},{key:"w_customer_weight",label:"Customer weight",description:"How much combined user value (importance, plan, etc.) counts.",kind:"weight"},{key:"w_company_weight",label:"Company weight",description:"How much combined company value counts â reflects B2B impact.",kind:"weight"},{key:"w_vote_score",label:"Vote score",description:"How much vote sentiment and volume count.",kind:"weight"},{key:"w_engagement",label:"Engagement",description:"How much comments and subscribers count.",kind:"weight"},{key:"w_user_happiness",label:"User happiness",description:"How much engaged usersâ satisfaction and promoter scores count.",kind:"weight"}],F=[{key:"w_recency",label:"Recency weight",description:"How much recent activity affects visibility at read time.",kind:"weight"},{key:"recency_window_days",label:"Recency window (days)",description:"After this many days with no activity, an item fully decays in visibility.",kind:"count"}],x=[...D,...z,...F],de=3e3;function ue(a){const t={};for(const l of x)t[l.key]=Number(a[l.key]);return t}const me=Z("impactScore",()=>{const a=y(null),t=y(!0),l=y(""),d=y(!1),f=y(!1),h=y(null);let g=null;function c(){g&&(clearTimeout(g),g=null)}async function I(n){const m=(await A.v1.get(`product/${n}/impact-score`)).parameters;a.value=ue(m),t.value=!!Number(m.ready??1),l.value=String(m.updated??"")}function _(n){c(),!t.value&&(g=setTimeout(async()=>{try{await I(n)}catch{c();return}_(n)},de))}async function r(n){h.value=n,d.value=!0,f.value=!1,c();try{await I(n),_(n)}catch{f.value=!0,a.value=null}finally{d.value=!1}}async function k(n){const u=h.value;if(u==null)throw new Error("No product loaded");await A.v1.put(`product/${u}/impact-score`,n),a.value={...n},t.value=!1,_(u)}return{params:a,ready:t,updated:l,loading:d,error:f,productId:h,load:r,save:k,stopPolling:c}}),pe={key:0,class:"flex justify-center py-16"},ye={key:3,class:"flex flex-col gap-10"},ve={class:"divide-y divide-border"},xe=R({__name:"SettingsImpactView",setup(a){const t=me(),{product:l,productId:d}=Y(),f=q();function h(e){f.show({kind:"info",message:e,dismissible:!0,autoDismissMs:2500})}function g(e,i){f.show({kind:"error",message:(e==null?void 0:e.message)||i,dism
1issible:!0,autoDismissMs:4e3})}const c=S(()=>{var e;return((e=l.value)==null?void 0:e.user_role)??""}),I=S(()=>c.value===""||c.value==="owner"||c.value==="admin"),_=[{label:"Normalization Limits",fields:D},{label:"Weights",fields:z},{label:"Recency",fields:F}],r=ie({...L});function k(){const e=t.params;if(e)for(const i of x)r[i.key]=e[i.key]}V(()=>t.productId,k,{immediate:!0}),V(()=>t.params,e=>{e&&k()}),V(d,e=>{e!=null&&t.load(e)},{immediate:!0}),te(()=>t.stopPolling());function n(e,i){return i==null||Number.isNaN(i)?!0:e.kind==="weight"?i<0||i>1:i<1}const u=S(()=>x.some(e=>n(e,r[e.key]))),m=S(()=>{const e=t.params;return e?x.some(i=>r[i.key]!==e[i.key]):!1}),M=y(!1);ne(m);async function O(){if(!t.params||u.value||!m.value||!t.ready)return;const e={};for(const i of x)e[i.key]=Number(r[i.key]);M.value=!0;try{await t.save(e),h("Impact settings saved â scores are recalculating.")}catch(i){g(i,"Could not save the impact settings")}finally{M.value=!1}}function j(){k()}return(e,i)=>(s(),w(W,{title:"Impact Score"},ae({default:v(()=>[p(t).loading&&!p(t).params?(s(),b("div",pe,[N(J,{center:""})])):I.value?p(t).error?(s(),w(P,{key:2,title:"Couldnât load the Impact Score settings",description:"Something went wrong. Please try again."})):(s(),b("div",ye,[i[1]||(i[1]=$("p",{class:"text-small leading-[1.55] text-fg-muted"}," The Impact Score ranks feedback by combining priority votes, vote sentiment, engagement, customer and company value, user happiness and recency. Tune the weights and normalization limits below to match how your team prioritizes. Saving recalculates every itemâs score. ",-1)),p(t).ready?E("",!0):(s(),w(Q,{key:0,loading:""},{default:v(()=>[...i[0]||(i[0]=[U(" Recalculating impact scores⦠you can edit again once this finishes. ",-1)])]),_:1})),(s(),b(B,null,H(_,T=>N(K,{key:T.label,label:T.label},{default:v(()=>[$("div",ve,[(s(!0),b(B,null,H(T.fields,o=>(s(),w(ce,{id:`impact-${o.key}`,key:o.key,label:o.label,description:o.description,"default-value":p(L)[o.key],"model-value":r[o.key],min:o.kind==="weight"?0:1,max:o.kind==="weight"?1:void 0,step:o.kind==="weight"?.01:1,disabled:!p(t).ready,invalid:n(o,r[o.key]),"invalid-message":o.kind==="weight"?"Enter a value between 0 and 1.":"Enter a whole number of 1 or more.","onUpdate:modelValue":G=>r[o.key]=G},null,8,["id","label","description","default-value","model-value","min","max","step","disabled","invalid","invalid-message","onUpdate:modelValue"]))),128))])]),_:2},1032,["label"])),64))])):(s(),w(P,{key:1,title:"No access",description:"Only workspace owners and admins can tune the Impact Score."}))]),_:2},[m.value?{name:"footer",fn:v(()=>[N(oe,{saving:M.value,disabled:u.value||!p(t).ready,onSave:O,onDiscard:j},null,8,["saving","disabled"])]),key:"0"}:void 0]),1024))}});export{xe as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.