@messagevisor/catalog 0.2.0 → 0.3.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/dist/assets/index-DrsX4U8c.css +1 -0
- package/dist/assets/index-OXIn4K-M.js +73 -0
- package/dist/index.html +2 -2
- package/package.json +2 -2
- package/src/components/details/FieldGrid.tsx +1 -1
- package/src/components/details/GroupSegmentTree.tsx +2 -1
- package/src/components/details/UsageLinks.tsx +3 -2
- package/src/components/history/HistoryTimeline.tsx +4 -3
- package/src/components/layout/PageHeader.tsx +13 -3
- package/src/components/lists/EntityList.tsx +2 -1
- package/src/components/ui/EntityKey.tsx +20 -0
- package/src/pages/EntityDetailPage.tsx +14 -5
- package/dist/assets/index-BoO0zn_O.js +0 -73
- package/dist/assets/index-Cn0qFwkD.css +0 -1
package/dist/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
|
7
7
|
<title>Messagevisor Catalog</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-OXIn4K-M.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DrsX4U8c.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@messagevisor/catalog",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Static catalog UI for Messagevisor projects",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"typescript": "^5.7.2",
|
|
58
58
|
"vite": "^6.0.7"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "62ca354700133c05c4466a4515f415be6f934eb2"
|
|
61
61
|
}
|
|
@@ -8,7 +8,7 @@ export function FieldGrid(props: {
|
|
|
8
8
|
{props.fields.map((field) => (
|
|
9
9
|
<div key={field.label} className={field.fullWidth ? "md:col-span-2" : ""}>
|
|
10
10
|
<dt className="text-sm font-medium text-muted">{field.label}</dt>
|
|
11
|
-
<dd className="mt-1 text-sm">{field.value || "n/a"}</dd>
|
|
11
|
+
<dd className="mt-1 min-w-0 text-sm [overflow-wrap:anywhere]">{field.value || "n/a"}</dd>
|
|
12
12
|
</div>
|
|
13
13
|
))}
|
|
14
14
|
</dl>
|
|
@@ -2,6 +2,7 @@ import { Link } from "react-router-dom";
|
|
|
2
2
|
import type { GroupSegment } from "@messagevisor/types";
|
|
3
3
|
|
|
4
4
|
import { Badge } from "../ui/Badge";
|
|
5
|
+
import { EntityKey } from "../ui/EntityKey";
|
|
5
6
|
import { getEntityRoute } from "../../entityTypes";
|
|
6
7
|
|
|
7
8
|
function SegmentLeaf(props: { segmentKey: string; setKey?: string }) {
|
|
@@ -13,7 +14,7 @@ function SegmentLeaf(props: { segmentKey: string; setKey?: string }) {
|
|
|
13
14
|
to={getEntityRoute("segment", props.segmentKey, props.setKey)}
|
|
14
15
|
className="font-semibold text-primary hover:underline"
|
|
15
16
|
>
|
|
16
|
-
{props.segmentKey}
|
|
17
|
+
<EntityKey value={props.segmentKey} className="font-semibold" />
|
|
17
18
|
</Link>
|
|
18
19
|
</div>
|
|
19
20
|
</div>
|
|
@@ -2,6 +2,7 @@ import { Link } from "react-router-dom";
|
|
|
2
2
|
|
|
3
3
|
import type { EntityType } from "../../types";
|
|
4
4
|
import { getEntityRoute } from "../../entityTypes";
|
|
5
|
+
import { EntityKey } from "../ui/EntityKey";
|
|
5
6
|
|
|
6
7
|
export function UsageLinks(props: { type: EntityType; keys?: string[]; setKey?: string }) {
|
|
7
8
|
if (!props.keys || props.keys.length === 0) {
|
|
@@ -11,7 +12,7 @@ export function UsageLinks(props: { type: EntityType; keys?: string[]; setKey?:
|
|
|
11
12
|
return (
|
|
12
13
|
<ul className="list-inside list-disc space-y-1 text-sm">
|
|
13
14
|
{props.keys.map((key) => (
|
|
14
|
-
<li key={key}>
|
|
15
|
+
<li key={key} className="[overflow-wrap:anywhere]">
|
|
15
16
|
<Link
|
|
16
17
|
className="text-primary hover:underline"
|
|
17
18
|
to={getEntityRoute(
|
|
@@ -20,7 +21,7 @@ export function UsageLinks(props: { type: EntityType; keys?: string[]; setKey?:
|
|
|
20
21
|
props.setKey,
|
|
21
22
|
)}
|
|
22
23
|
>
|
|
23
|
-
{key}
|
|
24
|
+
<EntityKey value={key} className="font-medium" />
|
|
24
25
|
</Link>
|
|
25
26
|
</li>
|
|
26
27
|
))}
|
|
@@ -7,6 +7,7 @@ import type { HistoryEntry } from "../../types";
|
|
|
7
7
|
import { formatCatalogTimestamp } from "../../utils/formatCatalogTimestamp";
|
|
8
8
|
import { CATALOG_HISTORY_VISIBLE_ENTITY_LIMIT } from "../../config";
|
|
9
9
|
import { Button } from "../ui/Button";
|
|
10
|
+
import { EntityKey } from "../ui/EntityKey";
|
|
10
11
|
import { EmptyState } from "../ui/EmptyState";
|
|
11
12
|
|
|
12
13
|
function HistoryEntryCard(props: { entry: HistoryEntry; setKey?: string; commitUrl?: string }) {
|
|
@@ -36,17 +37,17 @@ function HistoryEntryCard(props: { entry: HistoryEntry; setKey?: string; commitU
|
|
|
36
37
|
</div>
|
|
37
38
|
<ul className="mt-3 list-inside list-disc space-y-1 text-sm text-muted">
|
|
38
39
|
{visibleEntities.map((entity) => (
|
|
39
|
-
<li key={`${entity.type}-${entity.key}`}>
|
|
40
|
+
<li key={`${entity.type}-${entity.key}`} className="[overflow-wrap:anywhere]">
|
|
40
41
|
{entity.type !== "test" ? entityLabels[entity.type].singular : "Test"}{" "}
|
|
41
42
|
{entity.type !== "test" ? (
|
|
42
43
|
<Link
|
|
43
44
|
className="font-medium text-primary hover:underline"
|
|
44
45
|
to={getEntityRoute(entity.type, entity.key, entity.set || props.setKey)}
|
|
45
46
|
>
|
|
46
|
-
{entity.key}
|
|
47
|
+
<EntityKey value={entity.key} className="font-medium" />
|
|
47
48
|
</Link>
|
|
48
49
|
) : (
|
|
49
|
-
entity.key
|
|
50
|
+
<EntityKey value={entity.key} className="font-medium" />
|
|
50
51
|
)}
|
|
51
52
|
</li>
|
|
52
53
|
))}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
|
|
3
|
-
export function PageHeader(props: {
|
|
3
|
+
export function PageHeader(props: {
|
|
4
|
+
title: ReactNode;
|
|
5
|
+
description?: ReactNode;
|
|
6
|
+
actions?: ReactNode;
|
|
7
|
+
}) {
|
|
4
8
|
return (
|
|
5
9
|
<div className="mb-6 flex flex-col justify-between gap-4 border-b border-border px-6 pb-4 pt-8 md:flex-row md:items-start">
|
|
6
10
|
<div className="min-w-0 flex-1">
|
|
7
|
-
<h1 className="
|
|
8
|
-
|
|
11
|
+
<h1 className="min-w-0 text-3xl font-black text-text [overflow-wrap:anywhere]">
|
|
12
|
+
{props.title}
|
|
13
|
+
</h1>
|
|
14
|
+
{props.description && (
|
|
15
|
+
<div className="mt-2 min-w-0 text-sm text-muted [overflow-wrap:anywhere]">
|
|
16
|
+
{props.description}
|
|
17
|
+
</div>
|
|
18
|
+
)}
|
|
9
19
|
</div>
|
|
10
20
|
{props.actions ? <div className="shrink-0">{props.actions}</div> : null}
|
|
11
21
|
</div>
|
|
@@ -9,6 +9,7 @@ import { Badge } from "../ui/Badge";
|
|
|
9
9
|
import { EmptyState } from "../ui/EmptyState";
|
|
10
10
|
import { Input } from "../ui/Input";
|
|
11
11
|
import { Button } from "../ui/Button";
|
|
12
|
+
import { EntityKey } from "../ui/EntityKey";
|
|
12
13
|
import { CATALOG_LIST_INITIAL_LIMIT } from "../../config";
|
|
13
14
|
import type { ParsedQuery } from "../../utils/searchQuery";
|
|
14
15
|
import { parseQuery } from "../../utils/searchQuery";
|
|
@@ -409,7 +410,7 @@ export function EntityList(props: {
|
|
|
409
410
|
<div className="min-w-0 flex-1">
|
|
410
411
|
<div className="flex flex-col justify-between gap-2 md:flex-row md:items-start">
|
|
411
412
|
<div className="min-w-0">
|
|
412
|
-
<
|
|
413
|
+
<EntityKey value={entity.key} className="text-sm font-semibold text-primary" />
|
|
413
414
|
<div className="mt-1 truncate text-sm text-muted">
|
|
414
415
|
{entity.description || "No description"}
|
|
415
416
|
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function EntityKey(props: { value: string; className?: string }) {
|
|
2
|
+
const parts = props.value.split(".");
|
|
3
|
+
|
|
4
|
+
return (
|
|
5
|
+
<span
|
|
6
|
+
className={["inline leading-snug [overflow-wrap:anywhere]", props.className || ""].join(" ")}
|
|
7
|
+
>
|
|
8
|
+
{parts.map((part, index) => (
|
|
9
|
+
<span key={`${part}-${index}`}>
|
|
10
|
+
{part}
|
|
11
|
+
{index < parts.length - 1 ? (
|
|
12
|
+
<>
|
|
13
|
+
.<wbr />
|
|
14
|
+
</>
|
|
15
|
+
) : null}
|
|
16
|
+
</span>
|
|
17
|
+
))}
|
|
18
|
+
</span>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -30,6 +30,7 @@ import { PageHeader } from "../components/layout/PageHeader";
|
|
|
30
30
|
import { Tabs } from "../components/layout/Tabs";
|
|
31
31
|
import { Badge } from "../components/ui/Badge";
|
|
32
32
|
import { CodeBlock } from "../components/ui/CodeBlock";
|
|
33
|
+
import { EntityKey } from "../components/ui/EntityKey";
|
|
33
34
|
import { LabelValueBadge } from "../components/ui/LabelValueBadge";
|
|
34
35
|
import { EmptyState } from "../components/ui/EmptyState";
|
|
35
36
|
import { Input } from "../components/ui/Input";
|
|
@@ -1195,7 +1196,15 @@ export function EntityDetailPage() {
|
|
|
1195
1196
|
return (
|
|
1196
1197
|
<div>
|
|
1197
1198
|
<PageHeader
|
|
1198
|
-
title={
|
|
1199
|
+
title={
|
|
1200
|
+
<span className="flex min-w-0 flex-wrap items-baseline gap-x-2 gap-y-1">
|
|
1201
|
+
<span className="whitespace-nowrap">{entityLabels[type].singular}:</span>
|
|
1202
|
+
<EntityKey
|
|
1203
|
+
value={detail.key}
|
|
1204
|
+
className="min-w-0 text-[1.45rem] font-extrabold leading-tight"
|
|
1205
|
+
/>
|
|
1206
|
+
</span>
|
|
1207
|
+
}
|
|
1199
1208
|
description={
|
|
1200
1209
|
<div className="flex flex-wrap items-center gap-2">
|
|
1201
1210
|
{entity.archived && <Badge tone="danger">archived</Badge>}
|
|
@@ -1638,7 +1647,7 @@ function MessageTranslationOverridesDetails(props: {
|
|
|
1638
1647
|
to={`${getEntityRoute("message", props.messageKey, props.setKey)}/overrides#${key}`}
|
|
1639
1648
|
className="text-sm font-semibold text-primary hover:underline"
|
|
1640
1649
|
>
|
|
1641
|
-
{key}
|
|
1650
|
+
<EntityKey value={key} className="font-semibold" />
|
|
1642
1651
|
</Link>
|
|
1643
1652
|
{row.source === "inherited" && row.from && (
|
|
1644
1653
|
<LabelValueBadge
|
|
@@ -1800,8 +1809,8 @@ export function MessageOverridesTab() {
|
|
|
1800
1809
|
<section key={override.key} className="space-y-4">
|
|
1801
1810
|
<div className="space-y-3">
|
|
1802
1811
|
<div className="group flex items-center gap-2">
|
|
1803
|
-
<h2 id={override.key} className="font-semibold">
|
|
1804
|
-
{override.key}
|
|
1812
|
+
<h2 id={override.key} className="font-semibold [overflow-wrap:anywhere]">
|
|
1813
|
+
<EntityKey value={override.key} className="font-semibold" />
|
|
1805
1814
|
</h2>
|
|
1806
1815
|
<ExamplePermalink targetId={override.key} />
|
|
1807
1816
|
</div>
|
|
@@ -3141,7 +3150,7 @@ export function LocaleDuplicatesTab() {
|
|
|
3141
3150
|
<td className="min-w-0 border-b border-border px-3 py-2">
|
|
3142
3151
|
<Link
|
|
3143
3152
|
to={getEntityRoute("message", messageKey, setKey)}
|
|
3144
|
-
className="font-medium text-primary hover:underline"
|
|
3153
|
+
className="font-medium text-primary [overflow-wrap:anywhere] hover:underline"
|
|
3145
3154
|
>
|
|
3146
3155
|
<ExamplesSearchHighlight
|
|
3147
3156
|
text={messageKey}
|