From c3e971c41964a817959a9bd7cacb69c871b5c29a Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 12 Sep 2023 06:09:39 +0200 Subject: [PATCH] Rebuild frontend. --- .../assets/{dashboard-3bf5d492.js => dashboard-e6afec51.js} | 2 +- public/build/manifest.json | 4 ++-- resources/assets/v2/pages/dashboard/sankey.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename public/build/assets/{dashboard-3bf5d492.js => dashboard-e6afec51.js} (99%) diff --git a/public/build/assets/dashboard-3bf5d492.js b/public/build/assets/dashboard-e6afec51.js similarity index 99% rename from public/build/assets/dashboard-3bf5d492.js rename to public/build/assets/dashboard-e6afec51.js index 29cafa1c44..3f70709ffa 100644 --- a/public/build/assets/dashboard-3bf5d492.js +++ b/public/build/assets/dashboard-e6afec51.js @@ -38,7 +38,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho * (c) 2022 Jukka Kurkela * Released under the MIT license */function toTextLines(t){const e=[],a=isArray$c(t)?t:isNullOrUndef(t)?[]:[t];for(;a.length;){const n=a.pop();typeof n=="string"?e.unshift.apply(e,n.split(` -`)):Array.isArray(n)?a.push.apply(a,n):isNullOrUndef(a)||e.unshift(""+n)}return e}function validateSizeValue(t){return!t||["min","max"].indexOf(t)===-1?"max":t}const defined=t=>t!==void 0;function calculateX(t,e){const a=new Set(e.map(o=>o.to)),n=new Set(e.map(o=>o.from)),r=new Set([...t.keys()]);let i=0;for(;r.size;){const o=nextColumn([...r],a);for(const s of o){const l=t.get(s);defined(l.x)||(l.x=i),r.delete(s)}r.size&&(a.clear(),e.filter(s=>r.has(s.from)).forEach(s=>a.add(s.to)),i++)}return[...t.keys()].filter(o=>!n.has(o)).forEach(o=>{const s=t.get(o);s.column||(s.x=i)}),i}function nextColumn(t,e){const a=t.filter(n=>!e.has(n));return a.length?a:t.slice(0,1)}const nodeByXY=(t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y;let prevCountId=-1;function getCountId(){return prevCountId=prevCountId<100?prevCountId+1:0,prevCountId}function nodeCount(t,e,a=getCountId()){let n=0;for(const r of t)r.node._visited!==a&&(r.node._visited=a,n+=r.node[e].length+nodeCount(r.node[e],e,a));return n}const flowByNodeCount=t=>(e,a)=>nodeCount(e.node[t],t)-nodeCount(a.node[t],t)||e.node[t].length-a.node[t].length;function processFrom(t,e){t.from.sort(flowByNodeCount("from"));for(const a of t.from){const n=a.node;defined(n.y)||(n.y=e,processFrom(n,e)),e=Math.max(n.y+n.out,e)}return e}function processTo(t,e){t.to.sort(flowByNodeCount("to"));for(const a of t.to){const n=a.node;defined(n.y)||(n.y=e,processTo(n,e)),e=Math.max(n.y+n.in,e)}return e}function setOrGetY(t,e){return defined(t.y)?t.y:(t.y=e,e)}function processRest(t,e){const a=t.filter(c=>c.x===0),n=t.filter(c=>c.x===e),r=a.filter(c=>!defined(c.y)),i=n.filter(c=>!defined(c.y)),o=t.filter(c=>c.x>0&&c.xMath.max(c,d.y+d.out||0),0),l=n.reduce((c,d)=>Math.max(c,d.y+d.in||0),0),u=0;return s>=l?(r.forEach(c=>{s=setOrGetY(c,s),s=Math.max(s+c.out,processTo(c,s))}),i.forEach(c=>{l=setOrGetY(c,l),l=Math.max(l+c.in,processTo(c,l))})):(i.forEach(c=>{l=setOrGetY(c,l),l=Math.max(l+c.in,processTo(c,l))}),r.forEach(c=>{s=setOrGetY(c,s),s=Math.max(s+c.out,processTo(c,s))})),o.forEach(c=>{let d=t.filter(h=>h.x===c.x&&defined(h.y)).reduce((h,m)=>Math.max(h,m.y+Math.max(m.in,m.out)),0);d=setOrGetY(c,d),d=Math.max(d+c.in,processFrom(c,d)),d=Math.max(d+c.out,processTo(c,d)),u=Math.max(u,d)}),Math.max(s,l,u)}function calculateY(t,e){t.sort((o,s)=>Math.max(s.in,s.out)-Math.max(o.in,o.out));const a=t[0];a.y=0;const n=processFrom(a,0),r=processTo(a,0),i=processRest(t,e);return Math.max(n,r,i)}function calculateYUsingPriority(t,e){let a=0,n=0;for(let r=0;r<=e;r++){let i=n;const o=t.filter(s=>s.x===r).sort((s,l)=>s.priority-l.priority);n=o[0].to.filter(s=>s.node.x>r+1).reduce((s,l)=>s+l.flow,0)||0;for(const s of o)s.y=i,i+=Math.max(s.out,s.in);a=Math.max(i,a)}return a}function addPadding(t,e){let a=1,n=0,r=0,i=0;const o=[];t.sort(nodeByXY);for(const s of t){if(s.y){if(s.x===0)o.push(s.y);else{for(n!==s.x&&(n=s.x,r=0),a=r+1;as.y);a++);r=a}s.y+=a*e,a++}i=Math.max(i,s.y+Math.max(s.in,s.out))}return i}function sortFlows(t,e){t.forEach(a=>{const n=Math[e](a.in||a.out,a.out||a.in),r=nl.node.y+l.node.out/2-(u.node.y+u.node.out/2)).forEach((l,u)=>{r?l.addY=u*(n-l.flow)/(s-1):(l.addY=o,o+=l.flow)}),o=0,s=a.to.length,a.to.sort((l,u)=>l.node.y+l.node.in/2-(u.node.y+u.node.in/2)).forEach((l,u)=>{i?l.addY=u*(n-l.flow)/(s-1):(l.addY=o,o+=l.flow)})})}function layout(t,e,a,n){const r=[...t.values()],i=calculateX(t,e),s=(a?calculateYUsingPriority(r,i):calculateY(r,i))*.03,l=addPadding(r,s);return sortFlows(r,n),{maxX:i,maxY:l}}function buildNodesFromRawData(t){const e=new Map;for(let n=0;nr.flow-n.flow;return[...e.values()].forEach(n=>{n.from=n.from.sort(a),n.from.forEach(r=>{r.node=e.get(r.key)}),n.to=n.to.sort(a),n.to.forEach(r=>{r.node=e.get(r.key)})}),e}function getAddY(t,e,a){for(const n of t)if(n.key===e&&n.index===a)return n.addY;return 0}class SankeyController extends DatasetController{parseObjectData(e,a,n,r){const{from:i="from",to:o="to",flow:s="flow"}=this.options.parsing,l=a.map(({[i]:_,[o]:D,[s]:k})=>({from:_,to:D,flow:k})),{xScale:u,yScale:c}=e,d=[],h=this._nodes=buildNodesFromRawData(l),{column:m,priority:p,size:v}=this.getDataset();if(p)for(const _ of h.values())_.key in p&&(_.priority=p[_.key]);if(m)for(const _ of h.values())_.key in m&&(_.column=!0,_.x=m[_.key]);const{maxX:y,maxY:w}=layout(h,l,!!p,validateSizeValue(v));this._maxX=y,this._maxY=w;for(let _=0,D=l.length;_1){const h=u-c*l/2+d;for(let m=0;mt.type==="data"?(t.parsed._custom.x-t.parsed.x)*200:void 0,delay:t=>t.type==="data"?t.parsed.x*500+t.dataIndex*20:void 0},colors:{type:"color",properties:["colorFrom","colorTo"]}},transitions:{hide:{animations:{colors:{type:"color",properties:["colorFrom","colorTo"],to:"transparent"}}},show:{animations:{colors:{type:"color",properties:["colorFrom","colorTo"],from:"transparent"}}}}};SankeyController.overrides={interaction:{mode:"nearest",intersect:!0},datasets:{clip:!1,parsing:!0},plugins:{tooltip:{callbacks:{title(){return""},label(t){const e=t.dataset.data[t.dataIndex];return e.from+" -> "+e.to+": "+e.flow}}},legend:{display:!1}},scales:{x:{type:"linear",bounds:"data",display:!1,min:0,offset:!1},y:{type:"linear",bounds:"data",display:!1,min:0,reverse:!0,offset:!1}},layout:{padding:{top:3,left:3,right:13,bottom:3}}};const controlPoints=(t,e,a,n)=>t({x:t.x+a*(e.x-t.x),y:t.y+a*(e.y-t.y)});function setStyle(t,{x:e,x2:a,options:n}){let r;n.colorMode==="from"?r=color(n.colorFrom).alpha(.5).rgbString():n.colorMode==="to"?r=color(n.colorTo).alpha(.5).rgbString():(r=t.createLinearGradient(e,0,a,0),r.addColorStop(0,color(n.colorFrom).alpha(.5).rgbString()),r.addColorStop(1,color(n.colorTo).alpha(.5).rgbString())),t.fillStyle=r,t.strokeStyle=r,t.lineWidth=.5}class Flow extends Element$1{constructor(e){super(),this.options=void 0,this.x=void 0,this.y=void 0,this.x2=void 0,this.y2=void 0,this.height=void 0,e&&Object.assign(this,e)}draw(e){const a=this,{x:n,x2:r,y:i,y2:o,height:s,progress:l}=a,{cp1:u,cp2:c}=controlPoints(n,i,r,o);l!==0&&(e.save(),l<1&&(e.beginPath(),e.rect(n,Math.min(i,o),(r-n)*l+1,Math.abs(o-i)+s+1),e.clip()),setStyle(e,a),e.beginPath(),e.moveTo(n,i),e.bezierCurveTo(u.x,u.y,c.x,c.y,r,o),e.lineTo(r,o+s),e.bezierCurveTo(c.x,c.y+s,u.x,u.y+s,n,i+s),e.lineTo(n,i),e.stroke(),e.closePath(),e.fill(),e.restore())}inRange(e,a,n){const{x:r,y:i,x2:o,y2:s,height:l}=this.getProps(["x","y","x2","y2","height"],n);if(eo)return!1;const{cp1:u,cp2:c}=controlPoints(r,i,o,s),d=(e-r)/(o-r),h={x:r,y:i},m={x:o,y:s},p=pointInLine(h,u,d),v=pointInLine(u,c,d),y=pointInLine(c,m,d),w=pointInLine(p,v,d),_=pointInLine(v,y,d),D=pointInLine(w,_,d).y;return a>=D&&a<=D+l}inXRange(e,a){const{x:n,x2:r}=this.getProps(["x","x2"],a);return e>=n&&e<=r}inYRange(e,a){const{y:n,y2:r,height:i}=this.getProps(["y","y2","height"],a),o=Math.min(n,r),s=Math.max(n,r)+i;return e>=o&&e<=s}getCenterPoint(e){const{x:a,y:n,x2:r,y2:i,height:o}=this.getProps(["x","y","x2","y2","height"],e);return{x:(a+r)/2,y:(n+i+o)/2}}tooltipPosition(e){return this.getCenterPoint(e)}getRange(e){return e==="x"?this.width/2:this.height/2}}Flow.id="flow";Flow.defaults={colorFrom:"red",colorTo:"green",colorMode:"gradient",hoverColorFrom:(t,e)=>getHoverColor(e.colorFrom),hoverColorTo:(t,e)=>getHoverColor(e.colorTo)};Chart.register({SankeyController,Flow});const CACHE_KEY$2="dashboard-sankey-data";let i18n$2,afterPromises$2=!1,chart$1=null,transactions=[],autoConversion=!1,translations={category:null,unknown_category:null,in:null,out:null,unknown_source:null,unknown_dest:null,unknown_account:null,expense_account:null,revenue_account:null,budget:null,unknown_budget:null,all_money:null};const getColor=function(t){return t.includes(translations.revenue_account)?"forestgreen":t.includes("("+translations.in+",")?"green":t.includes(translations.budget)||t.includes(translations.unknown_budget)?"Orchid":t.includes("("+translations.out+",")?"MediumOrchid":t.includes(translations.all_money)?"blue":"red"};function getObjectName(t,e,a,n){if(t==="category"&&e!==null&&a==="in")return translations.category+' "'+e+'" ('+translations.in+(autoConversion?", "+n+")":")");if(t==="category"&&e===null&&a==="in")return translations.unknown_category+" ("+translations.in+(autoConversion?", "+n+")":")");if(t==="category"&&e!==null&&a==="out")return translations.category+' "'+e+'" ('+translations.out+(autoConversion?", "+n+")":")");if(t==="category"&&e===null&&a==="out")return translations.unknown_category+" ("+translations.out+(autoConversion?", "+n+")":")");if(t==="account"&&e===null&&a==="in")return translations.unknown_source+(autoConversion?" ("+n+")":"");if(t==="account"&&e!==null&&a==="in")return translations.revenue_account+'"'+e+'"'+(autoConversion?" ("+n+")":"");if(t==="account"&&e===null&&a==="out")return translations.unknown_dest+(autoConversion?" ("+n+")":"");if(t==="account"&&e!==null&&a==="out")return translations.expense_account+' "'+e+'"'+(autoConversion?" ("+n+")":"");if(t==="budget"&&e!==null)return translations.budget+' "'+e+'"'+(autoConversion?" ("+n+")":"");if(t==="budget"&&e===null)return translations.unknown_budget+(autoConversion?" ("+n+")":"");console.error('Cannot handle: type:"'+t+'", dir: "'+a+'"')}function getLabelName(t,e,a){if(t==="category"&&e!==null)return translations.category+' "'+e+'"'+(autoConversion?" ("+a+")":"");if(t==="category"&&e===null)return translations.unknown_category+(autoConversion?" ("+a+")":"");if(t==="account"&&e===null)return translations.unknown_account+(autoConversion?" ("+a+")":"");if(t==="account"&&e!==null)return e+(autoConversion?" ("+a+")":"");if(t==="budget"&&e!==null)return translations.budget+' "'+e+'"'+(autoConversion?" ("+a+")":"");if(t==="budget"&&e===null)return translations.unknown_budget+(autoConversion?" ("+a+")":"");console.error('Cannot handle: type:"'+t+'"')}const sankey=()=>({loading:!1,autoConversion:!1,generateOptions(){let t=getDefaultChartSettings("sankey"),e={},a={};for(let r in transactions)if(transactions.hasOwnProperty(r)){let i=transactions[r];for(let o in i.attributes.transactions)if(i.attributes.transactions.hasOwnProperty(o)){let s=i.attributes.transactions[o],l=this.autoConversion?s.native_code:s.currency_code,u=this.autoConversion?parseFloat(s.native_amount):parseFloat(s.amount),c;if(s.type==="deposit"){let d=getObjectName("category",s.category_name,"in",l),h=getObjectName("account",s.source_name,"in",l);a[d]=getLabelName("category",s.category_name,l),a[h]=getLabelName("account",s.source_name,l),c=h+"-"+d+"-"+l,e.hasOwnProperty(c)||(e[c]={from:h,to:d,amount:0}),e[c].amount+=u,c=d+"-"+translations.all_money+"-"+l,e.hasOwnProperty(c)||(e[c]={from:d,to:translations.all_money+(this.autoConversion?" ("+l+")":""),amount:0}),e[c].amount+=u}if(s.type==="withdrawal"){let d=getObjectName("budget",s.budget_name,"out",l);a[d]=getLabelName("budget",s.budget_name,l),c=translations.all_money+"-"+d+"-"+l,e.hasOwnProperty(c)||(e[c]={from:translations.all_money+" ("+l+")",to:d,amount:0}),e[c].amount+=u;let h=getObjectName("category",s.category_name,"out",l);a[h]=getLabelName("category",s.category_name,l),c=d+"-"+h+"-"+l,e.hasOwnProperty(c)||(e[c]={from:d,to:h,amount:0}),e[c].amount+=u;let m=getObjectName("account",s.destination_name,"out",l);a[m]=getLabelName("account",s.destination_name,l),c=h+"-"+m+"-"+l,e.hasOwnProperty(c)||(e[c]={from:h,to:m,amount:0}),e[c].amount+=u}}}let n={label:"Firefly III dashboard sankey chart",data:[],colorFrom:r=>getColor(r.dataset.data[r.dataIndex].from),colorTo:r=>getColor(r.dataset.data[r.dataIndex].to),colorMode:"gradient",labels:a,size:"min"};for(let r in e)if(e.hasOwnProperty(r)){let i=e[r];n.data.push({from:i.from,to:i.to,flow:i.amount})}return t.data.datasets.push(n),t},drawChart(t){if(chart$1!==null){chart$1.data.datasets=t.data.datasets,chart$1.update();return}chart$1=new Chart(document.querySelector("#sankey-chart"),t)},getFreshData(){const t=window.store.get("cacheValid");let e=window.store.get(CACHE_KEY$2);if(t&&typeof e<"u"){transactions=e,this.drawChart(this.generateOptions()),this.loading=!1;return}let a={start:window.store.get("start").slice(0,10),end:window.store.get("end").slice(0,10),type:"withdrawal,deposit",page:1};this.downloadTransactions(a)},downloadTransactions(t){new Get$2().get(t).then(a=>{if(transactions=[...transactions,...a.data.data],parseInt(a.data.meta.pagination.total_pages)>t.page){t.page++,this.downloadTransactions(t);return}window.store.set(CACHE_KEY$2,transactions),this.drawChart(this.generateOptions()),this.loading=!1})},loadChart(){if(this.loading!==!0){if(this.loading=!0,transactions.length!==0){this.drawChart(this.generateOptions()),this.loading=!1;return}this.getFreshData()}},init(){transactions=[],Promise.all([getVariable("autoConversion",!1),getVariable("language","en-US")]).then(t=>{this.autoConversion=t[0],autoConversion=t[0],i18n$2=new I18n,i18n$2.locale=t[1],loadTranslations(i18n$2,t[1]).then(()=>{translations.all_money=i18n$2.t("firefly.all_money"),translations.category=i18n$2.t("firefly.category"),translations.in=i18n$2.t("firefly.money_flowing_in"),translations.out=i18n$2.t("firefly.money_flowing_out"),translations.unknown_category=i18n$2.t("firefly.unknown_category_plain"),translations.unknown_source=i18n$2.t("firefly.unknown_source_plain"),translations.unknown_dest=i18n$2.t("firefly.unknown_dest_plain"),translations.unknown_account=i18n$2.t("firefly.unknown_any_plain"),translations.unknown_budget=i18n$2.t("firefly.unknown_budget_plain"),translations.expense_account=i18n$2.t("firefly.expense_account"),translations.revenue_account=i18n$2.t("firefly.revenue_account"),translations.budget=i18n$2.t("firefly.budget"),afterPromises$2=!0,this.loadChart()})}),window.store.observe("end",()=>{afterPromises$2&&(this.transactions=[],this.loadChart())}),window.store.observe("autoConversion",t=>{afterPromises$2&&(this.autoConversion=t,this.loadChart())})}});let Get$1=class{get(e){return api.get("/api/v2/subscriptions",{params:e})}paid(e){return api.get("/api/v2/subscriptions/sum/paid",{params:e})}unpaid(e){return api.get("/api/v2/subscriptions/sum/unpaid",{params:e})}};const CACHE_KEY$1="dashboard-subscriptions-data";let chart=null,afterPromises$1=!1,i18n$1;const subscriptions=()=>({loading:!1,autoConversion:!1,loadChart(){this.loading!==!0&&(this.loading=!0,this.getFreshData())},drawChart(t){if(chart!==null){chart.data.datasets=t.data.datasets,chart.update();return}chart=new Chart(document.querySelector("#subscriptions-chart"),t)},getFreshData(){const t=window.store.get("cacheValid");let e=window.store.get(CACHE_KEY$1);if(t&&typeof e<"u"){this.drawChart(this.generateOptions(e)),this.loading=!1;return}const a=new Get$1;let n={start:format$1(new Date(window.store.get("start")),"y-MM-dd"),end:format$1(new Date(window.store.get("end")),"y-MM-dd")};a.paid(n).then(r=>{let i=r.data;a.unpaid(n).then(o=>{let s=o.data,l={paid:i,unpaid:s};window.store.set(CACHE_KEY$1,l),this.drawChart(this.generateOptions(l)),this.loading=!1})})},generateOptions(t){let e=getDefaultChartSettings("pie");e.data.labels=[i18n$1.t("firefly.paid"),i18n$1.t("firefly.unpaid")],e.data.datasets=[];let a={};for(let n in t.paid)if(t.paid.hasOwnProperty(n)){let r=t.paid[n],i=this.autoConversion?r.native_code:r.currency_code,o=this.autoConversion?r.native_sum:r.sum;a.hasOwnProperty(i)||(a[i]={paid:0,unpaid:0}),a[i].paid+=parseFloat(o)*-1}for(let n in t.unpaid)if(t.unpaid.hasOwnProperty(n)){let r=t.unpaid[n],i=this.autoConversion?r.native_code:r.currency_code,o=this.autoConversion?r.native_sum:r.sum;a.hasOwnProperty(i)||(a[i]={paid:0,unpaid:0}),a[i].unpaid+=parseFloat(o)}for(let n in a)if(a.hasOwnProperty(n)){let r=a[n];e.data.datasets.push({label:n,data:[r.paid,r.unpaid],backgroundColor:["rgb(54, 162, 235)","rgb(255, 99, 132)"]})}return e},init(){Promise.all([getVariable("autoConversion",!1),getVariable("language","en-US")]).then(t=>{this.autoConversion=t[0],afterPromises$1=!0,i18n$1=new I18n,i18n$1.locale=t[1],loadTranslations(i18n$1,t[1]).then(()=>{this.loading===!1&&this.loadChart()})}),window.store.observe("end",()=>{afterPromises$1&&this.loading===!1&&(this.chartData=null,this.loadChart())}),window.store.observe("autoConversion",t=>{afterPromises$1&&(this.autoConversion=t,this.loading===!1&&this.loadChart())})}});class Get{get(e){return api.get("/api/v2/piggy-banks",{params:e})}}let apiData={},afterPromises=!1,i18n;const CACHE_KEY="dashboard-piggies-data",piggies=()=>({loading:!1,autoConversion:!1,sankeyGrouping:"account",piggies:[],getFreshData(){const t=window.store.get("cacheValid");let e=window.store.get(CACHE_KEY);if(t&&typeof e<"u"){apiData=e,this.parsePiggies(),this.loading=!1;return}let a={start:window.store.get("start").slice(0,10),end:window.store.get("end").slice(0,10),page:1};this.downloadPiggyBanks(a)},downloadPiggyBanks(t){new Get().get(t).then(a=>{if(apiData=[...apiData,...a.data.data],parseInt(a.data.meta.pagination.total_pages)>t.page){t.page++,this.downloadPiggyBanks(t);return}window.store.set(CACHE_KEY,apiData),this.parsePiggies(),this.loading=!1})},parsePiggies(){let t=[];for(let e in apiData)if(apiData.hasOwnProperty(e)){let a=apiData[e];if(a.attributes.percentage>=100||a.attributes.percentage===0)continue;let n=a.object_group_title??i18n.t("firefly.default_group_title_name_plain");t.hasOwnProperty(n)||(t[n]={id:a.object_group_id??0,title:n,order:a.object_group_order??0,piggies:[]});let r={id:a.id,name:a.attributes.name,percentage:parseInt(a.attributes.percentage),amount:this.autoConversion?a.attributes.native_current_amount:a.attributes.current_amount,left_to_save:this.autoConversion?a.attributes.native_left_to_save:a.attributes.left_to_save,target_amount:this.autoConversion?a.attributes.native_target_amount:a.attributes.target_amount,save_per_month:this.autoConversion?a.attributes.native_save_per_month:a.attributes.save_per_month,currency_code:this.autoConversion?a.attributes.native_code:a.attributes.currency_code};t[n].piggies.push(r)}this.piggies=Object.values(t)},loadPiggyBanks(){if(this.loading!==!0){if(this.loading=!0,this.piggies.length!==0){this.parsePiggies(),this.loading=!1;return}this.getFreshData()}},init(){apiData=[],Promise.all([getVariable("autoConversion",!1),getVariable("language","en-US")]).then(t=>{i18n=new I18n,i18n.locale=t[1],loadTranslations(i18n,t[1]).then(()=>{afterPromises=!0,this.autoConversion=t[0],this.loadPiggyBanks()})}),window.store.observe("end",()=>{afterPromises&&(apiData=[],this.loadPiggyBanks())}),window.store.observe("autoConversion",t=>{afterPromises&&(this.autoConversion=t,this.loadPiggyBanks())})}});/*! +`)):Array.isArray(n)?a.push.apply(a,n):isNullOrUndef(a)||e.unshift(""+n)}return e}function validateSizeValue(t){return!t||["min","max"].indexOf(t)===-1?"max":t}const defined=t=>t!==void 0;function calculateX(t,e){const a=new Set(e.map(o=>o.to)),n=new Set(e.map(o=>o.from)),r=new Set([...t.keys()]);let i=0;for(;r.size;){const o=nextColumn([...r],a);for(const s of o){const l=t.get(s);defined(l.x)||(l.x=i),r.delete(s)}r.size&&(a.clear(),e.filter(s=>r.has(s.from)).forEach(s=>a.add(s.to)),i++)}return[...t.keys()].filter(o=>!n.has(o)).forEach(o=>{const s=t.get(o);s.column||(s.x=i)}),i}function nextColumn(t,e){const a=t.filter(n=>!e.has(n));return a.length?a:t.slice(0,1)}const nodeByXY=(t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y;let prevCountId=-1;function getCountId(){return prevCountId=prevCountId<100?prevCountId+1:0,prevCountId}function nodeCount(t,e,a=getCountId()){let n=0;for(const r of t)r.node._visited!==a&&(r.node._visited=a,n+=r.node[e].length+nodeCount(r.node[e],e,a));return n}const flowByNodeCount=t=>(e,a)=>nodeCount(e.node[t],t)-nodeCount(a.node[t],t)||e.node[t].length-a.node[t].length;function processFrom(t,e){t.from.sort(flowByNodeCount("from"));for(const a of t.from){const n=a.node;defined(n.y)||(n.y=e,processFrom(n,e)),e=Math.max(n.y+n.out,e)}return e}function processTo(t,e){t.to.sort(flowByNodeCount("to"));for(const a of t.to){const n=a.node;defined(n.y)||(n.y=e,processTo(n,e)),e=Math.max(n.y+n.in,e)}return e}function setOrGetY(t,e){return defined(t.y)?t.y:(t.y=e,e)}function processRest(t,e){const a=t.filter(c=>c.x===0),n=t.filter(c=>c.x===e),r=a.filter(c=>!defined(c.y)),i=n.filter(c=>!defined(c.y)),o=t.filter(c=>c.x>0&&c.xMath.max(c,d.y+d.out||0),0),l=n.reduce((c,d)=>Math.max(c,d.y+d.in||0),0),u=0;return s>=l?(r.forEach(c=>{s=setOrGetY(c,s),s=Math.max(s+c.out,processTo(c,s))}),i.forEach(c=>{l=setOrGetY(c,l),l=Math.max(l+c.in,processTo(c,l))})):(i.forEach(c=>{l=setOrGetY(c,l),l=Math.max(l+c.in,processTo(c,l))}),r.forEach(c=>{s=setOrGetY(c,s),s=Math.max(s+c.out,processTo(c,s))})),o.forEach(c=>{let d=t.filter(h=>h.x===c.x&&defined(h.y)).reduce((h,m)=>Math.max(h,m.y+Math.max(m.in,m.out)),0);d=setOrGetY(c,d),d=Math.max(d+c.in,processFrom(c,d)),d=Math.max(d+c.out,processTo(c,d)),u=Math.max(u,d)}),Math.max(s,l,u)}function calculateY(t,e){t.sort((o,s)=>Math.max(s.in,s.out)-Math.max(o.in,o.out));const a=t[0];a.y=0;const n=processFrom(a,0),r=processTo(a,0),i=processRest(t,e);return Math.max(n,r,i)}function calculateYUsingPriority(t,e){let a=0,n=0;for(let r=0;r<=e;r++){let i=n;const o=t.filter(s=>s.x===r).sort((s,l)=>s.priority-l.priority);n=o[0].to.filter(s=>s.node.x>r+1).reduce((s,l)=>s+l.flow,0)||0;for(const s of o)s.y=i,i+=Math.max(s.out,s.in);a=Math.max(i,a)}return a}function addPadding(t,e){let a=1,n=0,r=0,i=0;const o=[];t.sort(nodeByXY);for(const s of t){if(s.y){if(s.x===0)o.push(s.y);else{for(n!==s.x&&(n=s.x,r=0),a=r+1;as.y);a++);r=a}s.y+=a*e,a++}i=Math.max(i,s.y+Math.max(s.in,s.out))}return i}function sortFlows(t,e){t.forEach(a=>{const n=Math[e](a.in||a.out,a.out||a.in),r=nl.node.y+l.node.out/2-(u.node.y+u.node.out/2)).forEach((l,u)=>{r?l.addY=u*(n-l.flow)/(s-1):(l.addY=o,o+=l.flow)}),o=0,s=a.to.length,a.to.sort((l,u)=>l.node.y+l.node.in/2-(u.node.y+u.node.in/2)).forEach((l,u)=>{i?l.addY=u*(n-l.flow)/(s-1):(l.addY=o,o+=l.flow)})})}function layout(t,e,a,n){const r=[...t.values()],i=calculateX(t,e),s=(a?calculateYUsingPriority(r,i):calculateY(r,i))*.03,l=addPadding(r,s);return sortFlows(r,n),{maxX:i,maxY:l}}function buildNodesFromRawData(t){const e=new Map;for(let n=0;nr.flow-n.flow;return[...e.values()].forEach(n=>{n.from=n.from.sort(a),n.from.forEach(r=>{r.node=e.get(r.key)}),n.to=n.to.sort(a),n.to.forEach(r=>{r.node=e.get(r.key)})}),e}function getAddY(t,e,a){for(const n of t)if(n.key===e&&n.index===a)return n.addY;return 0}class SankeyController extends DatasetController{parseObjectData(e,a,n,r){const{from:i="from",to:o="to",flow:s="flow"}=this.options.parsing,l=a.map(({[i]:_,[o]:D,[s]:k})=>({from:_,to:D,flow:k})),{xScale:u,yScale:c}=e,d=[],h=this._nodes=buildNodesFromRawData(l),{column:m,priority:p,size:v}=this.getDataset();if(p)for(const _ of h.values())_.key in p&&(_.priority=p[_.key]);if(m)for(const _ of h.values())_.key in m&&(_.column=!0,_.x=m[_.key]);const{maxX:y,maxY:w}=layout(h,l,!!p,validateSizeValue(v));this._maxX=y,this._maxY=w;for(let _=0,D=l.length;_1){const h=u-c*l/2+d;for(let m=0;mt.type==="data"?(t.parsed._custom.x-t.parsed.x)*200:void 0,delay:t=>t.type==="data"?t.parsed.x*500+t.dataIndex*20:void 0},colors:{type:"color",properties:["colorFrom","colorTo"]}},transitions:{hide:{animations:{colors:{type:"color",properties:["colorFrom","colorTo"],to:"transparent"}}},show:{animations:{colors:{type:"color",properties:["colorFrom","colorTo"],from:"transparent"}}}}};SankeyController.overrides={interaction:{mode:"nearest",intersect:!0},datasets:{clip:!1,parsing:!0},plugins:{tooltip:{callbacks:{title(){return""},label(t){const e=t.dataset.data[t.dataIndex];return e.from+" -> "+e.to+": "+e.flow}}},legend:{display:!1}},scales:{x:{type:"linear",bounds:"data",display:!1,min:0,offset:!1},y:{type:"linear",bounds:"data",display:!1,min:0,reverse:!0,offset:!1}},layout:{padding:{top:3,left:3,right:13,bottom:3}}};const controlPoints=(t,e,a,n)=>t({x:t.x+a*(e.x-t.x),y:t.y+a*(e.y-t.y)});function setStyle(t,{x:e,x2:a,options:n}){let r;n.colorMode==="from"?r=color(n.colorFrom).alpha(.5).rgbString():n.colorMode==="to"?r=color(n.colorTo).alpha(.5).rgbString():(r=t.createLinearGradient(e,0,a,0),r.addColorStop(0,color(n.colorFrom).alpha(.5).rgbString()),r.addColorStop(1,color(n.colorTo).alpha(.5).rgbString())),t.fillStyle=r,t.strokeStyle=r,t.lineWidth=.5}class Flow extends Element$1{constructor(e){super(),this.options=void 0,this.x=void 0,this.y=void 0,this.x2=void 0,this.y2=void 0,this.height=void 0,e&&Object.assign(this,e)}draw(e){const a=this,{x:n,x2:r,y:i,y2:o,height:s,progress:l}=a,{cp1:u,cp2:c}=controlPoints(n,i,r,o);l!==0&&(e.save(),l<1&&(e.beginPath(),e.rect(n,Math.min(i,o),(r-n)*l+1,Math.abs(o-i)+s+1),e.clip()),setStyle(e,a),e.beginPath(),e.moveTo(n,i),e.bezierCurveTo(u.x,u.y,c.x,c.y,r,o),e.lineTo(r,o+s),e.bezierCurveTo(c.x,c.y+s,u.x,u.y+s,n,i+s),e.lineTo(n,i),e.stroke(),e.closePath(),e.fill(),e.restore())}inRange(e,a,n){const{x:r,y:i,x2:o,y2:s,height:l}=this.getProps(["x","y","x2","y2","height"],n);if(eo)return!1;const{cp1:u,cp2:c}=controlPoints(r,i,o,s),d=(e-r)/(o-r),h={x:r,y:i},m={x:o,y:s},p=pointInLine(h,u,d),v=pointInLine(u,c,d),y=pointInLine(c,m,d),w=pointInLine(p,v,d),_=pointInLine(v,y,d),D=pointInLine(w,_,d).y;return a>=D&&a<=D+l}inXRange(e,a){const{x:n,x2:r}=this.getProps(["x","x2"],a);return e>=n&&e<=r}inYRange(e,a){const{y:n,y2:r,height:i}=this.getProps(["y","y2","height"],a),o=Math.min(n,r),s=Math.max(n,r)+i;return e>=o&&e<=s}getCenterPoint(e){const{x:a,y:n,x2:r,y2:i,height:o}=this.getProps(["x","y","x2","y2","height"],e);return{x:(a+r)/2,y:(n+i+o)/2}}tooltipPosition(e){return this.getCenterPoint(e)}getRange(e){return e==="x"?this.width/2:this.height/2}}Flow.id="flow";Flow.defaults={colorFrom:"red",colorTo:"green",colorMode:"gradient",hoverColorFrom:(t,e)=>getHoverColor(e.colorFrom),hoverColorTo:(t,e)=>getHoverColor(e.colorTo)};Chart.register({SankeyController,Flow});const CACHE_KEY$2="dashboard-sankey-data";let i18n$2,afterPromises$2=!1,chart$1=null,transactions=[],autoConversion=!1,translations={category:null,unknown_category:null,in:null,out:null,unknown_source:null,unknown_dest:null,unknown_account:null,expense_account:null,revenue_account:null,budget:null,unknown_budget:null,all_money:null};const getColor=function(t){return t.includes(translations.revenue_account)?"forestgreen":t.includes("("+translations.in+",")?"green":t.includes(translations.budget)||t.includes(translations.unknown_budget)?"Orchid":t.includes("("+translations.out+",")?"MediumOrchid":t.includes(translations.all_money)?"blue":"red"};function getObjectName(t,e,a,n){if(t==="category"&&e!==null&&a==="in")return translations.category+' "'+e+'" ('+translations.in+(autoConversion?", "+n+")":")");if(t==="category"&&e===null&&a==="in")return translations.unknown_category+" ("+translations.in+(autoConversion?", "+n+")":")");if(t==="category"&&e!==null&&a==="out")return translations.category+' "'+e+'" ('+translations.out+(autoConversion?", "+n+")":")");if(t==="category"&&e===null&&a==="out")return translations.unknown_category+" ("+translations.out+(autoConversion?", "+n+")":")");if(t==="account"&&e===null&&a==="in")return translations.unknown_source+(autoConversion?" ("+n+")":"");if(t==="account"&&e!==null&&a==="in")return translations.revenue_account+'"'+e+'"'+(autoConversion?" ("+n+")":"");if(t==="account"&&e===null&&a==="out")return translations.unknown_dest+(autoConversion?" ("+n+")":"");if(t==="account"&&e!==null&&a==="out")return translations.expense_account+' "'+e+'"'+(autoConversion?" ("+n+")":"");if(t==="budget"&&e!==null)return translations.budget+' "'+e+'"'+(autoConversion?" ("+n+")":"");if(t==="budget"&&e===null)return translations.unknown_budget+(autoConversion?" ("+n+")":"");console.error('Cannot handle: type:"'+t+'", dir: "'+a+'"')}function getLabelName(t,e,a){if(t==="category"&&e!==null)return translations.category+' "'+e+'"'+(autoConversion?" ("+a+")":"");if(t==="category"&&e===null)return translations.unknown_category+(autoConversion?" ("+a+")":"");if(t==="account"&&e===null)return translations.unknown_account+(autoConversion?" ("+a+")":"");if(t==="account"&&e!==null)return e+(autoConversion?" ("+a+")":"");if(t==="budget"&&e!==null)return translations.budget+' "'+e+'"'+(autoConversion?" ("+a+")":"");if(t==="budget"&&e===null)return translations.unknown_budget+(autoConversion?" ("+a+")":"");console.error('Cannot handle: type:"'+t+'"')}const sankey=()=>({loading:!1,autoConversion:!1,generateOptions(){let t=getDefaultChartSettings("sankey"),e={},a={};for(let r in transactions)if(transactions.hasOwnProperty(r)){let i=transactions[r];for(let o in i.attributes.transactions)if(i.attributes.transactions.hasOwnProperty(o)){let s=i.attributes.transactions[o],l=this.autoConversion?s.native_code:s.currency_code,u=this.autoConversion?parseFloat(s.native_amount):parseFloat(s.amount),c;if(s.type==="deposit"){let d=getObjectName("category",s.category_name,"in",l),h=getObjectName("account",s.source_name,"in",l);a[d]=getLabelName("category",s.category_name,l),a[h]=getLabelName("account",s.source_name,l),c=h+"-"+d+"-"+l,e.hasOwnProperty(c)||(e[c]={from:h,to:d,amount:0}),e[c].amount+=u,c=d+"-"+translations.all_money+"-"+l,e.hasOwnProperty(c)||(e[c]={from:d,to:translations.all_money+(this.autoConversion?" ("+l+")":""),amount:0}),e[c].amount+=u}if(s.type==="withdrawal"){let d=getObjectName("budget",s.budget_name,"out",l);a[d]=getLabelName("budget",s.budget_name,l),c=translations.all_money+"-"+d+"-"+l,e.hasOwnProperty(c)||(e[c]={from:translations.all_money+(this.autoConversion?" ("+l+")":""),to:d,amount:0}),e[c].amount+=u;let h=getObjectName("category",s.category_name,"out",l);a[h]=getLabelName("category",s.category_name,l),c=d+"-"+h+"-"+l,e.hasOwnProperty(c)||(e[c]={from:d,to:h,amount:0}),e[c].amount+=u;let m=getObjectName("account",s.destination_name,"out",l);a[m]=getLabelName("account",s.destination_name,l),c=h+"-"+m+"-"+l,e.hasOwnProperty(c)||(e[c]={from:h,to:m,amount:0}),e[c].amount+=u}}}let n={label:"Firefly III dashboard sankey chart",data:[],colorFrom:r=>getColor(r.dataset.data[r.dataIndex].from),colorTo:r=>getColor(r.dataset.data[r.dataIndex].to),colorMode:"gradient",labels:a,size:"min"};for(let r in e)if(e.hasOwnProperty(r)){let i=e[r];n.data.push({from:i.from,to:i.to,flow:i.amount})}return t.data.datasets.push(n),t},drawChart(t){if(chart$1!==null){chart$1.data.datasets=t.data.datasets,chart$1.update();return}chart$1=new Chart(document.querySelector("#sankey-chart"),t)},getFreshData(){const t=window.store.get("cacheValid");let e=window.store.get(CACHE_KEY$2);if(t&&typeof e<"u"){transactions=e,this.drawChart(this.generateOptions()),this.loading=!1;return}let a={start:window.store.get("start").slice(0,10),end:window.store.get("end").slice(0,10),type:"withdrawal,deposit",page:1};this.downloadTransactions(a)},downloadTransactions(t){new Get$2().get(t).then(a=>{if(transactions=[...transactions,...a.data.data],parseInt(a.data.meta.pagination.total_pages)>t.page){t.page++,this.downloadTransactions(t);return}window.store.set(CACHE_KEY$2,transactions),this.drawChart(this.generateOptions()),this.loading=!1})},loadChart(){if(this.loading!==!0){if(this.loading=!0,transactions.length!==0){this.drawChart(this.generateOptions()),this.loading=!1;return}this.getFreshData()}},init(){transactions=[],Promise.all([getVariable("autoConversion",!1),getVariable("language","en-US")]).then(t=>{this.autoConversion=t[0],autoConversion=t[0],i18n$2=new I18n,i18n$2.locale=t[1],loadTranslations(i18n$2,t[1]).then(()=>{translations.all_money=i18n$2.t("firefly.all_money"),translations.category=i18n$2.t("firefly.category"),translations.in=i18n$2.t("firefly.money_flowing_in"),translations.out=i18n$2.t("firefly.money_flowing_out"),translations.unknown_category=i18n$2.t("firefly.unknown_category_plain"),translations.unknown_source=i18n$2.t("firefly.unknown_source_plain"),translations.unknown_dest=i18n$2.t("firefly.unknown_dest_plain"),translations.unknown_account=i18n$2.t("firefly.unknown_any_plain"),translations.unknown_budget=i18n$2.t("firefly.unknown_budget_plain"),translations.expense_account=i18n$2.t("firefly.expense_account"),translations.revenue_account=i18n$2.t("firefly.revenue_account"),translations.budget=i18n$2.t("firefly.budget"),afterPromises$2=!0,this.loadChart()})}),window.store.observe("end",()=>{afterPromises$2&&(this.transactions=[],this.loadChart())}),window.store.observe("autoConversion",t=>{afterPromises$2&&(this.autoConversion=t,this.loadChart())})}});let Get$1=class{get(e){return api.get("/api/v2/subscriptions",{params:e})}paid(e){return api.get("/api/v2/subscriptions/sum/paid",{params:e})}unpaid(e){return api.get("/api/v2/subscriptions/sum/unpaid",{params:e})}};const CACHE_KEY$1="dashboard-subscriptions-data";let chart=null,afterPromises$1=!1,i18n$1;const subscriptions=()=>({loading:!1,autoConversion:!1,loadChart(){this.loading!==!0&&(this.loading=!0,this.getFreshData())},drawChart(t){if(chart!==null){chart.data.datasets=t.data.datasets,chart.update();return}chart=new Chart(document.querySelector("#subscriptions-chart"),t)},getFreshData(){const t=window.store.get("cacheValid");let e=window.store.get(CACHE_KEY$1);if(t&&typeof e<"u"){this.drawChart(this.generateOptions(e)),this.loading=!1;return}const a=new Get$1;let n={start:format$1(new Date(window.store.get("start")),"y-MM-dd"),end:format$1(new Date(window.store.get("end")),"y-MM-dd")};a.paid(n).then(r=>{let i=r.data;a.unpaid(n).then(o=>{let s=o.data,l={paid:i,unpaid:s};window.store.set(CACHE_KEY$1,l),this.drawChart(this.generateOptions(l)),this.loading=!1})})},generateOptions(t){let e=getDefaultChartSettings("pie");e.data.labels=[i18n$1.t("firefly.paid"),i18n$1.t("firefly.unpaid")],e.data.datasets=[];let a={};for(let n in t.paid)if(t.paid.hasOwnProperty(n)){let r=t.paid[n],i=this.autoConversion?r.native_code:r.currency_code,o=this.autoConversion?r.native_sum:r.sum;a.hasOwnProperty(i)||(a[i]={paid:0,unpaid:0}),a[i].paid+=parseFloat(o)*-1}for(let n in t.unpaid)if(t.unpaid.hasOwnProperty(n)){let r=t.unpaid[n],i=this.autoConversion?r.native_code:r.currency_code,o=this.autoConversion?r.native_sum:r.sum;a.hasOwnProperty(i)||(a[i]={paid:0,unpaid:0}),a[i].unpaid+=parseFloat(o)}for(let n in a)if(a.hasOwnProperty(n)){let r=a[n];e.data.datasets.push({label:n,data:[r.paid,r.unpaid],backgroundColor:["rgb(54, 162, 235)","rgb(255, 99, 132)"]})}return e},init(){Promise.all([getVariable("autoConversion",!1),getVariable("language","en-US")]).then(t=>{this.autoConversion=t[0],afterPromises$1=!0,i18n$1=new I18n,i18n$1.locale=t[1],loadTranslations(i18n$1,t[1]).then(()=>{this.loading===!1&&this.loadChart()})}),window.store.observe("end",()=>{afterPromises$1&&this.loading===!1&&(this.chartData=null,this.loadChart())}),window.store.observe("autoConversion",t=>{afterPromises$1&&(this.autoConversion=t,this.loading===!1&&this.loadChart())})}});class Get{get(e){return api.get("/api/v2/piggy-banks",{params:e})}}let apiData={},afterPromises=!1,i18n;const CACHE_KEY="dashboard-piggies-data",piggies=()=>({loading:!1,autoConversion:!1,sankeyGrouping:"account",piggies:[],getFreshData(){const t=window.store.get("cacheValid");let e=window.store.get(CACHE_KEY);if(t&&typeof e<"u"){apiData=e,this.parsePiggies(),this.loading=!1;return}let a={start:window.store.get("start").slice(0,10),end:window.store.get("end").slice(0,10),page:1};this.downloadPiggyBanks(a)},downloadPiggyBanks(t){new Get().get(t).then(a=>{if(apiData=[...apiData,...a.data.data],parseInt(a.data.meta.pagination.total_pages)>t.page){t.page++,this.downloadPiggyBanks(t);return}window.store.set(CACHE_KEY,apiData),this.parsePiggies(),this.loading=!1})},parsePiggies(){let t=[];for(let e in apiData)if(apiData.hasOwnProperty(e)){let a=apiData[e];if(a.attributes.percentage>=100||a.attributes.percentage===0)continue;let n=a.object_group_title??i18n.t("firefly.default_group_title_name_plain");t.hasOwnProperty(n)||(t[n]={id:a.object_group_id??0,title:n,order:a.object_group_order??0,piggies:[]});let r={id:a.id,name:a.attributes.name,percentage:parseInt(a.attributes.percentage),amount:this.autoConversion?a.attributes.native_current_amount:a.attributes.current_amount,left_to_save:this.autoConversion?a.attributes.native_left_to_save:a.attributes.left_to_save,target_amount:this.autoConversion?a.attributes.native_target_amount:a.attributes.target_amount,save_per_month:this.autoConversion?a.attributes.native_save_per_month:a.attributes.save_per_month,currency_code:this.autoConversion?a.attributes.native_code:a.attributes.currency_code};t[n].piggies.push(r)}this.piggies=Object.values(t)},loadPiggyBanks(){if(this.loading!==!0){if(this.loading=!0,this.piggies.length!==0){this.parsePiggies(),this.loading=!1;return}this.getFreshData()}},init(){apiData=[],Promise.all([getVariable("autoConversion",!1),getVariable("language","en-US")]).then(t=>{i18n=new I18n,i18n.locale=t[1],loadTranslations(i18n,t[1]).then(()=>{afterPromises=!0,this.autoConversion=t[0],this.loadPiggyBanks()})}),window.store.observe("end",()=>{afterPromises&&(apiData=[],this.loadPiggyBanks())}),window.store.observe("autoConversion",t=>{afterPromises&&(this.autoConversion=t,this.loadPiggyBanks())})}});/*! * chartjs-adapter-date-fns v3.0.0 * https://www.chartjs.org * (c) 2022 chartjs-adapter-date-fns Contributors diff --git a/public/build/manifest.json b/public/build/manifest.json index 230c2a15fb..ad442b3012 100644 --- a/public/build/manifest.json +++ b/public/build/manifest.json @@ -30,10 +30,10 @@ "integrity": "sha384-B73JAwYNSgI4rwb14zwxigHgAkg1Ms+j6+9sJoDpiL11+VW5RjQCLfIh0RVoi0h6" }, "resources/assets/v2/pages/dashboard/dashboard.js": { - "file": "assets/dashboard-3bf5d492.js", + "file": "assets/dashboard-e6afec51.js", "isEntry": true, "src": "resources/assets/v2/pages/dashboard/dashboard.js", - "integrity": "sha384-VbU3St9S+FpNVXcyT3HOrAFKugS69Q2RP7bTQfzoGWwlKhO23L7kJhx513OQ9smw" + "integrity": "sha384-XD/DlmRXlkNFLzbZu2S6Wor6xmQinxFelQCpT7KvalJaKR8J8iwjp2I0Hqo9/sAH" }, "resources/assets/v2/sass/app.scss": { "file": "assets/app-28a195fd.css", diff --git a/resources/assets/v2/pages/dashboard/sankey.js b/resources/assets/v2/pages/dashboard/sankey.js index 76c2d2615c..c2e4432221 100644 --- a/resources/assets/v2/pages/dashboard/sankey.js +++ b/resources/assets/v2/pages/dashboard/sankey.js @@ -214,7 +214,7 @@ export default () => ({ if (!amounts.hasOwnProperty(flowKey)) { amounts[flowKey] = { - from: translations.all_money + ' (' + currencyCode + ')', + from: translations.all_money + (this.autoConversion ? ' (' + currencyCode + ')' : ''), to: budget, amount: 0 };