@kopexa/extension-controlref 1.0.0 → 13.0.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/chunk-4C72VBLP.mjs +52 -0
- package/dist/chunk-A7FWOQDN.mjs +210 -0
- package/dist/chunk-AQTNFDGA.mjs +57 -0
- package/dist/chunk-D53W4HWR.mjs +245 -0
- package/dist/chunk-FTEE5U3H.mjs +37 -0
- package/dist/chunk-GYDJVHHG.mjs +250 -0
- package/dist/chunk-IMHLTRZJ.mjs +29 -0
- package/dist/chunk-JM66CQVD.mjs +10 -0
- package/dist/chunk-LMKP3DDN.mjs +189 -0
- package/dist/chunk-RTBFRPB3.mjs +186 -0
- package/dist/chunk-TEDXYIGO.mjs +38 -0
- package/dist/chunk-WIS7ZNTO.mjs +4 -0
- package/dist/chunk-X46EFFCE.mjs +148 -0
- package/dist/chunk-XHD2KFKQ.mjs +16 -0
- package/dist/chunk-ZRKYAFRY.mjs +46 -0
- package/dist/chunk-ZUR6XKMG.mjs +21 -0
- package/dist/components/control-block-view.d.mts +6 -0
- package/dist/components/control-block-view.d.ts +6 -0
- package/dist/components/control-block-view.js +789 -0
- package/dist/components/control-block-view.mjs +11 -0
- package/dist/components/control-implementation-view.d.mts +6 -0
- package/dist/components/control-implementation-view.d.ts +6 -0
- package/dist/components/control-implementation-view.js +52 -0
- package/dist/components/control-implementation-view.mjs +7 -0
- package/dist/components/control-picker.d.mts +25 -0
- package/dist/components/control-picker.d.ts +25 -0
- package/dist/components/control-picker.js +522 -0
- package/dist/components/control-picker.mjs +10 -0
- package/dist/components/control-view.js +677 -122
- package/dist/components/control-view.mjs +5 -5
- package/dist/components/use-control.d.mts +20 -0
- package/dist/components/use-control.d.ts +20 -0
- package/dist/components/use-control.js +127 -0
- package/dist/components/use-control.mjs +9 -0
- package/dist/control-block.d.mts +35 -0
- package/dist/control-block.d.ts +35 -0
- package/dist/control-block.js +1012 -0
- package/dist/control-block.mjs +17 -0
- package/dist/control-implementation.d.mts +7 -0
- package/dist/control-implementation.d.ts +7 -0
- package/dist/control-implementation.js +92 -0
- package/dist/control-implementation.mjs +9 -0
- package/dist/control.d.mts +31 -1
- package/dist/control.d.ts +31 -1
- package/dist/control.js +819 -136
- package/dist/control.mjs +7 -6
- package/dist/defaults.d.mts +3 -9
- package/dist/defaults.d.ts +3 -9
- package/dist/defaults.js +3 -20
- package/dist/defaults.mjs +3 -6
- package/dist/index.d.mts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +1229 -569
- package/dist/index.mjs +58 -21
- package/dist/messages/index.d.mts +135 -0
- package/dist/messages/index.d.ts +135 -0
- package/dist/messages/index.js +137 -2
- package/dist/messages/index.mjs +1 -2
- package/dist/role.d.mts +17 -0
- package/dist/role.d.ts +17 -0
- package/dist/role.js +5 -0
- package/dist/role.mjs +2 -0
- package/dist/types.d.mts +23 -16
- package/dist/types.d.ts +23 -16
- package/dist/utils/create-control-block.d.mts +7 -0
- package/dist/utils/create-control-block.d.ts +7 -0
- package/dist/utils/create-control-block.js +85 -0
- package/dist/utils/create-control-block.mjs +10 -0
- package/dist/utils/create-control-implementation.d.mts +8 -0
- package/dist/utils/create-control-implementation.d.ts +8 -0
- package/dist/utils/create-control-implementation.js +39 -0
- package/dist/utils/create-control-implementation.mjs +7 -0
- package/dist/utils/getControlNodeTypes.d.mts +5 -0
- package/dist/utils/getControlNodeTypes.d.ts +5 -0
- package/dist/utils/getControlNodeTypes.js +44 -0
- package/dist/utils/getControlNodeTypes.mjs +7 -0
- package/dist/utils/index.d.mts +7 -2
- package/dist/utils/index.d.ts +7 -2
- package/dist/utils/index.js +35 -3
- package/dist/utils/index.mjs +7 -4
- package/dist/utils/status-indicator.d.mts +18 -0
- package/dist/utils/status-indicator.d.ts +18 -0
- package/dist/utils/status-indicator.js +80 -0
- package/dist/utils/status-indicator.mjs +7 -0
- package/package.json +11 -11
- package/dist/card-variant.d.mts +0 -12
- package/dist/card-variant.d.ts +0 -12
- package/dist/card-variant.js +0 -66
- package/dist/card-variant.mjs +0 -8
- package/dist/chunk-AC4KL3WX.mjs +0 -29
- package/dist/chunk-AZ5M5MVC.mjs +0 -36
- package/dist/chunk-DTFR234X.mjs +0 -244
- package/dist/chunk-EDD7DYLE.mjs +0 -29
- package/dist/chunk-GC5EBQ7G.mjs +0 -10
- package/dist/chunk-H2ECPGOG.mjs +0 -81
- package/dist/chunk-KLX7Q3HL.mjs +0 -109
- package/dist/chunk-LKRTUIEV.mjs +0 -46
- package/dist/chunk-NAJ6IC4Y.mjs +0 -43
- package/dist/chunk-QI3ZPZTR.mjs +0 -26
- package/dist/chunk-SNRVOTF5.mjs +0 -8
- package/dist/chunk-VP5POY44.mjs +0 -57
- package/dist/chunk-WIR5FCIC.mjs +0 -110
- package/dist/control-ref-view.d.mts +0 -6
- package/dist/control-ref-view.d.ts +0 -6
- package/dist/control-ref-view.js +0 -615
- package/dist/control-ref-view.mjs +0 -15
- package/dist/control-ref.d.mts +0 -28
- package/dist/control-ref.d.ts +0 -28
- package/dist/control-ref.js +0 -687
- package/dist/control-ref.mjs +0 -16
- package/dist/i18n.d.mts +0 -4
- package/dist/i18n.d.ts +0 -4
- package/dist/i18n.js +0 -128
- package/dist/i18n.mjs +0 -10
- package/dist/lang/de.d.mts +0 -24
- package/dist/lang/de.d.ts +0 -24
- package/dist/lang/de.js +0 -25
- package/dist/lang/de.mjs +0 -8
- package/dist/lang/en.d.mts +0 -24
- package/dist/lang/en.d.ts +0 -24
- package/dist/lang/en.js +0 -25
- package/dist/lang/en.mjs +0 -8
- package/dist/settings-dialog.d.mts +0 -19
- package/dist/settings-dialog.d.ts +0 -19
- package/dist/settings-dialog.js +0 -371
- package/dist/settings-dialog.mjs +0 -9
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
ControlPicker
|
|
4
|
+
} from "./chunk-A7FWOQDN.mjs";
|
|
5
|
+
import {
|
|
6
|
+
useControl
|
|
7
|
+
} from "./chunk-4C72VBLP.mjs";
|
|
8
|
+
import {
|
|
9
|
+
messages
|
|
10
|
+
} from "./chunk-D53W4HWR.mjs";
|
|
11
|
+
|
|
12
|
+
// src/components/control-block-view.tsx
|
|
13
|
+
import { useSafeIntl } from "@kopexa/i18n";
|
|
14
|
+
import { SettingsIcon } from "@kopexa/icons";
|
|
15
|
+
import {
|
|
16
|
+
Button,
|
|
17
|
+
Callout,
|
|
18
|
+
Card,
|
|
19
|
+
Chip,
|
|
20
|
+
Dialog,
|
|
21
|
+
Heading,
|
|
22
|
+
IconButton,
|
|
23
|
+
Label,
|
|
24
|
+
Select,
|
|
25
|
+
Switch
|
|
26
|
+
} from "@kopexa/sight";
|
|
27
|
+
import {
|
|
28
|
+
NodeViewContent,
|
|
29
|
+
NodeViewWrapper
|
|
30
|
+
} from "@tiptap/react";
|
|
31
|
+
import { useState } from "react";
|
|
32
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
33
|
+
var ControlBlockView = (props) => {
|
|
34
|
+
var _a, _b, _c, _d, _e, _f;
|
|
35
|
+
const { node, editor, updateAttributes, getPos } = props;
|
|
36
|
+
const attrs = node.attrs;
|
|
37
|
+
const { showStatus, variant } = attrs.options || {};
|
|
38
|
+
const resolver = props.extension.options.resolver;
|
|
39
|
+
const intl = useSafeIntl();
|
|
40
|
+
const { interactive, ind, mapped, isMissing, isOutdated } = useControl({
|
|
41
|
+
attrs,
|
|
42
|
+
resolver,
|
|
43
|
+
editor
|
|
44
|
+
});
|
|
45
|
+
return /* @__PURE__ */ jsx(NodeViewWrapper, { "data-id": (_a = attrs.id) != null ? _a : "", children: /* @__PURE__ */ jsxs(Card.Root, { variant, children: [
|
|
46
|
+
/* @__PURE__ */ jsxs(Card.Header, { children: [
|
|
47
|
+
/* @__PURE__ */ jsx(Card.Heading, { children: /* @__PURE__ */ jsx(Heading, { level: "h3", contentEditable: false, children: (_b = attrs.title) != null ? _b : "Unmapped Control" }) }),
|
|
48
|
+
/* @__PURE__ */ jsxs(Card.Toolbar, { children: [
|
|
49
|
+
showStatus && /* @__PURE__ */ jsx(
|
|
50
|
+
Chip,
|
|
51
|
+
{
|
|
52
|
+
size: "sm",
|
|
53
|
+
"data-active": open,
|
|
54
|
+
contentEditable: false,
|
|
55
|
+
indicator: ind.indicator,
|
|
56
|
+
indicatorColor: ind.indicatorColor,
|
|
57
|
+
indicatorVariant: ind.indicatorVariant,
|
|
58
|
+
...((_c = attrs.options) == null ? void 0 : _c.showStatus) && (attrs == null ? void 0 : attrs.status) && { status: attrs.status },
|
|
59
|
+
variant: "bordered",
|
|
60
|
+
children: (_d = attrs.title) != null ? _d : "Unmapped Control"
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
interactive && /* @__PURE__ */ jsx(
|
|
64
|
+
SettingsDialog,
|
|
65
|
+
{
|
|
66
|
+
resolver,
|
|
67
|
+
initialSelection: attrs.id ? {
|
|
68
|
+
id: attrs.id,
|
|
69
|
+
title: (_e = attrs.title) != null ? _e : "",
|
|
70
|
+
status: (_f = attrs.status) != null ? _f : null
|
|
71
|
+
} : null,
|
|
72
|
+
initialOptions: attrs.options,
|
|
73
|
+
onSave: async ({ control, options }) => {
|
|
74
|
+
var _a2, _b2, _c2, _d2;
|
|
75
|
+
updateAttributes({
|
|
76
|
+
id: (_a2 = control == null ? void 0 : control.id) != null ? _a2 : null,
|
|
77
|
+
title: (_b2 = control == null ? void 0 : control.title) != null ? _b2 : null,
|
|
78
|
+
status: (_c2 = control == null ? void 0 : control.status) != null ? _c2 : null,
|
|
79
|
+
updatedAt: control == null ? void 0 : control.updatedAt,
|
|
80
|
+
options
|
|
81
|
+
});
|
|
82
|
+
const pos = typeof getPos === "function" ? getPos() : null;
|
|
83
|
+
if (pos == null) return;
|
|
84
|
+
const rows = (_d2 = control == null ? void 0 : control.implementations) != null ? _d2 : [];
|
|
85
|
+
try {
|
|
86
|
+
editor.commands.setControlImplementationsAt(pos, rows);
|
|
87
|
+
} catch {
|
|
88
|
+
editor.commands.setControlImplementationsAt(pos, []);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
onUnlink: () => {
|
|
92
|
+
updateAttributes({ id: null, title: null, status: null });
|
|
93
|
+
const pos = typeof getPos === "function" ? getPos() : null;
|
|
94
|
+
if (pos != null)
|
|
95
|
+
editor.commands.setControlImplementationsAt(pos, []);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
] })
|
|
100
|
+
] }),
|
|
101
|
+
/* @__PURE__ */ jsxs(Card.Body, { children: [
|
|
102
|
+
interactive && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
103
|
+
mapped && isMissing && /* @__PURE__ */ jsx(
|
|
104
|
+
Callout,
|
|
105
|
+
{
|
|
106
|
+
print: false,
|
|
107
|
+
variant: "destructive",
|
|
108
|
+
contentEditable: false,
|
|
109
|
+
className: "mb-4",
|
|
110
|
+
children: intl.formatMessage(messages.missing_callout)
|
|
111
|
+
}
|
|
112
|
+
),
|
|
113
|
+
!isMissing && isOutdated && /* @__PURE__ */ jsx(
|
|
114
|
+
Callout,
|
|
115
|
+
{
|
|
116
|
+
print: false,
|
|
117
|
+
variant: "warning",
|
|
118
|
+
contentEditable: false,
|
|
119
|
+
className: "mb-4",
|
|
120
|
+
children: intl.formatMessage(messages.outdated_callout)
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
] }),
|
|
124
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx(NodeViewContent, { className: "content is-editable", as: "div" }) })
|
|
125
|
+
] })
|
|
126
|
+
] }) });
|
|
127
|
+
};
|
|
128
|
+
var SettingsDialog = ({
|
|
129
|
+
initialSelection,
|
|
130
|
+
initialOptions,
|
|
131
|
+
resolver,
|
|
132
|
+
onSave
|
|
133
|
+
}) => {
|
|
134
|
+
const intl = useSafeIntl();
|
|
135
|
+
const [isOpen, onOpenChange] = useState(false);
|
|
136
|
+
const [selection, setSelection] = useState(
|
|
137
|
+
initialSelection
|
|
138
|
+
);
|
|
139
|
+
const [options, setOptions] = useState({
|
|
140
|
+
showStatus: false,
|
|
141
|
+
...initialOptions
|
|
142
|
+
});
|
|
143
|
+
return /* @__PURE__ */ jsxs(Dialog, { size: "2xl", open: isOpen, onOpenChange, children: [
|
|
144
|
+
/* @__PURE__ */ jsx(
|
|
145
|
+
Dialog.Trigger,
|
|
146
|
+
{
|
|
147
|
+
render: /* @__PURE__ */ jsx(IconButton, { variant: "outline", color: "default", "aria-label": "Settings", children: /* @__PURE__ */ jsx(SettingsIcon, {}) })
|
|
148
|
+
}
|
|
149
|
+
),
|
|
150
|
+
/* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
|
151
|
+
/* @__PURE__ */ jsxs(Dialog.Header, { children: [
|
|
152
|
+
/* @__PURE__ */ jsx(Dialog.Title, { children: (selection == null ? void 0 : selection.title) ? intl.formatMessage(messages.control_with_title, {
|
|
153
|
+
title: selection.title
|
|
154
|
+
}) : intl.formatMessage(messages.map_control) }),
|
|
155
|
+
/* @__PURE__ */ jsx(Dialog.Description, { children: intl.formatMessage(messages.settings_dialog_description) })
|
|
156
|
+
] }),
|
|
157
|
+
/* @__PURE__ */ jsxs(Dialog.Body, { children: [
|
|
158
|
+
/* @__PURE__ */ jsx(
|
|
159
|
+
ControlPicker,
|
|
160
|
+
{
|
|
161
|
+
resolver,
|
|
162
|
+
value: selection,
|
|
163
|
+
onChange: (next) => {
|
|
164
|
+
setSelection(next);
|
|
165
|
+
},
|
|
166
|
+
debounceMs: 300,
|
|
167
|
+
timeoutMs: 5e3
|
|
168
|
+
}
|
|
169
|
+
),
|
|
170
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-6 flex flex-col gap-3", children: [
|
|
171
|
+
/* @__PURE__ */ jsx(Label, { children: intl.formatMessage(messages.display_options) }),
|
|
172
|
+
/* @__PURE__ */ jsxs(
|
|
173
|
+
Label,
|
|
174
|
+
{
|
|
175
|
+
variant: "secondary",
|
|
176
|
+
className: "flex items-center justify-between gap-3",
|
|
177
|
+
children: [
|
|
178
|
+
/* @__PURE__ */ jsx("span", { children: intl.formatMessage(messages.header_status) }),
|
|
179
|
+
/* @__PURE__ */ jsx(
|
|
180
|
+
Switch,
|
|
181
|
+
{
|
|
182
|
+
"aria-label": intl.formatMessage(messages.header_status_aria),
|
|
183
|
+
checked: !!options.showStatus,
|
|
184
|
+
onCheckedChange: (checked) => setOptions((o) => ({ ...o, showStatus: checked }))
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
),
|
|
190
|
+
/* @__PURE__ */ jsx(Callout, { variant: "info", children: intl.formatMessage(messages.header_status_avv_tip) }),
|
|
191
|
+
/* @__PURE__ */ jsxs(
|
|
192
|
+
Label,
|
|
193
|
+
{
|
|
194
|
+
variant: "secondary",
|
|
195
|
+
className: "flex items-center justify-between gap-3",
|
|
196
|
+
children: [
|
|
197
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
198
|
+
/* @__PURE__ */ jsx("span", { children: intl.formatMessage(messages.variant) }),
|
|
199
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: intl.formatMessage(messages.variant_hint) })
|
|
200
|
+
] }),
|
|
201
|
+
/* @__PURE__ */ jsxs(
|
|
202
|
+
Select,
|
|
203
|
+
{
|
|
204
|
+
value: options.variant || "default",
|
|
205
|
+
onValueChange: (value) => setOptions((o) => ({
|
|
206
|
+
...o,
|
|
207
|
+
variant: value
|
|
208
|
+
})),
|
|
209
|
+
children: [
|
|
210
|
+
/* @__PURE__ */ jsx(Select.Trigger, { className: "w-[180px]", children: /* @__PURE__ */ jsx(Select.Value, { placeholder: "Select a variant" }) }),
|
|
211
|
+
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
212
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "default", children: "Default" }),
|
|
213
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "muted", children: "Muted" }),
|
|
214
|
+
/* @__PURE__ */ jsx(Select.Item, { value: "accent", children: "Accent" })
|
|
215
|
+
] })
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
)
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
)
|
|
222
|
+
] })
|
|
223
|
+
] }),
|
|
224
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { className: "sticky bottom-0 bg-background", children: [
|
|
225
|
+
/* @__PURE__ */ jsx(
|
|
226
|
+
Dialog.CloseTrigger,
|
|
227
|
+
{
|
|
228
|
+
render: /* @__PURE__ */ jsx(Button, { variant: "ghost", color: "default", children: intl.formatMessage(messages.cancel) })
|
|
229
|
+
}
|
|
230
|
+
),
|
|
231
|
+
/* @__PURE__ */ jsx(
|
|
232
|
+
Button,
|
|
233
|
+
{
|
|
234
|
+
color: "primary",
|
|
235
|
+
onClick: () => {
|
|
236
|
+
onSave({ control: selection, options });
|
|
237
|
+
onOpenChange(false);
|
|
238
|
+
},
|
|
239
|
+
disabled: JSON.stringify(selection) === JSON.stringify(initialSelection) && JSON.stringify(options) === JSON.stringify(initialOptions),
|
|
240
|
+
children: intl.formatMessage(messages.save_settings)
|
|
241
|
+
}
|
|
242
|
+
)
|
|
243
|
+
] })
|
|
244
|
+
] })
|
|
245
|
+
] });
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export {
|
|
249
|
+
ControlBlockView
|
|
250
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/components/control-implementation-view.tsx
|
|
4
|
+
import { NodeViewWrapper } from "@tiptap/react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
var ControlImplementationView = (props) => {
|
|
7
|
+
var _a;
|
|
8
|
+
const { node } = props;
|
|
9
|
+
const a = node.attrs;
|
|
10
|
+
return /* @__PURE__ */ jsx(
|
|
11
|
+
NodeViewWrapper,
|
|
12
|
+
{
|
|
13
|
+
as: "div",
|
|
14
|
+
role: "listitem",
|
|
15
|
+
"data-type": "control-implementation",
|
|
16
|
+
"data-id": a.id,
|
|
17
|
+
className: "flex items-start justify-between gap-3 py-3",
|
|
18
|
+
contentEditable: false,
|
|
19
|
+
children: /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-foreground truncate", children: (_a = a.title) != null ? _a : a.id }),
|
|
21
|
+
a.description ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground mt-0.5", children: a.description }) : null
|
|
22
|
+
] })
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
ControlImplementationView
|
|
29
|
+
};
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
ControlPicker
|
|
4
|
+
} from "./chunk-A7FWOQDN.mjs";
|
|
5
|
+
import {
|
|
6
|
+
useControl
|
|
7
|
+
} from "./chunk-4C72VBLP.mjs";
|
|
8
|
+
import {
|
|
9
|
+
messages
|
|
10
|
+
} from "./chunk-D53W4HWR.mjs";
|
|
11
|
+
|
|
12
|
+
// src/components/control-view.tsx
|
|
13
|
+
import { useSafeIntl } from "@kopexa/i18n";
|
|
14
|
+
import {
|
|
15
|
+
Button,
|
|
16
|
+
Callout,
|
|
17
|
+
Chip,
|
|
18
|
+
Dialog,
|
|
19
|
+
Label,
|
|
20
|
+
Switch,
|
|
21
|
+
Tooltip
|
|
22
|
+
} from "@kopexa/sight";
|
|
23
|
+
import { NodeViewWrapper } from "@tiptap/react";
|
|
24
|
+
import { useState } from "react";
|
|
25
|
+
import { useIntl } from "react-intl";
|
|
26
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
27
|
+
var ControlView = (props) => {
|
|
28
|
+
var _a, _b, _c, _d, _e, _f;
|
|
29
|
+
const { node, editor } = props;
|
|
30
|
+
const intl = useIntl();
|
|
31
|
+
const attrs = node.attrs;
|
|
32
|
+
const resolver = props.extension.options.resolver;
|
|
33
|
+
const { isEdit, interactive, ind, mapped, isMissing, isOutdated } = useControl({
|
|
34
|
+
attrs,
|
|
35
|
+
resolver,
|
|
36
|
+
editor
|
|
37
|
+
});
|
|
38
|
+
const [open, setOpen] = useState(false);
|
|
39
|
+
return /* @__PURE__ */ jsxs(NodeViewWrapper, { as: "span", "data-kpx-control": true, "data-id": (_a = attrs.id) != null ? _a : "", children: [
|
|
40
|
+
/* @__PURE__ */ jsxs(
|
|
41
|
+
Chip,
|
|
42
|
+
{
|
|
43
|
+
size: "sm",
|
|
44
|
+
"data-active": open,
|
|
45
|
+
contentEditable: false,
|
|
46
|
+
indicator: ind.indicator,
|
|
47
|
+
indicatorColor: ind.indicatorColor,
|
|
48
|
+
indicatorVariant: ind.indicatorVariant,
|
|
49
|
+
...((_b = attrs.options) == null ? void 0 : _b.showStatus) && (attrs == null ? void 0 : attrs.status) && { status: attrs.status },
|
|
50
|
+
variant: "bordered",
|
|
51
|
+
color: !attrs.id ? "warning" : isEdit && (isOutdated || isMissing) ? "destructive" : "default",
|
|
52
|
+
onClick: () => {
|
|
53
|
+
setOpen((o) => !o);
|
|
54
|
+
},
|
|
55
|
+
"aria-label": interactive ? "Map control" : "Control",
|
|
56
|
+
tabIndex: interactive ? 0 : -1,
|
|
57
|
+
onKeyDown: (e) => {
|
|
58
|
+
if (!interactive) return;
|
|
59
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
60
|
+
e.preventDefault();
|
|
61
|
+
setOpen((o) => !o);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
children: [
|
|
65
|
+
(_c = attrs.title) != null ? _c : "Unmapped Control",
|
|
66
|
+
isEdit && mapped && isOutdated && !isMissing && /* @__PURE__ */ jsx(Tooltip, { content: intl.formatMessage(messages.outdated_badge), children: /* @__PURE__ */ jsx("span", { className: "ml-1 inline-block h-2 w-2 rounded-full bg-warning" }) }),
|
|
67
|
+
mapped && isMissing && /* @__PURE__ */ jsx(Tooltip, { content: intl.formatMessage(messages.missing_badge), children: /* @__PURE__ */ jsx("span", { className: "ml-1 inline-block h-2 w-2 rounded-full bg-destructive" }) })
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
interactive && /* @__PURE__ */ jsx(
|
|
72
|
+
EditControlDialog,
|
|
73
|
+
{
|
|
74
|
+
open,
|
|
75
|
+
onOpenChange: setOpen,
|
|
76
|
+
resolver,
|
|
77
|
+
isMissing,
|
|
78
|
+
isOutdated,
|
|
79
|
+
initialSelection: attrs.id ? {
|
|
80
|
+
id: attrs.id,
|
|
81
|
+
title: (_d = attrs.title) != null ? _d : "",
|
|
82
|
+
status: (_e = attrs.status) != null ? _e : null
|
|
83
|
+
} : null,
|
|
84
|
+
initialOptions: (_f = attrs.options) != null ? _f : { showStatus: true },
|
|
85
|
+
onSave: (selection, options) => {
|
|
86
|
+
var _a2, _b2, _c2;
|
|
87
|
+
props.editor.commands.updateControl({
|
|
88
|
+
id: (_a2 = selection == null ? void 0 : selection.id) != null ? _a2 : null,
|
|
89
|
+
title: (_b2 = selection == null ? void 0 : selection.title) != null ? _b2 : null,
|
|
90
|
+
status: (_c2 = selection == null ? void 0 : selection.status) != null ? _c2 : null,
|
|
91
|
+
options: options != null ? options : null,
|
|
92
|
+
updatedAt: selection == null ? void 0 : selection.updatedAt
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
] });
|
|
98
|
+
};
|
|
99
|
+
var EditControlDialog = ({
|
|
100
|
+
open,
|
|
101
|
+
onOpenChange,
|
|
102
|
+
resolver,
|
|
103
|
+
initialSelection,
|
|
104
|
+
initialOptions,
|
|
105
|
+
onSave,
|
|
106
|
+
isMissing,
|
|
107
|
+
isOutdated
|
|
108
|
+
}) => {
|
|
109
|
+
const intl = useSafeIntl();
|
|
110
|
+
const [selection, setSelection] = useState(
|
|
111
|
+
initialSelection
|
|
112
|
+
);
|
|
113
|
+
const [options, setOptions] = useState(initialOptions);
|
|
114
|
+
const isDirty = JSON.stringify(selection) !== JSON.stringify(initialSelection) || JSON.stringify(options) !== JSON.stringify(initialOptions);
|
|
115
|
+
if (!resolver) return null;
|
|
116
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, size: "2xl", children: /* @__PURE__ */ jsxs(Dialog.Content, { "aria-label": "Map Control", children: [
|
|
117
|
+
/* @__PURE__ */ jsxs(Dialog.Header, { children: [
|
|
118
|
+
/* @__PURE__ */ jsx(Dialog.Title, { children: (selection == null ? void 0 : selection.title) ? intl.formatMessage(messages.control_with_title, {
|
|
119
|
+
title: selection.title
|
|
120
|
+
}) : intl.formatMessage(messages.map_control) }),
|
|
121
|
+
/* @__PURE__ */ jsx(Dialog.Description, { children: intl.formatMessage(messages.settings_dialog_description) })
|
|
122
|
+
] }),
|
|
123
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-6 pt-2", children: [
|
|
124
|
+
(selection == null ? void 0 : selection.id) && isMissing && /* @__PURE__ */ jsx(Callout, { variant: "destructive", children: intl.formatMessage(messages.missing_callout) }),
|
|
125
|
+
!isMissing && isOutdated && /* @__PURE__ */ jsx(Callout, { variant: "warning", children: intl.formatMessage(messages.outdated_callout) }),
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
ControlPicker,
|
|
128
|
+
{
|
|
129
|
+
resolver,
|
|
130
|
+
value: selection,
|
|
131
|
+
onChange: (next) => setSelection(next),
|
|
132
|
+
debounceMs: 300,
|
|
133
|
+
timeoutMs: 5e3
|
|
134
|
+
}
|
|
135
|
+
),
|
|
136
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
137
|
+
/* @__PURE__ */ jsx(Label, { children: intl.formatMessage(messages.display_options) }),
|
|
138
|
+
/* @__PURE__ */ jsxs(
|
|
139
|
+
Label,
|
|
140
|
+
{
|
|
141
|
+
variant: "secondary",
|
|
142
|
+
className: "flex items-center justify-between gap-3",
|
|
143
|
+
children: [
|
|
144
|
+
/* @__PURE__ */ jsx("span", { children: intl.formatMessage(messages.show_status_indicator) }),
|
|
145
|
+
/* @__PURE__ */ jsx(
|
|
146
|
+
Switch,
|
|
147
|
+
{
|
|
148
|
+
"aria-label": "Show status indicator",
|
|
149
|
+
checked: !!options.showStatus,
|
|
150
|
+
onCheckedChange: (checked) => setOptions((o) => ({
|
|
151
|
+
...o,
|
|
152
|
+
showStatus: checked
|
|
153
|
+
}))
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
] }) })
|
|
160
|
+
] }) }),
|
|
161
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { className: "sticky bottom-0 bg-background", children: [
|
|
162
|
+
/* @__PURE__ */ jsx(
|
|
163
|
+
Button,
|
|
164
|
+
{
|
|
165
|
+
variant: "ghost",
|
|
166
|
+
color: "default",
|
|
167
|
+
onClick: () => onOpenChange(false),
|
|
168
|
+
children: intl.formatMessage(messages.cancel)
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
/* @__PURE__ */ jsx(
|
|
172
|
+
Button,
|
|
173
|
+
{
|
|
174
|
+
color: "primary",
|
|
175
|
+
onClick: () => {
|
|
176
|
+
onSave(selection, options);
|
|
177
|
+
onOpenChange(false);
|
|
178
|
+
},
|
|
179
|
+
disabled: !isDirty,
|
|
180
|
+
children: intl.formatMessage(messages.save_settings)
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
] })
|
|
184
|
+
] }) });
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export {
|
|
188
|
+
ControlView
|
|
189
|
+
};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
createControlBlock
|
|
4
|
+
} from "./chunk-FTEE5U3H.mjs";
|
|
5
|
+
import {
|
|
6
|
+
createControlImplementation
|
|
7
|
+
} from "./chunk-XHD2KFKQ.mjs";
|
|
8
|
+
import {
|
|
9
|
+
getControlNodeTypes
|
|
10
|
+
} from "./chunk-ZUR6XKMG.mjs";
|
|
11
|
+
import {
|
|
12
|
+
DEFAULT_CONTROL_REF_OPTIONS
|
|
13
|
+
} from "./chunk-JM66CQVD.mjs";
|
|
14
|
+
import {
|
|
15
|
+
ControlBlockView
|
|
16
|
+
} from "./chunk-GYDJVHHG.mjs";
|
|
17
|
+
|
|
18
|
+
// src/control-block.ts
|
|
19
|
+
import { mergeAttributes, Node } from "@tiptap/core";
|
|
20
|
+
import { TextSelection } from "@tiptap/pm/state";
|
|
21
|
+
import { ReactNodeViewRenderer } from "@tiptap/react";
|
|
22
|
+
var ControlBlock = Node.create({
|
|
23
|
+
name: "controlBlock",
|
|
24
|
+
controlRole: "controlBlock",
|
|
25
|
+
group: "block",
|
|
26
|
+
isolating: true,
|
|
27
|
+
content: "block+ controlImplementation*",
|
|
28
|
+
addOptions() {
|
|
29
|
+
return {
|
|
30
|
+
resolver: void 0
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
addAttributes() {
|
|
34
|
+
return {
|
|
35
|
+
id: { default: null },
|
|
36
|
+
title: { default: null },
|
|
37
|
+
updatedAt: { default: null },
|
|
38
|
+
status: { default: null },
|
|
39
|
+
options: { default: DEFAULT_CONTROL_REF_OPTIONS }
|
|
40
|
+
// JSON Object <- all UI config lives here
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
parseHTML() {
|
|
44
|
+
return [{ tag: "div[data-kpx-control-ref]" }];
|
|
45
|
+
},
|
|
46
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
47
|
+
var _a;
|
|
48
|
+
return [
|
|
49
|
+
"span",
|
|
50
|
+
mergeAttributes(HTMLAttributes, {
|
|
51
|
+
"data-kpx-control-ref": "",
|
|
52
|
+
"data-id": node.attrs.id,
|
|
53
|
+
"data-title": node.attrs.title
|
|
54
|
+
}),
|
|
55
|
+
(_a = HTMLAttributes.title) != null ? _a : "Control"
|
|
56
|
+
];
|
|
57
|
+
},
|
|
58
|
+
addCommands() {
|
|
59
|
+
return {
|
|
60
|
+
insertControlBlock: () => ({ editor, tr, dispatch }) => {
|
|
61
|
+
const node = createControlBlock(editor.schema);
|
|
62
|
+
if (dispatch) {
|
|
63
|
+
const offset = tr.selection.from + 1;
|
|
64
|
+
tr.replaceSelectionWith(node).scrollIntoView().setSelection(TextSelection.near(tr.doc.resolve(offset)));
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
},
|
|
68
|
+
updateControlBlock: (payload) => ({ tr, state, dispatch }) => {
|
|
69
|
+
var _a, _b, _c, _d, _e;
|
|
70
|
+
const { selection } = state;
|
|
71
|
+
const pos = selection.from;
|
|
72
|
+
const node = tr.doc.nodeAt(pos);
|
|
73
|
+
if (!node || node.type.name !== "controlBlock") return false;
|
|
74
|
+
const next = {
|
|
75
|
+
id: (_a = payload.id) != null ? _a : null,
|
|
76
|
+
title: (_b = payload.title) != null ? _b : null,
|
|
77
|
+
status: (_c = payload.status) != null ? _c : null,
|
|
78
|
+
updatedAt: (_d = payload.updatedAt) != null ? _d : null,
|
|
79
|
+
options: (_e = payload.options) != null ? _e : node.attrs.options
|
|
80
|
+
};
|
|
81
|
+
if (dispatch) {
|
|
82
|
+
tr.setNodeMarkup(pos, void 0, next).scrollIntoView();
|
|
83
|
+
}
|
|
84
|
+
return true;
|
|
85
|
+
},
|
|
86
|
+
setControlImplementationsAt: (blockPos, rows) => ({ state, tr, dispatch }) => {
|
|
87
|
+
const implType = state.schema.nodes.controlImplementation;
|
|
88
|
+
if (!implType) return false;
|
|
89
|
+
const blockNode = state.doc.nodeAt(blockPos);
|
|
90
|
+
if (!blockNode || blockNode.type.name !== this.name) return false;
|
|
91
|
+
const contentStart = blockPos + 1;
|
|
92
|
+
const contentEnd = blockPos + blockNode.nodeSize - 1;
|
|
93
|
+
let firstImplOffset = null;
|
|
94
|
+
let running = 0;
|
|
95
|
+
blockNode.forEach((child) => {
|
|
96
|
+
if (firstImplOffset === null && child.type === implType) {
|
|
97
|
+
firstImplOffset = running;
|
|
98
|
+
}
|
|
99
|
+
running += child.nodeSize;
|
|
100
|
+
});
|
|
101
|
+
const insertPos = firstImplOffset !== null ? contentStart + firstImplOffset : contentEnd;
|
|
102
|
+
if (firstImplOffset !== null) {
|
|
103
|
+
tr.delete(insertPos, contentEnd);
|
|
104
|
+
}
|
|
105
|
+
const types = getControlNodeTypes(state.schema);
|
|
106
|
+
const newNodes = (rows != null ? rows : []).map(
|
|
107
|
+
(r) => createControlImplementation(types.controlImplementation, r)
|
|
108
|
+
).filter(Boolean);
|
|
109
|
+
if (newNodes.length) {
|
|
110
|
+
tr.insert(insertPos, newNodes);
|
|
111
|
+
}
|
|
112
|
+
if (dispatch) dispatch(tr.scrollIntoView());
|
|
113
|
+
return true;
|
|
114
|
+
},
|
|
115
|
+
setControlImplementations: (rows) => ({ state, tr, dispatch }) => {
|
|
116
|
+
const { $from } = state.selection;
|
|
117
|
+
let blockPos = -1, blockNode = null, depthHit = -1;
|
|
118
|
+
for (let d = $from.depth; d >= 0; d--) {
|
|
119
|
+
const n = $from.node(d);
|
|
120
|
+
if (n.type.name === this.name) {
|
|
121
|
+
blockNode = n;
|
|
122
|
+
depthHit = d;
|
|
123
|
+
blockPos = $from.start(d);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (!blockNode || blockPos < 0) return false;
|
|
128
|
+
const implType = state.schema.nodes.controlImplementation;
|
|
129
|
+
if (!implType) return false;
|
|
130
|
+
let offset = 0;
|
|
131
|
+
let firstImplOffset = null;
|
|
132
|
+
for (let i = 0; i < blockNode.childCount; i++) {
|
|
133
|
+
const child = blockNode.child(i);
|
|
134
|
+
if (child.type === implType && firstImplOffset === null) {
|
|
135
|
+
firstImplOffset = offset;
|
|
136
|
+
}
|
|
137
|
+
offset += child.nodeSize;
|
|
138
|
+
}
|
|
139
|
+
const blockContentStart = blockPos + 1;
|
|
140
|
+
const blockContentEnd = blockPos + blockNode.nodeSize - 1;
|
|
141
|
+
const insertPos = firstImplOffset !== null ? blockContentStart + firstImplOffset : blockContentEnd;
|
|
142
|
+
if (firstImplOffset !== null) {
|
|
143
|
+
tr.delete(blockContentStart + firstImplOffset, blockContentEnd);
|
|
144
|
+
}
|
|
145
|
+
const types = getControlNodeTypes(state.schema);
|
|
146
|
+
const newNodes = rows.map(
|
|
147
|
+
(r) => createControlImplementation(types.controlImplementation, r)
|
|
148
|
+
).filter(Boolean);
|
|
149
|
+
if (newNodes.length) {
|
|
150
|
+
tr.insert(insertPos, newNodes);
|
|
151
|
+
}
|
|
152
|
+
if (dispatch) dispatch(tr.scrollIntoView());
|
|
153
|
+
return true;
|
|
154
|
+
},
|
|
155
|
+
appendControlImplementations: (rows) => ({ state, tr, dispatch }) => {
|
|
156
|
+
const { $from } = state.selection;
|
|
157
|
+
let blockPos = -1, blockNode = null;
|
|
158
|
+
for (let d = $from.depth; d >= 0; d--) {
|
|
159
|
+
const n = $from.node(d);
|
|
160
|
+
if (n.type.name === this.name) {
|
|
161
|
+
blockNode = n;
|
|
162
|
+
blockPos = $from.start(d);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (!blockNode || blockPos < 0) return false;
|
|
167
|
+
const blockContentEnd = blockPos + blockNode.nodeSize - 1;
|
|
168
|
+
const types = getControlNodeTypes(state.schema);
|
|
169
|
+
const newNodes = rows.map(
|
|
170
|
+
(r) => createControlImplementation(types.controlImplementation, r)
|
|
171
|
+
).filter(Boolean);
|
|
172
|
+
if (!newNodes.length) return true;
|
|
173
|
+
tr.insert(blockContentEnd, newNodes);
|
|
174
|
+
if (dispatch) dispatch(tr.scrollIntoView());
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
},
|
|
179
|
+
addNodeView() {
|
|
180
|
+
return ReactNodeViewRenderer(ControlBlockView, { as: "div" });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
export {
|
|
185
|
+
ControlBlock
|
|
186
|
+
};
|