@railzai/railz-visualizations
Version:
Railz.ai Visualizations
321 lines (316 loc) • 17.7 kB
JavaScript
/*!
* Accounting Data as a Service™ is the solution that makes sense of your business customers' financial data.
* Built with Stencil
* Copyright (c) FIS.
*/
import { proxyCustomElement, HTMLElement, h } from '@stencil/core/internal/client';
import { T as Translations } from './en.js';
import { j as format, l as parseISO, m as RAILZ_DATE_FORMAT, e as errorLog, p as pick, R as RequestServiceInstance, r as isNil, g as getConfiguration, C as ConfigurationInstance, a as getFilter, b as getOptions, v as validateRequiredParams, x as isBusinessValuations, o as handleError, c as getTitleByReportType, s as formatCurrencyValue } from './chart.utils.js';
import { g as RVReportTypesUrlMapping } from './financial-ratios.js';
import { d as defineCustomElement$3 } from './error-image.js';
import { d as defineCustomElement$2 } from './loading.js';
import { d as defineCustomElement$1 } from './tooltip.js';
import { i as isEqual } from './isEqual.js';
import { i as isEmpty } from './isEmpty.js';
/**
* Percentage change calculation, 2 decimal places
*/
const getPercentageChange = (value1, value2) => {
if (isNil(value1) || isNil(value2) || value2 === 0) {
return null;
}
return Math.round(((value1 - value2) / value2) * 10000) / 100;
};
const getBusinessValuationsParams = (data) => {
var _a;
let liquidation = null;
let discountedCashflow = null;
let multipleToRevenue = null;
let firstChicago = null;
let liquidationPercentageChange = null;
let discountedCashflowPercentageChange = null;
let multipleToRevenuePercentageChange = null;
let firstChicagoPercentageChange = null;
let latestEndDate = null;
if (data === null || data === void 0 ? void 0 : data.reports) {
const reports = data.reports;
if (reports.length >= 1) {
// get latest report data
latestEndDate = reports[0].meta.updatedAt;
liquidation = reports[0].data.liquidationValue;
discountedCashflow = reports[0].data.discountedCashflowValue;
multipleToRevenue = reports[0].data.multipleToRevenueValue;
firstChicago = reports[0].data.firstChicagoValue;
}
if (reports.length >= 2) {
// liquidation percentage change over two reports
const liquidation2 = (_a = reports[reports.length - 1]) === null || _a === void 0 ? void 0 : _a.data.liquidationValue;
liquidationPercentageChange = getPercentageChange(liquidation, liquidation2);
// discountedCashflow percentage change over two reports
const discountedCashflow2 = reports[reports.length - 1].data.discountedCashflowValue;
discountedCashflowPercentageChange = getPercentageChange(discountedCashflow, discountedCashflow2);
// multipleToRevenue percentage change over two reports
const multipleToRevenue2 = reports[reports.length - 1].data.multipleToRevenueValue;
multipleToRevenuePercentageChange = getPercentageChange(multipleToRevenue, multipleToRevenue2);
// firstChicago percentage change over two reports
const firstChicago2 = reports[reports.length - 1].data.firstChicagoValue;
firstChicagoPercentageChange = getPercentageChange(firstChicago, firstChicago2);
}
}
return {
liquidation,
discountedCashflow,
multipleToRevenue,
firstChicago,
liquidationPercentageChange,
discountedCashflowPercentageChange,
multipleToRevenuePercentageChange,
firstChicagoPercentageChange,
latestEndDate,
};
};
/**
* Make API call to business valuations report
*/
const getReportData = async ({ filter, }) => {
let reportData;
try {
let startDate;
let endDate;
try {
startDate = format(parseISO(filter.startDate), RAILZ_DATE_FORMAT);
}
catch (error) {
errorLog(Translations.RV_ERROR_START_DATE);
}
try {
endDate = format(parseISO(filter.endDate), RAILZ_DATE_FORMAT);
}
catch (error) {
errorLog(Translations.RV_ERROR_END_DATE);
}
const allParameters = pick(Object.assign(Object.assign({}, filter), { startDate, endDate }), [
'startDate',
'endDate',
'connectionUuid',
]);
allParameters.offset = 0;
allParameters.limit = 100;
allParameters.orderBy = '-endDate';
reportData = await RequestServiceInstance.getReportData({
path: RVReportTypesUrlMapping[filter.reportType],
filter: allParameters,
});
}
catch (error) {
errorLog(Translations.RV_NOT_ABLE_TO_RETRIEVE_REPORT_DATA, error);
reportData = { error };
}
return reportData;
};
const businessValuationsCss = "@font-face{font-family:Inter;src:url(\"../assets/fonts/Inter-italic-var.woff2\");font-family:Inter;src:url(\"../assets/fonts/Inter-upright-var.woff2\")}body,div[class^=railz-],div[class*=\" railz-\"]{font-family:Inter, Roboto, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}.rv-container{display:flex;padding:16px;position:relative;border:1px solid #eee;border-radius:7px;flex-direction:column;justify-content:space-between;width:auto}.rv-container p{margin-block:0}.rv-container *{font-family:Inter, Roboto, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}.rv-header-container{display:flex;flex-direction:row;justify-content:space-between}.rv-valuation-group{width:calc(50% - 24px);min-width:480px;display:flex;justify-content:flex-start;margin-right:24px}@media screen and (max-width: 500px){.rv-valuation-group{flex-direction:column;min-width:780px}}.rv-valuation-section{display:flex;flex-direction:column;justify-content:space-between;align-items:flex-start;padding-bottom:8px;overflow:visible;flex-basis:50%;min-width:240px}@media screen and (min-width: 500px){.rv-valuation-section .rv-valuation-title{padding-left:24px}}@media screen and (min-width: 500px){.rv-valuation-section .rv-valuation-value-row{padding-left:24px;border-left:thin solid #e0e0e0}}@media screen and (min-width: 500px){.rv-valuation-section:first-child .rv-valuation-title{margin-left:-25px}}@media screen and (min-width: 500px){.rv-valuation-section:first-child .rv-valuation-value-row{margin-left:-25px}}.rv-valuation-container{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:center;width:100%;height:100%;padding-top:8px;overflow:hidden}@media screen and (min-width: 500px){.rv-valuation-container{row-gap:15px}}.rv-title{display:flex;color:#015b7e;font-size:18px;font-weight:600;margin:0;padding:0;text-align:left;flex-grow:1;line-height:1.235;align-items:baseline}.rv-valuation-title{font-weight:600;font-size:14px;color:#000;padding-bottom:6px}.rv-valuation-value-row{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;width:100%;height:100%}.rv-valuation-value{color:#212121;-webkit-font-smoothing:antialiased;font-size:24px;font-weight:600}.rv-valuation-percentage{font-weight:500;-webkit-font-smoothing:antialiased;font-size:14px}.rv-income-statements-chart-percentage{visibility:inherit;-webkit-font-smoothing:antialiased;margin:0;line-height:1.5;display:flex;flex-direction:row;font-size:14px;font-weight:500;padding-left:8px}.rv-income-statements-chart-percentage .rv-positive{color:#006037}.rv-income-statements-chart-percentage .rv-negative{color:#b30000}.rv-score-last-updated{align-self:center;text-align:center;font-size:12px;color:#757575;font-weight:500;line-height:28px}";
const renderPercentageChange = (percentage, options) => {
var _a, _b, _c, _d;
if (percentage < 0) {
return (h("div", { class: "rv-negative", style: (_b = (_a = options === null || options === void 0 ? void 0 : options.chart) === null || _a === void 0 ? void 0 : _a.pie) === null || _b === void 0 ? void 0 : _b.negative }, "\u25BC ", Math.abs(percentage), "%"));
}
else {
return (h("div", { class: "rv-positive", style: (_d = (_c = options === null || options === void 0 ? void 0 : options.chart) === null || _c === void 0 ? void 0 : _c.pie) === null || _d === void 0 ? void 0 : _d.positive }, "\u25B2", ' ', isNil(percentage) || isNaN(percentage) || Math.abs(percentage) === Infinity
? 0
: Math.abs(percentage), "%"));
}
};
const ValuationSection = (title, value, percentage, options) => {
const parsedValue = formatCurrencyValue(Math.round(value), 0, 'N/A');
const parsedPercentage = isNil(percentage) || isNaN(percentage) || Math.abs(percentage) === Infinity
? null
: renderPercentageChange(percentage, options);
return (h("div", { class: "rv-valuation-section" }, h("p", { class: "rv-valuation-title" }, title), h("div", { class: "rv-valuation-value-row" }, h("p", { class: "rv-valuation-value" }, parsedValue), h("div", { class: "rv-income-statements-chart-percentage" }, parsedPercentage))));
};
const BusinessValuations = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
constructor() {
super();
this.__registerHost();
this.__attachShadow();
this.loading = '';
this.updateBusinessValuationsParams = (summary) => {
const params = getBusinessValuationsParams(summary);
if (params) {
this.loading = '';
this.liquidationValue = params.liquidation;
this.discountedCashflowValue = params.discountedCashflow;
this.multipleToRevenueValue = params.multipleToRevenue;
this.firstChicagoValue = params.firstChicago;
this.liquidationPercentageChange = params.liquidationPercentageChange;
this.discountedCashflowPercentageChange = params.discountedCashflowPercentageChange;
this.multipleToRevenuePercentageChange = params.multipleToRevenuePercentageChange;
this.firstChicagoPercentageChange = params.firstChicagoPercentageChange;
}
};
/**
* Validates if configuration was passed correctly before setting filter
* @param configuration - Config for authentication
* @param filter - filter to decide chart type to show
* @param options: Whitelabeling options
* @param triggerRequest - indicate if api request should be made
*/
this.validateParams = async (configuration, filter, options, triggerRequest = true) => {
this._configuration = getConfiguration(configuration);
if (this._configuration) {
ConfigurationInstance.configuration = this._configuration;
try {
this._filter = getFilter(filter);
this._options = getOptions(options);
if (validateRequiredParams(this._filter)) {
if (isBusinessValuations(this._filter.reportType)) {
if (triggerRequest) {
await this.requestReportData();
}
}
else {
this.errorStatusCode = 500;
errorLog(Translations.RV_ERROR_INVALID_REPORT_TYPE);
}
}
else {
this.errorStatusCode = 204;
}
}
catch (e) {
this.errorStatusCode = 500;
errorLog(e);
}
}
else {
this.errorStatusCode = 0;
}
};
this.propsUpdated = async (triggerRequest = true) => {
await this.validateParams(this.configuration, this.filter, this.options, triggerRequest);
};
/**
* Request report data based on filter and configuration param
* Formats retrieved data into Highcharts format using formatData
*/
this.requestReportData = async () => {
this.errorStatusCode = undefined;
this.loading = Translations.RV_LOADING_REPORT;
try {
const reportData = (await getReportData({
filter: this._filter,
}));
if (reportData === null || reportData === void 0 ? void 0 : reportData.reports) {
this.updateBusinessValuationsParams(reportData);
}
else {
this.errorStatusCode = handleError(reportData);
}
}
catch (error) {
errorLog(Translations.RV_NOT_ABLE_TO_PARSE_REPORT_DATA, error);
}
finally {
this.loading = '';
}
};
}
async watchConfiguration(newValue, oldValue) {
if (newValue && oldValue && !isEqual(oldValue, newValue)) {
await this.validateParams(newValue, this.filter, this.options);
}
}
async watchFilter(newValue, oldValue) {
if (newValue && oldValue && !isEqual(oldValue, newValue)) {
await this.validateParams(this.configuration, newValue, this.options);
}
}
async watchOptions(newValue, oldValue) {
if (newValue && oldValue && !isEqual(oldValue, newValue)) {
await this.validateParams(this.configuration, this.filter, newValue);
}
}
componentWillLoad() {
this.propsUpdated && this.propsUpdated();
}
render() {
var _a, _b, _c, _d;
const TitleElement = () => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
return (h("p", { class: "rv-title", style: (_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.title) === null || _b === void 0 ? void 0 : _b.style }, ((_d = (_c = this._options) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.title) || getTitleByReportType((_e = this._filter) === null || _e === void 0 ? void 0 : _e.reportType) || '', ' ', ((_g = (_f = this._options) === null || _f === void 0 ? void 0 : _f.tooltipIndicator) === null || _g === void 0 ? void 0 : _g.visible) === false ? ('') : (h("railz-tooltip", { tooltipStyle: Object.assign(Object.assign({ position: 'bottom-center' }, (_h = this._options) === null || _h === void 0 ? void 0 : _h.tooltipIndicator), { style: Object.assign({ marginLeft: '6px' }, (_k = (_j = this._options) === null || _j === void 0 ? void 0 : _j.tooltipIndicator) === null || _k === void 0 ? void 0 : _k.style) }), tooltipText: ((_o = (_m = (_l = this._options) === null || _l === void 0 ? void 0 : _l.content) === null || _m === void 0 ? void 0 : _m.tooltip) === null || _o === void 0 ? void 0 : _o.description) ||
Translations.RV_TOOLTIP_BUSINESS_VALUATION }))));
};
const renderMain = () => {
var _a, _b;
if (isEmpty(this.loading) &&
this.errorStatusCode === undefined &&
isNil(this.liquidationValue) &&
isNil(this.discountedCashflowValue) &&
isNil(this.multipleToRevenueValue) &&
isNil(this.firstChicagoValue)) {
// if it's not loading and all are empty, show no data error
this.errorStatusCode = 204;
}
if (this.errorStatusCode !== undefined) {
return (h("railz-error-image", Object.assign({ statusCode: this.errorStatusCode || 500 }, (_a = this._options) === null || _a === void 0 ? void 0 : _a.errorIndicator)));
}
if (!isEmpty(this.loading)) {
return h("railz-loading", Object.assign({ loadingText: this.loading }, (_b = this._options) === null || _b === void 0 ? void 0 : _b.loadingIndicator));
}
return (h("div", { class: "rv-valuation-container" }, h("div", { class: "rv-valuation-group" }, ValuationSection(Translations.RV_BUSINESS_VALUATIONS_LIQUIDATION_VALUE, this.liquidationValue, this.liquidationPercentageChange, this._options), ValuationSection(Translations.RV_BUSINESS_VALUATIONS_DISCOUNTED_CASH_FLOW, this.discountedCashflowValue, this.discountedCashflowPercentageChange, this._options)), h("div", { class: "rv-valuation-group" }, ValuationSection(Translations.RV_BUSINESS_VALUATIONS_MULTIPLE_TO_REVENUE, this.multipleToRevenueValue, this.multipleToRevenuePercentageChange, this._options), ValuationSection(Translations.RV_BUSINESS_VALUATIONS_FIRST_CHICAGO, this.firstChicagoValue, this.firstChicagoPercentageChange, this._options))));
};
return (h("div", { class: "rv-container", style: (_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.container) === null || _b === void 0 ? void 0 : _b.style }, h("div", { class: "rv-header-container" }, ((_d = (_c = this._options) === null || _c === void 0 ? void 0 : _c.title) === null || _d === void 0 ? void 0 : _d.visible) === false ? '' : h(TitleElement, null)), renderMain()));
}
static get watchers() { return {
"configuration": ["watchConfiguration"],
"filter": ["watchFilter"],
"options": ["watchOptions"]
}; }
static get style() { return businessValuationsCss; }
}, [1, "railz-business-valuations", {
"configuration": [16],
"filter": [16],
"options": [16],
"_options": [32],
"loading": [32],
"_configuration": [32],
"_filter": [32],
"errorStatusCode": [32],
"liquidationValue": [32],
"discountedCashflowValue": [32],
"multipleToRevenueValue": [32],
"firstChicagoValue": [32],
"liquidationPercentageChange": [32],
"discountedCashflowPercentageChange": [32],
"multipleToRevenuePercentageChange": [32],
"firstChicagoPercentageChange": [32]
}]);
function defineCustomElement() {
if (typeof customElements === "undefined") {
return;
}
const components = ["railz-business-valuations", "railz-error-image", "railz-loading", "railz-tooltip"];
components.forEach(tagName => { switch (tagName) {
case "railz-business-valuations":
if (!customElements.get(tagName)) {
customElements.define(tagName, BusinessValuations);
}
break;
case "railz-error-image":
if (!customElements.get(tagName)) {
defineCustomElement$3();
}
break;
case "railz-loading":
if (!customElements.get(tagName)) {
defineCustomElement$2();
}
break;
case "railz-tooltip":
if (!customElements.get(tagName)) {
defineCustomElement$1();
}
break;
} });
}
export { BusinessValuations as B, defineCustomElement as d };
//# sourceMappingURL=business-valuations.js.map