@12-apps/ui 6.0.2 → 6.1.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@12-apps/ui",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"packageManager": "pnpm@9.0.0",
|
|
6
6
|
"type": "module",
|
|
@@ -592,7 +592,7 @@
|
|
|
592
592
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
593
593
|
},
|
|
594
594
|
"dependencies": {
|
|
595
|
-
"@12-apps/forms-core": "^1.
|
|
595
|
+
"@12-apps/forms-core": "^1.20.0",
|
|
596
596
|
"@emotion/react": "^11.14.0",
|
|
597
597
|
"@emotion/styled": "^11.14.0",
|
|
598
598
|
"@monaco-editor/react": "^4.7.0",
|
|
@@ -607,8 +607,8 @@
|
|
|
607
607
|
"recharts": "^3.5.1"
|
|
608
608
|
},
|
|
609
609
|
"devDependencies": {
|
|
610
|
-
"@12-apps/eslint-config": "^1.21.
|
|
611
|
-
"@12-apps/typescript-config": "^1.20.
|
|
610
|
+
"@12-apps/eslint-config": "^1.21.1",
|
|
611
|
+
"@12-apps/typescript-config": "^1.20.1",
|
|
612
612
|
"@playwright/test": "^1.55.0",
|
|
613
613
|
"@storybook/addon-docs": "^9.1.10",
|
|
614
614
|
"@storybook/addon-links": "^9.1.10",
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { DataViewQuery } from "./data-views-types";
|
|
2
|
-
/**
|
|
3
|
-
* THE "SERVER" FOR THE PEDIDOS STORY.
|
|
4
|
-
*
|
|
5
|
-
* Server mode means the grid does not filter, sort or paginate — it emits the
|
|
6
|
-
* query and renders exactly the page it is handed back. A story that wires
|
|
7
|
-
* `onQueryChange` to a no-op spy therefore looks broken in a specific and
|
|
8
|
-
* misleading way: the pills apply, the counter never moves, and every row
|
|
9
|
-
* stays. The controls are working; there is simply nobody on the other end.
|
|
10
|
-
*
|
|
11
|
-
* So this is the other end. It is deliberately fenced into its own module and
|
|
12
|
-
* written the way the real endpoint is: it is the ONLY code allowed to narrow
|
|
13
|
-
* the dataset, and the story never reaches past `data`.
|
|
14
|
-
*/
|
|
15
|
-
/** The subset of a row this fake backend knows how to query. */
|
|
16
|
-
export interface ServerRow extends Record<string, unknown> {
|
|
17
|
-
pedido: string;
|
|
18
|
-
cliente: string;
|
|
19
|
-
metodo: string;
|
|
20
|
-
pagamento: string;
|
|
21
|
-
situacao: string;
|
|
22
|
-
dataIso: string;
|
|
23
|
-
valor: number;
|
|
24
|
-
}
|
|
25
|
-
export interface ServerPage<T> {
|
|
26
|
-
data: T[];
|
|
27
|
-
totalCount: number;
|
|
28
|
-
/**
|
|
29
|
-
* Per-scope totals over search + pills + ranges, IGNORING the active scope —
|
|
30
|
-
* computed with it applied, every inactive tab reads zero.
|
|
31
|
-
*/
|
|
32
|
-
scopeCounts: Record<string, number>;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Answer one query: narrow, count, scope, sort, then cut the page.
|
|
36
|
-
*
|
|
37
|
-
* `scopeCounts` is computed BEFORE the scope is applied, which is the whole
|
|
38
|
-
* reason it cannot be done in the browser — a count taken from the loaded page
|
|
39
|
-
* is wrong the moment there is a second page.
|
|
40
|
-
*/
|
|
41
|
-
export declare function queryPedidos(rows: ServerRow[], query: DataViewQuery): ServerPage<ServerRow>;
|
|
42
|
-
//# sourceMappingURL=pedidos.server.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pedidos.server.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/pedidos.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,oBAAoB,CAAC;AAEpE;;;;;;;;;;;;GAYG;AAEH,gEAAgE;AAChE,MAAM,WAAW,SAAU,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAgDD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,CA2B3F"}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import type { DataViewQuery, RangeValue } from "./data-views-types";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* THE "SERVER" FOR THE PEDIDOS STORY.
|
|
5
|
-
*
|
|
6
|
-
* Server mode means the grid does not filter, sort or paginate — it emits the
|
|
7
|
-
* query and renders exactly the page it is handed back. A story that wires
|
|
8
|
-
* `onQueryChange` to a no-op spy therefore looks broken in a specific and
|
|
9
|
-
* misleading way: the pills apply, the counter never moves, and every row
|
|
10
|
-
* stays. The controls are working; there is simply nobody on the other end.
|
|
11
|
-
*
|
|
12
|
-
* So this is the other end. It is deliberately fenced into its own module and
|
|
13
|
-
* written the way the real endpoint is: it is the ONLY code allowed to narrow
|
|
14
|
-
* the dataset, and the story never reaches past `data`.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/** The subset of a row this fake backend knows how to query. */
|
|
18
|
-
export interface ServerRow extends Record<string, unknown> {
|
|
19
|
-
pedido: string;
|
|
20
|
-
cliente: string;
|
|
21
|
-
metodo: string;
|
|
22
|
-
pagamento: string;
|
|
23
|
-
situacao: string;
|
|
24
|
-
dataIso: string;
|
|
25
|
-
valor: number;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface ServerPage<T> {
|
|
29
|
-
data: T[];
|
|
30
|
-
totalCount: number;
|
|
31
|
-
/**
|
|
32
|
-
* Per-scope totals over search + pills + ranges, IGNORING the active scope —
|
|
33
|
-
* computed with it applied, every inactive tab reads zero.
|
|
34
|
-
*/
|
|
35
|
-
scopeCounts: Record<string, number>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** A row matches a pill field when ANY selected value matches. */
|
|
39
|
-
function matchesPills(row: ServerRow, pills: Record<string, string[]>): boolean {
|
|
40
|
-
return Object.entries(pills).every(([fieldId, values]) => {
|
|
41
|
-
if (!values || values.length === 0) return true;
|
|
42
|
-
return values.includes(String(row[fieldId] ?? ""));
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Ranges. A DAY bound is compared as an ISO STRING, never coerced to a
|
|
48
|
-
* timestamp: turning an `até` of 2026-07-15 into an instant lands on that day's
|
|
49
|
-
* midnight and silently drops the final day (FUT-668). Both ends are inclusive.
|
|
50
|
-
*/
|
|
51
|
-
function matchesRanges(row: ServerRow, ranges: Record<string, RangeValue>): boolean {
|
|
52
|
-
return Object.entries(ranges).every(([fieldId, range]) => {
|
|
53
|
-
if (!range || (range.min == null && range.max == null)) return true;
|
|
54
|
-
const value = fieldId === "data" ? row.dataIso : row.valor;
|
|
55
|
-
if (value == null) return false;
|
|
56
|
-
if (range.min != null && value < range.min) return false;
|
|
57
|
-
if (range.max != null && value > range.max) return false;
|
|
58
|
-
return true;
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function matchesSearch(row: ServerRow, search: string): boolean {
|
|
63
|
-
const term = search.trim().toLowerCase();
|
|
64
|
-
if (!term) return true;
|
|
65
|
-
return [row.pedido, row.cliente, row.metodo].some((field) =>
|
|
66
|
-
String(field).toLowerCase().includes(term),
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** The scopes this story declares, as predicates over a row's `situacao`. */
|
|
71
|
-
const SCOPES: Record<string, (row: ServerRow) => boolean> = {
|
|
72
|
-
todos: () => true,
|
|
73
|
-
"Em aberto": (row) => row.situacao === "Em aberto",
|
|
74
|
-
Cancelado: (row) => row.situacao === "Cancelado",
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
function compare(a: ServerRow, b: ServerRow, id: string): number {
|
|
78
|
-
const left = a[id];
|
|
79
|
-
const right = b[id];
|
|
80
|
-
if (typeof left === "number" && typeof right === "number") return left - right;
|
|
81
|
-
return String(left ?? "").localeCompare(String(right ?? ""), "pt-BR");
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Answer one query: narrow, count, scope, sort, then cut the page.
|
|
86
|
-
*
|
|
87
|
-
* `scopeCounts` is computed BEFORE the scope is applied, which is the whole
|
|
88
|
-
* reason it cannot be done in the browser — a count taken from the loaded page
|
|
89
|
-
* is wrong the moment there is a second page.
|
|
90
|
-
*/
|
|
91
|
-
export function queryPedidos(rows: ServerRow[], query: DataViewQuery): ServerPage<ServerRow> {
|
|
92
|
-
const narrowed = rows.filter(
|
|
93
|
-
(row) =>
|
|
94
|
-
matchesSearch(row, query.search) &&
|
|
95
|
-
matchesPills(row, query.pills) &&
|
|
96
|
-
matchesRanges(row, query.ranges ?? {}),
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
const scopeCounts = Object.fromEntries(
|
|
100
|
-
Object.entries(SCOPES).map(([id, predicate]) => [id, narrowed.filter(predicate).length]),
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
const predicate = query.scope ? SCOPES[query.scope] : undefined;
|
|
104
|
-
const scoped = predicate ? narrowed.filter(predicate) : narrowed;
|
|
105
|
-
|
|
106
|
-
const sorted = [...scoped];
|
|
107
|
-
const sort = query.sortBy?.[0];
|
|
108
|
-
if (sort) {
|
|
109
|
-
sorted.sort((a, b) => (sort.dir === "asc" ? compare(a, b, sort.id) : compare(b, a, sort.id)));
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const start = (query.page - 1) * query.pageSize;
|
|
113
|
-
return {
|
|
114
|
-
data: sorted.slice(start, start + query.pageSize),
|
|
115
|
-
totalCount: scoped.length,
|
|
116
|
-
scopeCounts,
|
|
117
|
-
};
|
|
118
|
-
}
|