Sign In

@erplora/outfitkit

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@erplora/outfitkit - npm Package Compare versions

Comparing version
0.1.37
to
0.1.38
+1
dist/components/ok-chart/ok-chart.test.d.ts
import './ok-chart.js';
import { LitElement } from 'lit';
import '../ok-gauge/ok-gauge.js';
import '../ok-chart/ok-chart.js';
/** Health status computed by the server for the metric. */
export type OkResourceStatus = 'ok' | 'warning' | 'critical' | 'unknown';
/** Server-computed metric: current reading + history + status. */
export interface OkResourceMetric {
/** False when the metric could not be read — renders the unreadable state. */
known: boolean;
/** Current reading (0-100 scale; values above 100 clamp visually). */
current: number | null;
/** History as [epochSeconds, value] pairs, oldest first. */
points: Array<[number, number]>;
/** Status decided by the server; drives every color in the panel. */
status: OkResourceStatus;
/** Optional server message shown in the status band / unreadable state. */
message: string | null;
}
/** Thresholds received from the server; only used for the gauge zone gradient. */
export interface OkResourceThresholds {
warning: number;
critical: number;
}
/** Optional upgrade call-to-action. */
export interface OkResourceUpgrade {
show: boolean;
message: string;
url: string;
}
export declare class OkResourceUsage extends LitElement {
static styles: import("lit").CSSResult;
/** Server-computed metric (reading + history + status). */
metric: OkResourceMetric;
/** Server thresholds; only feed the gauge zone gradient. */
thresholds: OkResourceThresholds;
/** Optional upgrade CTA; the link renders only when `show` is true. */
upgrade: OkResourceUpgrade | null;
/** Panel heading (e.g. 'RAM'). */
label: string;
/** Value suffix (default '%'). */
unit: string;
/** Small chip describing the history range (e.g. '3d'). */
rangeLabel: string;
/** Text of the not-measured state; the consumer passes its translation. */
unreadableLabel: string;
private get statusColor();
private get gaugeThresholds();
private renderHead;
private renderUnreadable;
private renderBody;
private renderUpgrade;
render(): unknown;
}
declare global {
interface HTMLElementTagNameMap {
'ok-resource-usage': OkResourceUsage;
}
}
import { LitElement, css, nothing, html } from "lit";
import { property } from "lit/decorators.js";
import { define } from "./define.js";
import { z as iconAlertCircleOutline } from "./shared/icons.js";
import "./ok-gauge.js";
import "./ok-chart.js";
var __defProp = Object.defineProperty;
var __decorateClass = (decorators, target, key, kind) => {
var result = void 0;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = decorator(target, key, result) || result;
if (result) __defProp(target, key, result);
return result;
};
const STATUS_COLOR = {
ok: "var(--ion-color-success, #2dd36f)",
warning: "var(--ion-color-warning, #ffc409)",
critical: "var(--ion-color-danger, #eb445a)",
unknown: "var(--ion-color-medium, #92949c)"
};
class OkResourceUsage extends LitElement {
constructor() {
super(...arguments);
this.metric = {
known: false,
current: null,
points: [],
status: "unknown",
message: null
};
this.thresholds = {
warning: 70,
critical: 80
};
this.upgrade = null;
this.label = "";
this.unit = "%";
this.rangeLabel = "";
this.unreadableLabel = "Could not read it";
}
static {
this.styles = css`
:host {
display: block;
width: 100%;
box-sizing: border-box;
--ink: var(--ok-text-color, var(--ion-text-color, #1f2933));
--ink-muted: var(--ok-color-medium, var(--ion-color-medium, #92949c));
--line: var(--ok-border-color, var(--ion-border-color, #e0e0e0));
--track: var(--ok-track-color, var(--ion-color-light, #f4f5f8));
}
.panel {
display: flex;
flex-direction: column;
gap: 0.75rem;
width: 100%;
box-sizing: border-box;
}
.head {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 0.5rem;
}
.label {
font-size: 0.6875rem;
font-weight: 600;
color: var(--ink-muted);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.range {
font-size: 0.6875rem;
color: var(--ink-muted);
font-variant-numeric: tabular-nums;
border: 1px solid var(--line);
border-radius: 999px;
padding: 1px 8px;
}
.body {
display: flex;
align-items: center;
gap: 1rem;
}
.dial {
flex: 0 0 auto;
}
.trend {
flex: 1 1 auto;
min-width: 0;
}
.status {
font-size: 0.8125rem;
border-radius: 8px;
padding: 6px 10px;
min-height: 1.25rem;
box-sizing: border-box;
}
.unreadable {
display: flex;
align-items: center;
gap: 0.625rem;
padding: 1rem;
border: 1px dashed var(--line);
border-radius: 8px;
color: var(--ink-muted);
background: var(--track);
}
.unreadable ion-icon {
font-size: 1.5rem;
flex-shrink: 0;
}
.unreadable-text {
font-weight: 600;
color: var(--ink);
}
.unreadable-message {
font-size: 0.8125rem;
}
a.upgrade {
align-self: flex-start;
font-size: 0.8125rem;
font-weight: 600;
text-decoration: none;
color: var(--ok-primary, var(--ion-color-primary, #3880ff));
}
a.upgrade:hover {
text-decoration: underline;
}
`;
}
// Every color in the panel derives from the received status (the server decides).
get statusColor() {
return STATUS_COLOR[this.metric?.status] ?? STATUS_COLOR.unknown;
}
// Gauge zones from the received thresholds (the one place they are used).
get gaugeThresholds() {
const t = this.thresholds ?? { warning: 70, critical: 80 };
return [
{ to: t.warning, color: STATUS_COLOR.ok },
{ to: t.critical, color: STATUS_COLOR.warning },
{ to: 100, color: STATUS_COLOR.critical }
];
}
renderHead() {
if (!this.label && !this.rangeLabel) return nothing;
return html`<div class="head">
${this.label ? html`<span class="label">${this.label}</span>` : nothing}
${this.rangeLabel ? html`<span class="range">${this.rangeLabel}</span>` : nothing}
</div>`;
}
// Not-measured state: icon + label, NEVER a gauge or a chart at zero.
renderUnreadable() {
return html`<div class="unreadable" role="status">
<ion-icon .icon=${iconAlertCircleOutline} aria-hidden="true"></ion-icon>
<span class="unreadable-text">${this.unreadableLabel}</span>
${this.metric?.message ? html`<span class="unreadable-message">${this.metric.message}</span>` : nothing}
</div>`;
}
renderBody() {
const m = this.metric;
const real = m.current;
const shown = real == null ? null : Math.min(real, 100);
const points = m.points ?? [];
return html`<div class="body">
${shown != null ? html`<div class="dial" title=${`${real}${this.unit}`}>
<ok-gauge
type="ring"
size="110"
unit=${this.unit}
.value=${shown}
.thresholds=${this.gaugeThresholds}
.color=${this.statusColor}
></ok-gauge>
</div>` : nothing}
${points.length ? html`<div class="trend">
<ok-chart
type="area"
height="96"
min="0"
max="100"
.series=${[{ color: this.statusColor, data: points.map(([, v]) => v) }]}
></ok-chart>
</div>` : nothing}
</div>
<div
class=${`status status--${m.status}`}
style=${`background:color-mix(in srgb, ${this.statusColor} 15%, transparent);color:${this.statusColor};`}
>
${m.message ?? nothing}
</div>`;
}
renderUpgrade() {
if (!this.upgrade?.show) return nothing;
return html`<a class="upgrade" href=${this.upgrade.url}>${this.upgrade.message}</a>`;
}
render() {
return html`<div class="panel">
${this.renderHead()}
${this.metric?.known ? this.renderBody() : this.renderUnreadable()}
${this.renderUpgrade()}
</div>`;
}
}
__decorateClass([
property({ attribute: false })
], OkResourceUsage.prototype, "metric");
__decorateClass([
property({ attribute: false })
], OkResourceUsage.prototype, "thresholds");
__decorateClass([
property({ attribute: false })
], OkResourceUsage.prototype, "upgrade");
__decorateClass([
property()
], OkResourceUsage.prototype, "label");
__decorateClass([
property()
], OkResourceUsage.prototype, "unit");
__decorateClass([
property({ attribute: "range-label" })
], OkResourceUsage.prototype, "rangeLabel");
__decorateClass([
property({ attribute: "unreadable-label" })
], OkResourceUsage.prototype, "unreadableLabel");
define("ok-resource-usage", OkResourceUsage);
export {
OkResourceUsage
};
+1
-0

@@ -62,2 +62,3 @@ import './components/ok-store/ok-store.js';

import './components/ok-chart/ok-chart.js';
import './components/ok-resource-usage/ok-resource-usage.js';
import './components/ok-donut/ok-donut.js';

@@ -64,0 +65,0 @@ import './components/ok-heatmap/ok-heatmap.js';

@@ -32,2 +32,6 @@ import { LitElement } from 'lit';

endpoint: boolean;
/** Mínimo explícito del eje de valor; si se omite, autoescala al mínimo de los datos. */
min?: number;
/** Máximo explícito del eje de valor; si se omite, autoescala al máximo de los datos. */
max?: number;
/** Texto de la etiqueta del endpoint; si se omite usa el último dato. */

@@ -34,0 +38,0 @@ endpointLabel: string;

@@ -91,2 +91,4 @@ export { createStore, store } from './store/store.js';

export type { OkChartSeries, OkChartType } from './components/ok-chart/ok-chart.js';
export { OkResourceUsage } from './components/ok-resource-usage/ok-resource-usage.js';
export type { OkResourceMetric, OkResourceStatus, OkResourceThresholds, OkResourceUpgrade, } from './components/ok-resource-usage/ok-resource-usage.js';
export { OkDonut } from './components/ok-donut/ok-donut.js';

@@ -93,0 +95,0 @@ export type { OkDonutSlice } from './components/ok-donut/ok-donut.js';

@@ -64,2 +64,3 @@ import { createStore, store } from "./store.js";

import { OkChart } from "./ok-chart.js";
import { OkResourceUsage } from "./ok-resource-usage.js";
import { OkDonut } from "./ok-donut.js";

@@ -169,2 +170,3 @@ import { OkHeatmap } from "./ok-heatmap.js";

OkReceipt,
OkResourceUsage,
OkReveal,

@@ -171,0 +173,0 @@ OkRichText,

@@ -119,10 +119,20 @@ import { LitElement, css, svg, html } from "lit";

}
// Mínimo/máximo global de todas las series (las barras crecen desde 0).
// Mínimo/máximo del eje: los props explícitos `min`/`max` mandan; sin ellos,
// autoescala al mínimo/máximo global de las series (las barras crecen desde 0).
get bounds() {
const all = [];
for (const s of this.series ?? []) for (const v of s.data ?? []) all.push(v);
if (!all.length) return { min: 0, max: 1 };
let min = Math.min(...all);
let max = Math.max(...all);
if (this.type !== "line") min = Math.min(min, 0);
let min;
let max;
if (!all.length) {
min = 0;
max = 1;
} else {
min = Math.min(...all);
max = Math.max(...all);
if (this.type !== "line") min = Math.min(min, 0);
if (min === max) max = min + 1;
}
if (this.min != null && Number.isFinite(this.min)) min = this.min;
if (this.max != null && Number.isFinite(this.max)) max = this.max;
if (min === max) max = min + 1;

@@ -321,2 +331,8 @@ return { min, max };

__decorateClass([
property({ type: Number })
], OkChart.prototype, "min");
__decorateClass([
property({ type: Number })
], OkChart.prototype, "max");
__decorateClass([
property()

@@ -323,0 +339,0 @@ ], OkChart.prototype, "endpointLabel");

@@ -62,2 +62,3 @@ import "./ok-store.js";

import "./ok-chart.js";
import "./ok-resource-usage.js";
import "./ok-donut.js";

@@ -64,0 +65,0 @@ import "./ok-heatmap.js";

+2
-1
{
"name": "@erplora/outfitkit",
"version": "0.1.37",
"version": "0.1.38",
"description": "OutfitKit — librería de Web Components (Lit) que CONSTRUYE lo que Ionic no tiene (tree, data-table rica, inline-feedback, kpi/stat, stepper/wizard, calendar, kanban…) sobre primitivos de Ionic. Ionic es la base; OutfitKit cubre los huecos. npm + CDN, imports individuales, CSP-safe. Tema vía tokens --ok-* (fallback a --ion-*).",

@@ -94,2 +94,3 @@ "type": "module",

"./ok-chart": "./dist/ok-chart.js",
"./ok-resource-usage": "./dist/ok-resource-usage.js",
"./ok-donut": "./dist/ok-donut.js",

@@ -96,0 +97,0 @@ "./ok-heatmap": "./dist/ok-heatmap.js",

@@ -122,2 +122,3 @@ # OutfitKit (`@erplora/outfitkit`)

| `ok-chart` | Gráfico SVG inline (línea/área/barras) sin librerías externas. | — |
| `ok-resource-usage` | Panel de recurso 0-100 % (gauge + histórico + banda de estado + CTA de upgrade); todo precalculado por el servidor. | — |
| `ok-donut` | Donut/pie proporcional con leyenda opcional. | — |

@@ -124,0 +125,0 @@ | `ok-heatmap` | Heatmap de calendario (estilo GitHub) o anual, con cuantiles e intensidad. | — |

Sorry, the diff of this file is too big to display