mobx-view-model-devtools 0.0.43 → 0.0.44
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/auto.global.js +1 -1
- package/index.cjs +1 -1
- package/index.d.ts +23 -1
- package/index.js +171 -29
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -101,6 +101,7 @@ interface SearchSuggestion {
|
|
|
101
101
|
value: string;
|
|
102
102
|
suffix: string;
|
|
103
103
|
vmName: string;
|
|
104
|
+
ownerKey: string;
|
|
104
105
|
}
|
|
105
106
|
declare class SearchEngine {
|
|
106
107
|
private config;
|
|
@@ -110,6 +111,8 @@ declare class SearchEngine {
|
|
|
110
111
|
selectedSuggestionIndex: number;
|
|
111
112
|
isSearchInputFocused: boolean;
|
|
112
113
|
isSuggestionsDismissed: boolean;
|
|
114
|
+
selectedPathOwnerKey: string | null;
|
|
115
|
+
selectedPathSegment: string | null;
|
|
113
116
|
searchCacheKey: string;
|
|
114
117
|
isSearching: boolean;
|
|
115
118
|
private searchTextToSearchTimeout;
|
|
@@ -128,6 +131,8 @@ declare class SearchEngine {
|
|
|
128
131
|
get isSearchTextDebouncing(): boolean;
|
|
129
132
|
get shouldShowSuggestions(): boolean;
|
|
130
133
|
get suggestionItems(): SearchSuggestion[];
|
|
134
|
+
private getActiveSearchText;
|
|
135
|
+
private buildSuggestionItemsForText;
|
|
131
136
|
get selectedSuggestion(): SearchSuggestion | null;
|
|
132
137
|
/**
|
|
133
138
|
* Суффикс выбранного свойства, которое начинается с последнего сегмента.
|
|
@@ -135,11 +140,25 @@ declare class SearchEngine {
|
|
|
135
140
|
* Например: ввод "_pay" → suggestionSuffix = "load" (от "_payload")
|
|
136
141
|
*/
|
|
137
142
|
get suggestionSuffix(): string;
|
|
138
|
-
|
|
143
|
+
selectSuggestionAtIndex: (index: number) => void;
|
|
144
|
+
applySuggestion: (suggestion: SearchSuggestion, options?: {
|
|
145
|
+
commitOwner?: boolean;
|
|
146
|
+
dismissSuggestions?: boolean;
|
|
147
|
+
}) => void;
|
|
148
|
+
applySuggestionFromClick: (suggestion: SearchSuggestion, index: number) => void;
|
|
139
149
|
handleSearchInput: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
140
150
|
handleSearchInputFocus: (_e: FocusEvent<HTMLInputElement>) => void;
|
|
141
151
|
handleSearchInputBlur: (_e: FocusEvent<HTMLInputElement>) => void;
|
|
142
152
|
handleKeyDown: (e: KeyboardEvent<HTMLInputElement>) => void;
|
|
153
|
+
private commitSuggestionOwner;
|
|
154
|
+
private handlePathOwnerSelectionFromInput;
|
|
155
|
+
/**
|
|
156
|
+
* При вводе точки debounce ещё не применил searchTextToSearch,
|
|
157
|
+
* поэтому owner берём из подсказок предыдущего сегмента.
|
|
158
|
+
* Если пользователь явно не выбирал — берём exact-match `service`, иначе первый в списке.
|
|
159
|
+
*/
|
|
160
|
+
private getFirstPathSegment;
|
|
161
|
+
private resolvePathOwnerSuggestion;
|
|
143
162
|
private clearSearchDebounce;
|
|
144
163
|
private scheduleSearchTextDebounce;
|
|
145
164
|
private scheduleScrollToFirstSearchMatch;
|
|
@@ -157,6 +176,8 @@ declare class SearchEngine {
|
|
|
157
176
|
private getOwnerMatchedPathCandidates;
|
|
158
177
|
private getPropertyPathCandidates;
|
|
159
178
|
private getDirectPropertyChildren;
|
|
179
|
+
private isOwnerAllowedForFirstPathSegment;
|
|
180
|
+
private isPathOwnerLockedToAnotherOwner;
|
|
160
181
|
/**
|
|
161
182
|
* Уже введённый path-сегмент должен совпадать строго:
|
|
162
183
|
* `product.` заходит только в `product`, а не в `productAsyncTasks`
|
|
@@ -164,6 +185,7 @@ declare class SearchEngine {
|
|
|
164
185
|
*/
|
|
165
186
|
private getPathMatchingProps;
|
|
166
187
|
private getOwnerVMName;
|
|
188
|
+
private getOwnerKey;
|
|
167
189
|
/**
|
|
168
190
|
* Навигация вглубь по цепочке свойств.
|
|
169
191
|
* Возвращает свойства на нужной глубине.
|
package/index.js
CHANGED
|
@@ -38024,7 +38024,7 @@ function getAllKeys(instance2) {
|
|
|
38024
38024
|
}
|
|
38025
38025
|
currentPrototype = nextPrototype;
|
|
38026
38026
|
}
|
|
38027
|
-
return
|
|
38027
|
+
return [...keysSet];
|
|
38028
38028
|
}
|
|
38029
38029
|
class MetaListItem extends ListItem {
|
|
38030
38030
|
constructor(devtools, key, content, _depth) {
|
|
@@ -39747,14 +39747,13 @@ const skipEvent = (e) => {
|
|
|
39747
39747
|
};
|
|
39748
39748
|
const FunctionPropertyContent = observer(
|
|
39749
39749
|
({ item }) => {
|
|
39750
|
-
const argLabels = Array.
|
|
39751
|
-
{ length: item.data.length },
|
|
39750
|
+
const argLabels = [...Array(item.data.length)].map(
|
|
39752
39751
|
(_14, i) => `arg${i + 1}`
|
|
39753
39752
|
);
|
|
39754
39753
|
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(jsxDevRuntimeExports.Fragment, { children: [
|
|
39755
39754
|
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("span", { className: css$1.propertyName, children: item.property }, void 0, false, {
|
|
39756
39755
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/list-items/property-list-item-render/function.tsx",
|
|
39757
|
-
lineNumber:
|
|
39756
|
+
lineNumber: 14,
|
|
39758
39757
|
columnNumber: 9
|
|
39759
39758
|
}, void 0),
|
|
39760
39759
|
item.isEditMode ? /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(jsxDevRuntimeExports.Fragment, { children: [
|
|
@@ -39772,7 +39771,7 @@ const FunctionPropertyContent = observer(
|
|
|
39772
39771
|
false,
|
|
39773
39772
|
{
|
|
39774
39773
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/list-items/property-list-item-render/function.tsx",
|
|
39775
|
-
lineNumber:
|
|
39774
|
+
lineNumber: 18,
|
|
39776
39775
|
columnNumber: 13
|
|
39777
39776
|
},
|
|
39778
39777
|
void 0
|
|
@@ -39780,12 +39779,12 @@ const FunctionPropertyContent = observer(
|
|
|
39780
39779
|
`)`
|
|
39781
39780
|
] }, void 0, true, {
|
|
39782
39781
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/list-items/property-list-item-render/function.tsx",
|
|
39783
|
-
lineNumber:
|
|
39782
|
+
lineNumber: 16,
|
|
39784
39783
|
columnNumber: 11
|
|
39785
39784
|
}, void 0) : `(${argLabels.join(", ")})`
|
|
39786
39785
|
] }, void 0, true, {
|
|
39787
39786
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/list-items/property-list-item-render/function.tsx",
|
|
39788
|
-
lineNumber:
|
|
39787
|
+
lineNumber: 13,
|
|
39789
39788
|
columnNumber: 7
|
|
39790
39789
|
}, void 0);
|
|
39791
39790
|
}
|
|
@@ -40193,7 +40192,7 @@ const Notifications = withViewModel(NotificationsVM, ({ model }) => {
|
|
|
40193
40192
|
if (!model.items.size) {
|
|
40194
40193
|
return null;
|
|
40195
40194
|
}
|
|
40196
|
-
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: css.notifications, children:
|
|
40195
|
+
return /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: css.notifications, children: [...model.items.values()].map((item) => /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: css.notification, children: item.title }, item.id, false, {
|
|
40197
40196
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/notifications/index.tsx",
|
|
40198
40197
|
lineNumber: 13,
|
|
40199
40198
|
columnNumber: 9
|
|
@@ -40387,9 +40386,15 @@ const VmDevtoolsContent = withViewModel(
|
|
|
40387
40386
|
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: css$2.inputSuggestionsList, children: devtools.searchEngine.suggestionItems.map((suggestion, index) => /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
|
|
40388
40387
|
"div",
|
|
40389
40388
|
{
|
|
40390
|
-
|
|
40389
|
+
onMouseEnter: () => {
|
|
40390
|
+
devtools.searchEngine.selectSuggestionAtIndex(index);
|
|
40391
|
+
},
|
|
40392
|
+
onMouseDown: (e) => {
|
|
40391
40393
|
e.preventDefault();
|
|
40392
|
-
devtools.searchEngine.
|
|
40394
|
+
devtools.searchEngine.applySuggestionFromClick(
|
|
40395
|
+
suggestion,
|
|
40396
|
+
index
|
|
40397
|
+
);
|
|
40393
40398
|
},
|
|
40394
40399
|
className: cx(
|
|
40395
40400
|
css$2.inputSuggestionItem,
|
|
@@ -40398,17 +40403,17 @@ const VmDevtoolsContent = withViewModel(
|
|
|
40398
40403
|
children: [
|
|
40399
40404
|
!devtools.searchEngine.isNestedSearch && /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("span", { className: css$2.inputSuggestionOwner, children: suggestion.vmName }, void 0, false, {
|
|
40400
40405
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/index.tsx",
|
|
40401
|
-
lineNumber:
|
|
40406
|
+
lineNumber: 138,
|
|
40402
40407
|
columnNumber: 27
|
|
40403
40408
|
}, void 0),
|
|
40404
40409
|
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("span", { className: css$2.inputSuggestionValue, children: suggestion.value }, void 0, false, {
|
|
40405
40410
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/index.tsx",
|
|
40406
|
-
lineNumber:
|
|
40411
|
+
lineNumber: 142,
|
|
40407
40412
|
columnNumber: 25
|
|
40408
40413
|
}, void 0)
|
|
40409
40414
|
]
|
|
40410
40415
|
},
|
|
40411
|
-
`${suggestion.
|
|
40416
|
+
`${suggestion.ownerKey}/${suggestion.value}`,
|
|
40412
40417
|
true,
|
|
40413
40418
|
{
|
|
40414
40419
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/index.tsx",
|
|
@@ -40451,7 +40456,7 @@ const VmDevtoolsContent = withViewModel(
|
|
|
40451
40456
|
false,
|
|
40452
40457
|
{
|
|
40453
40458
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/index.tsx",
|
|
40454
|
-
lineNumber:
|
|
40459
|
+
lineNumber: 156,
|
|
40455
40460
|
columnNumber: 11
|
|
40456
40461
|
},
|
|
40457
40462
|
void 0
|
|
@@ -40461,7 +40466,7 @@ const VmDevtoolsContent = withViewModel(
|
|
|
40461
40466
|
false,
|
|
40462
40467
|
{
|
|
40463
40468
|
fileName: "/home/js2me/projects/open-source/mobx-view-model-devtools/src/ui/devtools-content/index.tsx",
|
|
40464
|
-
lineNumber:
|
|
40469
|
+
lineNumber: 152,
|
|
40465
40470
|
columnNumber: 9
|
|
40466
40471
|
},
|
|
40467
40472
|
void 0
|
|
@@ -40685,6 +40690,8 @@ class SearchEngine {
|
|
|
40685
40690
|
selectedSuggestionIndex: observable.ref,
|
|
40686
40691
|
isSearchInputFocused: observable.ref,
|
|
40687
40692
|
isSuggestionsDismissed: observable.ref,
|
|
40693
|
+
selectedPathOwnerKey: observable.ref,
|
|
40694
|
+
selectedPathSegment: observable.ref,
|
|
40688
40695
|
formattedSearchText: computed,
|
|
40689
40696
|
segments: computed.struct,
|
|
40690
40697
|
endsWithDot: computed,
|
|
@@ -40695,7 +40702,9 @@ class SearchEngine {
|
|
|
40695
40702
|
suggestionItems: computed.struct,
|
|
40696
40703
|
selectedSuggestion: computed,
|
|
40697
40704
|
suggestionSuffix: computed,
|
|
40705
|
+
selectSuggestionAtIndex: action,
|
|
40698
40706
|
applySuggestion: action,
|
|
40707
|
+
applySuggestionFromClick: action,
|
|
40699
40708
|
handleSearchInput: action,
|
|
40700
40709
|
handleSearchInputFocus: action,
|
|
40701
40710
|
handleSearchInputBlur: action,
|
|
@@ -40709,6 +40718,8 @@ class SearchEngine {
|
|
|
40709
40718
|
selectedSuggestionIndex = 0;
|
|
40710
40719
|
isSearchInputFocused = false;
|
|
40711
40720
|
isSuggestionsDismissed = false;
|
|
40721
|
+
selectedPathOwnerKey = null;
|
|
40722
|
+
selectedPathSegment = null;
|
|
40712
40723
|
searchCacheKey = "";
|
|
40713
40724
|
isSearching = false;
|
|
40714
40725
|
searchTextToSearchTimeout = null;
|
|
@@ -40743,14 +40754,26 @@ class SearchEngine {
|
|
|
40743
40754
|
return this.isSearchInputFocused && !this.isSuggestionsDismissed && this.suggestionItems.length > 0;
|
|
40744
40755
|
}
|
|
40745
40756
|
get suggestionItems() {
|
|
40746
|
-
if (this.isSearchTextDebouncing) return [];
|
|
40747
|
-
|
|
40748
|
-
|
|
40757
|
+
if (this.isSearchTextDebouncing && !this.searchText.includes(".")) return [];
|
|
40758
|
+
return this.buildSuggestionItemsForText(this.getActiveSearchText());
|
|
40759
|
+
}
|
|
40760
|
+
getActiveSearchText() {
|
|
40761
|
+
if (this.searchText.includes(".")) {
|
|
40762
|
+
return this.searchText;
|
|
40763
|
+
}
|
|
40764
|
+
return this.searchTextToSearch;
|
|
40765
|
+
}
|
|
40766
|
+
buildSuggestionItemsForText(text2) {
|
|
40767
|
+
const formatted = text2.toLowerCase().trim();
|
|
40768
|
+
if (!formatted) return [];
|
|
40769
|
+
const all = formatted.split(".");
|
|
40770
|
+
const segments = all[all.length - 1] === "" ? all.slice(0, -1) : all;
|
|
40749
40771
|
if (segments.length === 0) return [];
|
|
40750
|
-
const
|
|
40751
|
-
|
|
40772
|
+
const endsWithDot = text2.trim().endsWith(".");
|
|
40773
|
+
const completingSegment = endsWithDot ? "" : segments[segments.length - 1];
|
|
40774
|
+
if (!endsWithDot && !completingSegment) return [];
|
|
40752
40775
|
const rootItems = this.config.getRootItems();
|
|
40753
|
-
const pathSegments =
|
|
40776
|
+
const pathSegments = endsWithDot ? segments : segments.slice(0, -1);
|
|
40754
40777
|
const candidates = this.getCandidatePropsAtDepth(rootItems, pathSegments);
|
|
40755
40778
|
const suggestionsByVM = /* @__PURE__ */ new Map();
|
|
40756
40779
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -40758,7 +40781,8 @@ class SearchEngine {
|
|
|
40758
40781
|
const nameLower = prop.searchData.property;
|
|
40759
40782
|
const nameOriginal = prop.property ?? "";
|
|
40760
40783
|
const vmName = this.getOwnerVMName(prop);
|
|
40761
|
-
const
|
|
40784
|
+
const ownerKey = this.getOwnerKey(prop);
|
|
40785
|
+
const uniqueKey = `${ownerKey}/${nameLower}`;
|
|
40762
40786
|
if (nameLower.startsWith(completingSegment) && nameLower.length >= completingSegment.length) {
|
|
40763
40787
|
if (seen.has(uniqueKey)) continue;
|
|
40764
40788
|
seen.add(uniqueKey);
|
|
@@ -40766,7 +40790,8 @@ class SearchEngine {
|
|
|
40766
40790
|
suggestions.push({
|
|
40767
40791
|
value: nameOriginal,
|
|
40768
40792
|
suffix: nameOriginal.slice(completingSegment.length),
|
|
40769
|
-
vmName
|
|
40793
|
+
vmName,
|
|
40794
|
+
ownerKey
|
|
40770
40795
|
});
|
|
40771
40796
|
suggestionsByVM.set(vmName, suggestions);
|
|
40772
40797
|
}
|
|
@@ -40806,20 +40831,45 @@ class SearchEngine {
|
|
|
40806
40831
|
get suggestionSuffix() {
|
|
40807
40832
|
return this.selectedSuggestion?.suffix ?? "";
|
|
40808
40833
|
}
|
|
40809
|
-
|
|
40834
|
+
selectSuggestionAtIndex = (index) => {
|
|
40835
|
+
if (index < 0 || index >= this.suggestionItems.length) return;
|
|
40836
|
+
this.selectedSuggestionIndex = index;
|
|
40837
|
+
this.isSuggestionsDismissed = false;
|
|
40838
|
+
};
|
|
40839
|
+
applySuggestion = (suggestion, options) => {
|
|
40810
40840
|
this.clearSearchDebounce();
|
|
40841
|
+
const hadPathSyntax = this.searchText.includes(".");
|
|
40811
40842
|
const nextSearchText = this.searchText + suggestion.suffix;
|
|
40812
40843
|
this.searchText = nextSearchText;
|
|
40813
40844
|
this.searchTextToSearch = nextSearchText;
|
|
40814
40845
|
this.selectedSuggestionIndex = 0;
|
|
40815
|
-
this.isSuggestionsDismissed = false;
|
|
40846
|
+
this.isSuggestionsDismissed = options?.dismissSuggestions ?? false;
|
|
40847
|
+
const lockedSegment = hadPathSyntax ? this.getFirstPathSegment(nextSearchText) : void 0;
|
|
40848
|
+
if (options?.commitOwner) {
|
|
40849
|
+
this.commitSuggestionOwner(suggestion, lockedSegment);
|
|
40850
|
+
} else if (!hadPathSyntax) {
|
|
40851
|
+
this.commitSuggestionOwner(suggestion);
|
|
40852
|
+
} else if (!this.selectedPathOwnerKey) {
|
|
40853
|
+
this.commitSuggestionOwner(suggestion, lockedSegment);
|
|
40854
|
+
}
|
|
40816
40855
|
this.searchInputRef.current?.focus();
|
|
40817
40856
|
this.scheduleScrollToFirstSearchMatch();
|
|
40818
40857
|
};
|
|
40858
|
+
applySuggestionFromClick = (suggestion, index) => {
|
|
40859
|
+
this.selectSuggestionAtIndex(index);
|
|
40860
|
+
this.applySuggestion(suggestion, { commitOwner: true });
|
|
40861
|
+
};
|
|
40819
40862
|
handleSearchInput = (e) => {
|
|
40863
|
+
const previousSearchText = this.searchText;
|
|
40864
|
+
const previousSelectedSuggestion = this.selectedSuggestion;
|
|
40820
40865
|
this.searchText = e.target.value;
|
|
40821
|
-
this.selectedSuggestionIndex = 0;
|
|
40822
40866
|
this.isSuggestionsDismissed = false;
|
|
40867
|
+
this.handlePathOwnerSelectionFromInput(
|
|
40868
|
+
previousSearchText,
|
|
40869
|
+
this.searchText,
|
|
40870
|
+
previousSelectedSuggestion
|
|
40871
|
+
);
|
|
40872
|
+
this.selectedSuggestionIndex = 0;
|
|
40823
40873
|
this.scheduleSearchTextDebounce();
|
|
40824
40874
|
};
|
|
40825
40875
|
handleSearchInputFocus = (_e) => {
|
|
@@ -40846,11 +40896,66 @@ class SearchEngine {
|
|
|
40846
40896
|
this.selectedSuggestionIndex = (this.selectedSuggestionIndex - 1 + this.suggestionItems.length) % this.suggestionItems.length;
|
|
40847
40897
|
return;
|
|
40848
40898
|
}
|
|
40849
|
-
if (e.key === "Tab" && this.
|
|
40899
|
+
if ((e.key === "Tab" || e.key === "Enter") && this.selectedSuggestion) {
|
|
40850
40900
|
e.preventDefault();
|
|
40851
|
-
this.applySuggestion(this.selectedSuggestion
|
|
40901
|
+
this.applySuggestion(this.selectedSuggestion, {
|
|
40902
|
+
dismissSuggestions: e.key === "Enter"
|
|
40903
|
+
});
|
|
40852
40904
|
}
|
|
40853
40905
|
};
|
|
40906
|
+
commitSuggestionOwner(suggestion, lockedSegment) {
|
|
40907
|
+
this.selectedPathOwnerKey = suggestion.ownerKey;
|
|
40908
|
+
this.selectedPathSegment = lockedSegment ?? suggestion.value.toLowerCase().trim();
|
|
40909
|
+
}
|
|
40910
|
+
handlePathOwnerSelectionFromInput(previousSearchText, nextSearchText, previousSelectedSuggestion) {
|
|
40911
|
+
const addedDot = nextSearchText.endsWith(".") && nextSearchText === `${previousSearchText}.`;
|
|
40912
|
+
const enteredPathSyntax = nextSearchText.includes(".") && !previousSearchText.includes(".");
|
|
40913
|
+
if (addedDot || enteredPathSyntax) {
|
|
40914
|
+
const pathSegment = this.getFirstPathSegment(
|
|
40915
|
+
addedDot ? previousSearchText : nextSearchText
|
|
40916
|
+
);
|
|
40917
|
+
if (this.selectedPathOwnerKey && this.selectedPathSegment === pathSegment) {
|
|
40918
|
+
this.searchTextToSearch = nextSearchText;
|
|
40919
|
+
this.clearSearchDebounce();
|
|
40920
|
+
return;
|
|
40921
|
+
}
|
|
40922
|
+
const suggestion = addedDot && previousSelectedSuggestion && previousSelectedSuggestion.value.toLowerCase() === pathSegment ? previousSelectedSuggestion : this.resolvePathOwnerSuggestion(
|
|
40923
|
+
pathSegment,
|
|
40924
|
+
this.selectedSuggestionIndex
|
|
40925
|
+
);
|
|
40926
|
+
if (suggestion) {
|
|
40927
|
+
this.commitSuggestionOwner(suggestion, pathSegment);
|
|
40928
|
+
}
|
|
40929
|
+
this.searchTextToSearch = nextSearchText;
|
|
40930
|
+
this.clearSearchDebounce();
|
|
40931
|
+
return;
|
|
40932
|
+
}
|
|
40933
|
+
const firstSegment = nextSearchText.toLowerCase().trim().split(".")[0] ?? "";
|
|
40934
|
+
if (!nextSearchText.includes(".") || !firstSegment || firstSegment !== this.selectedPathSegment) {
|
|
40935
|
+
this.selectedPathOwnerKey = null;
|
|
40936
|
+
this.selectedPathSegment = null;
|
|
40937
|
+
}
|
|
40938
|
+
}
|
|
40939
|
+
/**
|
|
40940
|
+
* При вводе точки debounce ещё не применил searchTextToSearch,
|
|
40941
|
+
* поэтому owner берём из подсказок предыдущего сегмента.
|
|
40942
|
+
* Если пользователь явно не выбирал — берём exact-match `service`, иначе первый в списке.
|
|
40943
|
+
*/
|
|
40944
|
+
getFirstPathSegment(text2) {
|
|
40945
|
+
return text2.toLowerCase().trim().split(".")[0] ?? "";
|
|
40946
|
+
}
|
|
40947
|
+
resolvePathOwnerSuggestion(pathSegment, selectedIndex) {
|
|
40948
|
+
if (!pathSegment) return null;
|
|
40949
|
+
const items = this.buildSuggestionItemsForText(pathSegment);
|
|
40950
|
+
if (items.length === 0) return null;
|
|
40951
|
+
const exactMatches = items.filter(
|
|
40952
|
+
(item) => item.value.toLowerCase() === pathSegment
|
|
40953
|
+
);
|
|
40954
|
+
if (exactMatches.length > 0) {
|
|
40955
|
+
return exactMatches[Math.min(selectedIndex, exactMatches.length - 1)] ?? exactMatches[0];
|
|
40956
|
+
}
|
|
40957
|
+
return items[Math.min(selectedIndex, items.length - 1)] ?? items[0];
|
|
40958
|
+
}
|
|
40854
40959
|
clearSearchDebounce() {
|
|
40855
40960
|
if (this.searchTextToSearchTimeout) {
|
|
40856
40961
|
clearTimeout(this.searchTextToSearchTimeout);
|
|
@@ -40933,6 +41038,7 @@ class SearchEngine {
|
|
|
40933
41038
|
const firstSeg = pathSegments[0];
|
|
40934
41039
|
const result = [];
|
|
40935
41040
|
for (const vm of allVMs) {
|
|
41041
|
+
if (!this.isOwnerAllowedForFirstPathSegment(vm, firstSeg)) continue;
|
|
40936
41042
|
const directProps = this.getDirectPropertyChildren(vm);
|
|
40937
41043
|
const firstSegmentIsExactProperty = directProps.some(
|
|
40938
41044
|
(prop) => prop.searchData.property === firstSeg
|
|
@@ -40945,6 +41051,7 @@ class SearchEngine {
|
|
|
40945
41051
|
}
|
|
40946
41052
|
}
|
|
40947
41053
|
for (const extra of extras) {
|
|
41054
|
+
if (!this.isOwnerAllowedForFirstPathSegment(extra, firstSeg)) continue;
|
|
40948
41055
|
const directProps = this.getDirectPropertyChildren(extra);
|
|
40949
41056
|
const firstSegmentIsExactProperty = directProps.some(
|
|
40950
41057
|
(prop) => prop.searchData.property === firstSeg
|
|
@@ -40975,6 +41082,15 @@ class SearchEngine {
|
|
|
40975
41082
|
(child) => child instanceof PropertyListItem
|
|
40976
41083
|
);
|
|
40977
41084
|
}
|
|
41085
|
+
isOwnerAllowedForFirstPathSegment(owner, firstSegment) {
|
|
41086
|
+
if (!this.selectedPathOwnerKey || this.selectedPathSegment !== firstSegment) {
|
|
41087
|
+
return true;
|
|
41088
|
+
}
|
|
41089
|
+
return owner.key === this.selectedPathOwnerKey;
|
|
41090
|
+
}
|
|
41091
|
+
isPathOwnerLockedToAnotherOwner(owner, firstSegment) {
|
|
41092
|
+
return !this.isOwnerAllowedForFirstPathSegment(owner, firstSegment);
|
|
41093
|
+
}
|
|
40978
41094
|
/**
|
|
40979
41095
|
* Уже введённый path-сегмент должен совпадать строго:
|
|
40980
41096
|
* `product.` заходит только в `product`, а не в `productAsyncTasks`
|
|
@@ -40996,6 +41112,13 @@ class SearchEngine {
|
|
|
40996
41112
|
}
|
|
40997
41113
|
return "";
|
|
40998
41114
|
}
|
|
41115
|
+
getOwnerKey(item) {
|
|
41116
|
+
let parent = item.parentListItem;
|
|
41117
|
+
while (parent instanceof PropertyListItem) {
|
|
41118
|
+
parent = parent.parentListItem;
|
|
41119
|
+
}
|
|
41120
|
+
return parent.key;
|
|
41121
|
+
}
|
|
40999
41122
|
/**
|
|
41000
41123
|
* Навигация вглубь по цепочке свойств.
|
|
41001
41124
|
* Возвращает свойства на нужной глубине.
|
|
@@ -41069,6 +41192,9 @@ class SearchEngine {
|
|
|
41069
41192
|
return [item];
|
|
41070
41193
|
}
|
|
41071
41194
|
getExtraSearchItems(item) {
|
|
41195
|
+
if (this.isPathOwnerLockedToAnotherOwner(item, this.segments[0] ?? "")) {
|
|
41196
|
+
return [];
|
|
41197
|
+
}
|
|
41072
41198
|
const directProps = this.getDirectPropertyChildren(item);
|
|
41073
41199
|
const matchesByProperty = directProps.some(
|
|
41074
41200
|
(prop) => prop.searchData.property.includes(this.segments[0] ?? "")
|
|
@@ -41078,6 +41204,15 @@ class SearchEngine {
|
|
|
41078
41204
|
}
|
|
41079
41205
|
getVMSearchItems(vmItem) {
|
|
41080
41206
|
const result = [];
|
|
41207
|
+
const firstSeg = this.segments[0] ?? "";
|
|
41208
|
+
if (this.isPathOwnerLockedToAnotherOwner(vmItem, firstSeg)) {
|
|
41209
|
+
for (const child of vmItem.children) {
|
|
41210
|
+
if (child instanceof VMListItem) {
|
|
41211
|
+
result.push(...this.getVMSearchItems(child));
|
|
41212
|
+
}
|
|
41213
|
+
}
|
|
41214
|
+
return result;
|
|
41215
|
+
}
|
|
41081
41216
|
if (!this.vmMatchesSearch(vmItem)) {
|
|
41082
41217
|
for (const child of vmItem.children) {
|
|
41083
41218
|
if (child instanceof VMListItem) {
|
|
@@ -41088,7 +41223,6 @@ class SearchEngine {
|
|
|
41088
41223
|
}
|
|
41089
41224
|
result.push(vmItem);
|
|
41090
41225
|
const { segments } = this;
|
|
41091
|
-
const firstSeg = segments[0] ?? "";
|
|
41092
41226
|
const directProps = vmItem.children.filter(
|
|
41093
41227
|
(c) => c instanceof PropertyListItem
|
|
41094
41228
|
);
|
|
@@ -41144,6 +41278,9 @@ class SearchEngine {
|
|
|
41144
41278
|
const { segments } = this;
|
|
41145
41279
|
if (segments.length === 0) return true;
|
|
41146
41280
|
const firstSegment = segments[0];
|
|
41281
|
+
if (this.isPathOwnerLockedToAnotherOwner(item, firstSegment)) {
|
|
41282
|
+
return false;
|
|
41283
|
+
}
|
|
41147
41284
|
if (item.searchData.name.includes(firstSegment) || item.searchData.id.includes(firstSegment)) {
|
|
41148
41285
|
return true;
|
|
41149
41286
|
}
|
|
@@ -41174,6 +41311,7 @@ class SearchEngine {
|
|
|
41174
41311
|
const { segments } = this;
|
|
41175
41312
|
if (segments.length === 0) return false;
|
|
41176
41313
|
const firstSeg = segments[0];
|
|
41314
|
+
if (this.isPathOwnerLockedToAnotherOwner(item, firstSeg)) return false;
|
|
41177
41315
|
const hasPathSyntax = this.endsWithDot || segments.length > 1;
|
|
41178
41316
|
const firstSegmentIsExactProperty = hasPathSyntax && item.children.some(
|
|
41179
41317
|
(child) => child instanceof PropertyListItem && child.searchData.property === firstSeg
|
|
@@ -41195,6 +41333,7 @@ class SearchEngine {
|
|
|
41195
41333
|
return false;
|
|
41196
41334
|
}
|
|
41197
41335
|
const firstSeg = segments[0];
|
|
41336
|
+
if (this.isPathOwnerLockedToAnotherOwner(parent, firstSeg)) return false;
|
|
41198
41337
|
const hasPathSyntax = this.endsWithDot || segments.length > 1;
|
|
41199
41338
|
const parentDirectProps = this.getDirectPropertyChildren(parent);
|
|
41200
41339
|
const firstSegmentIsExactProperty = hasPathSyntax && parentDirectProps.some((prop) => prop.searchData.property === firstSeg);
|
|
@@ -41244,6 +41383,7 @@ class SearchEngine {
|
|
|
41244
41383
|
return true;
|
|
41245
41384
|
}
|
|
41246
41385
|
const firstSeg = segments[0];
|
|
41386
|
+
if (this.isPathOwnerLockedToAnotherOwner(parent, firstSeg)) return false;
|
|
41247
41387
|
const hasPathSyntax = this.endsWithDot || segments.length > 1;
|
|
41248
41388
|
const parentDirectProps = this.getDirectPropertyChildren(parent);
|
|
41249
41389
|
const firstSegmentIsExactProperty = hasPathSyntax && parentDirectProps.some((prop) => prop.searchData.property === firstSeg);
|
|
@@ -41286,6 +41426,8 @@ class SearchEngine {
|
|
|
41286
41426
|
this.searchTextToSearch = "";
|
|
41287
41427
|
this.selectedSuggestionIndex = 0;
|
|
41288
41428
|
this.isSuggestionsDismissed = false;
|
|
41429
|
+
this.selectedPathOwnerKey = null;
|
|
41430
|
+
this.selectedPathSegment = null;
|
|
41289
41431
|
this.focusInput();
|
|
41290
41432
|
};
|
|
41291
41433
|
focusInput = () => {
|