@adminforth/dashboard 1.11.0 → 1.11.2
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/custom/skills/adminforth-dashboard/SKILL.md +4 -0
- package/custom/widgets/KpiCardWidget.vue +3 -3
- package/custom/widgets/chart/StackedBarChart.vue +6 -2
- package/dist/custom/skills/adminforth-dashboard/SKILL.md +4 -0
- package/dist/custom/widgets/KpiCardWidget.vue +3 -3
- package/dist/custom/widgets/chart/StackedBarChart.vue +6 -2
- package/package.json +1 -1
|
@@ -476,6 +476,10 @@ query:
|
|
|
476
476
|
|
|
477
477
|
Do not use bare query.steps without source: steps.
|
|
478
478
|
Do not use metric. Use select even when a step has only one aggregate.
|
|
479
|
+
All filters, including aggregate select item filters, must use filter expression shape.
|
|
480
|
+
Use `filters: { field: model, eq: gpt-5.4 }`, not shorthand maps like `filters: { model: gpt-5.4 }`.
|
|
481
|
+
When grouping by a derived date alias, repeat the source field object in `group_by`.
|
|
482
|
+
Example: if `select` has `{ field: used_at, grain: day, as: day }`, use `group_by: [{ field: used_at, grain: day, as: day }]`, not `group_by: [day]`.
|
|
479
483
|
|
|
480
484
|
## Date range rules
|
|
481
485
|
|
|
@@ -124,9 +124,9 @@ const label = computed(() => kpiConfig.value?.subtitle?.field
|
|
|
124
124
|
.join(': ')
|
|
125
125
|
: kpiConfig.value?.subtitle?.text ?? kpiConfig.value?.title ?? props.widget.label)
|
|
126
126
|
const formattedValue = computed(() => `${kpiConfig.value?.value.prefix ?? ''}${formatValue(value.value, kpiConfig.value?.value.format)}${kpiConfig.value?.value.suffix ?? ''}`)
|
|
127
|
-
const comparisonValue = computed(() =>
|
|
128
|
-
? firstRow.value[kpiConfig.value.comparison.field]
|
|
129
|
-
:
|
|
127
|
+
const comparisonValue = computed(() => kpiConfig.value?.comparison?.field
|
|
128
|
+
? value.value - toFiniteNumber(firstRow.value[kpiConfig.value.comparison.field])
|
|
129
|
+
: 0)
|
|
130
130
|
const comparison = computed(() => {
|
|
131
131
|
const config = kpiConfig.value?.comparison
|
|
132
132
|
|
|
@@ -120,7 +120,7 @@ const { el: rootEl, width: rootWidth } = useElementSize<HTMLDivElement>()
|
|
|
120
120
|
const { el: svgEl, width: svgWidth, height: svgHeight } = useElementSize<HTMLDivElement>()
|
|
121
121
|
|
|
122
122
|
const barGap = 10
|
|
123
|
-
const seriesNames = computed(() => Array.from(new Set(props.rows.map((row) =>
|
|
123
|
+
const seriesNames = computed(() => Array.from(new Set(props.rows.map((row) => formatSeriesLabel(row[props.seriesField])))))
|
|
124
124
|
const normalizedSeries = computed(() => seriesNames.value.map((name, index) => ({
|
|
125
125
|
name,
|
|
126
126
|
color: props.colors?.[index] || CHART_COLORS[index % CHART_COLORS.length],
|
|
@@ -141,7 +141,7 @@ const groupedRows = computed(() => {
|
|
|
141
141
|
for (const row of props.rows) {
|
|
142
142
|
const label = formatChartLabel(row[props.xField])
|
|
143
143
|
const item = grouped.get(label) ?? { [props.xField]: label }
|
|
144
|
-
const seriesName =
|
|
144
|
+
const seriesName = formatSeriesLabel(row[props.seriesField])
|
|
145
145
|
|
|
146
146
|
item[seriesName] = toFiniteNumber(item[seriesName]) + toFiniteNumber(row[props.yField])
|
|
147
147
|
|
|
@@ -240,4 +240,8 @@ function getBarTooltip(bar: { label: string, total: number, segments: Array<{ na
|
|
|
240
240
|
...segmentLines,
|
|
241
241
|
].join('\n')
|
|
242
242
|
}
|
|
243
|
+
|
|
244
|
+
function formatSeriesLabel(value: unknown) {
|
|
245
|
+
return typeof value === 'string' ? value : String(value)
|
|
246
|
+
}
|
|
243
247
|
</script>
|
|
@@ -476,6 +476,10 @@ query:
|
|
|
476
476
|
|
|
477
477
|
Do not use bare query.steps without source: steps.
|
|
478
478
|
Do not use metric. Use select even when a step has only one aggregate.
|
|
479
|
+
All filters, including aggregate select item filters, must use filter expression shape.
|
|
480
|
+
Use `filters: { field: model, eq: gpt-5.4 }`, not shorthand maps like `filters: { model: gpt-5.4 }`.
|
|
481
|
+
When grouping by a derived date alias, repeat the source field object in `group_by`.
|
|
482
|
+
Example: if `select` has `{ field: used_at, grain: day, as: day }`, use `group_by: [{ field: used_at, grain: day, as: day }]`, not `group_by: [day]`.
|
|
479
483
|
|
|
480
484
|
## Date range rules
|
|
481
485
|
|
|
@@ -124,9 +124,9 @@ const label = computed(() => kpiConfig.value?.subtitle?.field
|
|
|
124
124
|
.join(': ')
|
|
125
125
|
: kpiConfig.value?.subtitle?.text ?? kpiConfig.value?.title ?? props.widget.label)
|
|
126
126
|
const formattedValue = computed(() => `${kpiConfig.value?.value.prefix ?? ''}${formatValue(value.value, kpiConfig.value?.value.format)}${kpiConfig.value?.value.suffix ?? ''}`)
|
|
127
|
-
const comparisonValue = computed(() =>
|
|
128
|
-
? firstRow.value[kpiConfig.value.comparison.field]
|
|
129
|
-
:
|
|
127
|
+
const comparisonValue = computed(() => kpiConfig.value?.comparison?.field
|
|
128
|
+
? value.value - toFiniteNumber(firstRow.value[kpiConfig.value.comparison.field])
|
|
129
|
+
: 0)
|
|
130
130
|
const comparison = computed(() => {
|
|
131
131
|
const config = kpiConfig.value?.comparison
|
|
132
132
|
|
|
@@ -120,7 +120,7 @@ const { el: rootEl, width: rootWidth } = useElementSize<HTMLDivElement>()
|
|
|
120
120
|
const { el: svgEl, width: svgWidth, height: svgHeight } = useElementSize<HTMLDivElement>()
|
|
121
121
|
|
|
122
122
|
const barGap = 10
|
|
123
|
-
const seriesNames = computed(() => Array.from(new Set(props.rows.map((row) =>
|
|
123
|
+
const seriesNames = computed(() => Array.from(new Set(props.rows.map((row) => formatSeriesLabel(row[props.seriesField])))))
|
|
124
124
|
const normalizedSeries = computed(() => seriesNames.value.map((name, index) => ({
|
|
125
125
|
name,
|
|
126
126
|
color: props.colors?.[index] || CHART_COLORS[index % CHART_COLORS.length],
|
|
@@ -141,7 +141,7 @@ const groupedRows = computed(() => {
|
|
|
141
141
|
for (const row of props.rows) {
|
|
142
142
|
const label = formatChartLabel(row[props.xField])
|
|
143
143
|
const item = grouped.get(label) ?? { [props.xField]: label }
|
|
144
|
-
const seriesName =
|
|
144
|
+
const seriesName = formatSeriesLabel(row[props.seriesField])
|
|
145
145
|
|
|
146
146
|
item[seriesName] = toFiniteNumber(item[seriesName]) + toFiniteNumber(row[props.yField])
|
|
147
147
|
|
|
@@ -240,4 +240,8 @@ function getBarTooltip(bar: { label: string, total: number, segments: Array<{ na
|
|
|
240
240
|
...segmentLines,
|
|
241
241
|
].join('\n')
|
|
242
242
|
}
|
|
243
|
+
|
|
244
|
+
function formatSeriesLabel(value: unknown) {
|
|
245
|
+
return typeof value === 'string' ? value : String(value)
|
|
246
|
+
}
|
|
243
247
|
</script>
|