@messagevisor/catalog 0.0.1 → 0.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/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/assets/index-CfGbXx4X.css +1 -0
- package/dist/assets/index-r8ugP5JL.js +73 -0
- package/dist/favicon.png +0 -0
- package/dist/index.html +14 -0
- package/dist/logo-text.png +0 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +18 -0
- package/lib/index.js.map +1 -0
- package/lib/node/formatExamplePreview.d.ts +10 -0
- package/lib/node/formatExamplePreview.js +79 -0
- package/lib/node/formatExamplePreview.js.map +1 -0
- package/lib/node/index.d.ts +191 -0
- package/lib/node/index.js +1645 -0
- package/lib/node/index.js.map +1 -0
- package/package.json +59 -13
- package/src/App.tsx +73 -0
- package/src/api.spec.ts +42 -0
- package/src/api.ts +87 -0
- package/src/catalogBrandAssets.ts +8 -0
- package/src/components/details/ConditionTree.tsx +146 -0
- package/src/components/details/FieldGrid.tsx +16 -0
- package/src/components/details/GroupSegmentTree.tsx +73 -0
- package/src/components/details/MarkdownContent.tsx +23 -0
- package/src/components/details/TranslationsTable.tsx +263 -0
- package/src/components/details/UsageLinks.tsx +29 -0
- package/src/components/history/HistoryTimeline.tsx +122 -0
- package/src/components/layout/AppShell.tsx +338 -0
- package/src/components/layout/PageHeader.tsx +13 -0
- package/src/components/layout/Tabs.tsx +35 -0
- package/src/components/lists/EntityList.tsx +451 -0
- package/src/components/ui/Badge.tsx +21 -0
- package/src/components/ui/Button.tsx +12 -0
- package/src/components/ui/Card.tsx +9 -0
- package/src/components/ui/CodeBlock.tsx +7 -0
- package/src/components/ui/EmptyState.tsx +8 -0
- package/src/components/ui/Input.tsx +12 -0
- package/src/components/ui/LabelValueBadge.tsx +55 -0
- package/src/config.ts +2 -0
- package/src/context/CatalogContext.tsx +50 -0
- package/src/entityTypes.ts +49 -0
- package/src/index.ts +1 -0
- package/src/main.tsx +28 -0
- package/src/node/formatExamplePreview.ts +85 -0
- package/src/node/index.spec.ts +713 -0
- package/src/node/index.ts +2007 -0
- package/src/pages/EntityDetailPage.tsx +3345 -0
- package/src/pages/HistoryPage.tsx +26 -0
- package/src/pages/HomePage.tsx +21 -0
- package/src/pages/ListPage.tsx +59 -0
- package/src/styles.css +95 -0
- package/src/theme.ts +36 -0
- package/src/types.ts +127 -0
- package/src/utils/formatCatalogTimestamp.ts +77 -0
- package/src/utils/hashTranslationValue.spec.ts +20 -0
- package/src/utils/hashTranslationValue.ts +22 -0
- package/src/utils/searchQuery.ts +46 -0
package/src/main.tsx
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { BrowserRouter, HashRouter } from "react-router-dom";
|
|
4
|
+
|
|
5
|
+
import { fetchManifest, setCatalogRouterMode } from "./api";
|
|
6
|
+
import { App } from "./App";
|
|
7
|
+
import "./styles.css";
|
|
8
|
+
|
|
9
|
+
async function render() {
|
|
10
|
+
const manifest = await fetchManifest();
|
|
11
|
+
const Router = manifest.router === "browser" ? BrowserRouter : HashRouter;
|
|
12
|
+
|
|
13
|
+
setCatalogRouterMode(manifest.router);
|
|
14
|
+
|
|
15
|
+
createRoot(document.getElementById("root") as HTMLElement).render(
|
|
16
|
+
<React.StrictMode>
|
|
17
|
+
<Router>
|
|
18
|
+
<App manifest={manifest} />
|
|
19
|
+
</Router>
|
|
20
|
+
</React.StrictMode>,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
render().catch((error: Error) => {
|
|
25
|
+
createRoot(document.getElementById("root") as HTMLElement).render(
|
|
26
|
+
<div className="p-8 text-danger">{error.message}</div>,
|
|
27
|
+
);
|
|
28
|
+
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { FormatPresets } from "@messagevisor/types";
|
|
2
|
+
|
|
3
|
+
/** Fixed instants for stable catalog output across builds and locales. */
|
|
4
|
+
const SAMPLE_DATE_UTC = Date.UTC(2004, 2, 14, 15, 9, 26);
|
|
5
|
+
|
|
6
|
+
function sampleNumberForPreset(style: string | undefined): number {
|
|
7
|
+
switch (style) {
|
|
8
|
+
case "percent":
|
|
9
|
+
return 0.715;
|
|
10
|
+
case "currency":
|
|
11
|
+
return 1234.56;
|
|
12
|
+
case "unit":
|
|
13
|
+
return 3.5;
|
|
14
|
+
default:
|
|
15
|
+
return 1234.567;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function computePreviewForBucket(
|
|
20
|
+
locale: string,
|
|
21
|
+
kind: "number" | "date" | "time",
|
|
22
|
+
presetKey: string,
|
|
23
|
+
computedFormats: FormatPresets | undefined,
|
|
24
|
+
): string | undefined {
|
|
25
|
+
const bucket =
|
|
26
|
+
kind === "number"
|
|
27
|
+
? computedFormats?.number?.[presetKey]
|
|
28
|
+
: kind === "date"
|
|
29
|
+
? computedFormats?.date?.[presetKey]
|
|
30
|
+
: computedFormats?.time?.[presetKey];
|
|
31
|
+
|
|
32
|
+
if (!bucket || typeof bucket !== "object" || Array.isArray(bucket)) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
if (kind === "number") {
|
|
38
|
+
const opts = bucket as Record<string, unknown> & { style?: string };
|
|
39
|
+
const sample = sampleNumberForPreset(opts.style);
|
|
40
|
+
return new Intl.NumberFormat(locale, opts as Intl.NumberFormatOptions).format(sample);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const sampleDate = new Date(SAMPLE_DATE_UTC);
|
|
44
|
+
return new Intl.DateTimeFormat(locale, bucket as Intl.DateTimeFormatOptions).format(sampleDate);
|
|
45
|
+
} catch {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Adds `examplePreview` to format rows under `number.*`, `date.*`, and `time.*` (same preview
|
|
52
|
+
* for all rows that share the same preset bucket, e.g. `number.money`).
|
|
53
|
+
*/
|
|
54
|
+
export function attachFormatExamplePreviews<R extends { path: string }>(
|
|
55
|
+
localeKey: string,
|
|
56
|
+
computedFormats: FormatPresets | undefined,
|
|
57
|
+
rows: R[],
|
|
58
|
+
): Array<R & { examplePreview?: string }> {
|
|
59
|
+
const cache = new Map<string, string | undefined>();
|
|
60
|
+
|
|
61
|
+
return rows.map((row) => {
|
|
62
|
+
const segments = row.path.split(".").filter(Boolean);
|
|
63
|
+
if (segments.length < 2) {
|
|
64
|
+
return row;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const kind = segments[0];
|
|
68
|
+
if (kind !== "number" && kind !== "date" && kind !== "time") {
|
|
69
|
+
return row;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const presetKey = segments[1];
|
|
73
|
+
const cacheKey = `${kind}.${presetKey}`;
|
|
74
|
+
if (!cache.has(cacheKey)) {
|
|
75
|
+
cache.set(cacheKey, computePreviewForBucket(localeKey, kind, presetKey, computedFormats));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const preview = cache.get(cacheKey);
|
|
79
|
+
if (!preview) {
|
|
80
|
+
return row;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return { ...row, examplePreview: preview };
|
|
84
|
+
});
|
|
85
|
+
}
|