@nnkogift/dhis2-form-utils-devtools 0.1.0-alpha.4 → 0.1.0-alpha.6
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/EffectBadge.d.ts +17 -0
- package/dist/EffectBadge.js +55 -0
- package/dist/EffectBadge.js.map +1 -0
- package/dist/RuleDetailsModal.d.ts +30 -0
- package/dist/RuleDetailsModal.js +403 -0
- package/dist/RuleDetailsModal.js.map +1 -0
- package/dist/RuleDevtoolsScope.d.ts +14 -0
- package/dist/RuleDevtoolsScope.js +25 -0
- package/dist/RuleDevtoolsScope.js.map +1 -0
- package/dist/RuleGraphModal.d.ts +17 -0
- package/dist/RuleGraphModal.js +35 -0
- package/dist/RuleGraphModal.js.map +1 -0
- package/dist/RuleGraphView.d.ts +43 -0
- package/dist/RuleGraphView.js +401 -0
- package/dist/RuleGraphView.js.map +1 -0
- package/dist/RulesPanel.d.ts +19 -0
- package/dist/RulesPanel.js +463 -0
- package/dist/RulesPanel.js.map +1 -0
- package/dist/RulesPanelGraphFallback.d.ts +5 -0
- package/dist/RulesPanelGraphFallback.js +19 -0
- package/dist/RulesPanelGraphFallback.js.map +1 -0
- package/dist/TraceTimeline.d.ts +16 -0
- package/dist/TraceTimeline.js +227 -0
- package/dist/TraceTimeline.js.map +1 -0
- package/dist/attach.d.ts +12 -0
- package/dist/attach.js +14 -0
- package/dist/attach.js.map +1 -0
- package/dist/buildGraph.d.ts +25 -0
- package/dist/buildGraph.js +67 -0
- package/dist/buildGraph.js.map +1 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +5 -0
- package/dist/constants.js.map +1 -0
- package/dist/createLabelLookup.d.ts +25 -0
- package/dist/createLabelLookup.js +81 -0
- package/dist/createLabelLookup.js.map +1 -0
- package/dist/effectStyles.d.ts +28 -0
- package/dist/effectStyles.js +142 -0
- package/dist/effectStyles.js.map +1 -0
- package/dist/formatAgo.d.ts +3 -0
- package/dist/formatAgo.js +25 -0
- package/dist/formatAgo.js.map +1 -0
- package/dist/formatRuleActionSummary.d.ts +33 -0
- package/dist/formatRuleActionSummary.js +61 -0
- package/dist/formatRuleActionSummary.js.map +1 -0
- package/dist/graphLayout.d.ts +48 -0
- package/dist/graphLayout.js +137 -0
- package/dist/graphLayout.js.map +1 -0
- package/dist/graphNodeStyles.d.ts +9 -0
- package/dist/graphNodeStyles.js +22 -0
- package/dist/graphNodeStyles.js.map +1 -0
- package/dist/i18n.d.ts +4 -0
- package/dist/i18n.js +9 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.cjs +1364 -651
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.cts +12 -63
- package/dist/index.d.ts +12 -63
- package/dist/index.js +5 -1669
- package/dist/index.js.map +1 -1
- package/dist/programRuleDetailQuery.d.ts +70 -0
- package/dist/programRuleDetailQuery.js +42 -0
- package/dist/programRuleDetailQuery.js.map +1 -0
- package/dist/resolveProgramRulesList.d.ts +21 -0
- package/dist/resolveProgramRulesList.js +45 -0
- package/dist/resolveProgramRulesList.js.map +1 -0
- package/dist/traceEntry.d.ts +12 -0
- package/dist/traceEntry.js +20 -0
- package/dist/traceEntry.js.map +1 -0
- package/dist/traceStore.d.ts +12 -0
- package/dist/traceStore.js +39 -0
- package/dist/traceStore.js.map +1 -0
- package/dist/useFlipReorder.d.ts +8 -0
- package/dist/useFlipReorder.js +52 -0
- package/dist/useFlipReorder.js.map +1 -0
- package/dist/useProgramRuleDetail.d.ts +17 -0
- package/dist/useProgramRuleDetail.js +30 -0
- package/dist/useProgramRuleDetail.js.map +1 -0
- package/package.json +27 -4
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { IconInfo16, IconLink16, IconMail16, IconMessages16, IconErrorFilled16, IconWarningFilled16, IconStarFilled16, IconEdit16, IconView16, IconViewOff16 } from '@dhis2/ui';
|
|
2
|
+
|
|
3
|
+
const EFFECT_VARIANT = {
|
|
4
|
+
HIDEFIELD: "hide",
|
|
5
|
+
HIDEOPTION: "hide",
|
|
6
|
+
HIDEOPTIONGROUP: "hide",
|
|
7
|
+
HIDESECTION: "hide",
|
|
8
|
+
HIDEPROGRAMSTAGE: "hide",
|
|
9
|
+
SHOWFIELD: "show",
|
|
10
|
+
SHOWOPTION: "show",
|
|
11
|
+
SHOWOPTIONGROUP: "show",
|
|
12
|
+
ASSIGN: "assign",
|
|
13
|
+
SETMANDATORYFIELD: "mandatory",
|
|
14
|
+
UNSETMANDATORYFIELD: "mandatory",
|
|
15
|
+
SHOWWARNING: "warning",
|
|
16
|
+
WARNINGONCOMPLETE: "warning",
|
|
17
|
+
SHOWERROR: "error",
|
|
18
|
+
ERRORONCOMPLETE: "error",
|
|
19
|
+
DISPLAYTEXT: "feedback",
|
|
20
|
+
DISPLAYKEYVALUEPAIR: "feedback",
|
|
21
|
+
SENDMESSAGE: "message",
|
|
22
|
+
SCHEDULEMESSAGE: "message",
|
|
23
|
+
read: "read"
|
|
24
|
+
};
|
|
25
|
+
const EFFECT_VISUALS = {
|
|
26
|
+
hide: {
|
|
27
|
+
tagClassName: "bg-dhis2-grey-200 text-dhis2-grey-900",
|
|
28
|
+
edgeStroke: "#494949",
|
|
29
|
+
shortLabel: "hide"
|
|
30
|
+
},
|
|
31
|
+
show: {
|
|
32
|
+
tagClassName: "bg-dhis2-green-100 text-dhis2-green-900",
|
|
33
|
+
edgeStroke: "#388e3c",
|
|
34
|
+
shortLabel: "show"
|
|
35
|
+
},
|
|
36
|
+
assign: {
|
|
37
|
+
tagClassName: "bg-dhis2-blue-100 text-dhis2-blue-900",
|
|
38
|
+
edgeStroke: "#1565c0",
|
|
39
|
+
shortLabel: "assign"
|
|
40
|
+
},
|
|
41
|
+
mandatory: {
|
|
42
|
+
tagClassName: "bg-dhis2-yellow-100 text-dhis2-yellow-900",
|
|
43
|
+
edgeStroke: "#e56408",
|
|
44
|
+
shortLabel: "required"
|
|
45
|
+
},
|
|
46
|
+
warning: {
|
|
47
|
+
tagClassName: "bg-dhis2-yellow-100 text-dhis2-yellow-900",
|
|
48
|
+
edgeStroke: "#ff8302",
|
|
49
|
+
shortLabel: "warn"
|
|
50
|
+
},
|
|
51
|
+
error: {
|
|
52
|
+
tagClassName: "bg-dhis2-red-100 text-dhis2-red-900",
|
|
53
|
+
edgeStroke: "#c62828",
|
|
54
|
+
shortLabel: "error"
|
|
55
|
+
},
|
|
56
|
+
feedback: {
|
|
57
|
+
tagClassName: "bg-dhis2-purple-100 text-dhis2-purple-900",
|
|
58
|
+
edgeStroke: "#9c27b0",
|
|
59
|
+
shortLabel: "feedback"
|
|
60
|
+
},
|
|
61
|
+
message: {
|
|
62
|
+
tagClassName: "bg-dhis2-teal-100 text-dhis2-teal-900",
|
|
63
|
+
edgeStroke: "#00796b",
|
|
64
|
+
shortLabel: "message"
|
|
65
|
+
},
|
|
66
|
+
read: {
|
|
67
|
+
tagClassName: "bg-dhis2-teal-100 text-dhis2-teal-900",
|
|
68
|
+
edgeStroke: "#00796b",
|
|
69
|
+
shortLabel: "read"
|
|
70
|
+
},
|
|
71
|
+
default: {
|
|
72
|
+
tagClassName: "bg-dhis2-grey-100 text-dhis2-grey-800",
|
|
73
|
+
edgeStroke: "#494949",
|
|
74
|
+
shortLabel: "effect"
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const EFFECT_ICONS = {
|
|
78
|
+
hide: IconViewOff16,
|
|
79
|
+
show: IconView16,
|
|
80
|
+
assign: IconEdit16,
|
|
81
|
+
mandatory: IconStarFilled16,
|
|
82
|
+
warning: IconWarningFilled16,
|
|
83
|
+
error: IconErrorFilled16,
|
|
84
|
+
feedback: IconMessages16,
|
|
85
|
+
message: IconMail16,
|
|
86
|
+
read: IconLink16,
|
|
87
|
+
default: IconInfo16
|
|
88
|
+
};
|
|
89
|
+
function getEffectVariant(type) {
|
|
90
|
+
return EFFECT_VARIANT[type] ?? "default";
|
|
91
|
+
}
|
|
92
|
+
function getEffectVisual(type) {
|
|
93
|
+
const variant = getEffectVariant(type);
|
|
94
|
+
return { variant, ...EFFECT_VISUALS[variant] };
|
|
95
|
+
}
|
|
96
|
+
function getEffectTagVariant(type) {
|
|
97
|
+
return getEffectVariant(type);
|
|
98
|
+
}
|
|
99
|
+
const TAG_LAYOUT_CLASS = "max-w-full break-words";
|
|
100
|
+
function tagPropsForVariant(variant) {
|
|
101
|
+
switch (variant) {
|
|
102
|
+
case "show":
|
|
103
|
+
return { positive: true, className: TAG_LAYOUT_CLASS };
|
|
104
|
+
case "error":
|
|
105
|
+
return { negative: true, className: TAG_LAYOUT_CLASS };
|
|
106
|
+
case "assign":
|
|
107
|
+
return { neutral: true, className: TAG_LAYOUT_CLASS };
|
|
108
|
+
case "hide":
|
|
109
|
+
case "mandatory":
|
|
110
|
+
case "warning":
|
|
111
|
+
case "feedback":
|
|
112
|
+
case "message":
|
|
113
|
+
case "read":
|
|
114
|
+
return {
|
|
115
|
+
className: `${TAG_LAYOUT_CLASS} ${EFFECT_VISUALS[variant].tagClassName}`
|
|
116
|
+
};
|
|
117
|
+
default:
|
|
118
|
+
return {
|
|
119
|
+
className: `${TAG_LAYOUT_CLASS} ${EFFECT_VISUALS.default.tagClassName}`
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function getEffectTagRenderProps(type) {
|
|
124
|
+
return tagPropsForVariant(getEffectVariant(type));
|
|
125
|
+
}
|
|
126
|
+
function getEffectTagRenderPropsForVariant(variant) {
|
|
127
|
+
return tagPropsForVariant(variant);
|
|
128
|
+
}
|
|
129
|
+
function getEffectEdgeStroke(type, highlighted = true) {
|
|
130
|
+
const { edgeStroke } = getEffectVisual(type);
|
|
131
|
+
if (highlighted) {
|
|
132
|
+
return edgeStroke;
|
|
133
|
+
}
|
|
134
|
+
return "#bdbdbd";
|
|
135
|
+
}
|
|
136
|
+
function getEffectShortLabel(type) {
|
|
137
|
+
return getEffectVisual(type).shortLabel;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export { EFFECT_ICONS, getEffectEdgeStroke, getEffectShortLabel, getEffectTagRenderProps, getEffectTagRenderPropsForVariant, getEffectTagVariant, getEffectVariant, getEffectVisual };
|
|
141
|
+
//# sourceMappingURL=effectStyles.js.map
|
|
142
|
+
//# sourceMappingURL=effectStyles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/effectStyles.ts"],"names":[],"mappings":"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","file":"effectStyles.js","sourcesContent":["import type { FC } from 'react';\nimport {\n IconEdit16,\n IconErrorFilled16,\n IconInfo16,\n IconLink16,\n IconMail16,\n IconMessages16,\n IconStarFilled16,\n IconView16,\n IconViewOff16,\n IconWarningFilled16,\n type IconProps,\n} from '@dhis2/ui';\n\nexport type EffectVisualVariant =\n | 'hide'\n | 'show'\n | 'assign'\n | 'mandatory'\n | 'warning'\n | 'error'\n | 'feedback'\n | 'message'\n | 'read'\n | 'default';\n\nexport type EffectVisual = {\n variant: EffectVisualVariant;\n tagClassName: string;\n edgeStroke: string;\n shortLabel: string;\n};\n\nconst EFFECT_VARIANT: Record<string, EffectVisualVariant> = {\n HIDEFIELD: 'hide',\n HIDEOPTION: 'hide',\n HIDEOPTIONGROUP: 'hide',\n HIDESECTION: 'hide',\n HIDEPROGRAMSTAGE: 'hide',\n SHOWFIELD: 'show',\n SHOWOPTION: 'show',\n SHOWOPTIONGROUP: 'show',\n ASSIGN: 'assign',\n SETMANDATORYFIELD: 'mandatory',\n UNSETMANDATORYFIELD: 'mandatory',\n SHOWWARNING: 'warning',\n WARNINGONCOMPLETE: 'warning',\n SHOWERROR: 'error',\n ERRORONCOMPLETE: 'error',\n DISPLAYTEXT: 'feedback',\n DISPLAYKEYVALUEPAIR: 'feedback',\n SENDMESSAGE: 'message',\n SCHEDULEMESSAGE: 'message',\n read: 'read',\n};\n\nconst EFFECT_VISUALS: Record<EffectVisualVariant, Omit<EffectVisual, 'variant'>> = {\n hide: {\n tagClassName: 'bg-dhis2-grey-200 text-dhis2-grey-900',\n edgeStroke: '#494949',\n shortLabel: 'hide',\n },\n show: {\n tagClassName: 'bg-dhis2-green-100 text-dhis2-green-900',\n edgeStroke: '#388e3c',\n shortLabel: 'show',\n },\n assign: {\n tagClassName: 'bg-dhis2-blue-100 text-dhis2-blue-900',\n edgeStroke: '#1565c0',\n shortLabel: 'assign',\n },\n mandatory: {\n tagClassName: 'bg-dhis2-yellow-100 text-dhis2-yellow-900',\n edgeStroke: '#e56408',\n shortLabel: 'required',\n },\n warning: {\n tagClassName: 'bg-dhis2-yellow-100 text-dhis2-yellow-900',\n edgeStroke: '#ff8302',\n shortLabel: 'warn',\n },\n error: {\n tagClassName: 'bg-dhis2-red-100 text-dhis2-red-900',\n edgeStroke: '#c62828',\n shortLabel: 'error',\n },\n feedback: {\n tagClassName: 'bg-dhis2-purple-100 text-dhis2-purple-900',\n edgeStroke: '#9c27b0',\n shortLabel: 'feedback',\n },\n message: {\n tagClassName: 'bg-dhis2-teal-100 text-dhis2-teal-900',\n edgeStroke: '#00796b',\n shortLabel: 'message',\n },\n read: {\n tagClassName: 'bg-dhis2-teal-100 text-dhis2-teal-900',\n edgeStroke: '#00796b',\n shortLabel: 'read',\n },\n default: {\n tagClassName: 'bg-dhis2-grey-100 text-dhis2-grey-800',\n edgeStroke: '#494949',\n shortLabel: 'effect',\n },\n};\n\nexport const EFFECT_ICONS: Record<EffectVisualVariant, FC<IconProps>> = {\n hide: IconViewOff16,\n show: IconView16,\n assign: IconEdit16,\n mandatory: IconStarFilled16,\n warning: IconWarningFilled16,\n error: IconErrorFilled16,\n feedback: IconMessages16,\n message: IconMail16,\n read: IconLink16,\n default: IconInfo16,\n};\n\n/** @deprecated Use getEffectVisual().variant */\nexport type EffectTagVariant = EffectVisualVariant;\n\nexport function getEffectVariant(type: string): EffectVisualVariant {\n return EFFECT_VARIANT[type] ?? 'default';\n}\n\nexport function getEffectVisual(type: string): EffectVisual {\n const variant = getEffectVariant(type);\n return { variant, ...EFFECT_VISUALS[variant] };\n}\n\nexport function getEffectTagVariant(type: string): EffectVisualVariant {\n return getEffectVariant(type);\n}\n\nexport type EffectTagRenderProps = {\n neutral?: boolean;\n positive?: boolean;\n negative?: boolean;\n className?: string;\n};\n\nconst TAG_LAYOUT_CLASS = 'max-w-full break-words';\n\nfunction tagPropsForVariant(variant: EffectVisualVariant): EffectTagRenderProps {\n switch (variant) {\n case 'show':\n return { positive: true, className: TAG_LAYOUT_CLASS };\n case 'error':\n return { negative: true, className: TAG_LAYOUT_CLASS };\n case 'assign':\n return { neutral: true, className: TAG_LAYOUT_CLASS };\n case 'hide':\n case 'mandatory':\n case 'warning':\n case 'feedback':\n case 'message':\n case 'read':\n return {\n className: `${TAG_LAYOUT_CLASS} ${EFFECT_VISUALS[variant].tagClassName}`,\n };\n default:\n return {\n className: `${TAG_LAYOUT_CLASS} ${EFFECT_VISUALS.default.tagClassName}`,\n };\n }\n}\n\nexport function getEffectTagRenderProps(type: string): EffectTagRenderProps {\n return tagPropsForVariant(getEffectVariant(type));\n}\n\nexport function getEffectTagRenderPropsForVariant(\n variant: EffectVisualVariant\n): EffectTagRenderProps {\n return tagPropsForVariant(variant);\n}\n\nexport function getEffectEdgeStroke(type: string, highlighted = true): string {\n const { edgeStroke } = getEffectVisual(type);\n if (highlighted) {\n return edgeStroke;\n }\n return '#bdbdbd';\n}\n\nexport function getEffectShortLabel(type: string): string {\n return getEffectVisual(type).shortLabel;\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { translate } from './i18n.js';
|
|
2
|
+
|
|
3
|
+
function formatAgo(timestamp, now = Date.now()) {
|
|
4
|
+
const diffMs = Math.max(0, now - timestamp);
|
|
5
|
+
if (diffMs < 5e3) {
|
|
6
|
+
return translate("just now");
|
|
7
|
+
}
|
|
8
|
+
const seconds = Math.floor(diffMs / 1e3);
|
|
9
|
+
if (seconds < 60) {
|
|
10
|
+
return translate("{{seconds}}s ago", { seconds });
|
|
11
|
+
}
|
|
12
|
+
const minutes = Math.floor(seconds / 60);
|
|
13
|
+
if (minutes < 60) {
|
|
14
|
+
return translate("{{minutes}}m ago", { minutes });
|
|
15
|
+
}
|
|
16
|
+
const hours = Math.floor(minutes / 60);
|
|
17
|
+
if (hours < 24) {
|
|
18
|
+
return translate("{{hours}}h ago", { hours });
|
|
19
|
+
}
|
|
20
|
+
return new Date(timestamp).toLocaleString();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { formatAgo };
|
|
24
|
+
//# sourceMappingURL=formatAgo.js.map
|
|
25
|
+
//# sourceMappingURL=formatAgo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/formatAgo.ts"],"names":[],"mappings":";;AAEO,SAAS,SAAA,CAAU,SAAA,EAAmB,GAAA,GAAM,IAAA,CAAK,KAAI,EAAW;AACnE,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,SAAS,CAAA;AAE1C,EAAA,IAAI,SAAS,GAAA,EAAO;AAChB,IAAA,OAAO,UAAU,UAAU,CAAA;AAAA,EAC/B;AAEA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,GAAK,CAAA;AACzC,EAAA,IAAI,UAAU,EAAA,EAAI;AACd,IAAA,OAAO,SAAA,CAAU,kBAAA,EAAoB,EAAE,OAAA,EAAS,CAAA;AAAA,EACpD;AAEA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,EAAE,CAAA;AACvC,EAAA,IAAI,UAAU,EAAA,EAAI;AACd,IAAA,OAAO,SAAA,CAAU,kBAAA,EAAoB,EAAE,OAAA,EAAS,CAAA;AAAA,EACpD;AAEA,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,EAAE,CAAA;AACrC,EAAA,IAAI,QAAQ,EAAA,EAAI;AACZ,IAAA,OAAO,SAAA,CAAU,gBAAA,EAAkB,EAAE,KAAA,EAAO,CAAA;AAAA,EAChD;AAEA,EAAA,OAAO,IAAI,IAAA,CAAK,SAAS,CAAA,CAAE,cAAA,EAAe;AAC9C","file":"formatAgo.js","sourcesContent":["import { translate } from './i18n.js';\n\nexport function formatAgo(timestamp: number, now = Date.now()): string {\n const diffMs = Math.max(0, now - timestamp);\n\n if (diffMs < 5_000) {\n return translate('just now');\n }\n\n const seconds = Math.floor(diffMs / 1_000);\n if (seconds < 60) {\n return translate('{{seconds}}s ago', { seconds });\n }\n\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) {\n return translate('{{minutes}}m ago', { minutes });\n }\n\n const hours = Math.floor(minutes / 60);\n if (hours < 24) {\n return translate('{{hours}}h ago', { hours });\n }\n\n return new Date(timestamp).toLocaleString();\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DevtoolsLabelLookup } from './createLabelLookup.js';
|
|
2
|
+
import '@nnkogift/dhis2-form-utils-metadata';
|
|
3
|
+
|
|
4
|
+
type RuleActionLike = {
|
|
5
|
+
programRuleActionType?: string;
|
|
6
|
+
dataElement?: {
|
|
7
|
+
id?: string;
|
|
8
|
+
displayName?: string;
|
|
9
|
+
};
|
|
10
|
+
trackedEntityAttribute?: {
|
|
11
|
+
id?: string;
|
|
12
|
+
displayName?: string;
|
|
13
|
+
};
|
|
14
|
+
programStageSection?: {
|
|
15
|
+
id?: string;
|
|
16
|
+
displayName?: string;
|
|
17
|
+
};
|
|
18
|
+
programSection?: {
|
|
19
|
+
id?: string;
|
|
20
|
+
displayName?: string;
|
|
21
|
+
};
|
|
22
|
+
data?: string | null;
|
|
23
|
+
content?: string | null;
|
|
24
|
+
location?: string | null;
|
|
25
|
+
};
|
|
26
|
+
type FormattedRuleAction = {
|
|
27
|
+
type: string;
|
|
28
|
+
targetLabel: string;
|
|
29
|
+
detail?: string;
|
|
30
|
+
};
|
|
31
|
+
declare function formatRuleActionSummary(action: RuleActionLike, labelLookup?: DevtoolsLabelLookup): FormattedRuleAction;
|
|
32
|
+
|
|
33
|
+
export { type FormattedRuleAction, type RuleActionLike, formatRuleActionSummary };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
function resolveFieldLabel(id, displayName, labelLookup) {
|
|
2
|
+
if (labelLookup) {
|
|
3
|
+
const resolved = labelLookup.resolveFieldName(id);
|
|
4
|
+
if (resolved !== id) {
|
|
5
|
+
return resolved;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return displayName ?? id;
|
|
9
|
+
}
|
|
10
|
+
function resolveSectionLabel(id, displayName, labelLookup) {
|
|
11
|
+
if (labelLookup) {
|
|
12
|
+
const resolved = labelLookup.resolveSectionName(id);
|
|
13
|
+
if (resolved !== id) {
|
|
14
|
+
return resolved;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return displayName ?? id;
|
|
18
|
+
}
|
|
19
|
+
function formatRuleActionSummary(action, labelLookup) {
|
|
20
|
+
const type = action.programRuleActionType ?? "UNKNOWN";
|
|
21
|
+
let targetLabel = "";
|
|
22
|
+
if (action.dataElement?.id) {
|
|
23
|
+
targetLabel = resolveFieldLabel(
|
|
24
|
+
action.dataElement.id,
|
|
25
|
+
action.dataElement.displayName,
|
|
26
|
+
labelLookup
|
|
27
|
+
);
|
|
28
|
+
} else if (action.trackedEntityAttribute?.id) {
|
|
29
|
+
targetLabel = resolveFieldLabel(
|
|
30
|
+
action.trackedEntityAttribute.id,
|
|
31
|
+
action.trackedEntityAttribute.displayName,
|
|
32
|
+
labelLookup
|
|
33
|
+
);
|
|
34
|
+
} else if (action.programStageSection?.id) {
|
|
35
|
+
targetLabel = resolveSectionLabel(
|
|
36
|
+
action.programStageSection.id,
|
|
37
|
+
action.programStageSection.displayName,
|
|
38
|
+
labelLookup
|
|
39
|
+
);
|
|
40
|
+
} else if (action.programSection?.id) {
|
|
41
|
+
targetLabel = resolveSectionLabel(
|
|
42
|
+
action.programSection.id,
|
|
43
|
+
action.programSection.displayName,
|
|
44
|
+
labelLookup
|
|
45
|
+
);
|
|
46
|
+
} else if (type === "DISPLAYTEXT" || type === "DISPLAYKEYVALUEPAIR") {
|
|
47
|
+
targetLabel = action.location ?? "feedback";
|
|
48
|
+
}
|
|
49
|
+
let detail;
|
|
50
|
+
if (action.data) {
|
|
51
|
+
detail = action.data;
|
|
52
|
+
}
|
|
53
|
+
if (action.content && (type === "DISPLAYTEXT" || type === "DISPLAYKEYVALUEPAIR")) {
|
|
54
|
+
detail = action.content;
|
|
55
|
+
}
|
|
56
|
+
return { type, targetLabel, detail };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { formatRuleActionSummary };
|
|
60
|
+
//# sourceMappingURL=formatRuleActionSummary.js.map
|
|
61
|
+
//# sourceMappingURL=formatRuleActionSummary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/formatRuleActionSummary.ts"],"names":[],"mappings":"AAmBA,SAAS,iBAAA,CACL,EAAA,EACA,WAAA,EACA,WAAA,EACM;AACN,EAAA,IAAI,WAAA,EAAa;AACb,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,gBAAA,CAAiB,EAAE,CAAA;AAChD,IAAA,IAAI,aAAa,EAAA,EAAI;AACjB,MAAA,OAAO,QAAA;AAAA,IACX;AAAA,EACJ;AACA,EAAA,OAAO,WAAA,IAAe,EAAA;AAC1B;AAEA,SAAS,mBAAA,CACL,EAAA,EACA,WAAA,EACA,WAAA,EACM;AACN,EAAA,IAAI,WAAA,EAAa;AACb,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,kBAAA,CAAmB,EAAE,CAAA;AAClD,IAAA,IAAI,aAAa,EAAA,EAAI;AACjB,MAAA,OAAO,QAAA;AAAA,IACX;AAAA,EACJ;AACA,EAAA,OAAO,WAAA,IAAe,EAAA;AAC1B;AAEO,SAAS,uBAAA,CACZ,QACA,WAAA,EACmB;AACnB,EAAA,MAAM,IAAA,GAAO,OAAO,qBAAA,IAAyB,SAAA;AAE7C,EAAA,IAAI,WAAA,GAAc,EAAA;AAClB,EAAA,IAAI,MAAA,CAAO,aAAa,EAAA,EAAI;AACxB,IAAA,WAAA,GAAc,iBAAA;AAAA,MACV,OAAO,WAAA,CAAY,EAAA;AAAA,MACnB,OAAO,WAAA,CAAY,WAAA;AAAA,MACnB;AAAA,KACJ;AAAA,EACJ,CAAA,MAAA,IAAW,MAAA,CAAO,sBAAA,EAAwB,EAAA,EAAI;AAC1C,IAAA,WAAA,GAAc,iBAAA;AAAA,MACV,OAAO,sBAAA,CAAuB,EAAA;AAAA,MAC9B,OAAO,sBAAA,CAAuB,WAAA;AAAA,MAC9B;AAAA,KACJ;AAAA,EACJ,CAAA,MAAA,IAAW,MAAA,CAAO,mBAAA,EAAqB,EAAA,EAAI;AACvC,IAAA,WAAA,GAAc,mBAAA;AAAA,MACV,OAAO,mBAAA,CAAoB,EAAA;AAAA,MAC3B,OAAO,mBAAA,CAAoB,WAAA;AAAA,MAC3B;AAAA,KACJ;AAAA,EACJ,CAAA,MAAA,IAAW,MAAA,CAAO,cAAA,EAAgB,EAAA,EAAI;AAClC,IAAA,WAAA,GAAc,mBAAA;AAAA,MACV,OAAO,cAAA,CAAe,EAAA;AAAA,MACtB,OAAO,cAAA,CAAe,WAAA;AAAA,MACtB;AAAA,KACJ;AAAA,EACJ,CAAA,MAAA,IAAW,IAAA,KAAS,aAAA,IAAiB,IAAA,KAAS,qBAAA,EAAuB;AACjE,IAAA,WAAA,GAAc,OAAO,QAAA,IAAY,UAAA;AAAA,EACrC;AAEA,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,OAAO,IAAA,EAAM;AACb,IAAA,MAAA,GAAS,MAAA,CAAO,IAAA;AAAA,EACpB;AACA,EAAA,IAAI,MAAA,CAAO,OAAA,KAAY,IAAA,KAAS,aAAA,IAAiB,SAAS,qBAAA,CAAA,EAAwB;AAC9E,IAAA,MAAA,GAAS,MAAA,CAAO,OAAA;AAAA,EACpB;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,WAAA,EAAa,MAAA,EAAO;AACvC","file":"formatRuleActionSummary.js","sourcesContent":["import type { DevtoolsLabelLookup } from './createLabelLookup.js';\n\nexport type RuleActionLike = {\n programRuleActionType?: string;\n dataElement?: { id?: string; displayName?: string };\n trackedEntityAttribute?: { id?: string; displayName?: string };\n programStageSection?: { id?: string; displayName?: string };\n programSection?: { id?: string; displayName?: string };\n data?: string | null;\n content?: string | null;\n location?: string | null;\n};\n\nexport type FormattedRuleAction = {\n type: string;\n targetLabel: string;\n detail?: string;\n};\n\nfunction resolveFieldLabel(\n id: string,\n displayName: string | undefined,\n labelLookup?: DevtoolsLabelLookup\n): string {\n if (labelLookup) {\n const resolved = labelLookup.resolveFieldName(id);\n if (resolved !== id) {\n return resolved;\n }\n }\n return displayName ?? id;\n}\n\nfunction resolveSectionLabel(\n id: string,\n displayName: string | undefined,\n labelLookup?: DevtoolsLabelLookup\n): string {\n if (labelLookup) {\n const resolved = labelLookup.resolveSectionName(id);\n if (resolved !== id) {\n return resolved;\n }\n }\n return displayName ?? id;\n}\n\nexport function formatRuleActionSummary(\n action: RuleActionLike,\n labelLookup?: DevtoolsLabelLookup\n): FormattedRuleAction {\n const type = action.programRuleActionType ?? 'UNKNOWN';\n\n let targetLabel = '';\n if (action.dataElement?.id) {\n targetLabel = resolveFieldLabel(\n action.dataElement.id,\n action.dataElement.displayName,\n labelLookup\n );\n } else if (action.trackedEntityAttribute?.id) {\n targetLabel = resolveFieldLabel(\n action.trackedEntityAttribute.id,\n action.trackedEntityAttribute.displayName,\n labelLookup\n );\n } else if (action.programStageSection?.id) {\n targetLabel = resolveSectionLabel(\n action.programStageSection.id,\n action.programStageSection.displayName,\n labelLookup\n );\n } else if (action.programSection?.id) {\n targetLabel = resolveSectionLabel(\n action.programSection.id,\n action.programSection.displayName,\n labelLookup\n );\n } else if (type === 'DISPLAYTEXT' || type === 'DISPLAYKEYVALUEPAIR') {\n targetLabel = action.location ?? 'feedback';\n }\n\n let detail: string | undefined;\n if (action.data) {\n detail = action.data;\n }\n if (action.content && (type === 'DISPLAYTEXT' || type === 'DISPLAYKEYVALUEPAIR')) {\n detail = action.content;\n }\n\n return { type, targetLabel, detail };\n}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { GraphNodeKind, GraphEdge, RuleDependencyGraph } from './buildGraph.js';
|
|
2
|
+
import '@nnkogift/dhis2-form-utils-hooks';
|
|
3
|
+
import './createLabelLookup.js';
|
|
4
|
+
import '@nnkogift/dhis2-form-utils-metadata';
|
|
5
|
+
|
|
6
|
+
type GraphNodePosition = {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
};
|
|
10
|
+
type FlowGraphRole = 'source' | 'rule' | 'target';
|
|
11
|
+
/** A single visual node in the React Flow canvas (may differ from the semantic graph node). */
|
|
12
|
+
type FlowGraphNode = {
|
|
13
|
+
id: string;
|
|
14
|
+
graphNodeId: string;
|
|
15
|
+
kind: GraphNodeKind;
|
|
16
|
+
label: string;
|
|
17
|
+
role: FlowGraphRole;
|
|
18
|
+
};
|
|
19
|
+
type PreparedFlowGraph = {
|
|
20
|
+
nodes: FlowGraphNode[];
|
|
21
|
+
edges: GraphEdge[];
|
|
22
|
+
};
|
|
23
|
+
/** Column x-coordinates by node role. Effect targets always sit to the right of rules. */
|
|
24
|
+
declare const ROLE_COLUMNS: Record<FlowGraphRole, number>;
|
|
25
|
+
/** Feedback targets get an extra column so they never overlap sections/field targets. */
|
|
26
|
+
declare const FEEDBACK_COLUMN = 720;
|
|
27
|
+
/** Vertical distance between rule lanes. */
|
|
28
|
+
declare const LANE_HEIGHT = 104;
|
|
29
|
+
/**
|
|
30
|
+
* Expands the semantic graph into flow nodes so every edge runs left → right.
|
|
31
|
+
* Fields that are both read sources and effect targets are split into `@src` /
|
|
32
|
+
* `@tgt` copies at the source and target columns respectively.
|
|
33
|
+
*/
|
|
34
|
+
declare function prepareFlowGraph(graph: RuleDependencyGraph): PreparedFlowGraph;
|
|
35
|
+
/**
|
|
36
|
+
* Rule-centric lane layout on flow nodes. Each rule owns one horizontal lane;
|
|
37
|
+
* sources sit left, targets right, so every edge flows in the same direction.
|
|
38
|
+
*/
|
|
39
|
+
declare function computeGraphLayout(flowNodes: FlowGraphNode[], flowEdges: GraphEdge[]): Map<string, GraphNodePosition>;
|
|
40
|
+
/** @deprecated Use ROLE_COLUMNS.source */
|
|
41
|
+
declare const KIND_COLUMNS: {
|
|
42
|
+
readonly field: number;
|
|
43
|
+
readonly rule: number;
|
|
44
|
+
readonly section: number;
|
|
45
|
+
readonly feedback: 720;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export { FEEDBACK_COLUMN, type FlowGraphNode, type FlowGraphRole, type GraphNodePosition, KIND_COLUMNS, LANE_HEIGHT, type PreparedFlowGraph, ROLE_COLUMNS, computeGraphLayout, prepareFlowGraph };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
const ROLE_COLUMNS = {
|
|
2
|
+
source: 0,
|
|
3
|
+
rule: 280,
|
|
4
|
+
target: 560
|
|
5
|
+
};
|
|
6
|
+
const FEEDBACK_COLUMN = 720;
|
|
7
|
+
const LANE_HEIGHT = 104;
|
|
8
|
+
const STAGGER = 24;
|
|
9
|
+
function median(values) {
|
|
10
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
11
|
+
const mid = Math.floor(sorted.length / 2);
|
|
12
|
+
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
13
|
+
}
|
|
14
|
+
function staggerOffset(indexInBucket) {
|
|
15
|
+
if (indexInBucket === 0) {
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
const magnitude = Math.ceil(indexInBucket / 2) * STAGGER;
|
|
19
|
+
return indexInBucket % 2 === 1 ? magnitude : -magnitude;
|
|
20
|
+
}
|
|
21
|
+
function columnFor(node) {
|
|
22
|
+
if (node.role === "target" && node.kind === "feedback") {
|
|
23
|
+
return FEEDBACK_COLUMN;
|
|
24
|
+
}
|
|
25
|
+
return ROLE_COLUMNS[node.role];
|
|
26
|
+
}
|
|
27
|
+
function prepareFlowGraph(graph) {
|
|
28
|
+
const readSources = /* @__PURE__ */ new Set();
|
|
29
|
+
const effectTargets = /* @__PURE__ */ new Set();
|
|
30
|
+
for (const edge of graph.edges) {
|
|
31
|
+
if (edge.effectType === "read") {
|
|
32
|
+
readSources.add(edge.source);
|
|
33
|
+
} else {
|
|
34
|
+
effectTargets.add(edge.target);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const flowNodes = [];
|
|
38
|
+
const endpointByGraphId = /* @__PURE__ */ new Map();
|
|
39
|
+
for (const node of graph.nodes) {
|
|
40
|
+
if (node.kind === "rule") {
|
|
41
|
+
flowNodes.push({
|
|
42
|
+
id: node.id,
|
|
43
|
+
graphNodeId: node.id,
|
|
44
|
+
kind: node.kind,
|
|
45
|
+
label: node.label,
|
|
46
|
+
role: "rule"
|
|
47
|
+
});
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const isSource = readSources.has(node.id);
|
|
51
|
+
const isTarget = effectTargets.has(node.id);
|
|
52
|
+
const endpoints = {};
|
|
53
|
+
if (isSource) {
|
|
54
|
+
const flowId = isTarget ? `${node.id}@src` : node.id;
|
|
55
|
+
endpoints.source = flowId;
|
|
56
|
+
flowNodes.push({
|
|
57
|
+
id: flowId,
|
|
58
|
+
graphNodeId: node.id,
|
|
59
|
+
kind: node.kind,
|
|
60
|
+
label: node.label,
|
|
61
|
+
role: "source"
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (isTarget) {
|
|
65
|
+
const flowId = isSource ? `${node.id}@tgt` : node.id;
|
|
66
|
+
endpoints.target = flowId;
|
|
67
|
+
flowNodes.push({
|
|
68
|
+
id: flowId,
|
|
69
|
+
graphNodeId: node.id,
|
|
70
|
+
kind: node.kind,
|
|
71
|
+
label: node.label,
|
|
72
|
+
role: "target"
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
endpointByGraphId.set(node.id, endpoints);
|
|
76
|
+
}
|
|
77
|
+
const flowEdges = graph.edges.map((edge) => {
|
|
78
|
+
if (edge.effectType === "read") {
|
|
79
|
+
const endpoints2 = endpointByGraphId.get(edge.source);
|
|
80
|
+
return { ...edge, source: endpoints2?.source ?? edge.source };
|
|
81
|
+
}
|
|
82
|
+
const endpoints = endpointByGraphId.get(edge.target);
|
|
83
|
+
return { ...edge, target: endpoints?.target ?? edge.target };
|
|
84
|
+
});
|
|
85
|
+
return { nodes: flowNodes, edges: flowEdges };
|
|
86
|
+
}
|
|
87
|
+
function computeGraphLayout(flowNodes, flowEdges) {
|
|
88
|
+
const positions = /* @__PURE__ */ new Map();
|
|
89
|
+
const ruleLane = /* @__PURE__ */ new Map();
|
|
90
|
+
flowNodes.filter((node) => node.role === "rule").forEach((node, index) => {
|
|
91
|
+
ruleLane.set(node.id, index);
|
|
92
|
+
positions.set(node.id, { x: ROLE_COLUMNS.rule, y: index * LANE_HEIGHT });
|
|
93
|
+
});
|
|
94
|
+
const connectedRuleLanes = /* @__PURE__ */ new Map();
|
|
95
|
+
const addLane = (nodeId, lane) => {
|
|
96
|
+
const lanes = connectedRuleLanes.get(nodeId) ?? /* @__PURE__ */ new Set();
|
|
97
|
+
lanes.add(lane);
|
|
98
|
+
connectedRuleLanes.set(nodeId, lanes);
|
|
99
|
+
};
|
|
100
|
+
for (const edge of flowEdges) {
|
|
101
|
+
const sourceLane = ruleLane.get(edge.source);
|
|
102
|
+
const targetLane = ruleLane.get(edge.target);
|
|
103
|
+
if (targetLane !== void 0 && sourceLane === void 0) {
|
|
104
|
+
addLane(edge.source, targetLane);
|
|
105
|
+
}
|
|
106
|
+
if (sourceLane !== void 0 && targetLane === void 0) {
|
|
107
|
+
addLane(edge.target, sourceLane);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const bucketCounts = /* @__PURE__ */ new Map();
|
|
111
|
+
for (const node of flowNodes) {
|
|
112
|
+
if (node.role === "rule") {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const lanes = connectedRuleLanes.get(node.id);
|
|
116
|
+
const lane = lanes && lanes.size > 0 ? median([...lanes]) : 0;
|
|
117
|
+
const column = columnFor(node);
|
|
118
|
+
const bucketKey = `${String(column)}:${String(lane)}`;
|
|
119
|
+
const indexInBucket = bucketCounts.get(bucketKey) ?? 0;
|
|
120
|
+
bucketCounts.set(bucketKey, indexInBucket + 1);
|
|
121
|
+
positions.set(node.id, {
|
|
122
|
+
x: column,
|
|
123
|
+
y: lane * LANE_HEIGHT + staggerOffset(indexInBucket)
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return positions;
|
|
127
|
+
}
|
|
128
|
+
const KIND_COLUMNS = {
|
|
129
|
+
field: ROLE_COLUMNS.source,
|
|
130
|
+
rule: ROLE_COLUMNS.rule,
|
|
131
|
+
section: ROLE_COLUMNS.target,
|
|
132
|
+
feedback: FEEDBACK_COLUMN
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export { FEEDBACK_COLUMN, KIND_COLUMNS, LANE_HEIGHT, ROLE_COLUMNS, computeGraphLayout, prepareFlowGraph };
|
|
136
|
+
//# sourceMappingURL=graphLayout.js.map
|
|
137
|
+
//# sourceMappingURL=graphLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/graphLayout.ts"],"names":["endpoints"],"mappings":"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","file":"graphLayout.js","sourcesContent":["import type { GraphEdge, GraphNodeKind, RuleDependencyGraph } from './buildGraph.js';\n\nexport type GraphNodePosition = { x: number; y: number };\n\nexport type FlowGraphRole = 'source' | 'rule' | 'target';\n\n/** A single visual node in the React Flow canvas (may differ from the semantic graph node). */\nexport type FlowGraphNode = {\n id: string;\n graphNodeId: string;\n kind: GraphNodeKind;\n label: string;\n role: FlowGraphRole;\n};\n\nexport type PreparedFlowGraph = {\n nodes: FlowGraphNode[];\n edges: GraphEdge[];\n};\n\n/** Column x-coordinates by node role. Effect targets always sit to the right of rules. */\nexport const ROLE_COLUMNS: Record<FlowGraphRole, number> = {\n source: 0,\n rule: 280,\n target: 560,\n};\n\n/** Feedback targets get an extra column so they never overlap sections/field targets. */\nexport const FEEDBACK_COLUMN = 720;\n\n/** Vertical distance between rule lanes. */\nexport const LANE_HEIGHT = 104;\n\n/** Vertical spread applied to nodes that land in the same column and lane. */\nconst STAGGER = 24;\n\nfunction median(values: number[]): number {\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];\n}\n\n/** Centered spread: 0, +24, -24, +48, -48, … so a bucket fans out around its lane. */\nfunction staggerOffset(indexInBucket: number): number {\n if (indexInBucket === 0) {\n return 0;\n }\n const magnitude = Math.ceil(indexInBucket / 2) * STAGGER;\n return indexInBucket % 2 === 1 ? magnitude : -magnitude;\n}\n\nfunction columnFor(node: FlowGraphNode): number {\n if (node.role === 'target' && node.kind === 'feedback') {\n return FEEDBACK_COLUMN;\n }\n return ROLE_COLUMNS[node.role];\n}\n\n/**\n * Expands the semantic graph into flow nodes so every edge runs left → right.\n * Fields that are both read sources and effect targets are split into `@src` /\n * `@tgt` copies at the source and target columns respectively.\n */\nexport function prepareFlowGraph(graph: RuleDependencyGraph): PreparedFlowGraph {\n const readSources = new Set<string>();\n const effectTargets = new Set<string>();\n\n for (const edge of graph.edges) {\n if (edge.effectType === 'read') {\n readSources.add(edge.source);\n } else {\n effectTargets.add(edge.target);\n }\n }\n\n const flowNodes: FlowGraphNode[] = [];\n const endpointByGraphId = new Map<string, { source?: string; target?: string }>();\n\n for (const node of graph.nodes) {\n if (node.kind === 'rule') {\n flowNodes.push({\n id: node.id,\n graphNodeId: node.id,\n kind: node.kind,\n label: node.label,\n role: 'rule',\n });\n continue;\n }\n\n const isSource = readSources.has(node.id);\n const isTarget = effectTargets.has(node.id);\n const endpoints: { source?: string; target?: string } = {};\n\n if (isSource) {\n const flowId = isTarget ? `${node.id}@src` : node.id;\n endpoints.source = flowId;\n flowNodes.push({\n id: flowId,\n graphNodeId: node.id,\n kind: node.kind,\n label: node.label,\n role: 'source',\n });\n }\n\n if (isTarget) {\n const flowId = isSource ? `${node.id}@tgt` : node.id;\n endpoints.target = flowId;\n flowNodes.push({\n id: flowId,\n graphNodeId: node.id,\n kind: node.kind,\n label: node.label,\n role: 'target',\n });\n }\n\n endpointByGraphId.set(node.id, endpoints);\n }\n\n const flowEdges = graph.edges.map((edge) => {\n if (edge.effectType === 'read') {\n const endpoints = endpointByGraphId.get(edge.source);\n return { ...edge, source: endpoints?.source ?? edge.source };\n }\n const endpoints = endpointByGraphId.get(edge.target);\n return { ...edge, target: endpoints?.target ?? edge.target };\n });\n\n return { nodes: flowNodes, edges: flowEdges };\n}\n\n/**\n * Rule-centric lane layout on flow nodes. Each rule owns one horizontal lane;\n * sources sit left, targets right, so every edge flows in the same direction.\n */\nexport function computeGraphLayout(\n flowNodes: FlowGraphNode[],\n flowEdges: GraphEdge[]\n): Map<string, GraphNodePosition> {\n const positions = new Map<string, GraphNodePosition>();\n\n const ruleLane = new Map<string, number>();\n flowNodes\n .filter((node) => node.role === 'rule')\n .forEach((node, index) => {\n ruleLane.set(node.id, index);\n positions.set(node.id, { x: ROLE_COLUMNS.rule, y: index * LANE_HEIGHT });\n });\n\n const connectedRuleLanes = new Map<string, Set<number>>();\n const addLane = (nodeId: string, lane: number) => {\n const lanes = connectedRuleLanes.get(nodeId) ?? new Set<number>();\n lanes.add(lane);\n connectedRuleLanes.set(nodeId, lanes);\n };\n\n for (const edge of flowEdges) {\n const sourceLane = ruleLane.get(edge.source);\n const targetLane = ruleLane.get(edge.target);\n if (targetLane !== undefined && sourceLane === undefined) {\n addLane(edge.source, targetLane);\n }\n if (sourceLane !== undefined && targetLane === undefined) {\n addLane(edge.target, sourceLane);\n }\n }\n\n const bucketCounts = new Map<string, number>();\n for (const node of flowNodes) {\n if (node.role === 'rule') {\n continue;\n }\n const lanes = connectedRuleLanes.get(node.id);\n const lane = lanes && lanes.size > 0 ? median([...lanes]) : 0;\n const column = columnFor(node);\n const bucketKey = `${String(column)}:${String(lane)}`;\n const indexInBucket = bucketCounts.get(bucketKey) ?? 0;\n bucketCounts.set(bucketKey, indexInBucket + 1);\n positions.set(node.id, {\n x: column,\n y: lane * LANE_HEIGHT + staggerOffset(indexInBucket),\n });\n }\n\n return positions;\n}\n\n/** @deprecated Use ROLE_COLUMNS.source */\nexport const KIND_COLUMNS = {\n field: ROLE_COLUMNS.source,\n rule: ROLE_COLUMNS.rule,\n section: ROLE_COLUMNS.target,\n feedback: FEEDBACK_COLUMN,\n} as const;\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GraphNode } from './buildGraph.js';
|
|
2
|
+
import '@nnkogift/dhis2-form-utils-hooks';
|
|
3
|
+
import './createLabelLookup.js';
|
|
4
|
+
import '@nnkogift/dhis2-form-utils-metadata';
|
|
5
|
+
|
|
6
|
+
declare function getGraphNodeClassName(kind: GraphNode['kind'], highlighted: boolean): string;
|
|
7
|
+
declare function getLegendSwatchClassName(kind: GraphNode['kind']): string;
|
|
8
|
+
|
|
9
|
+
export { getGraphNodeClassName, getLegendSwatchClassName };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const GRAPH_NODE_CLASSES = {
|
|
2
|
+
field: "border-dhis2-blue-500",
|
|
3
|
+
rule: "border-dhis2-teal-600 bg-dhis2-teal-050",
|
|
4
|
+
section: "border-dhis2-grey-600",
|
|
5
|
+
feedback: "border-dhis2-purple-500"
|
|
6
|
+
};
|
|
7
|
+
const LEGEND_SWATCH_CLASSES = {
|
|
8
|
+
field: "bg-dhis2-blue-500",
|
|
9
|
+
rule: "bg-dhis2-teal-600",
|
|
10
|
+
section: "bg-dhis2-grey-600",
|
|
11
|
+
feedback: "bg-dhis2-purple-500"
|
|
12
|
+
};
|
|
13
|
+
function getGraphNodeClassName(kind, highlighted) {
|
|
14
|
+
return `p-dp8 rounded border bg-white min-w-28 max-w-[180px] text-xs shadow-[0_1px_2px_rgb(0_0_0/6%)] transition-opacity duration-150 ease-out cursor-grab active:cursor-grabbing ${GRAPH_NODE_CLASSES[kind]} ${highlighted ? "" : "opacity-35"}`;
|
|
15
|
+
}
|
|
16
|
+
function getLegendSwatchClassName(kind) {
|
|
17
|
+
return `size-2.5 shrink-0 rounded-sm ${LEGEND_SWATCH_CLASSES[kind]}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { getGraphNodeClassName, getLegendSwatchClassName };
|
|
21
|
+
//# sourceMappingURL=graphNodeStyles.js.map
|
|
22
|
+
//# sourceMappingURL=graphNodeStyles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/graphNodeStyles.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAA,GAAwD;AAAA,EAC1D,KAAA,EAAO,uBAAA;AAAA,EACP,IAAA,EAAM,yCAAA;AAAA,EACN,OAAA,EAAS,uBAAA;AAAA,EACT,QAAA,EAAU;AACd,CAAA;AAEA,MAAM,qBAAA,GAA2D;AAAA,EAC7D,KAAA,EAAO,mBAAA;AAAA,EACP,IAAA,EAAM,mBAAA;AAAA,EACN,OAAA,EAAS,mBAAA;AAAA,EACT,QAAA,EAAU;AACd,CAAA;AAEO,SAAS,qBAAA,CAAsB,MAAyB,WAAA,EAA8B;AACzF,EAAA,OAAO,6KAA6K,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA,EACxM,WAAA,GAAc,KAAK,YACvB,CAAA,CAAA;AACJ;AAEO,SAAS,yBAAyB,IAAA,EAAiC;AACtE,EAAA,OAAO,CAAA,6BAAA,EAAgC,qBAAA,CAAsB,IAAI,CAAC,CAAA,CAAA;AACtE","file":"graphNodeStyles.js","sourcesContent":["import type { GraphNode } from './buildGraph.js';\n\nconst GRAPH_NODE_CLASSES: Record<GraphNode['kind'], string> = {\n field: 'border-dhis2-blue-500',\n rule: 'border-dhis2-teal-600 bg-dhis2-teal-050',\n section: 'border-dhis2-grey-600',\n feedback: 'border-dhis2-purple-500',\n};\n\nconst LEGEND_SWATCH_CLASSES: Record<GraphNode['kind'], string> = {\n field: 'bg-dhis2-blue-500',\n rule: 'bg-dhis2-teal-600',\n section: 'bg-dhis2-grey-600',\n feedback: 'bg-dhis2-purple-500',\n};\n\nexport function getGraphNodeClassName(kind: GraphNode['kind'], highlighted: boolean): string {\n return `p-dp8 rounded border bg-white min-w-28 max-w-[180px] text-xs shadow-[0_1px_2px_rgb(0_0_0/6%)] transition-opacity duration-150 ease-out cursor-grab active:cursor-grabbing ${GRAPH_NODE_CLASSES[kind]} ${\n highlighted ? '' : 'opacity-35'\n }`;\n}\n\nexport function getLegendSwatchClassName(kind: GraphNode['kind']): string {\n return `size-2.5 shrink-0 rounded-sm ${LEGEND_SWATCH_CLASSES[kind]}`;\n}\n"]}
|
package/dist/i18n.d.ts
ADDED
package/dist/i18n.js
ADDED
package/dist/i18n.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/i18n.ts"],"names":[],"mappings":";;AAIO,SAAS,SAAA,CAAU,SAAiB,SAAA,EAAwC;AAC/E,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,OAAA,EAAS,SAAS,CAAC,CAAA;AAC5C","file":"i18n.js","sourcesContent":["import i18n from '@dhis2/d2-i18n';\n\ntype TranslateVariables = Record<string, string | number>;\n\nexport function translate(message: string, variables?: TranslateVariables): string {\n return String(i18n.t(message, variables));\n}\n"]}
|