@mintplayer/ng-spark 22.31.0 → 22.33.0

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.
Files changed (75) hide show
  1. package/README.md +101 -1
  2. package/fesm2022/mintplayer-ng-spark-attribute-description.mjs +3 -3
  3. package/fesm2022/mintplayer-ng-spark-auth-account.mjs +18 -18
  4. package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs +16 -8
  5. package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs.map +1 -1
  6. package/fesm2022/mintplayer-ng-spark-auth-confirm-email.mjs +3 -3
  7. package/fesm2022/mintplayer-ng-spark-auth-core.mjs +6 -6
  8. package/fesm2022/mintplayer-ng-spark-auth-external-login.mjs +3 -3
  9. package/fesm2022/mintplayer-ng-spark-auth-forgot-password.mjs +3 -3
  10. package/fesm2022/mintplayer-ng-spark-auth-login.mjs +3 -3
  11. package/fesm2022/mintplayer-ng-spark-auth-pipes.mjs +3 -3
  12. package/fesm2022/mintplayer-ng-spark-auth-register.mjs +3 -3
  13. package/fesm2022/mintplayer-ng-spark-auth-reset-password.mjs +3 -3
  14. package/fesm2022/mintplayer-ng-spark-auth-sign-in.mjs +3 -3
  15. package/fesm2022/mintplayer-ng-spark-auth-two-factor.mjs +3 -3
  16. package/fesm2022/mintplayer-ng-spark-client-operations.mjs +24 -24
  17. package/fesm2022/mintplayer-ng-spark-column-filter.mjs +3 -3
  18. package/fesm2022/mintplayer-ng-spark-contributions.mjs +9 -9
  19. package/fesm2022/mintplayer-ng-spark-grid.mjs +220 -49
  20. package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
  21. package/fesm2022/mintplayer-ng-spark-history.mjs +9 -9
  22. package/fesm2022/mintplayer-ng-spark-icon.mjs +3 -3
  23. package/fesm2022/mintplayer-ng-spark-identity-provider-connected-applications.mjs +3 -3
  24. package/fesm2022/mintplayer-ng-spark-identity-provider-core.mjs +9 -9
  25. package/fesm2022/mintplayer-ng-spark-identity-provider-developers.mjs +6 -6
  26. package/fesm2022/mintplayer-ng-spark-identity-provider-management.mjs +3 -3
  27. package/fesm2022/mintplayer-ng-spark-models.mjs +44 -1
  28. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
  29. package/fesm2022/mintplayer-ng-spark-moderation.mjs +21 -21
  30. package/fesm2022/mintplayer-ng-spark-notifications.mjs +687 -0
  31. package/fesm2022/mintplayer-ng-spark-notifications.mjs.map +1 -0
  32. package/fesm2022/mintplayer-ng-spark-organizations-accept.mjs +179 -0
  33. package/fesm2022/mintplayer-ng-spark-organizations-accept.mjs.map +1 -0
  34. package/fesm2022/mintplayer-ng-spark-organizations.mjs +202 -0
  35. package/fesm2022/mintplayer-ng-spark-organizations.mjs.map +1 -0
  36. package/fesm2022/mintplayer-ng-spark-pipes.mjs +125 -85
  37. package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
  38. package/fesm2022/mintplayer-ng-spark-po-create.mjs +3 -3
  39. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +90 -26
  40. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
  41. package/fesm2022/mintplayer-ng-spark-po-edit.mjs +84 -12
  42. package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
  43. package/fesm2022/mintplayer-ng-spark-po-form.mjs +9 -9
  44. package/fesm2022/mintplayer-ng-spark-pwa.mjs +74 -6
  45. package/fesm2022/mintplayer-ng-spark-pwa.mjs.map +1 -1
  46. package/fesm2022/mintplayer-ng-spark-query-list.mjs +10 -109
  47. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
  48. package/fesm2022/mintplayer-ng-spark-renderers.mjs +3 -3
  49. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +3 -3
  50. package/fesm2022/mintplayer-ng-spark-score-renderers.mjs +801 -0
  51. package/fesm2022/mintplayer-ng-spark-score-renderers.mjs.map +1 -0
  52. package/fesm2022/mintplayer-ng-spark-services.mjs +424 -72
  53. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
  54. package/fesm2022/mintplayer-ng-spark-share-page.mjs +334 -0
  55. package/fesm2022/mintplayer-ng-spark-share-page.mjs.map +1 -0
  56. package/fesm2022/mintplayer-ng-spark-share.mjs +10 -0
  57. package/fesm2022/mintplayer-ng-spark-share.mjs.map +1 -0
  58. package/fesm2022/mintplayer-ng-spark-shell.mjs +38 -36
  59. package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -1
  60. package/fesm2022/mintplayer-ng-spark-soft-delete.mjs +9 -9
  61. package/package.json +25 -1
  62. package/types/mintplayer-ng-spark-grid.d.ts +77 -26
  63. package/types/mintplayer-ng-spark-models.d.ts +150 -17
  64. package/types/mintplayer-ng-spark-notifications.d.ts +188 -0
  65. package/types/mintplayer-ng-spark-organizations-accept.d.ts +40 -0
  66. package/types/mintplayer-ng-spark-organizations.d.ts +72 -0
  67. package/types/mintplayer-ng-spark-pipes.d.ts +10 -0
  68. package/types/mintplayer-ng-spark-po-detail.d.ts +26 -0
  69. package/types/mintplayer-ng-spark-po-edit.d.ts +37 -0
  70. package/types/mintplayer-ng-spark-pwa.d.ts +48 -2
  71. package/types/mintplayer-ng-spark-query-list.d.ts +8 -23
  72. package/types/mintplayer-ng-spark-score-renderers.d.ts +340 -0
  73. package/types/mintplayer-ng-spark-services.d.ts +146 -6
  74. package/types/mintplayer-ng-spark-share-page.d.ts +67 -0
  75. package/types/mintplayer-ng-spark-share.d.ts +26 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-spark-score-renderers.mjs","names":[],"sources":["../../score-renderers/src/score-bands.ts","../../score-renderers/src/option-readers.ts","../../score-renderers/src/spark-threshold-bar.component.ts","../../score-renderers/src/spark-delta.component.ts","../../score-renderers/src/spark-trend-options.ts","../../score-renderers/src/spark-trend-base.ts","../../score-renderers/src/spark-trend-sparkline.component.ts","../../score-renderers/src/spark-trend-chart.component.ts","../../score-renderers/src/spark-trend.component.ts","../../score-renderers/src/spark-gauge.component.ts","../../score-renderers/src/provide-spark-score-renderers.ts"],"sourcesContent":["import { Color } from '@mintplayer/ng-bootstrap';\n\n/** A Bootstrap theme colour a band paints with: `bg-*` on a bar, `--bs-*` on a gauge, `text-bg-*` on a grade. */\nexport type SparkScoreColor = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark';\n\n/**\n * One band of a score scale: it applies to a value `>= min`. The band without a `min` is the floor,\n * applying to everything below the lowest `min`. Bands may be listed in any order; the highest `min`\n * the value reaches wins.\n */\nexport interface SparkScoreBand {\n /** Inclusive lower bound. Omit for the floor band. */\n min?: number;\n color: SparkScoreColor;\n /** A grade shown next to a gauge (\"A\"). Ignored by the threshold bar. */\n label?: string;\n}\n\n/**\n * The bands a `bands` / `grades` option accepts: a list, or the name of a preset (so a model's\n * `rendererOptions` JSON, which cannot reference a TypeScript constant, can still pick one).\n */\nexport type SparkScoreBandsOption = readonly SparkScoreBand[] | 'traffic-light' | 'letter-grades';\n\n/**\n * Green from 80, amber from 60, red below: the coverage thresholds the CodeCoverage badge and bar\n * have always used. The default of every score renderer.\n */\nexport const sparkTrafficLightBands: readonly SparkScoreBand[] = [\n { min: 80, color: 'success' },\n { min: 60, color: 'warning' },\n { color: 'danger' },\n];\n\n/** A ≥ 90, B ≥ 80, C ≥ 70, D ≥ 50, else F: the grade scale of a 0–100 score (SeoTester). */\nexport const sparkLetterGrades: readonly SparkScoreBand[] = [\n { min: 90, color: 'success', label: 'A' },\n { min: 80, color: 'success', label: 'B' },\n { min: 70, color: 'warning', label: 'C' },\n { min: 50, color: 'warning', label: 'D' },\n { color: 'danger', label: 'F' },\n];\n\n/** The bands an option names, or `fallback` for an absent or unrecognised one. */\nexport function resolveSparkScoreBands(option: unknown, fallback: readonly SparkScoreBand[] = sparkTrafficLightBands): readonly SparkScoreBand[] {\n if (option === 'traffic-light') return sparkTrafficLightBands;\n if (option === 'letter-grades') return sparkLetterGrades;\n if (Array.isArray(option) && option.length > 0) return option as SparkScoreBand[];\n return fallback;\n}\n\n/** The band `value` falls in: the one with the highest `min` it reaches, else the floor, else none. */\nexport function sparkScoreBand(value: number | null | undefined, bands: readonly SparkScoreBand[]): SparkScoreBand | null {\n if (value === null || value === undefined || Number.isNaN(value)) return null;\n let best: SparkScoreBand | null = null;\n for (const band of bands) {\n const min = band.min ?? -Infinity;\n if (value >= min && (best === null || min > (best.min ?? -Infinity))) best = band;\n }\n return best;\n}\n\n/** The ng-bootstrap {@link Color} of `value`'s band; `secondary` when there is no value or no band. */\nexport function sparkScoreColor(value: number | null | undefined, bands: readonly SparkScoreBand[] = sparkTrafficLightBands): Color {\n const band = sparkScoreBand(value, bands);\n return band ? Color[band.color] : Color.secondary;\n}\n\n/**\n * A cell value as a number, or null for \"no value\". Numbers pass through, numeric strings parse,\n * and null, undefined, the empty string and anything unparseable are no value. Never 0: an absent\n * measurement must not draw as a real zero.\n */\nexport function toSparkScoreNumber(raw: unknown): number | null {\n const value = typeof raw === 'number' ? raw : raw === null || raw === undefined || raw === '' ? NaN : Number(raw);\n return Number.isNaN(value) ? null : value;\n}\n","// Internal: not exported from the entry point.\n\n/** An option that must be a finite number, else `fallback`. */\nexport function numberOption(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : fallback;\n}\n\n/** An option that must be a string, else `fallback`. */\nexport function stringOption(value: unknown, fallback: string): string {\n return typeof value === 'string' ? value : fallback;\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input, LOCALE_ID } from '@angular/core';\nimport { formatNumber } from '@angular/common';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsProgressComponent, BsProgressBarComponent } from '@mintplayer/ng-bootstrap/progress-bar';\nimport type { SparkAttributeColumnRenderer, SparkAttributeDetailRenderer } from '@mintplayer/ng-spark/renderers';\nimport { resolveSparkScoreBands, SparkScoreBandsOption, sparkScoreColor, toSparkScoreNumber } from './score-bands';\nimport { numberOption, stringOption } from './option-readers';\n\n/** `rendererOptions` of the `spark-threshold-bar` renderer. Every member is optional. */\nexport interface SparkThresholdBarOptions {\n /** Scale minimum. Default 0. */\n min?: number;\n /** Scale maximum. Default 100. */\n max?: number;\n /** Colour bands. Default `'traffic-light'` (green ≥ 80, amber ≥ 60, red below). */\n bands?: SparkScoreBandsOption;\n /** Decimals of the shown value. Default 1. */\n decimals?: number;\n /** Text after the shown value. Default `'%'`. */\n suffix?: string;\n /** The bar's accessible name. Default `'Value'`. */\n label?: string;\n /** CSS width of the bar. Default `'80px'`. */\n width?: string;\n /** CSS height of the bar. Default `'8px'`. */\n height?: string;\n /** Show the value as text next to the bar. Default true. */\n showValue?: boolean;\n}\n\ninterface ThresholdBarView {\n value: number;\n text: string;\n color: Color;\n}\n\n/**\n * The `spark-threshold-bar` renderer: a compact progress bar coloured by the band the value falls\n * in, with the value next to it. No value (null, undefined, empty, unparseable) draws a muted dash\n * rather than an empty bar, which would read as a real 0. The colour comes from the unrounded value,\n * so 59.95 shows \"60.0%\" yet stays below a 60 threshold.\n *\n * Generalised from CodeCoverage's coverage bar, which is this renderer with `label: 'Coverage'`.\n */\n@Component({\n selector: 'spark-threshold-bar',\n imports: [BsProgressComponent, BsProgressBarComponent],\n template: `\n @if (view(); as v) {\n <div class=\"d-flex align-items-center gap-2\">\n <bs-progress [style.width]=\"settings().width\" [style.height]=\"settings().height\">\n <bs-progress-bar [value]=\"v.value\" [minimum]=\"settings().min\" [maximum]=\"settings().max\" [color]=\"v.color\"\n [ariaLabel]=\"settings().label\" [valueText]=\"v.text\" />\n </bs-progress>\n @if (settings().showValue) {\n <span class=\"small text-nowrap\">{{ v.text }}</span>\n }\n </div>\n } @else {\n <span class=\"text-muted small\">—</span>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SparkThresholdBarComponent implements SparkAttributeColumnRenderer, SparkAttributeDetailRenderer {\n private readonly locale = inject(LOCALE_ID);\n\n readonly value = input<any>();\n readonly options = input<Record<string, any> | undefined>();\n\n protected readonly settings = computed(() => {\n const o = (this.options() ?? {}) as SparkThresholdBarOptions;\n const decimals = Math.max(0, Math.trunc(numberOption(o.decimals, 1)));\n return {\n min: numberOption(o.min, 0),\n max: numberOption(o.max, 100),\n bands: resolveSparkScoreBands(o.bands),\n decimals,\n suffix: stringOption(o.suffix, '%'),\n label: stringOption(o.label, 'Value'),\n width: stringOption(o.width, '80px'),\n height: stringOption(o.height, '8px'),\n showValue: o.showValue !== false,\n };\n });\n\n protected readonly view = computed<ThresholdBarView | null>(() => {\n const value = toSparkScoreNumber(this.value());\n if (value === null) return null;\n const s = this.settings();\n return {\n value,\n text: formatNumber(value, this.locale, `1.${s.decimals}-${s.decimals}`) + s.suffix,\n color: sparkScoreColor(value, s.bands),\n };\n });\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport type { SparkAttributeColumnRenderer, SparkAttributeDetailRenderer } from '@mintplayer/ng-spark/renderers';\nimport { toSparkScoreNumber } from './score-bands';\nimport { numberOption, stringOption } from './option-readers';\n\n/** `rendererOptions` of the `spark-delta` renderer. Every member is optional. */\nexport interface SparkDeltaOptions {\n /** Decimals of the shown change. Default 1. */\n decimals?: number;\n /** A rise is good (green) and a drop bad (red). Set false for a cost, an error count, a load time. Default true. */\n higherIsBetter?: boolean;\n /** Text after the number, e.g. `' pt'` or `'%'`. Default none. */\n suffix?: string;\n /** Text for \"no comparison\". Default `'—'`. */\n empty?: string;\n}\n\n/** How a delta reads: the text and its tone. */\nexport interface SparkDeltaView {\n /** The raw change is positive. Rounding does not change it: +0.04 at one decimal is `+0.0`, still up. */\n up: boolean;\n /** The raw change is negative. */\n down: boolean;\n /** `+1.3`, `-0.3`, `0.0`, or the empty text when there is nothing to compare. */\n text: string;\n /** `text-success`, `text-danger` or `text-muted`, honouring `higherIsBetter`. */\n tone: 'text-success' | 'text-danger' | 'text-muted';\n}\n\n/**\n * Formats a signed change. No value (null, undefined, empty, unparseable) is the empty text and\n * never `0.0`, which would claim a comparison that did not happen; an exact zero is a real, neutral\n * comparison.\n */\nexport function formatSparkDelta(raw: unknown, options?: SparkDeltaOptions | Record<string, any> | null): SparkDeltaView {\n const o = (options ?? {}) as SparkDeltaOptions;\n const value = toSparkScoreNumber(raw);\n if (value === null) return { up: false, down: false, text: stringOption(o.empty, '—'), tone: 'text-muted' };\n\n const decimals = Math.min(100, Math.max(0, Math.trunc(numberOption(o.decimals, 1))));\n const up = value > 0;\n const down = value < 0;\n const good = o.higherIsBetter === false ? down : up;\n const bad = o.higherIsBetter === false ? up : down;\n return {\n up,\n down,\n text: `${up ? '+' : ''}${value.toFixed(decimals)}${stringOption(o.suffix, '')}`,\n tone: good ? 'text-success' : bad ? 'text-danger' : 'text-muted',\n };\n}\n\n/**\n * The `spark-delta` renderer: a signed change, green when it improves and red when it worsens\n * (`higherIsBetter`), muted for no change, and a muted dash when there is nothing to compare.\n *\n * Generalised from CodeCoverage's coverage delta, which is this renderer with its defaults.\n */\n@Component({\n selector: 'spark-delta',\n template: `<span class=\"small\" [class]=\"view().tone\">{{ view().text }}</span>`,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SparkDeltaComponent implements SparkAttributeColumnRenderer, SparkAttributeDetailRenderer {\n readonly value = input<any>();\n readonly options = input<Record<string, any> | undefined>();\n\n protected readonly view = computed(() => formatSparkDelta(this.value(), this.options()));\n}\n","import type { TrendPoint } from '@mintplayer/ng-bootstrap/charts/trend';\n\n/** `rendererOptions` of the `spark-trend` renderer. Every member is optional. */\nexport interface SparkTrendOptions {\n /** `'sparkline'` (default): a compact inline line for a cell. `'chart'`: an interactive chart with axes. */\n display?: 'sparkline' | 'chart';\n /** Fixed scale minimum, e.g. 0 for a percentage. Default: fitted to the data. */\n yMin?: number;\n /** Fixed scale maximum, e.g. 100 for a percentage. Default: fitted to the data. */\n yMax?: number;\n /** Accessible name of the line or chart. */\n label?: string;\n /** Fewer points than this draw the dash: one point is not a trend. Default 2. */\n minPoints?: number;\n /** Sparkline CSS width. Default `'90px'`. */\n width?: string;\n /** Sparkline CSS height. Default `'24px'`. */\n height?: string;\n /** Chart only: a goal line at this value. */\n goal?: number;\n /** Chart only: the goal line's label. */\n goalLabel?: string;\n /** Chart only: the series id. Default `'value'`. */\n seriesId?: string;\n /** Chart only: the series label (legend, tooltip). Default `label`. */\n seriesLabel?: string;\n}\n\n/** One point of a trend value: a plain number (x = its index), null for a gap, or an explicit `{ x, y }`. */\nexport type SparkTrendValuePoint = number | null | { x: number | Date; y: number | null };\n\n/**\n * The value as `{ x, y }` points, or null when it is not a series or has fewer than `minPoints`.\n * A number is a point at its index; an array holding anything else is not a series.\n */\nexport function toSparkTrendPoints(value: unknown, minPoints = 2): TrendPoint[] | null {\n if (!Array.isArray(value)) return null;\n const points: TrendPoint[] = [];\n for (let i = 0; i < value.length; i++) {\n const point = value[i] as SparkTrendValuePoint;\n if (point === null || typeof point === 'number') {\n points.push({ x: i, y: point });\n } else if (typeof point === 'object' && 'y' in point) {\n points.push({ x: point.x, y: point.y });\n } else {\n return null;\n }\n }\n return points.length >= minPoints ? points : null;\n}\n","import { computed, Directive, input } from '@angular/core';\nimport type { SparkAttributeColumnRenderer, SparkAttributeDetailRenderer } from '@mintplayer/ng-spark/renderers';\nimport { SparkTrendOptions, toSparkTrendPoints } from './spark-trend-options';\nimport { numberOption, stringOption } from './option-readers';\n\n// Internal: not exported from the entry point.\n\n/** What the three trend components share: the inputs, the options read once, and the points. */\n@Directive()\nexport abstract class SparkTrendBase implements SparkAttributeColumnRenderer, SparkAttributeDetailRenderer {\n readonly value = input<any>();\n readonly options = input<Record<string, any> | undefined>();\n\n protected readonly settings = computed(() => {\n const o = (this.options() ?? {}) as SparkTrendOptions;\n const label = typeof o.label === 'string' ? o.label : undefined;\n return {\n display: o.display === 'chart' ? 'chart' as const : 'sparkline' as const,\n yMin: typeof o.yMin === 'number' ? o.yMin : undefined,\n yMax: typeof o.yMax === 'number' ? o.yMax : undefined,\n label,\n minPoints: Math.max(1, Math.trunc(numberOption(o.minPoints, 2))),\n width: stringOption(o.width, '90px'),\n height: stringOption(o.height, '24px'),\n goal: typeof o.goal === 'number' ? o.goal : undefined,\n goalLabel: typeof o.goalLabel === 'string' ? o.goalLabel : undefined,\n seriesId: stringOption(o.seriesId, 'value'),\n seriesLabel: stringOption(o.seriesLabel, label ?? ''),\n };\n });\n\n protected readonly points = computed(() => toSparkTrendPoints(this.value(), this.settings().minPoints));\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { BsSparklineComponent } from '@mintplayer/ng-bootstrap/charts/sparkline';\nimport type { TrendPoint } from '@mintplayer/ng-bootstrap/charts/trend';\nimport { SparkTrendBase } from './spark-trend-base';\n\n// A file of its own, apart from the chart: a bundler splits by module, so a module holding both\n// halves would put the trend chart in every chunk that draws a sparkline.\n\n/**\n * The sparkline half of `spark-trend`, usable on its own: a compact line for a cell, or a muted dash.\n * Imports only the sparkline, so an app drawing sparklines does not load the trend chart with them.\n */\n@Component({\n selector: 'spark-trend-sparkline',\n imports: [BsSparklineComponent],\n template: `\n @if (points(); as p) {\n <bs-sparkline class=\"d-inline-block\" [style.width]=\"settings().width\" [style.height]=\"settings().height\"\n [points]=\"ys(p)\" [yMin]=\"settings().yMin\" [yMax]=\"settings().yMax\"\n [inputLabel]=\"settings().label\" />\n } @else {\n <span class=\"text-muted small\">—</span>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SparkTrendSparklineComponent extends SparkTrendBase {\n protected ys(points: TrendPoint[]): (number | null)[] {\n return points.map(p => p.y);\n }\n}\n","import { ChangeDetectionStrategy, Component, computed } from '@angular/core';\nimport { BsTrendChartComponent, type TrendSeries } from '@mintplayer/ng-bootstrap/charts/trend';\nimport { SparkTrendBase } from './spark-trend-base';\n\n/**\n * The chart half of `spark-trend`, usable on its own: an interactive trend chart of one series with\n * an optional goal line, or a muted dash. Imports only the trend chart.\n */\n@Component({\n selector: 'spark-trend-chart',\n imports: [BsTrendChartComponent],\n template: `\n @if (points()) {\n <bs-trend-chart [series]=\"series()\" [yMin]=\"settings().yMin\" [yMax]=\"settings().yMax\"\n [goal]=\"settings().goal\" [goalLabel]=\"settings().goalLabel\" [inputLabel]=\"settings().label\" />\n } @else {\n <span class=\"text-muted small\">—</span>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SparkTrendChartComponent extends SparkTrendBase {\n protected readonly series = computed<TrendSeries[]>(() => {\n const s = this.settings();\n return [{ id: s.seriesId, label: s.seriesLabel, points: this.points() ?? [] }];\n });\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SparkTrendBase } from './spark-trend-base';\nimport { SparkTrendChartComponent } from './spark-trend-chart.component';\nimport { SparkTrendSparklineComponent } from './spark-trend-sparkline.component';\n\n/**\n * The `spark-trend` renderer: a series as a sparkline in a cell, or with `display: 'chart'` as an\n * interactive trend chart. The value is an array of numbers (null for a gap) or of `{ x, y }` points\n * (x a number or a Date); anything else, or fewer than `minPoints` points, draws a muted dash.\n *\n * Generalised from CodeCoverage's repository sparkline (90×24 on a fixed 0–100 scale) and its\n * \"coverage over time\" chart (an 80% goal line). Registering this renderer loads both charts; a\n * template that needs only one uses `<spark-trend-sparkline>` or `<spark-trend-chart>`.\n */\n@Component({\n selector: 'spark-trend',\n imports: [SparkTrendSparklineComponent, SparkTrendChartComponent],\n template: `\n @if (settings().display === 'chart') {\n <spark-trend-chart [value]=\"value()\" [options]=\"options()\" />\n } @else {\n <spark-trend-sparkline [value]=\"value()\" [options]=\"options()\" />\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SparkTrendComponent extends SparkTrendBase {}\n","import { ChangeDetectionStrategy, Component, computed, inject, input, LOCALE_ID } from '@angular/core';\nimport { formatNumber } from '@angular/common';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsBadgeComponent } from '@mintplayer/ng-bootstrap/badge';\nimport type { SparkAttributeColumnRenderer, SparkAttributeDetailRenderer } from '@mintplayer/ng-spark/renderers';\nimport { resolveSparkScoreBands, SparkScoreBandsOption, sparkScoreBand, SparkScoreColor, toSparkScoreNumber } from './score-bands';\nimport { numberOption, stringOption } from './option-readers';\n\n/** `rendererOptions` of the `spark-gauge` renderer. Every member is optional. */\nexport interface SparkGaugeOptions {\n /** Scale minimum. Default 0. */\n min?: number;\n /** Scale maximum. Default 100. */\n max?: number;\n /**\n * The bands that colour the ring and, when they carry a `label`, name the grade drawn next to it.\n * `'letter-grades'` is A ≥ 90, B ≥ 80, C ≥ 70, D ≥ 50, else F. Default `'traffic-light'` (no grade).\n */\n bands?: SparkScoreBandsOption;\n /** Decimals of the score in the ring. Default 0. */\n decimals?: number;\n /** Text after the score, e.g. `'%'`. Default none. */\n suffix?: string;\n /** The gauge's accessible name. Default `'Score'`. */\n label?: string;\n /** Diameter in CSS pixels. Default 48. */\n size?: number;\n}\n\ninterface GaugeView {\n value: number;\n text: string;\n color: SparkScoreColor;\n grade: string | null;\n /** The grade badge's colour (the band's). */\n badge: Color;\n /** Arc length on a ring of circumference 100: the share of the scale reached, clamped to 0–100. */\n arc: number;\n}\n\n/**\n * The `spark-gauge` renderer: a score as a ring filled to its share of the scale, coloured by its\n * band, with the score inside and the band's grade (when the bands carry labels) beside it. No value\n * draws a muted dash rather than an empty ring, which would read as a real 0.\n *\n * Exposed as an ARIA `meter` whose value text includes the grade (\"72 (C)\").\n */\n@Component({\n selector: 'spark-gauge',\n // The grade is ng-bootstrap's badge: its CSS ships with the component, so a bare `.badge` class drew an unstyled letter.\n imports: [BsBadgeComponent],\n template: `\n @if (view(); as v) {\n <span class=\"d-inline-flex align-items-center gap-2\" role=\"meter\"\n [attr.aria-label]=\"settings().label\" [attr.aria-valuenow]=\"v.value\"\n [attr.aria-valuemin]=\"settings().min\" [attr.aria-valuemax]=\"settings().max\"\n [attr.aria-valuetext]=\"v.grade ? v.text + ' (' + v.grade + ')' : v.text\">\n <svg viewBox=\"0 0 36 36\" [attr.width]=\"settings().size\" [attr.height]=\"settings().size\" aria-hidden=\"true\">\n <circle class=\"spark-gauge-track\" cx=\"18\" cy=\"18\" r=\"15.9155\" fill=\"none\" stroke-width=\"3.5\" />\n <circle class=\"spark-gauge-arc\" cx=\"18\" cy=\"18\" r=\"15.9155\" fill=\"none\" stroke-width=\"3.5\"\n stroke-linecap=\"round\" transform=\"rotate(-90 18 18)\"\n [attr.stroke]=\"'var(--bs-' + v.color + ')'\" [attr.stroke-dasharray]=\"v.arc + ' 100'\" />\n <text x=\"18\" y=\"18\" text-anchor=\"middle\" dominant-baseline=\"central\" class=\"spark-gauge-text\">{{ v.text }}</text>\n </svg>\n @if (v.grade) {\n <bs-badge [type]=\"v.badge\">{{ v.grade }}</bs-badge>\n }\n </span>\n } @else {\n <span class=\"text-muted small\">—</span>\n }\n `,\n styles: [`\n .spark-gauge-track { stroke: var(--bs-secondary-bg); }\n .spark-gauge-text { fill: var(--bs-body-color); font-size: 10px; font-weight: 600; }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SparkGaugeComponent implements SparkAttributeColumnRenderer, SparkAttributeDetailRenderer {\n private readonly locale = inject(LOCALE_ID);\n\n readonly value = input<any>();\n readonly options = input<Record<string, any> | undefined>();\n\n protected readonly settings = computed(() => {\n const o = (this.options() ?? {}) as SparkGaugeOptions;\n return {\n min: numberOption(o.min, 0),\n max: numberOption(o.max, 100),\n bands: resolveSparkScoreBands(o.bands),\n decimals: Math.max(0, Math.trunc(numberOption(o.decimals, 0))),\n suffix: stringOption(o.suffix, ''),\n label: stringOption(o.label, 'Score'),\n size: Math.max(1, numberOption(o.size, 48)),\n };\n });\n\n protected readonly view = computed<GaugeView | null>(() => {\n const value = toSparkScoreNumber(this.value());\n if (value === null) return null;\n const s = this.settings();\n const band = sparkScoreBand(value, s.bands);\n const span = s.max - s.min;\n const share = span > 0 ? (value - s.min) / span : 0;\n return {\n value,\n text: formatNumber(value, this.locale, `1.${s.decimals}-${s.decimals}`) + s.suffix,\n color: band?.color ?? 'secondary',\n grade: band?.label ?? null,\n badge: Color[band?.color ?? 'secondary'],\n arc: Math.round(Math.min(1, Math.max(0, share)) * 1000) / 10,\n };\n });\n}\n","import { Provider } from '@angular/core';\nimport { provideSparkAttributeRenderers, SparkAttributeRendererRegistration } from '@mintplayer/ng-spark/renderers';\nimport { SparkGaugeComponent } from './spark-gauge.component';\nimport { SparkThresholdBarComponent } from './spark-threshold-bar.component';\nimport { SparkTrendComponent } from './spark-trend.component';\nimport { SparkDeltaComponent } from './spark-delta.component';\n\n/**\n * The score renderers under their generic names, each drawing both a grid cell and a detail value.\n * Configured per attribute through the model's `rendererOptions`.\n */\nexport const sparkScoreRenderers: readonly SparkAttributeRendererRegistration[] = [\n { name: 'spark-gauge', columnComponent: SparkGaugeComponent, detailComponent: SparkGaugeComponent },\n { name: 'spark-threshold-bar', columnComponent: SparkThresholdBarComponent, detailComponent: SparkThresholdBarComponent },\n { name: 'spark-trend', columnComponent: SparkTrendComponent, detailComponent: SparkTrendComponent },\n { name: 'spark-delta', columnComponent: SparkDeltaComponent, detailComponent: SparkDeltaComponent },\n];\n\n/**\n * Registers the score renderers (`spark-gauge`, `spark-threshold-bar`, `spark-trend`, `spark-delta`)\n * together with the app's own. Use it **instead of** `provideSparkAttributeRenderers`, not next to\n * it: both provide the one renderer list, and the last provider would win.\n *\n * The app's registrations come first, so an app renderer of the same name replaces a score renderer.\n *\n * @example\n * provideSparkScoreRenderers([\n * { name: 'coverage-delta', columnComponent: SparkDeltaComponent, detailComponent: SparkDeltaComponent },\n * ])\n */\nexport function provideSparkScoreRenderers(renderers: SparkAttributeRendererRegistration[] = []): Provider {\n return provideSparkAttributeRenderers([...renderers, ...sparkScoreRenderers]);\n}\n"],"mappings":"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"}