@septkit/ui 0.0.49 → 0.0.51
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/dialecte/composables/use-active-document.js +27 -17
- package/dist/dialecte/composables/use-live-data.js +13 -13
- package/dist/dialecte/create-document-store.js +3 -3
- package/dist/external/.pnpm/{@dialecte_core@0.4.7 → @dialecte_core@0.4.9}/node_modules/@dialecte/core/dist/helpers.js +16 -19
- package/dist/external/.pnpm/{@dialecte_core@0.4.7 → @dialecte_core@0.4.9}/node_modules/@dialecte/core/dist/index.js +1 -1
- package/dist/external/.pnpm/{@dialecte_core@0.4.7/node_modules/@dialecte/core/dist/project-DxIu-3AU.js → @dialecte_core@0.4.9/node_modules/@dialecte/core/dist/project-D-KS3OPN.js} +1 -1
- package/dist/external/.pnpm/{@dialecte_core@0.4.7 → @dialecte_core@0.4.9}/node_modules/@dialecte/core/dist/utils-C5_11hqg.js +1 -1
- package/dist/external/.pnpm/{@dialecte_scl@0.3.8/node_modules/@dialecte/scl/dist/hooks-DJJN-WU2.js → @dialecte_scl@0.3.12/node_modules/@dialecte/scl/dist/hooks-Cm_UYBBt.js} +48 -5277
- package/dist/external/.pnpm/@dialecte_scl@0.3.12/node_modules/@dialecte/scl/dist/v2019C1/index.js +22 -0
- package/dist/index.d.ts +48 -10
- package/dist/merge/build-view-model.js +101 -74
- package/dist/merge/decision-toggle.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/merge/element-detail.vue_vue_type_script_setup_true_lang.js +154 -45
- package/dist/merge/merge-correlate.js +46 -0
- package/dist/merge/merge-decision.js +6 -0
- package/dist/merge/merge-highlight.js +44 -0
- package/dist/merge/merge-preflight.js +5 -0
- package/dist/merge/merge-preflight.vue_vue_type_script_setup_true_lang.js +41 -0
- package/dist/merge/merge-progress.vue_vue_type_script_setup_true_lang.js +12 -20
- package/dist/merge/merge-review.vue_vue_type_script_setup_true_lang.js +230 -181
- package/dist/merge/merge-summary.vue_vue_type_script_setup_true_lang.js +47 -25
- package/dist/merge/merge-tree.vue_vue_type_script_setup_true_lang.js +73 -62
- package/dist/merge/merge.service.js +36 -23
- package/dist/merge/use-document-progress.js +8 -9
- package/dist/merge/use-merge-session.js +122 -108
- package/dist/ui.css +1 -1
- package/package.json +3 -3
- package/dist/external/.pnpm/@dialecte_scl@0.3.8/node_modules/@dialecte/scl/dist/v2019C1/index.js +0 -3
package/dist/external/.pnpm/@dialecte_scl@0.3.12/node_modules/@dialecte/scl/dist/v2019C1/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import "../../../../../../@dialecte_core@0.4.9/node_modules/@dialecte/core/dist/index.js";
|
|
2
|
+
import { i as e } from "../hooks-Cm_UYBBt.js";
|
|
3
|
+
//#region node_modules/.pnpm/@dialecte+scl@0.3.12/node_modules/@dialecte/scl/dist/v2019C1/index.js
|
|
4
|
+
var t = {
|
|
5
|
+
"cross-type-template-uuid": {
|
|
6
|
+
title: "Placeholder templateUuid reused across element types",
|
|
7
|
+
description: "One templateUuid is carried by elements of several different types, so it cannot identify a single template element — it is an authoring placeholder, not real lineage.",
|
|
8
|
+
fallback: "Template lineage is ignored for these elements; each instance is recognised by its name within its parent instead, so the merge still proceeds."
|
|
9
|
+
},
|
|
10
|
+
"duplicate-instance-uuid": {
|
|
11
|
+
title: "Duplicate instance uuid",
|
|
12
|
+
description: "The same uuid is used by more than one element. Every instance uuid in an SCL must be unique, so uuid-based identity is ambiguous for the affected elements.",
|
|
13
|
+
fallback: "The affected elements are matched by name and position rather than uuid, so the merge still proceeds — resolve the duplication to restore reliable identity."
|
|
14
|
+
},
|
|
15
|
+
"template-uuid-type-mismatch": {
|
|
16
|
+
title: "templateUuid resolves to a different element type",
|
|
17
|
+
description: "A templateUuid points in-file to an element of a different type than the one carrying it. An instance cannot derive from a template of another type, so the lineage is inconsistent.",
|
|
18
|
+
fallback: "The mismatched lineage is ignored and the element is recognised by name, so the merge still proceeds."
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { t as TEMPLATE_UUID_WARNING_INFO, e as presentationScope };
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { Reactive } from 'vue';
|
|
|
21
21
|
import { Ref } from 'vue';
|
|
22
22
|
import { Scl } from '@dialecte/scl/v2019C1';
|
|
23
23
|
import { ShallowRef } from 'vue';
|
|
24
|
+
import { TemplateUuidWarning } from '@dialecte/scl/v2019C1';
|
|
24
25
|
|
|
25
26
|
declare const __VLS_component: DefineComponent<__VLS_Props, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLButtonElement>;
|
|
26
27
|
|
|
@@ -100,6 +101,8 @@ declare type __VLS_Props_11 = {
|
|
|
100
101
|
detail: ElementDetailVM | undefined;
|
|
101
102
|
/** Consumer-supplied fixed prefix/suffix per attribute; the user edits only the core. */
|
|
102
103
|
affixMask?: AffixMaskResolver;
|
|
104
|
+
/** The selected group is skipped: lock editing and show the skip (current) value. */
|
|
105
|
+
disabled?: boolean;
|
|
103
106
|
};
|
|
104
107
|
|
|
105
108
|
declare type __VLS_Props_12 = MergeSessionParams & {
|
|
@@ -405,7 +408,7 @@ export declare const Button: __VLS_WithTemplateSlots<typeof __VLS_component, __V
|
|
|
405
408
|
export declare const CATEGORY_ELEMENTS: Record<string, string[]>;
|
|
406
409
|
|
|
407
410
|
/** How an element or attribute changed between the template and the instance. */
|
|
408
|
-
export declare type ChangeStatus = 'added' | 'removed' | 'modified' | 'unchanged';
|
|
411
|
+
export declare type ChangeStatus = 'added' | 'removed' | 'modified' | 'unchanged' | 'target-only';
|
|
409
412
|
|
|
410
413
|
declare function closeDropdown(): void;
|
|
411
414
|
|
|
@@ -462,10 +465,15 @@ export declare const DecisionToggle: DefineComponent<__VLS_PublicProps_2, {}, {}
|
|
|
462
465
|
export declare type DetailAttribute = {
|
|
463
466
|
name: string;
|
|
464
467
|
status: ChangeStatus;
|
|
465
|
-
/** The current/instance value — the `-` line, present when modified/removed. */
|
|
468
|
+
/** The current/instance value — the `-` line, present when modified/removed. (Skip target.) */
|
|
466
469
|
before?: string;
|
|
467
|
-
/** The
|
|
470
|
+
/** The incoming/proposed value — the `+` line, present when added/modified. (Accept target.) */
|
|
468
471
|
after?: string;
|
|
472
|
+
/**
|
|
473
|
+
* The live value that will actually be written — the user's edit, or accept/skip choice.
|
|
474
|
+
* Defaults to `after` (accept) when unset; a skip sets it to `before`. The input binds to this.
|
|
475
|
+
*/
|
|
476
|
+
written?: string;
|
|
469
477
|
/** When set, the attribute is user-editable and its value renders as an input. */
|
|
470
478
|
editable?: EditableMode;
|
|
471
479
|
/** The engine auto-resolved a placement collision on this field (value = the resolved one). */
|
|
@@ -656,8 +664,23 @@ export declare type MergeNodeMeta = {
|
|
|
656
664
|
role: 'primary' | 'companion' | 'plain';
|
|
657
665
|
/** The decision group this node belongs to (primary + companions share it). */
|
|
658
666
|
groupId?: string;
|
|
667
|
+
/**
|
|
668
|
+
* The topmost changed node of a change region (no changed same-group ancestor above it).
|
|
669
|
+
* Only region heads carry a status marker, so one badge shows per change instead of
|
|
670
|
+
* scattering across correlated companions but not their uuid-less siblings.
|
|
671
|
+
*/
|
|
672
|
+
regionHead?: boolean;
|
|
659
673
|
/** For a satellite companion that lives elsewhere: its real document path (shown as subtitle). */
|
|
660
674
|
path?: string;
|
|
675
|
+
/**
|
|
676
|
+
* Present on an instance ROOT (Application/Function): its linkage to the loaded template
|
|
677
|
+
* and its member cluster. Drives the "linked / up to date" badge and the select-to-highlight
|
|
678
|
+
* of the whole instance (subtree + folded satellites).
|
|
679
|
+
*/
|
|
680
|
+
instance?: {
|
|
681
|
+
linked: boolean;
|
|
682
|
+
upToDate: boolean;
|
|
683
|
+
};
|
|
661
684
|
};
|
|
662
685
|
|
|
663
686
|
export declare const MergeReview: DefineComponent<__VLS_Props_12, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
@@ -737,14 +760,21 @@ export declare type UnifiedDiff = {
|
|
|
737
760
|
};
|
|
738
761
|
|
|
739
762
|
/**
|
|
740
|
-
* Reactively
|
|
763
|
+
* Reactively resolve the shell's active document — race-safe across realms.
|
|
741
764
|
*
|
|
742
765
|
* The active-document id (shell `localStorage` `storage` event) and the
|
|
743
766
|
* project's document registry (BroadcastChannel) are not ordered across realms,
|
|
744
767
|
* so in an iframe extension the id can arrive before the document is registered
|
|
745
768
|
* / its records are readable. `project.getDocumentStatus(id)` reconciles this
|
|
746
|
-
* realm's store against persisted state first, so
|
|
747
|
-
* of the document. Results from a superseded switch are ignored.
|
|
769
|
+
* realm's store against persisted state first, so the exposed document never
|
|
770
|
+
* races ahead of the document. Results from a superseded switch are ignored.
|
|
771
|
+
*
|
|
772
|
+
* The resolved document is returned as a nullable `document` ref (single source
|
|
773
|
+
* of truth); `isReady` is derived from it. When the active id changes, the
|
|
774
|
+
* previous document is dropped *before* the new one's readiness is probed, so a
|
|
775
|
+
* stale document is never exposed for the new id. Consumers should gate on
|
|
776
|
+
* `isReady`/`document` and can pass optional `hydrate`/`clear` callbacks to also
|
|
777
|
+
* mirror the value into a module-level document store.
|
|
748
778
|
*
|
|
749
779
|
* Cleanup runs automatically when used inside a component/effect scope; the
|
|
750
780
|
* returned `stop` lets scope-less callers (e.g. an extension bootstrap) tear it
|
|
@@ -753,10 +783,11 @@ export declare type UnifiedDiff = {
|
|
|
753
783
|
export declare function useActiveDocument<GenericDocument>(params: {
|
|
754
784
|
project: ActiveDocumentProject<GenericDocument>;
|
|
755
785
|
activeDocumentId: ActiveDocumentObservable<string>;
|
|
756
|
-
hydrate
|
|
757
|
-
clear
|
|
786
|
+
hydrate?: (doc: GenericDocument) => void;
|
|
787
|
+
clear?: () => void;
|
|
758
788
|
}): {
|
|
759
|
-
|
|
789
|
+
document: Ref<GenericDocument | undefined>;
|
|
790
|
+
isReady: ComputedRef<boolean>;
|
|
760
791
|
activeDocumentId: Ref<string | undefined>;
|
|
761
792
|
stop: () => void;
|
|
762
793
|
};
|
|
@@ -790,9 +821,15 @@ export declare function useDialog(): DialogController;
|
|
|
790
821
|
* a `commit` message for this documentId — posted by any Document instance,
|
|
791
822
|
* in this tab or another — re-runs the fetcher. Document state itself is plain,
|
|
792
823
|
* non-reactive data in core; do not watch it.
|
|
824
|
+
*
|
|
825
|
+
* The document may be absent (`undefined`): the composable then holds `initial`,
|
|
826
|
+
* subscribes to nothing, and starts fetching once a document appears — mirroring
|
|
827
|
+
* {@link useProjectLiveData}. This lets a caller pass a document that is null
|
|
828
|
+
* before hydration or during a teardown/switch without pre-guarding a value
|
|
829
|
+
* that would otherwise throw.
|
|
793
830
|
*/
|
|
794
831
|
export declare function useLiveData<T>(params: {
|
|
795
|
-
document: LiveDataDocument |
|
|
832
|
+
document: MaybeRefOrGetter<LiveDataDocument | undefined>;
|
|
796
833
|
fetcher: () => Promise<T>;
|
|
797
834
|
initial: T;
|
|
798
835
|
}): {
|
|
@@ -815,6 +852,7 @@ export declare function useMergeSession(params: MergeSessionParams): {
|
|
|
815
852
|
previewXml: ShallowRef<string | undefined, string | undefined>;
|
|
816
853
|
previewBeforeXml: ShallowRef<string | undefined, string | undefined>;
|
|
817
854
|
previewLoading: ShallowRef<boolean, boolean>;
|
|
855
|
+
warnings: ShallowRef<TemplateUuidWarning[], TemplateUuidWarning[]>;
|
|
818
856
|
load: () => Promise<void>;
|
|
819
857
|
setDecision: (groupId: string, action: "accept" | "skip") => void;
|
|
820
858
|
setValue: (groupId: string, attr: string, value: string) => void;
|
|
@@ -1,89 +1,104 @@
|
|
|
1
1
|
import { extractTitle as e, getAttributes as t } from "./merge.service.js";
|
|
2
2
|
//#region lib/merge/build-view-model.ts
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
function n(e) {
|
|
4
|
+
return e.instances.flatMap((e) => e.groups);
|
|
5
|
+
}
|
|
6
|
+
function r(e) {
|
|
7
|
+
let { report: t, correlation: r } = e, i = /* @__PURE__ */ new Map();
|
|
8
|
+
for (let e of n(t)) i.set(e.primary, {
|
|
9
|
+
role: "primary",
|
|
10
|
+
groupId: e.id
|
|
11
|
+
});
|
|
12
|
+
let a = /* @__PURE__ */ new Map();
|
|
13
|
+
function o(e) {
|
|
14
|
+
let t = r.get(e);
|
|
15
|
+
if (!t) return;
|
|
16
|
+
let n = i.get(e);
|
|
17
|
+
a.set(t, {
|
|
18
|
+
change: e.change,
|
|
19
|
+
role: n?.role ?? "plain",
|
|
20
|
+
groupId: n?.groupId,
|
|
21
|
+
node: e
|
|
13
22
|
});
|
|
14
23
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (e.sourceRef) {
|
|
19
|
-
let n = await t(i, e.sourceRef);
|
|
20
|
-
return n.uuid ? r.get(n.uuid)?.id : void 0;
|
|
21
|
-
}
|
|
24
|
+
function s(e) {
|
|
25
|
+
o(e);
|
|
26
|
+
for (let t of e.children) s(t);
|
|
22
27
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
o.set(t, {
|
|
28
|
+
function c(e, t) {
|
|
29
|
+
if (e.change !== "unchanged") {
|
|
30
|
+
let n = r.get(e);
|
|
31
|
+
n && a.set(n, {
|
|
28
32
|
change: e.change,
|
|
29
|
-
role:
|
|
30
|
-
groupId:
|
|
33
|
+
role: "companion",
|
|
34
|
+
groupId: t,
|
|
31
35
|
node: e
|
|
32
36
|
});
|
|
33
37
|
}
|
|
38
|
+
for (let n of e.children) c(n, t);
|
|
34
39
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
for (let e of n.roots) await l(e);
|
|
40
|
-
for (let e of n.groups) for (let t of e.companions) await c(t);
|
|
41
|
-
return o;
|
|
40
|
+
for (let e of t.instances) s(e.tree);
|
|
41
|
+
for (let e of n(t)) for (let t of e.companions) c(t, e.id);
|
|
42
|
+
return a;
|
|
42
43
|
}
|
|
43
|
-
async function
|
|
44
|
+
async function i(t) {
|
|
44
45
|
let { tree: n, changeByStagedId: r, query: i } = t, a = {
|
|
45
46
|
items: [],
|
|
46
47
|
meta: {},
|
|
47
48
|
index: {},
|
|
48
49
|
expanded: []
|
|
49
50
|
};
|
|
50
|
-
async function o(t, n) {
|
|
51
|
-
let
|
|
51
|
+
async function o(t, n, s) {
|
|
52
|
+
let c = r.get(t.id), l = c?.change ?? (n.added ? "added" : "unchanged"), u = c?.groupId ?? (l === "unchanged" ? void 0 : n.groupId), d = c?.role ?? "plain", f = {
|
|
52
53
|
tagName: t.tagName,
|
|
53
54
|
id: t.id
|
|
54
|
-
},
|
|
55
|
-
added:
|
|
56
|
-
groupId:
|
|
57
|
-
},
|
|
58
|
-
for (let e of t.tree ?? [])
|
|
59
|
-
|
|
55
|
+
}, p = l !== "unchanged" && (!s || s.change === "unchanged" || s.groupId !== u || s.change !== l), m = {
|
|
56
|
+
added: c ? c.change === "added" : n.added,
|
|
57
|
+
groupId: u ?? n.groupId
|
|
58
|
+
}, h = [];
|
|
59
|
+
for (let e of t.tree ?? []) h.push(await o(e, m, {
|
|
60
|
+
change: l,
|
|
61
|
+
groupId: u
|
|
62
|
+
}));
|
|
63
|
+
let g = l !== "unchanged" || h.some((e) => e.changed);
|
|
60
64
|
return a.meta[t.id] = {
|
|
61
|
-
change:
|
|
62
|
-
role:
|
|
63
|
-
groupId:
|
|
65
|
+
change: l,
|
|
66
|
+
role: d,
|
|
67
|
+
groupId: u,
|
|
68
|
+
regionHead: p
|
|
64
69
|
}, a.index[t.id] = {
|
|
65
|
-
previewRef:
|
|
66
|
-
change:
|
|
67
|
-
role:
|
|
68
|
-
groupId:
|
|
69
|
-
node:
|
|
70
|
-
},
|
|
70
|
+
previewRef: f,
|
|
71
|
+
change: l,
|
|
72
|
+
role: d,
|
|
73
|
+
groupId: u,
|
|
74
|
+
node: c?.node
|
|
75
|
+
}, g && a.expanded.push(t.id), {
|
|
71
76
|
node: {
|
|
72
77
|
tag: t.tagName,
|
|
73
78
|
id: t.id,
|
|
74
|
-
name: await e(i,
|
|
79
|
+
name: await e(i, f),
|
|
75
80
|
selectable: !0,
|
|
76
|
-
children:
|
|
81
|
+
children: h.length ? h.map((e) => e.node) : void 0
|
|
77
82
|
},
|
|
78
|
-
changed:
|
|
83
|
+
changed: g
|
|
79
84
|
};
|
|
80
85
|
}
|
|
81
|
-
|
|
86
|
+
a.items.push((await o(n, {
|
|
82
87
|
added: !1,
|
|
83
88
|
groupId: void 0
|
|
84
|
-
})).node)
|
|
89
|
+
}, void 0)).node);
|
|
90
|
+
let s = /* @__PURE__ */ new Map();
|
|
91
|
+
for (let [e, t] of r) s.set(t.node, e);
|
|
92
|
+
for (let e of t.instances) {
|
|
93
|
+
let t = s.get(e.tree);
|
|
94
|
+
!t || !a.meta[t] || (a.meta[t].instance = {
|
|
95
|
+
linked: e.linked,
|
|
96
|
+
upToDate: e.upToDate
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return a;
|
|
85
100
|
}
|
|
86
|
-
async function
|
|
101
|
+
async function a(e, n, r) {
|
|
87
102
|
let i = new Map((n?.editableAttributes ?? []).map((e) => [e.attr, e])), a = [];
|
|
88
103
|
if (e.change === "added" && e.sourceRef) {
|
|
89
104
|
let n = await t(r.sourceQuery, e.sourceRef);
|
|
@@ -138,51 +153,63 @@ async function i(e, n, r) {
|
|
|
138
153
|
}
|
|
139
154
|
return {
|
|
140
155
|
tag: e.tagName,
|
|
141
|
-
title: await
|
|
156
|
+
title: await s(e, r),
|
|
142
157
|
change: e.change,
|
|
143
158
|
attributes: a
|
|
144
159
|
};
|
|
145
160
|
}
|
|
146
|
-
async function
|
|
147
|
-
let
|
|
161
|
+
async function o(e, t, r, i) {
|
|
162
|
+
let a = {
|
|
148
163
|
added: [],
|
|
149
164
|
updated: [],
|
|
150
165
|
skipped: [],
|
|
166
|
+
preserved: [],
|
|
167
|
+
removed: [],
|
|
151
168
|
renamed: []
|
|
152
169
|
};
|
|
153
|
-
for (let
|
|
154
|
-
let e = await o
|
|
155
|
-
if (
|
|
156
|
-
|
|
170
|
+
for (let o of n(e)) {
|
|
171
|
+
let e = await s(o.primary, i), n = o.primary.tagName, c = o.companions.length;
|
|
172
|
+
if (o.primary.change === "target-only") {
|
|
173
|
+
t(o.id) === "skip" ? a.preserved.push({
|
|
174
|
+
title: e,
|
|
175
|
+
tag: n
|
|
176
|
+
}) : a.removed.push({
|
|
177
|
+
title: e,
|
|
178
|
+
tag: n
|
|
179
|
+
});
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (t(o.id) === "skip") {
|
|
183
|
+
a.skipped.push({
|
|
157
184
|
title: e,
|
|
158
|
-
tag:
|
|
185
|
+
tag: n
|
|
159
186
|
});
|
|
160
187
|
continue;
|
|
161
188
|
}
|
|
162
|
-
for (let t of
|
|
189
|
+
for (let t of o.editableAttributes ?? []) t.conflict && t.suggestedValue && r(o.id, t.attr) == null && a.renamed.push({
|
|
163
190
|
title: e,
|
|
164
191
|
field: t.attr,
|
|
165
192
|
to: t.suggestedValue
|
|
166
193
|
});
|
|
167
|
-
let l =
|
|
168
|
-
if (
|
|
194
|
+
let l = o.editableAttributes?.find((e) => e.attr === "name" && e.conflict), u = r(o.id, "name") ?? l?.suggestedValue ?? e;
|
|
195
|
+
if (o.primary.change === "added") a.added.push({
|
|
169
196
|
title: u,
|
|
170
|
-
tag:
|
|
197
|
+
tag: n,
|
|
171
198
|
detail: c ? `+${c} companion${c > 1 ? "s" : ""}` : void 0
|
|
172
199
|
});
|
|
173
|
-
else if (
|
|
174
|
-
let e =
|
|
175
|
-
|
|
200
|
+
else if (o.primary.change === "modified") {
|
|
201
|
+
let e = o.primary.attributeChanges?.length ?? 0;
|
|
202
|
+
a.updated.push({
|
|
176
203
|
title: u,
|
|
177
|
-
tag:
|
|
204
|
+
tag: n,
|
|
178
205
|
detail: e ? `${e} attribute change${e > 1 ? "s" : ""}` : void 0
|
|
179
206
|
});
|
|
180
207
|
}
|
|
181
208
|
}
|
|
182
|
-
return
|
|
209
|
+
return a;
|
|
183
210
|
}
|
|
184
|
-
async function
|
|
211
|
+
async function s(t, n) {
|
|
185
212
|
return t.instanceRef ? e(n.targetQuery, t.instanceRef) : t.sourceRef ? e(n.sourceQuery, t.sourceRef) : t.tagName;
|
|
186
213
|
}
|
|
187
214
|
//#endregion
|
|
188
|
-
export { n as buildChangeIndex,
|
|
215
|
+
export { n as allGroups, r as buildChangeIndex, a as buildDetail, i as buildStructuralTree, o as buildSummary };
|
|
@@ -23,13 +23,13 @@ var c = {
|
|
|
23
23
|
})[d.size ?? "undefined"]);
|
|
24
24
|
return (e, s) => (o(), t("div", c, [n("button", {
|
|
25
25
|
type: "button",
|
|
26
|
-
class: a(["btn join-item", [f.value, i.value === "accept" ? "btn-success" : "btn-ghost"]]),
|
|
26
|
+
class: a(["btn join-item font-semibold", [f.value, i.value === "accept" ? "btn-success text-success-content" : "btn-ghost"]]),
|
|
27
27
|
disabled: r.disabled,
|
|
28
28
|
"aria-pressed": i.value === "accept",
|
|
29
29
|
onClick: s[0] ||= (e) => i.value = "accept"
|
|
30
30
|
}, " Accept ", 10, l), n("button", {
|
|
31
31
|
type: "button",
|
|
32
|
-
class: a(["btn join-item", [f.value, i.value === "skip" ? "btn-warning" : "btn-ghost"]]),
|
|
32
|
+
class: a(["btn join-item font-semibold", [f.value, i.value === "skip" ? "btn-warning text-black" : "btn-ghost"]]),
|
|
33
33
|
disabled: r.disabled,
|
|
34
34
|
"aria-pressed": i.value === "skip",
|
|
35
35
|
onClick: s[1] ||= (e) => i.value = "skip"
|
|
@@ -1,76 +1,185 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import e from "../external/.pnpm/@lucide_vue@1.23.0_vue@3.5.39_typescript@5.8.3_/node_modules/@lucide/vue/dist/esm/icons/pencil.js";
|
|
2
|
+
import { composeAffix as t, splitAffix as n } from "./affix.js";
|
|
3
|
+
import { Fragment as r, computed as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, nextTick as d, normalizeClass as f, openBlock as p, reactive as m, renderList as h, toDisplayString as g, unref as ee } from "vue";
|
|
3
4
|
//#region lib/merge/element-detail.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
-
var
|
|
5
|
+
var te = {
|
|
5
6
|
key: 0,
|
|
6
7
|
class: "flex h-full flex-col gap-3 overflow-auto p-3 text-sm"
|
|
7
|
-
},
|
|
8
|
+
}, ne = { class: "flex items-center gap-2" }, _ = { class: "font-medium" }, v = { class: "badge badge-sm opacity-70" }, y = {
|
|
8
9
|
key: 0,
|
|
9
|
-
class: "flex flex-col gap-2
|
|
10
|
-
},
|
|
10
|
+
class: "flex flex-col gap-2 text-xs"
|
|
11
|
+
}, b = { class: "flex items-center gap-2" }, x = ["title"], S = ["aria-label"], C = ["aria-checked", "onClick"], w = ["title"], re = ["aria-checked", "onClick"], ie = ["title"], T = ["aria-checked", "onClick"], E = {
|
|
11
12
|
key: 0,
|
|
12
13
|
class: "shrink-0 select-none opacity-60"
|
|
13
|
-
},
|
|
14
|
+
}, D = [
|
|
15
|
+
"value",
|
|
16
|
+
"readonly",
|
|
17
|
+
"onInput"
|
|
18
|
+
], O = {
|
|
14
19
|
key: 1,
|
|
15
20
|
class: "shrink-0 select-none opacity-60"
|
|
16
|
-
},
|
|
17
|
-
key:
|
|
21
|
+
}, k = {
|
|
22
|
+
key: 2,
|
|
18
23
|
class: "badge badge-warning badge-xs shrink-0",
|
|
19
24
|
title: "Auto-resolved to avoid a naming collision — edit to override"
|
|
20
|
-
},
|
|
25
|
+
}, A = {
|
|
26
|
+
key: 0,
|
|
27
|
+
class: "mt-1.5 flex items-center gap-2"
|
|
28
|
+
}, j = { class: "flex w-full items-center font-mono" }, M = {
|
|
29
|
+
key: 0,
|
|
30
|
+
class: "shrink-0 select-none opacity-60"
|
|
31
|
+
}, N = ["value", "onInput"], P = {
|
|
32
|
+
key: 1,
|
|
33
|
+
class: "shrink-0 select-none opacity-60"
|
|
34
|
+
}, F = {
|
|
21
35
|
key: 1,
|
|
22
36
|
class: "text-xs opacity-60"
|
|
23
|
-
},
|
|
37
|
+
}, I = {
|
|
24
38
|
key: 1,
|
|
25
39
|
class: "grid h-full place-items-center p-4 text-sm opacity-60"
|
|
26
|
-
},
|
|
40
|
+
}, L = /*@__PURE__*/ u({
|
|
27
41
|
__name: "element-detail",
|
|
28
42
|
props: {
|
|
29
43
|
detail: {},
|
|
30
|
-
affixMask: { type: Function }
|
|
44
|
+
affixMask: { type: Function },
|
|
45
|
+
disabled: { type: Boolean }
|
|
31
46
|
},
|
|
32
47
|
emits: ["edit"],
|
|
33
|
-
setup(
|
|
34
|
-
let
|
|
48
|
+
setup(u, { emit: L }) {
|
|
49
|
+
let R = {
|
|
50
|
+
accept: {
|
|
51
|
+
border: "border-success",
|
|
52
|
+
label: "bg-success text-success-content",
|
|
53
|
+
value: "bg-success/15 text-success"
|
|
54
|
+
},
|
|
55
|
+
skip: {
|
|
56
|
+
border: "border-warning",
|
|
57
|
+
label: "bg-warning text-black",
|
|
58
|
+
value: "bg-warning/20 text-black"
|
|
59
|
+
},
|
|
60
|
+
other: {
|
|
61
|
+
border: "border-info",
|
|
62
|
+
label: "bg-info text-info-content",
|
|
63
|
+
value: "bg-info/15 text-info"
|
|
64
|
+
}
|
|
65
|
+
}, z = u, B = L, V = m(/* @__PURE__ */ new Set()), H = /* @__PURE__ */ new Map(), U = i(() => ({
|
|
35
66
|
added: "badge-success",
|
|
36
67
|
removed: "badge-error",
|
|
37
68
|
modified: "badge-warning",
|
|
38
|
-
unchanged: "badge-ghost"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
69
|
+
unchanged: "badge-ghost",
|
|
70
|
+
"target-only": "badge-info"
|
|
71
|
+
})[z.detail?.change ?? "unchanged"]), W = i(() => [...z.detail?.attributes ?? []].filter((e) => e.editable).sort((e, t) => Number(J(t)) - Number(J(e))));
|
|
72
|
+
function G(e) {
|
|
73
|
+
if (!(!z.detail || !z.affixMask)) return z.affixMask({
|
|
74
|
+
tag: z.detail.tag,
|
|
43
75
|
attr: e.name
|
|
44
76
|
});
|
|
45
77
|
}
|
|
46
|
-
function
|
|
47
|
-
return
|
|
78
|
+
function K(e) {
|
|
79
|
+
return z.disabled ? e.before ?? e.after ?? "" : e.written ?? e.after ?? "";
|
|
80
|
+
}
|
|
81
|
+
function q(e) {
|
|
82
|
+
return n(K(e), G(e));
|
|
83
|
+
}
|
|
84
|
+
function J(e) {
|
|
85
|
+
return e.status === "modified";
|
|
86
|
+
}
|
|
87
|
+
function Y(e) {
|
|
88
|
+
return e && e.length > 0 ? e : "∅";
|
|
89
|
+
}
|
|
90
|
+
function X(e) {
|
|
91
|
+
if (V.has(e.name)) return "other";
|
|
92
|
+
let t = K(e);
|
|
93
|
+
return t === (e.after ?? "") ? "accept" : t === (e.before ?? "") ? "skip" : "other";
|
|
94
|
+
}
|
|
95
|
+
function Z(e, t) {
|
|
96
|
+
if (t === "other") {
|
|
97
|
+
V.add(e.name), d(() => H.get(e.name)?.focus());
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
V.delete(e.name), B("edit", e.name, t === "accept" ? e.after ?? "" : e.before ?? "");
|
|
101
|
+
}
|
|
102
|
+
function Q(e, t) {
|
|
103
|
+
t instanceof HTMLInputElement ? H.set(e.name, t) : H.delete(e.name);
|
|
48
104
|
}
|
|
49
|
-
function
|
|
105
|
+
function $(e, n) {
|
|
50
106
|
let r = n.target.value;
|
|
51
|
-
|
|
107
|
+
B("edit", e.name, t(r, G(e)));
|
|
52
108
|
}
|
|
53
|
-
return (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
]),
|
|
58
|
-
key:
|
|
59
|
-
class: "
|
|
60
|
-
}, [
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
109
|
+
return (t, n) => u.detail ? (p(), o("div", te, [s("header", ne, [
|
|
110
|
+
s("span", _, g(u.detail.title), 1),
|
|
111
|
+
s("span", v, g(u.detail.tag), 1),
|
|
112
|
+
s("span", { class: f(["badge badge-sm", U.value]) }, g(u.detail.change), 3)
|
|
113
|
+
]), W.value.length ? (p(), o("div", y, [(p(!0), o(r, null, h(W.value, (t) => (p(), o("div", {
|
|
114
|
+
key: t.name,
|
|
115
|
+
class: f(["rounded-md border px-2 py-1.5", J(t) ? "border-warning/40 bg-warning/5" : "border-base-200"])
|
|
116
|
+
}, [s("div", b, [
|
|
117
|
+
s("span", {
|
|
118
|
+
class: "w-24 shrink-0 truncate opacity-70",
|
|
119
|
+
title: t.name
|
|
120
|
+
}, g(t.name), 9, x),
|
|
121
|
+
J(t) ? (p(), o("div", {
|
|
122
|
+
key: 0,
|
|
123
|
+
class: f(["flex flex-1 flex-wrap items-center gap-1.5", u.disabled && "pointer-events-none opacity-60"]),
|
|
124
|
+
role: "radiogroup",
|
|
125
|
+
"aria-label": `Decision for ${t.name}`
|
|
126
|
+
}, [
|
|
127
|
+
s("button", {
|
|
128
|
+
type: "button",
|
|
129
|
+
class: f(["inline-flex items-stretch overflow-hidden rounded-md border-2 text-xs transition", X(t) === "accept" ? R.accept.border : "border-transparent opacity-55 hover:opacity-100"]),
|
|
130
|
+
role: "radio",
|
|
131
|
+
"aria-checked": X(t) === "accept",
|
|
132
|
+
onClick: (e) => Z(t, "accept")
|
|
133
|
+
}, [s("span", { class: f(["px-2 py-0.5 font-semibold", R.accept.label]) }, " Accept ", 2), s("span", {
|
|
134
|
+
class: f(["max-w-[12ch] truncate px-2 py-0.5 font-mono", R.accept.value]),
|
|
135
|
+
title: Y(t.after)
|
|
136
|
+
}, g(Y(t.after)), 11, w)], 10, C),
|
|
137
|
+
s("button", {
|
|
138
|
+
type: "button",
|
|
139
|
+
class: f(["inline-flex items-stretch overflow-hidden rounded-md border-2 text-xs transition", X(t) === "skip" ? R.skip.border : "border-transparent opacity-55 hover:opacity-100"]),
|
|
140
|
+
role: "radio",
|
|
141
|
+
"aria-checked": X(t) === "skip",
|
|
142
|
+
onClick: (e) => Z(t, "skip")
|
|
143
|
+
}, [s("span", { class: f(["px-2 py-0.5 font-semibold", R.skip.label]) }, " Skip ", 2), s("span", {
|
|
144
|
+
class: f(["max-w-[12ch] truncate px-2 py-0.5 font-mono", R.skip.value]),
|
|
145
|
+
title: Y(t.before)
|
|
146
|
+
}, g(Y(t.before)), 11, ie)], 10, re),
|
|
147
|
+
s("button", {
|
|
148
|
+
type: "button",
|
|
149
|
+
class: f(["inline-flex items-stretch overflow-hidden rounded-md border-2 text-xs transition", X(t) === "other" ? R.other.border : "border-transparent opacity-55 hover:opacity-100"]),
|
|
150
|
+
role: "radio",
|
|
151
|
+
"aria-checked": X(t) === "other",
|
|
152
|
+
onClick: (e) => Z(t, "other")
|
|
153
|
+
}, [s("span", { class: f(["flex items-center gap-1 px-2 py-0.5 font-semibold", R.other.label]) }, [l(ee(e), { class: "size-3" }), n[0] ||= c(" Other ", -1)], 2)], 10, T)
|
|
154
|
+
], 10, S)) : (p(), o("span", {
|
|
155
|
+
key: 1,
|
|
156
|
+
class: f(["flex w-full items-center font-mono", u.disabled && "pointer-events-none opacity-60"])
|
|
157
|
+
}, [
|
|
158
|
+
q(t).prefix ? (p(), o("span", E, g(q(t).prefix), 1)) : a("", !0),
|
|
159
|
+
s("input", {
|
|
160
|
+
ref_for: !0,
|
|
161
|
+
ref: (e) => Q(t, e),
|
|
162
|
+
class: f(["input input-xs input-bordered w-full font-mono", { "input-warning": t.conflict }]),
|
|
163
|
+
value: q(t).core,
|
|
164
|
+
readonly: u.disabled,
|
|
165
|
+
onInput: (e) => $(t, e)
|
|
166
|
+
}, null, 42, D),
|
|
167
|
+
q(t).suffix ? (p(), o("span", O, g(q(t).suffix), 1)) : a("", !0)
|
|
168
|
+
], 2)),
|
|
169
|
+
t.conflict ? (p(), o("span", k, " conflict ")) : a("", !0)
|
|
170
|
+
]), J(t) && X(t) === "other" ? (p(), o("div", A, [n[1] ||= s("span", { class: "w-24 shrink-0" }, null, -1), s("span", j, [
|
|
171
|
+
q(t).prefix ? (p(), o("span", M, g(q(t).prefix), 1)) : a("", !0),
|
|
172
|
+
s("input", {
|
|
173
|
+
ref_for: !0,
|
|
174
|
+
ref: (e) => Q(t, e),
|
|
175
|
+
class: f(["input input-xs input-bordered w-full font-mono", { "input-warning": t.conflict }]),
|
|
176
|
+
value: q(t).core,
|
|
177
|
+
placeholder: "custom value",
|
|
178
|
+
onInput: (e) => $(t, e)
|
|
179
|
+
}, null, 42, N),
|
|
180
|
+
q(t).suffix ? (p(), o("span", P, g(q(t).suffix), 1)) : a("", !0)
|
|
181
|
+
])])) : a("", !0)], 2))), 128))])) : (p(), o("div", F, "No editable fields. See the diff below."))])) : (p(), o("div", I, " Select an element to see its changes. "));
|
|
73
182
|
}
|
|
74
183
|
});
|
|
75
184
|
//#endregion
|
|
76
|
-
export {
|
|
185
|
+
export { L as default };
|