Skip to content

Commit de9a6c8

Browse files
committed
feat(chat): replace Analyze CTA with button inside input bar and refine analysis prompt
1 parent de725c9 commit de9a6c8

1 file changed

Lines changed: 45 additions & 25 deletions

File tree

src/Dashboard/frontend/src/components/ChatView.vue

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,24 +1339,7 @@
13391339

13401340
<!-- Input bar -->
13411341
<div class="input-area">
1342-
<!-- One-click Analyze when files are attached (above the input wrapper) -->
1343-
<div
1344-
v-if="readyAttachments.length && messages.length === 0"
1345-
class="attach-analyze-row"
1346-
>
1347-
<button
1348-
class="attach-analyze-btn"
1349-
:disabled="streaming"
1350-
@click="sendQuestion(analyzePrompt)"
1351-
:title="`Inspect ${readyAttachments.length} attached file${readyAttachments.length > 1 ? 's' : ''} and surface FinOps insights`"
1352-
>
1353-
<span
1354-
>Analyze {{ readyAttachments.length }} file{{
1355-
readyAttachments.length > 1 ? "s" : ""
1356-
}}</span
1357-
>
1358-
</button>
1359-
</div>
1342+
<!-- (Removed) Analyze CTA above input — replaced by the Analyze button inside the input bar. -->
13601343

13611344
<div
13621345
class="input-wrapper"
@@ -2907,6 +2890,43 @@ function buildEChartsOption(raw) {
29072890
Array.isArray(d) ? String(d[0]) : d.name,
29082891
);
29092892
2893+
// X-axis label formatter: wrap long category names onto 2 lines so they're
2894+
// readable without going horizontal. Splits on spaces, dashes, dots, slashes.
2895+
// Falls back to a hard mid-string break if there is no separator.
2896+
const wrapXLabel = (raw) => {
2897+
const s = String(raw ?? "");
2898+
if (s.length <= 14) return s;
2899+
// Find the best mid-ish split character
2900+
const seps = [/\s+/, /-/, /\./, /\//];
2901+
for (const re of seps) {
2902+
const parts = s.split(re);
2903+
if (parts.length >= 2) {
2904+
// Greedy 2-line wrap aiming for balance
2905+
const half = Math.ceil(parts.length / 2);
2906+
const a = parts.slice(0, half).join(" ");
2907+
const b = parts.slice(half).join(" ");
2908+
return `${a}\n${b}`;
2909+
}
2910+
}
2911+
// Hard split
2912+
const mid = Math.ceil(s.length / 2);
2913+
return `${s.slice(0, mid)}\n${s.slice(mid)}`;
2914+
};
2915+
// Decide rotation: only rotate if the longest single label is huge AND many
2916+
// categories — otherwise prefer the 2-line wrap which stays horizontal.
2917+
const longest = categories.reduce((m, c) => Math.max(m, String(c).length), 0);
2918+
const xRotate = categories.length > 14 && longest > 18 ? 30 : 0;
2919+
const xAxisLabel = {
2920+
fontSize: 11,
2921+
color: "#1f2328",
2922+
fontWeight: 500,
2923+
interval: 0,
2924+
rotate: xRotate,
2925+
lineHeight: 13,
2926+
formatter: wrapXLabel,
2927+
};
2928+
const yAxisLabel = { fontSize: 11, color: "#1f2328", fontWeight: 500 };
2929+
29102930
// Detect multi-series: objects with keys beyond "name" and "value"
29112931
const firstItem = dataArr[0];
29122932
const isMultiSeries =
@@ -2940,14 +2960,14 @@ function buildEChartsOption(raw) {
29402960
name: xAxisName,
29412961
nameLocation: "center",
29422962
nameGap: 30,
2943-
axisLabel: { fontSize: 10, rotate: categories.length > 10 ? 45 : 0 },
2963+
axisLabel: xAxisLabel,
29442964
},
29452965
yAxis: {
29462966
type: "value",
29472967
name: yAxisName,
29482968
nameLocation: "center",
29492969
nameGap: 45,
2950-
axisLabel: { fontSize: 10 },
2970+
axisLabel: yAxisLabel,
29512971
},
29522972
series: seriesKeys.map((key) => ({
29532973
name: key,
@@ -2987,14 +3007,14 @@ function buildEChartsOption(raw) {
29873007
name: xAxisName,
29883008
nameLocation: "center",
29893009
nameGap: 30,
2990-
axisLabel: { fontSize: 10, rotate: categories.length > 10 ? 45 : 0 },
3010+
axisLabel: xAxisLabel,
29913011
},
29923012
yAxis: {
29933013
type: "value",
29943014
name: yAxisName,
29953015
nameLocation: "center",
29963016
nameGap: 45,
2997-
axisLabel: { fontSize: 10 },
3017+
axisLabel: yAxisLabel,
29983018
},
29993019
series: seriesKeys.map((key, idx) => ({
30003020
name: key,
@@ -3022,14 +3042,14 @@ function buildEChartsOption(raw) {
30223042
name: xAxisName,
30233043
nameLocation: "center",
30243044
nameGap: 30,
3025-
axisLabel: { fontSize: 10, rotate: categories.length > 10 ? 45 : 0 },
3045+
axisLabel: xAxisLabel,
30263046
},
30273047
yAxis: {
30283048
type: "value",
30293049
name: yAxisName,
30303050
nameLocation: "center",
30313051
nameGap: 45,
3032-
axisLabel: { fontSize: 10 },
3052+
axisLabel: yAxisLabel,
30333053
},
30343054
series: [
30353055
{
@@ -3869,7 +3889,7 @@ async function requestAnalyze() {
38693889
const list = readyAttachments.value;
38703890
if (list.length) {
38713891
const names = list.map((a) => `'${a.fileName}'`).join(", ");
3872-
input.value = `Analyze the uploaded file${list.length > 1 ? "s" : ""} ${names}. Find the biggest cost waste and tell me exactly what to do about it. Only use data from the upload — do not give generic advice.`;
3892+
input.value = `Analyze the uploaded file${list.length > 1 ? "s" : ""} ${names}. Find the biggest cost waste and tell me exactly what to do about it.`;
38733893
} else {
38743894
input.value =
38753895
"Find the biggest cost waste and tell me what to do about it.";

0 commit comments

Comments
 (0)