@squadbase/vantage 0.6.2-dev1.48b34e1 → 0.6.2-dev1.51e401a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-57GHR5LN.js → chunk-3RJEOP3J.js} +29 -18
- package/dist/chunk-3RJEOP3J.js.map +1 -0
- package/dist/{chunk-QOXXOFGL.js → chunk-77CISBMG.js} +994 -464
- package/dist/chunk-77CISBMG.js.map +1 -0
- package/dist/{chunk-JXFCSF3K.js → chunk-EG4PX726.js} +12 -7
- package/dist/chunk-EG4PX726.js.map +1 -0
- package/dist/{chunk-2N72FKLB.js → chunk-NZ5QIIG4.js} +33 -11
- package/dist/chunk-NZ5QIIG4.js.map +1 -0
- package/dist/{chunk-7S52M2SL.js → chunk-QNOX7WLZ.js} +3 -3
- package/dist/{chunk-7S52M2SL.js.map → chunk-QNOX7WLZ.js.map} +1 -1
- package/dist/{chunk-PDOBHMUQ.js → chunk-ROHNXP7J.js} +72 -3
- package/dist/chunk-ROHNXP7J.js.map +1 -0
- package/dist/{chunk-6OTTGAPO.js → chunk-TRMHNMMZ.js} +24 -7
- package/dist/chunk-TRMHNMMZ.js.map +1 -0
- package/dist/components/index.d.ts +49 -29
- package/dist/components/index.js +5 -5
- package/dist/{delta-text-CvwBGJ95.d.ts → delta-text-CbrOaW83.d.ts} +4 -2
- package/dist/doc/index.d.ts +14 -14
- package/dist/doc/index.js +198 -84
- package/dist/doc/index.js.map +1 -1
- package/dist/{format-U0cQl069.d.ts → format-DihQkL1N.d.ts} +17 -11
- package/dist/slide/index.d.ts +2 -2
- package/dist/slide/index.js +95 -44
- package/dist/slide/index.js.map +1 -1
- package/dist/table/index.js +6 -6
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +5 -5
- package/package.json +2 -2
- package/registry/ui/app-shell.tsx +138 -1
- package/registry/ui/area-chart.tsx +344 -85
- package/registry/ui/attention-list.tsx +177 -15
- package/registry/ui/bar-chart.tsx +341 -85
- package/registry/ui/bar-list.tsx +332 -77
- package/registry/ui/box-plot-chart.tsx +405 -97
- package/registry/ui/category-bar.tsx +248 -40
- package/registry/ui/chart-frame.tsx +257 -46
- package/registry/ui/data-table.tsx +229 -37
- package/registry/ui/date-range-picker.tsx +190 -36
- package/registry/ui/delta.tsx +171 -12
- package/registry/ui/donut-chart.tsx +339 -84
- package/registry/ui/echart.tsx +142 -4
- package/registry/ui/filter-bar.tsx +179 -20
- package/registry/ui/funnel-steps.tsx +354 -80
- package/registry/ui/heatmap.tsx +293 -52
- package/registry/ui/histogram-chart.tsx +395 -97
- package/registry/ui/kpi-card.tsx +245 -44
- package/registry/ui/legend.tsx +330 -76
- package/registry/ui/line-chart.tsx +344 -85
- package/registry/ui/multi-select.tsx +159 -9
- package/registry/ui/page-shell.tsx +141 -3
- package/registry/ui/paired-chart.tsx +349 -90
- package/registry/ui/progress-circle.tsx +205 -39
- package/registry/ui/sample-data.tsx +153 -9
- package/registry/ui/scatter-chart.tsx +391 -100
- package/registry/ui/searchable-select.tsx +145 -7
- package/registry/ui/states.tsx +170 -13
- package/registry/ui/status-badge.tsx +193 -28
- package/registry/ui/tracker.tsx +205 -39
- package/registry/ui/trend-indicator.tsx +149 -6
- package/registry/ui/updated-at.tsx +170 -16
- package/registry/ui/waterfall-chart.tsx +415 -102
- package/skills/vantage-add-feature/SKILL.md +5 -0
- package/templates/AGENTS.md +10 -8
- package/templates/agents/api.md +7 -0
- package/templates/agents/page.md +36 -0
- package/dist/chunk-2N72FKLB.js.map +0 -1
- package/dist/chunk-57GHR5LN.js.map +0 -1
- package/dist/chunk-6OTTGAPO.js.map +0 -1
- package/dist/chunk-JXFCSF3K.js.map +0 -1
- package/dist/chunk-PDOBHMUQ.js.map +0 -1
- package/dist/chunk-QOXXOFGL.js.map +0 -1
package/dist/slide/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { DeltaText } from '../chunk-
|
|
2
|
-
export { DeltaText } from '../chunk-
|
|
1
|
+
import { DeltaText } from '../chunk-TRMHNMMZ.js';
|
|
2
|
+
export { DeltaText } from '../chunk-TRMHNMMZ.js';
|
|
3
3
|
import { useSearchState } from '../chunk-ZO62C6T4.js';
|
|
4
4
|
import '../chunk-6S4BAIGV.js';
|
|
5
|
-
import { EChart } from '../chunk-
|
|
6
|
-
import { formatValue, EMPTY_VALUE } from '../chunk-
|
|
7
|
-
import '../chunk-
|
|
5
|
+
import { EChart } from '../chunk-EG4PX726.js';
|
|
6
|
+
import { formatValue, EMPTY_VALUE } from '../chunk-3RJEOP3J.js';
|
|
7
|
+
import { uiLanguage, useLocale } from '../chunk-ROHNXP7J.js';
|
|
8
8
|
import '../chunk-U736PVHY.js';
|
|
9
9
|
import { createContext, useRef, useState, useLayoutEffect, useContext, createElement, Children, isValidElement, useCallback, cloneElement, useMemo, useEffect } from 'react';
|
|
10
10
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
@@ -1700,8 +1700,13 @@ function SlideHeading({ title, eyebrow }) {
|
|
|
1700
1700
|
heading
|
|
1701
1701
|
] });
|
|
1702
1702
|
}
|
|
1703
|
+
var TEXT = {
|
|
1704
|
+
ja: { asOf: (asOf) => `${asOf} \u6642\u70B9`, source: (source) => `\u51FA\u5178: ${source}` },
|
|
1705
|
+
en: { asOf: (asOf) => `As of ${asOf}`, source: (source) => `Source: ${source}` }
|
|
1706
|
+
};
|
|
1703
1707
|
function SlideSourceLine({ asOf, source, page }) {
|
|
1704
|
-
const
|
|
1708
|
+
const t = TEXT[uiLanguage(useLocale())];
|
|
1709
|
+
const text = [asOf ? t.asOf(asOf) : null, source ? t.source(source) : null].filter(Boolean).join(" / ");
|
|
1705
1710
|
if (!text && !page) return null;
|
|
1706
1711
|
return /* @__PURE__ */ jsx(
|
|
1707
1712
|
"p",
|
|
@@ -1725,7 +1730,7 @@ var MAX_INSIGHTS = 3;
|
|
|
1725
1730
|
var MAX_INSIGHT_CHARS = 40;
|
|
1726
1731
|
var LINE_TYPES = ["solid", "dashed", "dotted"];
|
|
1727
1732
|
var SYMBOLS = ["circle", "rect", "triangle", "diamond"];
|
|
1728
|
-
function buildSlideChartOption(chart) {
|
|
1733
|
+
function buildSlideChartOption(chart, locale) {
|
|
1729
1734
|
return {
|
|
1730
1735
|
animation: false,
|
|
1731
1736
|
textStyle: { fontSize: SLIDE_SPEC.fontSize.caption },
|
|
@@ -1761,7 +1766,7 @@ function buildSlideChartOption(chart) {
|
|
|
1761
1766
|
axisLabel: {
|
|
1762
1767
|
fontSize: SLIDE_SPEC.fontSize.caption,
|
|
1763
1768
|
hideOverlap: true,
|
|
1764
|
-
formatter: (v) => formatValue(v, "compact")
|
|
1769
|
+
formatter: (v) => formatValue(v, "compact", locale)
|
|
1765
1770
|
}
|
|
1766
1771
|
},
|
|
1767
1772
|
...chart.type === "bar" && chart.series.length > 1 ? { aria: { enabled: true, decal: { show: true } } } : {},
|
|
@@ -1782,7 +1787,8 @@ function SlideChartInsight({ title, chart, insights, chartSide = "left", asOf, s
|
|
|
1782
1787
|
const hasSource = Boolean(asOf || source);
|
|
1783
1788
|
if (insights.some((t) => t.length > MAX_INSIGHT_CHARS)) console.warn(`SlideChartInsight: an insight is over ${MAX_INSIGHT_CHARS} characters; the column is narrow. Shorten it.`);
|
|
1784
1789
|
if (insights.length > MAX_INSIGHTS) console.warn(`SlideChartInsight: ${insights.length} insights; ${MAX_INSIGHTS} fit beside the chart. Split the slide.`);
|
|
1785
|
-
const
|
|
1790
|
+
const locale = useLocale();
|
|
1791
|
+
const option = useMemo(() => buildSlideChartOption(chart, locale), [chart, locale]);
|
|
1786
1792
|
const chartFirst = chartSide === "left";
|
|
1787
1793
|
const chartColumn = /* @__PURE__ */ jsx(SlideColumn, { span: 7, children: /* @__PURE__ */ jsx("div", { "data-waitfor": "canvas", style: { minHeight: 0, height: "100%" }, children: /* @__PURE__ */ jsx(EChart, { option, height: "100%", ariaLabel: title }) }) });
|
|
1788
1794
|
const insightsColumn = /* @__PURE__ */ jsx(SlideColumn, { span: 5, children: /* @__PURE__ */ jsx(
|
|
@@ -1843,11 +1849,16 @@ function SlideChartInsight({ title, chart, insights, chartSide = "left", asOf, s
|
|
|
1843
1849
|
}
|
|
1844
1850
|
);
|
|
1845
1851
|
}
|
|
1852
|
+
var TEXT2 = {
|
|
1853
|
+
ja: { asOf: (asOf) => `${asOf} \u6642\u70B9`, source: (source) => `\u51FA\u5178: ${source}`, separator: "\u3000|\u3000" },
|
|
1854
|
+
en: { asOf: (asOf) => `As of ${asOf}`, source: (source) => `Source: ${source}`, separator: " | " }
|
|
1855
|
+
};
|
|
1846
1856
|
function SlideCover({ title, subtitle, period, author, asOf, source }) {
|
|
1857
|
+
const t = TEXT2[uiLanguage(useLocale())];
|
|
1847
1858
|
const meta = [
|
|
1848
1859
|
period,
|
|
1849
1860
|
author,
|
|
1850
|
-
[asOf ?
|
|
1861
|
+
[asOf ? t.asOf(asOf) : null, source ? t.source(source) : null].filter(Boolean).join(" / ") || void 0
|
|
1851
1862
|
].filter(Boolean);
|
|
1852
1863
|
return /* @__PURE__ */ jsxs(
|
|
1853
1864
|
"section",
|
|
@@ -1909,7 +1920,7 @@ function SlideCover({ title, subtitle, period, author, asOf, source }) {
|
|
|
1909
1920
|
lineHeight: SLIDE_SPEC.lineHeight.body,
|
|
1910
1921
|
color: "var(--slide-muted)"
|
|
1911
1922
|
},
|
|
1912
|
-
children: meta.join(
|
|
1923
|
+
children: meta.join(t.separator)
|
|
1913
1924
|
}
|
|
1914
1925
|
)
|
|
1915
1926
|
]
|
|
@@ -2014,21 +2025,38 @@ function SlideExecSummary({ title, points, layout = "rows", asOf, source }) {
|
|
|
2014
2025
|
}
|
|
2015
2026
|
var MAX_ITEMS = 4;
|
|
2016
2027
|
var ARROW = { up: "\u25B2", down: "\u25BC", flat: "\u25AC" };
|
|
2017
|
-
var
|
|
2018
|
-
|
|
2028
|
+
var TEXT3 = {
|
|
2029
|
+
ja: {
|
|
2030
|
+
up: "\u5897",
|
|
2031
|
+
down: "\u6E1B",
|
|
2032
|
+
flat: "\u6A2A\u3070\u3044",
|
|
2033
|
+
target: (target) => `\u76EE\u6A19 ${target}`,
|
|
2034
|
+
attainment: (shown, rate) => `${shown}(\u9054\u6210\u7387 ${rate})`
|
|
2035
|
+
},
|
|
2036
|
+
en: {
|
|
2037
|
+
up: "Up",
|
|
2038
|
+
down: "Down",
|
|
2039
|
+
flat: "Flat",
|
|
2040
|
+
target: (target) => `Target ${target}`,
|
|
2041
|
+
attainment: (shown, rate) => `${shown} (${rate} attained)`
|
|
2042
|
+
}
|
|
2043
|
+
};
|
|
2044
|
+
function deltaView(delta, betterWhen, locale) {
|
|
2019
2045
|
const direction = delta.value > 0 ? "up" : delta.value < 0 ? "down" : "flat";
|
|
2020
2046
|
const color = direction === "flat" ? "var(--slide-muted)" : direction === betterWhen ? "var(--positive)" : "var(--negative)";
|
|
2021
|
-
const amount = formatValue(delta.value, delta.format,
|
|
2022
|
-
return { color, text: `${ARROW[direction]} ${
|
|
2047
|
+
const amount = formatValue(delta.value, delta.format, locale, { signDisplay: "exceptZero" });
|
|
2048
|
+
return { color, text: `${ARROW[direction]} ${TEXT3[uiLanguage(locale)][direction]} ${amount}` };
|
|
2023
2049
|
}
|
|
2024
|
-
function targetText(item) {
|
|
2050
|
+
function targetText(item, locale) {
|
|
2025
2051
|
if (item.target === void 0) return void 0;
|
|
2052
|
+
const t = TEXT3[uiLanguage(locale)];
|
|
2026
2053
|
const { value, target, betterWhen = "up" } = item;
|
|
2027
2054
|
const rate = value === null ? void 0 : betterWhen === "down" ? target / value : value / target;
|
|
2028
|
-
const shown =
|
|
2029
|
-
return rate === void 0 || !Number.isFinite(rate) ? shown :
|
|
2055
|
+
const shown = t.target(formatValue(target, item.format, locale));
|
|
2056
|
+
return rate === void 0 || !Number.isFinite(rate) ? shown : t.attainment(shown, formatValue(rate, { type: "percent", digits: 0 }, locale));
|
|
2030
2057
|
}
|
|
2031
2058
|
function SlideKpiGrid({ title, items, asOf, source }) {
|
|
2059
|
+
const locale = useLocale();
|
|
2032
2060
|
const hasSource = Boolean(asOf || source);
|
|
2033
2061
|
if (items.length > MAX_ITEMS) console.warn(`SlideKpiGrid: ${items.length} items; ${MAX_ITEMS} fit the canvas. Split the slide.`);
|
|
2034
2062
|
return /* @__PURE__ */ jsxs(
|
|
@@ -2062,8 +2090,8 @@ function SlideKpiGrid({ title, items, asOf, source }) {
|
|
|
2062
2090
|
alignItems: "center"
|
|
2063
2091
|
},
|
|
2064
2092
|
children: items.map((item, i) => {
|
|
2065
|
-
const delta = item.delta ? deltaView({ value: item.delta.value, format: item.delta.format ?? item.format }, item.betterWhen ?? "up") : void 0;
|
|
2066
|
-
const target = targetText(item);
|
|
2093
|
+
const delta = item.delta ? deltaView({ value: item.delta.value, format: item.delta.format ?? item.format }, item.betterWhen ?? "up", locale) : void 0;
|
|
2094
|
+
const target = targetText(item, locale);
|
|
2067
2095
|
return /* @__PURE__ */ jsxs(
|
|
2068
2096
|
"div",
|
|
2069
2097
|
{
|
|
@@ -2089,7 +2117,7 @@ function SlideKpiGrid({ title, items, asOf, source }) {
|
|
|
2089
2117
|
fontWeight: 700,
|
|
2090
2118
|
fontVariantNumeric: "tabular-nums"
|
|
2091
2119
|
},
|
|
2092
|
-
children: item.display ?? formatValue(item.value, item.format)
|
|
2120
|
+
children: item.display ?? formatValue(item.value, item.format, locale)
|
|
2093
2121
|
}
|
|
2094
2122
|
),
|
|
2095
2123
|
delta && /* @__PURE__ */ jsxs("span", { style: { fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.heading, fontWeight: 700, color: delta.color }, children: [
|
|
@@ -2113,16 +2141,21 @@ function SlideKpiGrid({ title, items, asOf, source }) {
|
|
|
2113
2141
|
);
|
|
2114
2142
|
}
|
|
2115
2143
|
var ARROW2 = { up: "\u25B2", down: "\u25BC", flat: "\u25AC" };
|
|
2116
|
-
var
|
|
2117
|
-
|
|
2144
|
+
var TEXT4 = {
|
|
2145
|
+
ja: { up: "\u5897", down: "\u6E1B", flat: "\u6A2A\u3070\u3044", trend: (label) => `${label}\u306E\u63A8\u79FB` },
|
|
2146
|
+
en: { up: "Up", down: "Down", flat: "Flat", trend: (label) => `${label} trend` }
|
|
2147
|
+
};
|
|
2148
|
+
function deltaView2(delta, betterWhen, locale) {
|
|
2118
2149
|
const direction = delta.value > 0 ? "up" : delta.value < 0 ? "down" : "flat";
|
|
2119
2150
|
const color = direction === "flat" ? "var(--slide-muted)" : direction === betterWhen ? "var(--positive)" : "var(--negative)";
|
|
2120
|
-
const amount = formatValue(delta.value, delta.format,
|
|
2121
|
-
return { color, text: `${ARROW2[direction]} ${
|
|
2151
|
+
const amount = formatValue(delta.value, delta.format, locale, { signDisplay: "exceptZero" });
|
|
2152
|
+
return { color, text: `${ARROW2[direction]} ${TEXT4[uiLanguage(locale)][direction]} ${amount}` };
|
|
2122
2153
|
}
|
|
2123
2154
|
function SlideKpiHero({ title, label, value, format, display, delta, betterWhen = "up", comparisonLabel, trend, asOf, source }) {
|
|
2155
|
+
const locale = useLocale();
|
|
2156
|
+
const t = TEXT4[uiLanguage(locale)];
|
|
2124
2157
|
const hasSource = Boolean(asOf || source);
|
|
2125
|
-
const deltaShown = delta ? deltaView2({ value: delta.value, format: delta.format ?? format }, betterWhen) : void 0;
|
|
2158
|
+
const deltaShown = delta ? deltaView2({ value: delta.value, format: delta.format ?? format }, betterWhen, locale) : void 0;
|
|
2126
2159
|
const option = useMemo(() => {
|
|
2127
2160
|
if (!trend || trend.length === 0) return void 0;
|
|
2128
2161
|
return {
|
|
@@ -2140,7 +2173,7 @@ function SlideKpiHero({ title, label, value, format, display, delta, betterWhen
|
|
|
2140
2173
|
yAxis: {
|
|
2141
2174
|
type: "value",
|
|
2142
2175
|
scale: true,
|
|
2143
|
-
axisLabel: { fontSize: SLIDE_SPEC.fontSize.caption, hideOverlap: true, formatter: (v) => formatValue(v, "compact") }
|
|
2176
|
+
axisLabel: { fontSize: SLIDE_SPEC.fontSize.caption, hideOverlap: true, formatter: (v) => formatValue(v, "compact", locale) }
|
|
2144
2177
|
},
|
|
2145
2178
|
series: [
|
|
2146
2179
|
{
|
|
@@ -2153,7 +2186,7 @@ function SlideKpiHero({ title, label, value, format, display, delta, betterWhen
|
|
|
2153
2186
|
}
|
|
2154
2187
|
]
|
|
2155
2188
|
};
|
|
2156
|
-
}, [trend]);
|
|
2189
|
+
}, [trend, locale]);
|
|
2157
2190
|
return /* @__PURE__ */ jsxs(
|
|
2158
2191
|
"section",
|
|
2159
2192
|
{
|
|
@@ -2198,7 +2231,7 @@ function SlideKpiHero({ title, label, value, format, display, delta, betterWhen
|
|
|
2198
2231
|
fontWeight: 700,
|
|
2199
2232
|
fontVariantNumeric: "tabular-nums"
|
|
2200
2233
|
},
|
|
2201
|
-
children: display ?? formatValue(value, format)
|
|
2234
|
+
children: display ?? formatValue(value, format, locale)
|
|
2202
2235
|
}
|
|
2203
2236
|
),
|
|
2204
2237
|
(deltaShown || comparisonLabel) && /* @__PURE__ */ jsxs("span", { style: { display: "flex", flexWrap: "wrap", alignItems: "baseline", gap: SLIDE_SPEC.space.sm, fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.heading }, children: [
|
|
@@ -2208,7 +2241,7 @@ function SlideKpiHero({ title, label, value, format, display, delta, betterWhen
|
|
|
2208
2241
|
]
|
|
2209
2242
|
}
|
|
2210
2243
|
) }),
|
|
2211
|
-
option && /* @__PURE__ */ jsx(SlideColumn, { span: 6, children: /* @__PURE__ */ jsx("div", { "data-waitfor": "canvas", style: { minHeight: 0, height: "100%" }, children: /* @__PURE__ */ jsx(EChart, { option, height: "100%", ariaLabel:
|
|
2244
|
+
option && /* @__PURE__ */ jsx(SlideColumn, { span: 6, children: /* @__PURE__ */ jsx("div", { "data-waitfor": "canvas", style: { minHeight: 0, height: "100%" }, children: /* @__PURE__ */ jsx(EChart, { option, height: "100%", ariaLabel: t.trend(label) }) }) })
|
|
2212
2245
|
] }),
|
|
2213
2246
|
hasSource && /* @__PURE__ */ jsx(SlideSourceLine, { asOf, source })
|
|
2214
2247
|
]
|
|
@@ -2217,14 +2250,19 @@ function SlideKpiHero({ title, label, value, format, display, delta, betterWhen
|
|
|
2217
2250
|
}
|
|
2218
2251
|
var MAX_ITEMS2 = 5;
|
|
2219
2252
|
var MAX_DUE_CHARS = 10;
|
|
2253
|
+
var HEADS = {
|
|
2254
|
+
ja: { owner: "\u62C5\u5F53", due: "\u671F\u9650", metric: "\u78BA\u8A8D\u3059\u308B\u6307\u6A19" },
|
|
2255
|
+
en: { owner: "Owner", due: "Due", metric: "Metric to watch" }
|
|
2256
|
+
};
|
|
2220
2257
|
function SlideNextActions({ title, items, asOf, source }) {
|
|
2258
|
+
const head = HEADS[uiLanguage(useLocale())];
|
|
2221
2259
|
const hasSource = Boolean(asOf || source);
|
|
2222
2260
|
if (items.length > MAX_ITEMS2) console.warn(`SlideNextActions: ${items.length} items; ${MAX_ITEMS2} fit the canvas. Split the slide.`);
|
|
2223
2261
|
if (items.some((it) => (it.due?.length ?? 0) > MAX_DUE_CHARS)) console.warn(`SlideNextActions: a due date is over ${MAX_DUE_CHARS} characters; the column is one line wide. Shorten it.`);
|
|
2224
2262
|
const cols = [
|
|
2225
|
-
{ key: "owner", head:
|
|
2226
|
-
{ key: "due", head:
|
|
2227
|
-
{ key: "metric", head:
|
|
2263
|
+
{ key: "owner", head: head.owner, fr: 2 },
|
|
2264
|
+
{ key: "due", head: head.due, fr: 2 },
|
|
2265
|
+
{ key: "metric", head: head.metric, fr: 3 }
|
|
2228
2266
|
];
|
|
2229
2267
|
const shown = cols.filter((c) => items.some((it) => it[c.key]));
|
|
2230
2268
|
const template = [`${SLIDE_SPEC.grid.columnWidth}px`, "minmax(0, 6fr)", ...shown.map((c) => `minmax(0, ${c.fr}fr)`)].join(" ");
|
|
@@ -2300,10 +2338,20 @@ function SlideNextActions({ title, items, asOf, source }) {
|
|
|
2300
2338
|
}
|
|
2301
2339
|
var MAX_ROWS = 8;
|
|
2302
2340
|
var DENSE_ROWS = 6;
|
|
2303
|
-
var
|
|
2304
|
-
on:
|
|
2305
|
-
risk:
|
|
2306
|
-
off:
|
|
2341
|
+
var STATUS_COLOR = {
|
|
2342
|
+
on: "var(--positive)",
|
|
2343
|
+
risk: "var(--warning)",
|
|
2344
|
+
off: "var(--negative)"
|
|
2345
|
+
};
|
|
2346
|
+
var TEXT5 = {
|
|
2347
|
+
ja: {
|
|
2348
|
+
status: { on: "\u9806\u8ABF", risk: "\u8981\u6CE8\u610F", off: "\u9045\u5EF6" },
|
|
2349
|
+
head: { metric: "\u6307\u6A19", target: "\u76EE\u6A19", actual: "\u5B9F\u7E3E", attainment: "\u9054\u6210\u7387", status: "\u72B6\u614B" }
|
|
2350
|
+
},
|
|
2351
|
+
en: {
|
|
2352
|
+
status: { on: "On track", risk: "At risk", off: "Off track" },
|
|
2353
|
+
head: { metric: "Metric", target: "Target", actual: "Actual", attainment: "Attainment", status: "Status" }
|
|
2354
|
+
}
|
|
2307
2355
|
};
|
|
2308
2356
|
function attainment(row) {
|
|
2309
2357
|
if (row.value === null || row.target === void 0) return void 0;
|
|
@@ -2311,9 +2359,11 @@ function attainment(row) {
|
|
|
2311
2359
|
return Number.isFinite(rate) ? rate : void 0;
|
|
2312
2360
|
}
|
|
2313
2361
|
function SlideScorecardTable({ title, rows, columns, asOf, source }) {
|
|
2362
|
+
const locale = useLocale();
|
|
2363
|
+
const t = TEXT5[uiLanguage(locale)];
|
|
2314
2364
|
const hasSource = Boolean(asOf || source);
|
|
2315
2365
|
if (rows.length > MAX_ROWS) console.warn(`SlideScorecardTable: ${rows.length} rows; ${MAX_ROWS} fit the canvas. Split the slide.`);
|
|
2316
|
-
const head = {
|
|
2366
|
+
const head = { ...t.head, ...columns };
|
|
2317
2367
|
const showAttainment = rows.some((r) => attainment(r) !== void 0);
|
|
2318
2368
|
const cellSize = rows.length > DENSE_ROWS ? SLIDE_SPEC.fontSize.caption : "var(--slide-size-body)";
|
|
2319
2369
|
const cell = {
|
|
@@ -2353,13 +2403,13 @@ function SlideScorecardTable({ title, rows, columns, asOf, source }) {
|
|
|
2353
2403
|
] }) }),
|
|
2354
2404
|
/* @__PURE__ */ jsx("tbody", { children: rows.map((r, i) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
2355
2405
|
/* @__PURE__ */ jsx("th", { scope: "row", style: { ...cell, fontWeight: 700 }, children: r.metric }),
|
|
2356
|
-
/* @__PURE__ */ jsx("td", { style: num, children: r.target === void 0 ? EMPTY_VALUE : formatValue(r.target, r.format) }),
|
|
2357
|
-
/* @__PURE__ */ jsx("td", { style: { ...num, fontWeight: 700 }, children: r.display ?? formatValue(r.value, r.format) }),
|
|
2358
|
-
showAttainment && /* @__PURE__ */ jsx("td", { style: num, children: attainment(r) === void 0 ? EMPTY_VALUE : formatValue(attainment(r), { type: "percent", digits: 0 }) }),
|
|
2406
|
+
/* @__PURE__ */ jsx("td", { style: num, children: r.target === void 0 ? EMPTY_VALUE : formatValue(r.target, r.format, locale) }),
|
|
2407
|
+
/* @__PURE__ */ jsx("td", { style: { ...num, fontWeight: 700 }, children: r.display ?? formatValue(r.value, r.format, locale) }),
|
|
2408
|
+
showAttainment && /* @__PURE__ */ jsx("td", { style: num, children: attainment(r) === void 0 ? EMPTY_VALUE : formatValue(attainment(r), { type: "percent", digits: 0 }, locale) }),
|
|
2359
2409
|
/* @__PURE__ */ jsxs("td", { style: cell, children: [
|
|
2360
|
-
/* @__PURE__ */ jsx("span", { "aria-hidden": true, style: { color:
|
|
2410
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, style: { color: STATUS_COLOR[r.status] }, children: "\u25CF" }),
|
|
2361
2411
|
" ",
|
|
2362
|
-
|
|
2412
|
+
t.status[r.status]
|
|
2363
2413
|
] })
|
|
2364
2414
|
] }, i)) })
|
|
2365
2415
|
] }) }),
|
|
@@ -2400,6 +2450,7 @@ function SlideChartFull({ title, chart, note, asOf, source }) {
|
|
|
2400
2450
|
var MAX_POINTS2 = 3;
|
|
2401
2451
|
var MAX_POINT_CHARS = 24;
|
|
2402
2452
|
function SlideComparison({ title, columns, verdict, asOf, source }) {
|
|
2453
|
+
const locale = useLocale();
|
|
2403
2454
|
const hasSource = Boolean(asOf || source);
|
|
2404
2455
|
if (columns.length < 2 || columns.length > 3) console.warn(`SlideComparison: ${columns.length} columns; 2\u20133 fit. Split the slide.`);
|
|
2405
2456
|
if (columns.some((c) => c.points.length > MAX_POINTS2 || c.points.some((t) => t.length > MAX_POINT_CHARS)))
|
|
@@ -2425,7 +2476,7 @@ function SlideComparison({ title, columns, verdict, asOf, source }) {
|
|
|
2425
2476
|
children: [
|
|
2426
2477
|
/* @__PURE__ */ jsx(SlideHeading, { title }),
|
|
2427
2478
|
/* @__PURE__ */ jsx(SlideColumns, { children: columns.map((col, i) => {
|
|
2428
|
-
const main = col.display ?? (col.value === void 0 ? void 0 : col.value === null ? "\u2014" : formatValue(col.value, col.format));
|
|
2479
|
+
const main = col.display ?? (col.value === void 0 ? void 0 : col.value === null ? "\u2014" : formatValue(col.value, col.format, locale));
|
|
2429
2480
|
return /* @__PURE__ */ jsx(SlideColumn, { span, children: /* @__PURE__ */ jsxs(
|
|
2430
2481
|
"div",
|
|
2431
2482
|
{
|