@pb33f/cowboy-components 0.3.5 → 0.5.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/README.md +1 -1
- package/dist/assets/css.worker-CTSQecos.js +84 -0
- package/dist/assets/editor.worker-CYC0jP-p.js +12 -0
- package/dist/assets/equalizer.worker-CdIiiqfH.js +1 -0
- package/dist/assets/html.worker-C1BIaUKh.js +461 -0
- package/dist/assets/json.worker-BCyBlh8h.js +49 -0
- package/dist/assets/rule-documentation.worker-B7xOWY5M.js +1 -0
- package/dist/components/credit-ticker/credit-ticker.css.d.ts +2 -0
- package/dist/components/credit-ticker/credit-ticker.css.js +36 -0
- package/dist/components/credit-ticker/credit-ticker.d.ts +14 -0
- package/dist/components/credit-ticker/credit-ticker.js +88 -0
- package/dist/components/editor/editor-breadcrumb.css.d.ts +2 -0
- package/dist/components/editor/editor-breadcrumb.css.js +49 -0
- package/dist/components/editor/editor-breadcrumb.d.ts +9 -0
- package/dist/components/editor/editor-breadcrumb.js +60 -0
- package/dist/components/editor/editor.css.d.ts +2 -0
- package/dist/components/editor/editor.css.js +62 -0
- package/dist/components/editor/editor.d.ts +25 -4
- package/dist/components/editor/editor.js +412 -76
- package/dist/components/manage-ruleset/manage-ruleset.css.js +5 -0
- package/dist/components/manage-ruleset/manage-ruleset.js +8 -6
- package/dist/components/model-icon/model-icon.d.ts +7 -0
- package/dist/components/model-icon/model-icon.js +56 -7
- package/dist/components/model-renderer/clickable-ref.d.ts +2 -2
- package/dist/components/model-renderer/clickable-ref.js +5 -4
- package/dist/components/model-renderer/header.js +10 -10
- package/dist/components/model-renderer/operation.js +2 -2
- package/dist/components/model-renderer/rendered-node.css.js +1 -1
- package/dist/components/model-renderer/schema.js +1 -1
- package/dist/components/model-tree/tree.css.js +1 -0
- package/dist/components/model-tree/tree.d.ts +8 -0
- package/dist/components/model-tree/tree.js +232 -24
- package/dist/components/paginator/paginator.css.js +6 -2
- package/dist/components/paginator/paginator.d.ts +1 -0
- package/dist/components/paginator/paginator.js +8 -4
- package/dist/components/problem-list/details-drawer.css.js +1 -1
- package/dist/components/problem-list/problem-item.js +6 -3
- package/dist/components/problem-list/problem-label-view-filter.d.ts +2 -1
- package/dist/components/problem-list/problem-label-view-filter.js +1 -0
- package/dist/components/problem-list/problem-list.d.ts +1 -0
- package/dist/components/problem-list/problem-list.js +19 -1
- package/dist/components/problem-list/problem-mainview.css.js +1 -1
- package/dist/components/problem-list/problem-mainview.js +6 -0
- package/dist/components/problem-list/problem-sort-filter.d.ts +2 -1
- package/dist/components/problem-list/problem-sort-filter.js +1 -0
- package/dist/components/problems-overview/diagnostic-evaluation.css.js +14 -4
- package/dist/components/problems-overview/diagnostic-evaluation.js +42 -1
- package/dist/components/problems-overview/problems-overview.css.js +1 -0
- package/dist/components/the-doctor/nuke-workspace.d.ts +13 -0
- package/dist/components/the-doctor/nuke-workspace.js +70 -0
- package/dist/components/the-doctor/sparks.d.ts +1 -0
- package/dist/components/the-doctor/sparks.js +11 -2
- package/dist/components/the-doctor/status-bar.css.js +6 -5
- package/dist/components/the-doctor/the-doctor.css.js +117 -16
- package/dist/components/the-doctor/the-doctor.d.ts +70 -21
- package/dist/components/the-doctor/the-doctor.js +1023 -166
- package/dist/components/the-doctor/upload-archive.css.d.ts +2 -0
- package/dist/components/the-doctor/upload-archive.css.js +98 -0
- package/dist/components/the-doctor/upload-archive.d.ts +33 -0
- package/dist/components/the-doctor/upload-archive.js +281 -0
- package/dist/components/visualizer/equalizer.d.ts +3 -1
- package/dist/components/visualizer/equalizer.js +55 -31
- package/dist/components/visualizer/explorer.js +9 -5
- package/dist/cowboy-components.umd.cjs +1846 -1273
- package/dist/css/hr.css.d.ts +2 -0
- package/dist/css/hr.css.js +12 -0
- package/dist/css/pb33f-theme.css +1 -0
- package/dist/events/doctor.d.ts +19 -1
- package/dist/events/doctor.js +5 -0
- package/dist/model/channels.d.ts +1 -0
- package/dist/model/channels.js +1 -0
- package/dist/model/graph.d.ts +17 -0
- package/dist/model/graph.js +17 -1
- package/dist/model/link.d.ts +8 -0
- package/dist/model/node_type.d.ts +22 -1
- package/dist/model/node_type.js +22 -0
- package/dist/model/panel-state.d.ts +5 -0
- package/dist/model/panel-state.js +1 -0
- package/dist/model/problem.d.ts +3 -1
- package/dist/model/problem.js +4 -2
- package/dist/model/rolodex.d.ts +34 -0
- package/dist/model/rolodex.js +1 -0
- package/dist/services/linting-service.d.ts +1 -1
- package/dist/services/linting-service.js +23 -11
- package/dist/services/model-service.d.ts +8 -1
- package/dist/services/model-service.js +127 -0
- package/dist/style.css +1 -1
- package/dist/workers/equalizer.worker.js +4 -3
- package/dist/workers/rule-documentation.worker.d.ts +2 -2
- package/dist/workers/rule-documentation.worker.js +26 -15
- package/package.json +3 -3
- package/dist/assets/css.worker-B_qZXUzt.js +0 -84
- package/dist/assets/editor.worker-HEmB0D7P.js +0 -11
- package/dist/assets/equalizer.worker-icLzyXQ7.js +0 -1
- package/dist/assets/html.worker-D3WUrk8Q.js +0 -458
- package/dist/assets/json.worker-CAhUaBo4.js +0 -42
- package/dist/assets/rule-documentation.worker-D39NS8Lx.js +0 -1
|
@@ -16,7 +16,7 @@ import '@shoelace-style/shoelace/dist/components/avatar/avatar.js';
|
|
|
16
16
|
import { customElement, property, query, state } from "lit/decorators.js";
|
|
17
17
|
import { html, LitElement } from "lit";
|
|
18
18
|
import { SpecEditor } from "../editor/editor.js";
|
|
19
|
-
import { ActiveView, AddToast, CustomRulesetEnabled, EditorClicked, EditorUpdated,
|
|
19
|
+
import { ActiveView, AddToast, ArchiveURLRequested, BuiltInRulesetChanged, CustomRulesetEnabled, DocumentReferenceClicked, EditorClicked, EditorUpdated, ExplorerEqualizerChanged, ExplorerEqualizerFiltered, ExplorerNodeClicked, ExportRuleset, ModelTreeNodeClicked, NodeReferenceClicked, OpenProblemDrawer, ProblemClicked, ProblemRuleFilterChangedManual, RolodexRootFileSelected, RolodexTreeNodeClicked, RuleClicked, RulesetSaved, RuleViolationClicked, NukeWorkspaceEvent } from "../../events/doctor.js";
|
|
20
20
|
import { ProblemDetailsDrawer, ProblemDrawerEventType } from "../problem-list/details-drawer.js";
|
|
21
21
|
import { CreateBagManager } from "@pb33f/saddlebag";
|
|
22
22
|
import { LintingService } from "../../services/linting-service.js";
|
|
@@ -40,19 +40,30 @@ import buttonCss from "../../css/button.css.js";
|
|
|
40
40
|
import radioGroupsCss from "../../css/radiogroups.css.js";
|
|
41
41
|
import { MarkerSeverity } from "monaco-editor";
|
|
42
42
|
import { ModelService } from "../../services/model-service.js";
|
|
43
|
+
import { SearchNodeTreeForPath } from "../../model/graph.js";
|
|
43
44
|
import { ModelTree } from "../model-tree/tree.js";
|
|
44
45
|
import { ExplorerComponent } from "../visualizer/explorer.js";
|
|
45
46
|
import { RenderedNodeComponent } from "../model-renderer/rendered-node.js";
|
|
46
47
|
import tabsCss from "../../css/tabs.css.js";
|
|
47
48
|
import { CreateBus } from "@pb33f/ranch";
|
|
48
|
-
import { Command, DoctorServiceChannel, isBrokerResponse, QueuePrefix, SpecStreamChannel } from "../../model/channels";
|
|
49
|
+
import { Command, CreditStreamChannel, DoctorServiceChannel, isBrokerResponse, QueuePrefix, SpecStreamChannel, } from "../../model/channels";
|
|
49
50
|
import formsCss from "../../css/forms.css";
|
|
50
|
-
import { PixelSparks } from "./sparks.js";
|
|
51
51
|
import spinnerCss from "../../css/spinner.css";
|
|
52
|
+
import { UploadArchiveComponent } from "./upload-archive";
|
|
53
|
+
import { NodeType } from "../../model/node_type";
|
|
54
|
+
import tooltipCss from "../../css/tooltip.css";
|
|
55
|
+
import { NukeWorkspaceComponent } from "./nuke-workspace";
|
|
56
|
+
import { CreditTicker } from "../credit-ticker/credit-ticker";
|
|
52
57
|
export const GraphBag = "pb33f-doctor-graph";
|
|
58
|
+
export const PanelStateBag = "pb33f-doctor-panel-state";
|
|
59
|
+
export const RolodexResponseBag = "pb33f-doctor-rolodex-response";
|
|
60
|
+
export const RolodexFilesBag = "pb33f-doctor-rolodex-files";
|
|
61
|
+
export const RolodexStateBag = "pb33f-doctor-rolodex-state";
|
|
62
|
+
export const ReferenceMapBag = "pb33f-doctor-reference-map";
|
|
53
63
|
export const DoctorDocumentBag = "pb33f-doctor-editor";
|
|
54
64
|
export const HowToFixBag = "pb33f-doctor-howtofix";
|
|
55
65
|
export const FunctionDocumentationBag = "pb33f-doctor-funcdocs";
|
|
66
|
+
export const DocumentationExpirationBag = "pb33f-doctor-doc-expiration";
|
|
56
67
|
export const RuleDocumentationBag = "pb33f-doctor-ruledocs";
|
|
57
68
|
export const DiagnosticBag = "pb33f-doctor-diagnostic";
|
|
58
69
|
export const DefaultRulesetBag = "pb33f-doctor-default-ruleset";
|
|
@@ -63,8 +74,8 @@ export const FunctionsSchemaBag = "pb33f-doctor-function-schema";
|
|
|
63
74
|
export const CustomRulesetBag = "pb33f-doctor-custom-ruleset";
|
|
64
75
|
export const RuleConfigurationBag = "pb33f-doctor-rule-configuration";
|
|
65
76
|
export const SessionRulesetMapBag = "pb33f-doctor-session-rulesetmap";
|
|
66
|
-
export const DefaultDocument = "document";
|
|
67
|
-
export const DocumentProblems = "problems";
|
|
77
|
+
export const DefaultDocument = "pb33f-doctor-document";
|
|
78
|
+
export const DocumentProblems = "pb33f-doctor-problems";
|
|
68
79
|
export const DoctorEndpoint = "doctor-endpoint";
|
|
69
80
|
let TheDoctor = class TheDoctor extends LitElement {
|
|
70
81
|
constructor(doctorEndpoint = "https://doctor.pb33f.io") {
|
|
@@ -73,19 +84,27 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
73
84
|
this.debounceTimeRuleset = 900;
|
|
74
85
|
this.bounceId = 0;
|
|
75
86
|
this.useTLS = false;
|
|
87
|
+
// rolodex divider state (because it may not exist)
|
|
88
|
+
this.rolodexDividerPosition = 40;
|
|
89
|
+
this._firstRun = true;
|
|
76
90
|
// bus it up
|
|
77
91
|
this.bus = CreateBus();
|
|
78
92
|
this.doctorServiceChannel = this.bus.createChannel(DoctorServiceChannel);
|
|
79
93
|
this.specStreamChannel = this.bus.createChannel(SpecStreamChannel);
|
|
94
|
+
this.creditStreamChannel = this.bus.createChannel(CreditStreamChannel);
|
|
80
95
|
this.bus.mapChannelToBrokerDestination(QueuePrefix + DoctorServiceChannel, DoctorServiceChannel);
|
|
81
96
|
this.bus.mapChannelToBrokerDestination(QueuePrefix + SpecStreamChannel, SpecStreamChannel);
|
|
97
|
+
this.bus.mapChannelToBrokerDestination(QueuePrefix + CreditStreamChannel, CreditStreamChannel);
|
|
82
98
|
this.doctorChannelSubscription = this.doctorServiceChannel.subscribe(this.doctorServiceHandler());
|
|
83
99
|
this.specChannelSubscription = this.specStreamChannel.subscribe(this.specStreamHandler());
|
|
100
|
+
this.creditChannelSubscription = this.creditStreamChannel.subscribe(this.creditStreamHandler());
|
|
84
101
|
// create a stateful bag manager
|
|
85
102
|
this.bagManager = CreateBagManager(true);
|
|
86
103
|
this.bagManager.loadStatefulBags().then(this.loadState.bind(this));
|
|
87
104
|
this.editor = new SpecEditor();
|
|
88
|
-
this.
|
|
105
|
+
this.uploadArchive = new UploadArchiveComponent();
|
|
106
|
+
this.nukeWorkspace = new NukeWorkspaceComponent();
|
|
107
|
+
this.rulesetEditor = new SpecEditor('ruleset-editor');
|
|
89
108
|
this.problemList = new ProblemList();
|
|
90
109
|
this.detailsDrawer = new ProblemDetailsDrawer();
|
|
91
110
|
this.problemsOverview = new ProblemsOverview();
|
|
@@ -97,21 +116,32 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
97
116
|
this.activitySpinner = new ActivitySpinner();
|
|
98
117
|
this.manageRuleset = new ManageRuleset();
|
|
99
118
|
this.toastManager = new ToastManager();
|
|
119
|
+
this.creditTicker = new CreditTicker();
|
|
100
120
|
this.editorMap = new Map();
|
|
101
121
|
this.editorMap.set("spec", this.editor);
|
|
102
|
-
this.editorMap.set("ruleset", this.rulesetEditor);
|
|
122
|
+
this.editorMap.set("ruleset-editor", this.rulesetEditor);
|
|
103
123
|
this.selectedEditorTab = "spec";
|
|
104
124
|
this.sidebarClosed = false;
|
|
105
125
|
this.explorerVisible = false;
|
|
106
126
|
this.explorerBooted = false;
|
|
127
|
+
this.rolodexNeedsReset = false;
|
|
128
|
+
this.rolodexProblemMap = new Map();
|
|
129
|
+
this.rolodexRootHash = "";
|
|
130
|
+
this.rolodexRootPath = "";
|
|
131
|
+
this.importDisabled = false;
|
|
132
|
+
this.pendingLine = 0;
|
|
107
133
|
this.nodeMap = new Map();
|
|
108
134
|
this.nodeIdMap = new Map();
|
|
109
135
|
this.nodeIdHashMap = new Map();
|
|
110
136
|
this.renderedNodeMap = new Map();
|
|
111
137
|
this.filteredNodes = new Map();
|
|
112
138
|
this.modelTree = new ModelTree(this.nodeMap, this.nodeIdMap, this.nodeIdHashMap);
|
|
139
|
+
this.rolodexTree = new ModelTree(this.nodeMap, this.nodeIdMap, this.nodeIdHashMap);
|
|
140
|
+
this.rolodexActiveHash = "";
|
|
113
141
|
this.explorer = new ExplorerComponent();
|
|
114
142
|
this.renderedNode = new RenderedNodeComponent();
|
|
143
|
+
this.references = [];
|
|
144
|
+
this.minimapVisible = true;
|
|
115
145
|
this.nodeLimit = 150;
|
|
116
146
|
// extract the doctor endpoint from session storage.
|
|
117
147
|
const sessionEndpoint = sessionStorage.getItem(DoctorEndpoint);
|
|
@@ -122,7 +152,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
122
152
|
this.doctorEndpoint = doctorEndpoint;
|
|
123
153
|
}
|
|
124
154
|
// TODO: make this configurable
|
|
125
|
-
this.editor.language = "yaml";
|
|
155
|
+
//this.editor.language = "yaml";
|
|
126
156
|
//@ts-ignore
|
|
127
157
|
this.addEventListener(EditorUpdated, this.specChanged);
|
|
128
158
|
//@ts-ignore
|
|
@@ -147,21 +177,30 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
147
177
|
// @ts-ignore
|
|
148
178
|
this.addEventListener(ModelTreeNodeClicked, this.modelTreeNodeClicked);
|
|
149
179
|
// @ts-ignore
|
|
180
|
+
this.addEventListener(RolodexTreeNodeClicked, this.rolodexTreeNodeClicked);
|
|
181
|
+
// @ts-ignore
|
|
182
|
+
this.addEventListener(RolodexRootFileSelected, this.rolodexRootFileSelected);
|
|
183
|
+
// @ts-ignore
|
|
150
184
|
this.addEventListener(NodeReferenceClicked, this.explorerReferenceClicked);
|
|
151
185
|
// @ts-ignore
|
|
152
186
|
this.addEventListener(ExplorerNodeClicked, this.explorerNodeClicked.bind(this));
|
|
187
|
+
// @ts-ignore
|
|
188
|
+
this.addEventListener(ArchiveURLRequested, this.fetchUrl.bind(this));
|
|
189
|
+
// @ts-ignore
|
|
190
|
+
this.addEventListener(DocumentReferenceClicked, this.documentReferenceClicked.bind(this));
|
|
153
191
|
//@ts-ignore
|
|
154
192
|
this.explorer.equalizer.addEventListener(ExplorerEqualizerChanged, this.filterTreeModel.bind(this));
|
|
155
193
|
//@ts-ignore
|
|
156
194
|
this.explorer.equalizer.addEventListener(ExplorerEqualizerFiltered, this.filterTreeModel.bind(this));
|
|
195
|
+
this.nukeWorkspace.addEventListener(NukeWorkspaceEvent, this.nukeWorkspaceHandler.bind(this));
|
|
157
196
|
// extract port from session storage.
|
|
158
197
|
this.busPort = sessionStorage.getItem("pb33f-doctor-port");
|
|
159
198
|
this.busHost = sessionStorage.getItem("pb33f-doctor-host");
|
|
160
199
|
if (!this.busPort) {
|
|
161
|
-
this.busPort = "
|
|
200
|
+
this.busPort = "443"; // default port
|
|
162
201
|
}
|
|
163
202
|
if (!this.busHost) {
|
|
164
|
-
this.busHost = "
|
|
203
|
+
this.busHost = "doctor.pb33f.io"; // default host
|
|
165
204
|
}
|
|
166
205
|
const useTLS = sessionStorage.getItem("pb33f-doctor-tls");
|
|
167
206
|
if (useTLS && useTLS == 'true') {
|
|
@@ -179,9 +218,33 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
179
218
|
}
|
|
180
219
|
}));
|
|
181
220
|
}
|
|
221
|
+
if (state.ref) {
|
|
222
|
+
this.documentReferenceClicked(new CustomEvent(DocumentReferenceClicked, {
|
|
223
|
+
detail: {
|
|
224
|
+
jsonPath: state.ref,
|
|
225
|
+
noState: true
|
|
226
|
+
}
|
|
227
|
+
}));
|
|
228
|
+
}
|
|
182
229
|
}
|
|
183
230
|
});
|
|
184
231
|
}
|
|
232
|
+
nukeWorkspaceHandler() {
|
|
233
|
+
this.bagManager.resetBags();
|
|
234
|
+
ModelService.resetWorkspace().then(() => {
|
|
235
|
+
window.location.reload();
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
minimapToggled() {
|
|
239
|
+
this.minimapVisible = !this.minimapVisible;
|
|
240
|
+
this.editor.toggleMinimap();
|
|
241
|
+
this.rulesetEditor.toggleMinimap();
|
|
242
|
+
}
|
|
243
|
+
firstUpdated() {
|
|
244
|
+
// https://github.com/microsoft/monaco-editor/issues/3409
|
|
245
|
+
this.editor = this.querySelector('pb33f-editor#spec-editor');
|
|
246
|
+
this.rulesetEditor = this.querySelector('pb33f-editor#ruleset-editor');
|
|
247
|
+
}
|
|
185
248
|
whoAmI() {
|
|
186
249
|
this.bus.publish({
|
|
187
250
|
destination: "/p/q/" + DoctorServiceChannel,
|
|
@@ -203,23 +266,31 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
203
266
|
this.whoAmI();
|
|
204
267
|
}
|
|
205
268
|
};
|
|
269
|
+
// TODO re-enable
|
|
206
270
|
this.bus.connectToBroker(config);
|
|
271
|
+
//this.startTheDoctor()
|
|
207
272
|
}
|
|
208
273
|
addClickTrack(node) {
|
|
209
274
|
history.pushState({ activeNode: node.idHash }, "", `?view=explore&node=${node.idHash}`);
|
|
210
275
|
}
|
|
276
|
+
addRefTrack(ref) {
|
|
277
|
+
history.pushState({ ref: ref }, "", `?view=spec&ref=${ref}`);
|
|
278
|
+
}
|
|
211
279
|
doctorServiceHandler() {
|
|
212
280
|
return (msg) => {
|
|
213
281
|
if (msg.payload?.payload != null) {
|
|
214
282
|
if (isBrokerResponse(msg.payload.payload)) {
|
|
215
283
|
this.brokerConnectionId = msg.payload.payload.broker;
|
|
216
|
-
console.log("💊 Welcome
|
|
217
|
-
this.
|
|
218
|
-
this.loadingOverlay.hide();
|
|
284
|
+
console.log("💊 Welcome to the clinic, the %cdoctor %cis ready to see you.", 'color: #62C4FFFF; font-weight: bold', 'color: default');
|
|
285
|
+
this.startTheDoctor();
|
|
219
286
|
}
|
|
220
287
|
}
|
|
221
288
|
};
|
|
222
289
|
}
|
|
290
|
+
startTheDoctor() {
|
|
291
|
+
this.boostrap();
|
|
292
|
+
this.loadingOverlay.hide();
|
|
293
|
+
}
|
|
223
294
|
specStreamHandler() {
|
|
224
295
|
return (msg) => {
|
|
225
296
|
if (msg.payload?.payload != null) {
|
|
@@ -233,6 +304,13 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
233
304
|
}
|
|
234
305
|
};
|
|
235
306
|
}
|
|
307
|
+
creditStreamHandler() {
|
|
308
|
+
return (msg) => {
|
|
309
|
+
if (msg.payload?.payload != null) {
|
|
310
|
+
this.creditTicker.credits = parseInt(msg.payload.payload);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
236
314
|
filterTreeModel(event) {
|
|
237
315
|
this.filteredNodes = new Map();
|
|
238
316
|
event.detail.graph.nodes.forEach((node) => {
|
|
@@ -241,6 +319,76 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
241
319
|
this.modelTree.filteredNodes = this.filteredNodes;
|
|
242
320
|
this.modelTree.renderedNodes = this.renderedNodeMap;
|
|
243
321
|
}
|
|
322
|
+
documentReferenceClicked(evt) {
|
|
323
|
+
let location = '';
|
|
324
|
+
let line, col = 1;
|
|
325
|
+
let path = evt.detail.jsonPath;
|
|
326
|
+
let fullPath = '';
|
|
327
|
+
let file = '';
|
|
328
|
+
let rolodexId = '';
|
|
329
|
+
if (evt.detail.jsonPath.includes('||')) {
|
|
330
|
+
location = evt.detail.jsonPath.split('||')[1];
|
|
331
|
+
path = evt.detail.jsonPath.split('||')[0];
|
|
332
|
+
// location is formatted line:col-endCol
|
|
333
|
+
line = parseInt(location.split(':')[0]);
|
|
334
|
+
col = parseInt(location.split(':')[1]);
|
|
335
|
+
fullPath = evt.detail.jsonPath.split('||')[2];
|
|
336
|
+
if (fullPath != '') {
|
|
337
|
+
file = fullPath.split('#')[0];
|
|
338
|
+
}
|
|
339
|
+
rolodexId = evt.detail.jsonPath.split('||')[3];
|
|
340
|
+
}
|
|
341
|
+
this.editor.editor?.setPosition({ lineNumber: line, column: col });
|
|
342
|
+
this.editor.editor?.revealLineInCenter(line);
|
|
343
|
+
if (this.nodeIdMap.has(path)) {
|
|
344
|
+
const node = this.nodeIdMap.get(path);
|
|
345
|
+
if (node) {
|
|
346
|
+
if (this.nodeIdHashMap.has(node.idHash)) {
|
|
347
|
+
const renderedNode = this.renderedNodeMap.get(node.idHash);
|
|
348
|
+
if (renderedNode) {
|
|
349
|
+
this.renderedNode.node = renderedNode;
|
|
350
|
+
this.modelTree.explorerClicked(node.idHash);
|
|
351
|
+
// add a ref click
|
|
352
|
+
if (!evt.detail.noState) {
|
|
353
|
+
this.addRefTrack(evt.detail.jsonPath);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
this.toastManager.addToastManually({
|
|
360
|
+
id: crypto.randomUUID(),
|
|
361
|
+
type: ToastType.INFO,
|
|
362
|
+
title: "Reference not found",
|
|
363
|
+
body: `Something went wrong, '${path}' not found`
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
if (this.rolodexActivePath != undefined && this.rolodexActivePath != file) {
|
|
369
|
+
ModelService.queryRolodex(rolodexId, file).then((result) => {
|
|
370
|
+
this.editor.showBreadcrumb = true;
|
|
371
|
+
this.rolodexActivePath = file;
|
|
372
|
+
this.editor.clearDecorations();
|
|
373
|
+
this.editor.setValue(result.rolodexRoot.instance, true);
|
|
374
|
+
this.editor.editor?.setPosition({ lineNumber: line, column: 1 });
|
|
375
|
+
this.editor.editor?.revealLineInCenter(line);
|
|
376
|
+
this.rolodexTree.explorerClicked(rolodexId);
|
|
377
|
+
this.editor.setCurrentPath(file);
|
|
378
|
+
this.lintSpec(result.rolodexRoot.instance);
|
|
379
|
+
// apply problems
|
|
380
|
+
if (this.rolodexProblemMap.has(this.rolodexActivePath)) {
|
|
381
|
+
const probs = this.rolodexProblemMap.get(this.rolodexActivePath);
|
|
382
|
+
if (probs) {
|
|
383
|
+
this.editor.setMarkers(probs);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}).catch((e) => {
|
|
387
|
+
console.error('rolodex query failed', e);
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
244
392
|
explorerReferenceClicked(evt) {
|
|
245
393
|
let hashId = '';
|
|
246
394
|
this.explorer.nodeComponents.forEach((node) => {
|
|
@@ -267,10 +415,189 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
267
415
|
this.explorer.requestUpdate();
|
|
268
416
|
this.viewerPanel.click();
|
|
269
417
|
}
|
|
418
|
+
if (evt.detail.nodePath) {
|
|
419
|
+
let p = evt.detail.nodePath;
|
|
420
|
+
if (!p.startsWith('/') && !p.includes('#')) {
|
|
421
|
+
const dir = this.rolodexRootPath.substring(0, this.rolodexRootPath.lastIndexOf('/') + 1);
|
|
422
|
+
p = dir + p;
|
|
423
|
+
}
|
|
424
|
+
if (!p.startsWith('#/')) {
|
|
425
|
+
this.rolodexTreeNodeClicked(new CustomEvent(RolodexTreeNodeClicked, {
|
|
426
|
+
detail: {
|
|
427
|
+
path: p,
|
|
428
|
+
}
|
|
429
|
+
}));
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
rolodexTreeNodeClicked(evt) {
|
|
434
|
+
const fileBag = this.rolodexFilesBag?.get(RolodexFilesBag);
|
|
435
|
+
const handleRolodexResponse = (result) => {
|
|
436
|
+
this.rolodexActivePath = evt.detail.path;
|
|
437
|
+
this.rolodexActiveHash = evt.detail.nodeHashId;
|
|
438
|
+
this.editor.setValue(result.instance, true);
|
|
439
|
+
this.editor.setCurrentPath(this.rolodexActivePath);
|
|
440
|
+
const probs = this.rolodexProblemMap.get(this.rolodexActivePath);
|
|
441
|
+
if (probs) {
|
|
442
|
+
this.editor.setMarkers(probs);
|
|
443
|
+
}
|
|
444
|
+
// set the editor file type
|
|
445
|
+
let language = 'yaml';
|
|
446
|
+
const ext = evt.detail?.path?.split('.').pop();
|
|
447
|
+
if (ext) {
|
|
448
|
+
switch (ext) {
|
|
449
|
+
case NodeType.JSON:
|
|
450
|
+
language = NodeType.JSON;
|
|
451
|
+
break;
|
|
452
|
+
case NodeType.GO:
|
|
453
|
+
language = NodeType.GO;
|
|
454
|
+
break;
|
|
455
|
+
case NodeType.PY:
|
|
456
|
+
language = 'python';
|
|
457
|
+
break;
|
|
458
|
+
case NodeType.JS:
|
|
459
|
+
language = 'javascript';
|
|
460
|
+
break;
|
|
461
|
+
case NodeType.TS:
|
|
462
|
+
language = 'typescript';
|
|
463
|
+
break;
|
|
464
|
+
case NodeType.PHP:
|
|
465
|
+
language = NodeType.PHP;
|
|
466
|
+
break;
|
|
467
|
+
case NodeType.XML:
|
|
468
|
+
language = NodeType.XML;
|
|
469
|
+
break;
|
|
470
|
+
case NodeType.JAVA:
|
|
471
|
+
language = NodeType.JAVA;
|
|
472
|
+
break;
|
|
473
|
+
case NodeType.RB:
|
|
474
|
+
language = 'ruby';
|
|
475
|
+
break;
|
|
476
|
+
case NodeType.RS:
|
|
477
|
+
language = 'rust';
|
|
478
|
+
break;
|
|
479
|
+
case NodeType.C:
|
|
480
|
+
language = NodeType.C;
|
|
481
|
+
break;
|
|
482
|
+
case NodeType.CPP:
|
|
483
|
+
language = NodeType.CPP;
|
|
484
|
+
break;
|
|
485
|
+
case NodeType.CS:
|
|
486
|
+
language = 'csharp';
|
|
487
|
+
break;
|
|
488
|
+
case NodeType.MD:
|
|
489
|
+
language = 'markdown';
|
|
490
|
+
break;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
const existingState = this.rolodexStateBag?.get(RolodexStateBag);
|
|
494
|
+
if (existingState) {
|
|
495
|
+
existingState.activePath = evt.detail.path;
|
|
496
|
+
existingState.activeHash = evt.detail.nodeHashId;
|
|
497
|
+
existingState.activeLanguage = language;
|
|
498
|
+
existingState.activeNode = result;
|
|
499
|
+
existingState.rootPath = this.rolodexRootPath;
|
|
500
|
+
this.rolodexStateBag?.set(RolodexStateBag, existingState);
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
const existingState = {
|
|
504
|
+
activePath: evt.detail.path,
|
|
505
|
+
activeHash: evt.detail.nodeHashId,
|
|
506
|
+
activeLanguage: language,
|
|
507
|
+
activeNode: result,
|
|
508
|
+
rootHash: this.rolodexRootHash,
|
|
509
|
+
rootPath: this.rolodexRootPath
|
|
510
|
+
};
|
|
511
|
+
this.rolodexStateBag?.set(RolodexStateBag, existingState);
|
|
512
|
+
}
|
|
513
|
+
this.editor.switchLanguage(language);
|
|
514
|
+
let line = 1;
|
|
515
|
+
let col = 0;
|
|
516
|
+
if (evt.detail.line) {
|
|
517
|
+
line = evt.detail.line;
|
|
518
|
+
}
|
|
519
|
+
if (evt.detail.column) {
|
|
520
|
+
col = evt.detail.column;
|
|
521
|
+
}
|
|
522
|
+
this.editor.editor?.setPosition({ lineNumber: line, column: col });
|
|
523
|
+
this.editor.editor?.revealLineInCenter(line, col);
|
|
524
|
+
this.lintSpec(result.instance);
|
|
525
|
+
if (evt.detail.path) {
|
|
526
|
+
this.rolodexTree.openNodeByPath(evt.detail.path);
|
|
527
|
+
}
|
|
528
|
+
return language;
|
|
529
|
+
};
|
|
530
|
+
ModelService.queryRolodex(evt.detail.nodeHashId, evt.detail.path).then((result) => {
|
|
531
|
+
this.editor.showBreadcrumb = true;
|
|
532
|
+
// clear all references
|
|
533
|
+
this.referenceMapBag?.reset();
|
|
534
|
+
handleRolodexResponse(result.rolodexRoot);
|
|
535
|
+
if (evt.detail.path) {
|
|
536
|
+
if (fileBag && !fileBag.files[evt.detail.path]) {
|
|
537
|
+
fileBag.files[evt.detail.path] = result.rolodexRoot;
|
|
538
|
+
this.rolodexFilesBag?.set(RolodexFilesBag, fileBag);
|
|
539
|
+
}
|
|
540
|
+
if (!fileBag) {
|
|
541
|
+
const rf = {
|
|
542
|
+
files: { [evt.detail.path]: result.rolodexRoot }
|
|
543
|
+
};
|
|
544
|
+
this.rolodexFilesBag?.set(RolodexFilesBag, rf);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
rolodexRootFileSelected(evt) {
|
|
550
|
+
this.rolodexActivePath = evt.detail.path;
|
|
551
|
+
this.rolodexActiveHash = evt.detail.nodeHashId;
|
|
552
|
+
this.rolodexRootPath = evt.detail.path;
|
|
553
|
+
this.importDisabled = true;
|
|
554
|
+
const existingState = this.rolodexStateBag?.get(RolodexStateBag);
|
|
555
|
+
if (existingState) {
|
|
556
|
+
existingState.activePath = evt.detail.path;
|
|
557
|
+
existingState.activeHash = evt.detail.nodeHashId;
|
|
558
|
+
existingState.rootPath = evt.detail.path;
|
|
559
|
+
existingState.rootHash = evt.detail.nodeHashId;
|
|
560
|
+
this.rolodexStateBag?.set(RolodexStateBag, existingState);
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
const existingState = {
|
|
564
|
+
activePath: evt.detail.path,
|
|
565
|
+
activeHash: evt.detail.nodeHashId,
|
|
566
|
+
rootPath: evt.detail.path,
|
|
567
|
+
rootHash: evt.detail.nodeHashId
|
|
568
|
+
};
|
|
569
|
+
this.rolodexStateBag?.set(RolodexStateBag, existingState);
|
|
570
|
+
}
|
|
571
|
+
if (evt.detail.nodeHashId) {
|
|
572
|
+
this.rolodexRootHash = evt.detail.nodeHashId;
|
|
573
|
+
}
|
|
574
|
+
if (evt.detail.content) {
|
|
575
|
+
this.rolodexNeedsReset = true;
|
|
576
|
+
this.editor.setValue(evt.detail.content, true);
|
|
577
|
+
this.lintSpec(evt.detail.content);
|
|
578
|
+
}
|
|
270
579
|
}
|
|
271
580
|
modelTreeNodeClicked(evt) {
|
|
272
581
|
const node = this.nodeIdHashMap.get(evt.detail.nodeHashId);
|
|
273
582
|
if (node) {
|
|
583
|
+
if (node.origin && node.origin != this.rolodexActivePath && (node.origin != '/root.yaml' && node.origin != 'root.yaml')) {
|
|
584
|
+
// extract the rolodex id using the path
|
|
585
|
+
let hashId = '';
|
|
586
|
+
const fb = this.rolodexFilesBag?.get(RolodexFilesBag);
|
|
587
|
+
if (fb) {
|
|
588
|
+
if (fb.files[node.origin]) {
|
|
589
|
+
hashId = fb.files[node.origin].idHash;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
// we need to fire a rolodex tree node change event.
|
|
593
|
+
this.rolodexTreeNodeClicked(new CustomEvent(RolodexTreeNodeClicked, {
|
|
594
|
+
detail: {
|
|
595
|
+
nodeHashId: hashId,
|
|
596
|
+
path: node.origin
|
|
597
|
+
}
|
|
598
|
+
}));
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
274
601
|
this.editor.editor?.setPosition({ lineNumber: node.keyLine, column: 0 });
|
|
275
602
|
this.editor.editor?.revealLineInCenter(node.keyLine);
|
|
276
603
|
if (this.explorerVisible) {
|
|
@@ -288,15 +615,21 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
288
615
|
evt.detail.noState = true;
|
|
289
616
|
}
|
|
290
617
|
this.explorerNodeClicked(evt);
|
|
291
|
-
this.
|
|
618
|
+
if (this._firstRun) {
|
|
619
|
+
this._firstRun = false;
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
this.viewerPanel.click();
|
|
623
|
+
}
|
|
292
624
|
}
|
|
293
625
|
}
|
|
294
626
|
explorerNodeClicked(evt) {
|
|
295
627
|
let found = false;
|
|
628
|
+
let foundRenderedNode;
|
|
296
629
|
this.explorer.nodeComponents.forEach((node) => {
|
|
297
630
|
if (node.id === evt.detail.nodeHashId) {
|
|
298
631
|
const renderedNode = this.renderedNodeMap.get(node.id);
|
|
299
|
-
if (renderedNode) {
|
|
632
|
+
if (renderedNode && !this._firstRun) {
|
|
300
633
|
this.renderedNode.node = renderedNode;
|
|
301
634
|
}
|
|
302
635
|
this.selectedNodeHashId = node.body.node.idHash;
|
|
@@ -304,6 +637,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
304
637
|
this.activeNode = node.body.node;
|
|
305
638
|
this.explorer.activeNode = node.body.node;
|
|
306
639
|
found = true;
|
|
640
|
+
foundRenderedNode = renderedNode;
|
|
307
641
|
if (!evt.detail.noState) {
|
|
308
642
|
this.addClickTrack(node.body.node);
|
|
309
643
|
}
|
|
@@ -322,8 +656,14 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
322
656
|
this.explorer.equalizer.activeNode = node;
|
|
323
657
|
}
|
|
324
658
|
}
|
|
659
|
+
if (foundRenderedNode) {
|
|
660
|
+
// when jumping back to the spec view, we need to set the line
|
|
661
|
+
this.pendingLine = foundRenderedNode.keyLine;
|
|
662
|
+
}
|
|
325
663
|
this.modelTree.explorerClicked(evt.detail.nodeHashId);
|
|
326
|
-
this.
|
|
664
|
+
if (!this._firstRun) {
|
|
665
|
+
this.viewerPanel.click();
|
|
666
|
+
}
|
|
327
667
|
this.explorer.requestUpdate();
|
|
328
668
|
}
|
|
329
669
|
exportRuleset() {
|
|
@@ -412,17 +752,17 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
412
752
|
// lint spec
|
|
413
753
|
if (this.docBag) {
|
|
414
754
|
const doc = this.docBag.get(DefaultDocument);
|
|
415
|
-
const config = this.
|
|
755
|
+
const config = this.ruleConfigBag?.get(RuleConfigurationBag);
|
|
416
756
|
if (evt.detail.rules) {
|
|
417
|
-
this.
|
|
757
|
+
this.customRulesetBag?.set(CustomRulesetBag, evt.detail.rules);
|
|
418
758
|
// get ruleset config and disable everything,
|
|
419
759
|
// then enable the custom rules.
|
|
420
760
|
if (config) {
|
|
421
761
|
// extract config from the event
|
|
422
762
|
const newConfig = evt.detail.config;
|
|
423
|
-
if (newConfig && this.
|
|
763
|
+
if (newConfig && this.ruleConfigBag) {
|
|
424
764
|
newConfig.returnedRuleset = evt.detail.returnedRules;
|
|
425
|
-
this.
|
|
765
|
+
this.ruleConfigBag?.set(RuleConfigurationBag, newConfig);
|
|
426
766
|
}
|
|
427
767
|
}
|
|
428
768
|
RulesetService.getSessionRulesetAsYAML().then((yaml) => {
|
|
@@ -433,42 +773,267 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
433
773
|
this.fetchRulesetMap();
|
|
434
774
|
});
|
|
435
775
|
// lint the spec
|
|
436
|
-
this.lintSpec(doc);
|
|
776
|
+
this.lintSpec(doc, '');
|
|
437
777
|
}
|
|
438
778
|
}
|
|
439
779
|
}
|
|
780
|
+
buildRolodexResultMap(results) {
|
|
781
|
+
this.rolodexProblemMap.clear();
|
|
782
|
+
results.forEach((problem) => {
|
|
783
|
+
// check if the source location is '/root.yaml'
|
|
784
|
+
if (problem.sourceLocation === '/root.yaml' || problem.sourceLocation === 'root.yaml') {
|
|
785
|
+
problem.sourceLocation = "root";
|
|
786
|
+
}
|
|
787
|
+
if (this.rolodexProblemMap.has(problem.sourceLocation)) {
|
|
788
|
+
const problems = this.rolodexProblemMap.get(problem.sourceLocation);
|
|
789
|
+
if (problems) {
|
|
790
|
+
problems.push(problem);
|
|
791
|
+
if (problem.sourceLocation) {
|
|
792
|
+
this.rolodexProblemMap.set(problem.sourceLocation, problems);
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
if (!this.rolodexRootPath) {
|
|
796
|
+
this.rolodexProblemMap.set("root", problems);
|
|
797
|
+
}
|
|
798
|
+
else {
|
|
799
|
+
this.rolodexProblemMap.set(this.rolodexRootPath, problems);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
else {
|
|
805
|
+
if (problem.sourceLocation) {
|
|
806
|
+
this.rolodexProblemMap.set(problem.sourceLocation, [problem]);
|
|
807
|
+
}
|
|
808
|
+
else {
|
|
809
|
+
if (!this.rolodexRootPath) {
|
|
810
|
+
this.rolodexProblemMap.set("root", [problem]);
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
this.rolodexProblemMap.set(this.rolodexRootPath, [problem]);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
return this.rolodexProblemMap;
|
|
819
|
+
}
|
|
820
|
+
/* LINT SPEC <---------------------------------------------------------------------------------------------
|
|
821
|
+
*
|
|
822
|
+
* This is our main function, man we need to clean this all up, it's bloated to fuck
|
|
823
|
+
*
|
|
824
|
+
* <--------------------------------------------------------------------------------------------------------
|
|
825
|
+
*/
|
|
440
826
|
lintSpec(value, url) {
|
|
441
827
|
this.activitySpinner.show();
|
|
828
|
+
this.editor.breadcumb.isInvalid = false;
|
|
442
829
|
if (url) {
|
|
830
|
+
if (url === 'root') {
|
|
831
|
+
url = '';
|
|
832
|
+
}
|
|
833
|
+
else {
|
|
834
|
+
this.urlProblem.style.display = 'none';
|
|
835
|
+
this.urlOverlay.style.display = "block";
|
|
836
|
+
this.urlSpinner.style.display = "block";
|
|
837
|
+
this.referenceMapBag?.reset(); // wipe out refs.
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
443
841
|
this.urlProblem.style.display = 'none';
|
|
444
|
-
this.urlOverlay.style.display = "
|
|
445
|
-
this.urlSpinner.style.display = "
|
|
842
|
+
this.urlOverlay.style.display = "none";
|
|
843
|
+
this.urlSpinner.style.display = "none";
|
|
844
|
+
}
|
|
845
|
+
let replaceResults = false;
|
|
846
|
+
let currentPath = this.rolodexActivePath;
|
|
847
|
+
if (this.rolodexActivePath === this.rolodexRootPath || this.rolodexActivePath === 'root') {
|
|
848
|
+
replaceResults = true;
|
|
849
|
+
currentPath = '';
|
|
850
|
+
this.editor.showBreadcrumb = false;
|
|
851
|
+
}
|
|
852
|
+
if (url && url != '') {
|
|
853
|
+
try {
|
|
854
|
+
const parsedUrl = new URL(url);
|
|
855
|
+
if (parsedUrl) {
|
|
856
|
+
currentPath = parsedUrl.pathname;
|
|
857
|
+
this.rolodexActivePath = currentPath;
|
|
858
|
+
this.rolodexRootPath = currentPath;
|
|
859
|
+
replaceResults = true;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
catch (e) {
|
|
863
|
+
// do nothing for now.
|
|
864
|
+
}
|
|
446
865
|
}
|
|
447
|
-
|
|
866
|
+
const fetchRefMap = (dead = false) => {
|
|
867
|
+
const currentRefs = this.referenceMapBag?.export().size;
|
|
868
|
+
ModelService.fetchReferenceMap().then((result) => {
|
|
869
|
+
if (dead) {
|
|
870
|
+
this.editor.clearDecorations();
|
|
871
|
+
this.editor.clearAllMarkers();
|
|
872
|
+
this.editor.breadcumb.isInvalid = true;
|
|
873
|
+
this.editor.dead();
|
|
874
|
+
this.problemList.isInvalid = true;
|
|
875
|
+
this.editor.requestUpdate();
|
|
876
|
+
}
|
|
877
|
+
else {
|
|
878
|
+
this.references = result;
|
|
879
|
+
this.editor.links = result;
|
|
880
|
+
this.editor.applyLinkDecorations();
|
|
881
|
+
}
|
|
882
|
+
// add references to our stateful bag
|
|
883
|
+
this.updateRefmapBag(currentPath, result);
|
|
884
|
+
}).catch(() => {
|
|
885
|
+
this.editor.clearDecorations();
|
|
886
|
+
this.editor.clearAllMarkers();
|
|
887
|
+
this.toastManager.addToastManually({
|
|
888
|
+
id: crypto.randomUUID(),
|
|
889
|
+
type: ToastType.INFO,
|
|
890
|
+
title: "File not analyzed",
|
|
891
|
+
body: "This file is not a JSON or YAML file, it has not been analyzed."
|
|
892
|
+
});
|
|
893
|
+
});
|
|
894
|
+
};
|
|
895
|
+
let revive = true;
|
|
896
|
+
LintingService.lintFile(value, this.brokerConnectionId, url, currentPath).then((result) => {
|
|
897
|
+
//if (replaceResults) {
|
|
898
|
+
const map = this.buildRolodexResultMap(result);
|
|
448
899
|
if (url) {
|
|
449
900
|
this.urlOverlay.style.display = "none";
|
|
450
901
|
this.urlSpinner.style.display = "none";
|
|
451
902
|
this.urlProblem.style.display = 'none';
|
|
452
903
|
}
|
|
904
|
+
// extract empty location problems as we are replacing the root results
|
|
905
|
+
let rootProblems = this.rolodexProblemMap.get("root");
|
|
906
|
+
if (!this.rolodexRoot) {
|
|
907
|
+
rootProblems = [];
|
|
908
|
+
}
|
|
453
909
|
if (result && !Array.isArray(result)) {
|
|
454
|
-
|
|
455
|
-
this.
|
|
456
|
-
|
|
457
|
-
|
|
910
|
+
const r = [result];
|
|
911
|
+
if (this.rolodexProblemMap.size > 0 && this.rolodexProblemMap.has(this.rolodexActivePath)) {
|
|
912
|
+
const probs = this.rolodexProblemMap.get(this.rolodexActivePath);
|
|
913
|
+
if (probs) {
|
|
914
|
+
if (rootProblems) {
|
|
915
|
+
probs.push(...rootProblems);
|
|
916
|
+
}
|
|
917
|
+
this.editor.setMarkers(probs);
|
|
918
|
+
}
|
|
919
|
+
else {
|
|
920
|
+
if (rootProblems) {
|
|
921
|
+
r.push(...rootProblems);
|
|
922
|
+
}
|
|
923
|
+
this.editor.setMarkers(r);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
else {
|
|
927
|
+
if (rootProblems) {
|
|
928
|
+
r.push(...rootProblems);
|
|
929
|
+
}
|
|
930
|
+
this.editor.setMarkers(r);
|
|
931
|
+
}
|
|
932
|
+
this.problemBag?.set(DocumentProblems, r);
|
|
933
|
+
this.problemList.problems = r;
|
|
934
|
+
this.problems = r;
|
|
458
935
|
this.problemsOverview.problems = this.problemList.problemItems;
|
|
459
936
|
}
|
|
460
937
|
if (result && Array.isArray(result)) {
|
|
461
|
-
|
|
938
|
+
if (result.length == 0) {
|
|
939
|
+
this.editor.clearAllMarkers();
|
|
940
|
+
this.editor.breadcumb.isInvalid = false;
|
|
941
|
+
this.editor.showBreadcrumb = false;
|
|
942
|
+
revive = true;
|
|
943
|
+
this.problemList.isInvalid = false;
|
|
944
|
+
}
|
|
945
|
+
// check if this problem is 'unable to parse'
|
|
946
|
+
if (result.length == 1 && result[0].message.startsWith('unable to parse')) {
|
|
947
|
+
// short circuit, we are dead.
|
|
948
|
+
this.editor.clearDecorations();
|
|
949
|
+
this.editor.clearAllMarkers();
|
|
950
|
+
this.editor.setMarkers(result);
|
|
951
|
+
this.editor.breadcumb.isInvalid = true;
|
|
952
|
+
this.editor.showBreadcrumb = true;
|
|
953
|
+
this.editor.dead();
|
|
954
|
+
this.problemList.isInvalid = true;
|
|
955
|
+
revive = false;
|
|
956
|
+
}
|
|
957
|
+
// extract empty location problems as we are replacing the root results
|
|
958
|
+
if (revive && this.rolodexProblemMap.size > 0 && this.rolodexProblemMap.has(this.rolodexActivePath)) {
|
|
959
|
+
const probs = this.rolodexProblemMap.get(this.rolodexActivePath);
|
|
960
|
+
if (probs) {
|
|
961
|
+
if (rootProblems) {
|
|
962
|
+
probs.push(...rootProblems);
|
|
963
|
+
}
|
|
964
|
+
this.editor.setMarkers(probs);
|
|
965
|
+
}
|
|
966
|
+
else {
|
|
967
|
+
if (rootProblems) {
|
|
968
|
+
result.push(...rootProblems);
|
|
969
|
+
}
|
|
970
|
+
this.editor.setMarkers(result);
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
974
|
+
if (replaceResults) {
|
|
975
|
+
this.editor.setMarkers(result);
|
|
976
|
+
}
|
|
977
|
+
else {
|
|
978
|
+
fetchRefMap();
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
462
982
|
this.problemBag?.set(DocumentProblems, result);
|
|
463
983
|
this.problemList.problems = result;
|
|
464
984
|
this.problems = result;
|
|
465
985
|
this.problemsOverview.problems = this.problemList.problemItems;
|
|
986
|
+
if (this.problemsOverview.statistics) {
|
|
987
|
+
if (result.length == 1) {
|
|
988
|
+
this.problemsOverview.statistics.statistics.totalErrors = 1;
|
|
989
|
+
this.problemsOverview.statistics.statistics.overallScore = 0;
|
|
990
|
+
this.problemsOverview.statistics.evaluation = 'Useless';
|
|
991
|
+
this.problemsOverview.statistics.diagnosis = '<strong>Specification cannot be used</strong>: <br/><br/>' + result[0].message;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
// enable pb33f theme.
|
|
996
|
+
if (revive) {
|
|
997
|
+
this.editor.revive();
|
|
998
|
+
}
|
|
999
|
+
else {
|
|
1000
|
+
return;
|
|
466
1001
|
}
|
|
467
1002
|
// fetch graph
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
1003
|
+
if (this.rolodexRootPath == this.rolodexActivePath || this.rolodexActivePath == 'root') {
|
|
1004
|
+
ModelService.createGraph().then((result) => {
|
|
1005
|
+
this.extractGraph(result);
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
fetchRefMap();
|
|
1009
|
+
// TODO: rolodex query should happen elsewhere too!
|
|
1010
|
+
if (this.rolodexNeedsReset) {
|
|
1011
|
+
ModelService.queryRolodex().then((result) => {
|
|
1012
|
+
this.importDisabled = true;
|
|
1013
|
+
this.editor.showBreadcrumb = true;
|
|
1014
|
+
this.rolodexNeedsReset = false;
|
|
1015
|
+
result.rolodexRoot.treeExpanded = true;
|
|
1016
|
+
this.rolodexTree.isRolodex = true;
|
|
1017
|
+
this.rolodexTree.node = result.rolodexRoot;
|
|
1018
|
+
this.rolodexRoot = result.rolodexRoot;
|
|
1019
|
+
if (this.rolodexActiveHash) {
|
|
1020
|
+
this.rolodexTree.pendingNavigationHash = this.rolodexActiveHash;
|
|
1021
|
+
}
|
|
1022
|
+
if (this.rolodexActivePath) {
|
|
1023
|
+
this.rolodexTree.pendingNavigationPath = this.rolodexActivePath;
|
|
1024
|
+
}
|
|
1025
|
+
this.rolodexResponseBag?.set(RolodexResponseBag, result);
|
|
1026
|
+
const existingState = this.rolodexStateBag?.get(RolodexStateBag);
|
|
1027
|
+
if (!existingState) {
|
|
1028
|
+
const existingState = {
|
|
1029
|
+
activePath: this.rolodexActivePath,
|
|
1030
|
+
rootPath: this.rolodexRootPath,
|
|
1031
|
+
};
|
|
1032
|
+
this.rolodexStateBag?.set(RolodexStateBag, existingState);
|
|
1033
|
+
}
|
|
1034
|
+
this.requestUpdate();
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
472
1037
|
// update the overview statistics
|
|
473
1038
|
LintingService.fetchStatistics().then((result) => {
|
|
474
1039
|
let oldScore = 0;
|
|
@@ -485,32 +1050,37 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
485
1050
|
}
|
|
486
1051
|
// determine if the score went up or down and toast it!
|
|
487
1052
|
this.problemsOverview.statistics = result;
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
1053
|
+
// TODO: re-evaluate these toasts, they get annoying, fucking fast.
|
|
1054
|
+
// if (this.problemsOverview.statistics) {
|
|
1055
|
+
// const newScore = result.statistics.overallScore;
|
|
1056
|
+
// if (oldScore > newScore) {
|
|
1057
|
+
// this.sendToast({
|
|
1058
|
+
// id: crypto.randomUUID(),
|
|
1059
|
+
// type: ToastType.SCOREDOWN,
|
|
1060
|
+
// body: "Your score has decreased. It is now " + newScore + "%",
|
|
1061
|
+
// title: "Score went down by " + (oldScore - newScore) + "%"
|
|
1062
|
+
// });
|
|
1063
|
+
// }
|
|
1064
|
+
// if (oldScore < newScore) {
|
|
1065
|
+
// this.sendToast({
|
|
1066
|
+
// id: crypto.randomUUID(),
|
|
1067
|
+
// type: ToastType.SCOREUP,
|
|
1068
|
+
// body: "Your score has increased to " + newScore + "%",
|
|
1069
|
+
// title: "Score went up by " + (newScore - oldScore) + "%"
|
|
1070
|
+
// });
|
|
1071
|
+
// }
|
|
1072
|
+
// }
|
|
507
1073
|
}).catch((e) => {
|
|
508
1074
|
console.error("statistics service is down", e);
|
|
509
1075
|
this.platformUnavailable(e);
|
|
510
1076
|
});
|
|
1077
|
+
if (!this.explorerBooted) {
|
|
1078
|
+
this.explorer.equalizer.initializeEqualizer();
|
|
1079
|
+
this.explorerBooted = true;
|
|
1080
|
+
}
|
|
511
1081
|
}).catch((e) => {
|
|
512
1082
|
if (!url) {
|
|
513
|
-
this.platformUnavailable(e);
|
|
1083
|
+
//this.platformUnavailable(e);
|
|
514
1084
|
console.error("so sorry, the doctor cannot see you right now, the clinic is closed.");
|
|
515
1085
|
if (e) {
|
|
516
1086
|
console.error(e.detail);
|
|
@@ -531,6 +1101,50 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
531
1101
|
}
|
|
532
1102
|
});
|
|
533
1103
|
}
|
|
1104
|
+
updateInspectorDivider() {
|
|
1105
|
+
const panelState = this.panelStateBag?.get(PanelStateBag);
|
|
1106
|
+
if (panelState) {
|
|
1107
|
+
panelState.inspectorPanel = this.splitPanelInspector.position;
|
|
1108
|
+
this.panelStateBag?.set(PanelStateBag, panelState);
|
|
1109
|
+
}
|
|
1110
|
+
else {
|
|
1111
|
+
this.panelStateBag?.set(PanelStateBag, { inspectorPanel: this.splitPanelInspector.position });
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
updateExplorerDivider() {
|
|
1115
|
+
const panelState = this.panelStateBag?.get(PanelStateBag);
|
|
1116
|
+
if (panelState) {
|
|
1117
|
+
panelState.explorerPanel = this.splitPanelExplorer.position;
|
|
1118
|
+
this.panelStateBag?.set(PanelStateBag, panelState);
|
|
1119
|
+
}
|
|
1120
|
+
else {
|
|
1121
|
+
this.panelStateBag?.set(PanelStateBag, { explorerPanel: this.splitPanelExplorer.position });
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
updateRolodexDivider() {
|
|
1125
|
+
const panelState = this.panelStateBag?.get(PanelStateBag);
|
|
1126
|
+
if (panelState) {
|
|
1127
|
+
panelState.rolodexPanel = this.splitPanelRolodex.position;
|
|
1128
|
+
this.panelStateBag?.set(PanelStateBag, panelState);
|
|
1129
|
+
}
|
|
1130
|
+
else {
|
|
1131
|
+
this.panelStateBag?.set(PanelStateBag, { rolodexPanel: this.splitPanelRolodex.position });
|
|
1132
|
+
}
|
|
1133
|
+
this.rolodexDividerPosition = this.splitPanelRolodex.position;
|
|
1134
|
+
}
|
|
1135
|
+
updateRefmapBag(currentPath, result) {
|
|
1136
|
+
let refMap = this.referenceMapBag?.get(ReferenceMapBag);
|
|
1137
|
+
let cp = currentPath;
|
|
1138
|
+
if (refMap) {
|
|
1139
|
+
refMap.references[cp] = result;
|
|
1140
|
+
}
|
|
1141
|
+
else {
|
|
1142
|
+
refMap = {
|
|
1143
|
+
references: { [cp]: result }
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
this.referenceMapBag?.set(ReferenceMapBag, refMap);
|
|
1147
|
+
}
|
|
534
1148
|
platformUnavailable(error) {
|
|
535
1149
|
if (!this.unavailable) {
|
|
536
1150
|
this.loadingOverlay.hide();
|
|
@@ -610,6 +1224,28 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
610
1224
|
this.editorTabGroup.show("spec");
|
|
611
1225
|
this.selectedEditorTab = "spec";
|
|
612
1226
|
}
|
|
1227
|
+
let sourceLocation = event.detail.problem.problemObject.sourceLocation;
|
|
1228
|
+
// no source? use root
|
|
1229
|
+
if (sourceLocation == '' || sourceLocation == undefined || sourceLocation == 'root') {
|
|
1230
|
+
sourceLocation = this.rolodexRootPath;
|
|
1231
|
+
}
|
|
1232
|
+
// locate the node in rolodex root
|
|
1233
|
+
const node = SearchNodeTreeForPath(this.rolodexRoot, sourceLocation);
|
|
1234
|
+
if (node) {
|
|
1235
|
+
// trigger a rolodex load
|
|
1236
|
+
this.rolodexTreeNodeClicked(new CustomEvent(RolodexTreeNodeClicked, {
|
|
1237
|
+
detail: {
|
|
1238
|
+
nodeHashId: node.idHash,
|
|
1239
|
+
path: sourceLocation,
|
|
1240
|
+
line: event.detail.problem.problemObject.startLineNumber,
|
|
1241
|
+
column: event.detail.problem.problemObject.startColumn
|
|
1242
|
+
}
|
|
1243
|
+
}));
|
|
1244
|
+
this.detailsDrawer.close();
|
|
1245
|
+
// make sure we select the file in the rolodex
|
|
1246
|
+
this.rolodexTree.openNodeByPath(sourceLocation);
|
|
1247
|
+
return;
|
|
1248
|
+
}
|
|
613
1249
|
this.controlTabGroup.show(ActiveView.Problems);
|
|
614
1250
|
this.editor.editor?.revealLineInCenter(event.detail.problem.line);
|
|
615
1251
|
this.editor.editor?.setPosition({
|
|
@@ -629,7 +1265,94 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
629
1265
|
this.connectToBroker();
|
|
630
1266
|
this.graphBag = this.bagManager.getBag(GraphBag);
|
|
631
1267
|
this.docBag = this.bagManager.getBag(DoctorDocumentBag);
|
|
632
|
-
|
|
1268
|
+
this.rolodexResponseBag = this.bagManager.getBag(RolodexResponseBag);
|
|
1269
|
+
this.rolodexFilesBag = this.bagManager.getBag(RolodexFilesBag);
|
|
1270
|
+
this.rolodexStateBag = this.bagManager.getBag(RolodexStateBag);
|
|
1271
|
+
this.referenceMapBag = this.bagManager.getBag(ReferenceMapBag);
|
|
1272
|
+
this.docExpirationBag = this.bagManager.getBag(DocumentationExpirationBag);
|
|
1273
|
+
this.panelStateBag = this.bagManager.getBag(PanelStateBag);
|
|
1274
|
+
// load the rolodex
|
|
1275
|
+
if (this.rolodexResponseBag) {
|
|
1276
|
+
const response = this.rolodexResponseBag.get(RolodexResponseBag);
|
|
1277
|
+
if (response) {
|
|
1278
|
+
this.rolodexRoot = response.rolodexRoot;
|
|
1279
|
+
this.rolodexTree.isRolodex = true;
|
|
1280
|
+
this.rolodexTree.node = response.rolodexRoot;
|
|
1281
|
+
response.rolodexRoot.treeExpanded = true;
|
|
1282
|
+
this.requestUpdate();
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
let skipDocBag = false;
|
|
1286
|
+
const checkRefMap = (key) => {
|
|
1287
|
+
let refMap = this.referenceMapBag?.get(ReferenceMapBag);
|
|
1288
|
+
if (refMap) {
|
|
1289
|
+
// TODO: replace with scehduled task to refresh the reference map
|
|
1290
|
+
setTimeout(() => {
|
|
1291
|
+
let refs = refMap?.references[key];
|
|
1292
|
+
if (!refs) {
|
|
1293
|
+
refs = refMap?.references[""]; // single file
|
|
1294
|
+
}
|
|
1295
|
+
if (refs) {
|
|
1296
|
+
this.references = refs;
|
|
1297
|
+
this.editor.links = refs;
|
|
1298
|
+
this.editor.applyLinkDecorations();
|
|
1299
|
+
}
|
|
1300
|
+
}, 5); // editor has not loaded yet, give it a second to breathe.
|
|
1301
|
+
}
|
|
1302
|
+
else {
|
|
1303
|
+
ModelService.fetchReferenceMap().then((result) => {
|
|
1304
|
+
this.references = result;
|
|
1305
|
+
this.editor.links = result;
|
|
1306
|
+
this.editor.applyLinkDecorations();
|
|
1307
|
+
}).catch(() => {
|
|
1308
|
+
this.editor.clearDecorations();
|
|
1309
|
+
this.editor.clearAllMarkers();
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
};
|
|
1313
|
+
if (this.rolodexStateBag) {
|
|
1314
|
+
const state = this.rolodexStateBag.get(RolodexStateBag);
|
|
1315
|
+
if (state) {
|
|
1316
|
+
this.rolodexActivePath = state.activePath;
|
|
1317
|
+
this.rolodexActiveHash = state.activeHash;
|
|
1318
|
+
// load the root.
|
|
1319
|
+
if (state.rootHash) {
|
|
1320
|
+
this.rolodexTree.pendingNavigationHash = state.rootHash;
|
|
1321
|
+
}
|
|
1322
|
+
if (state.rootPath) {
|
|
1323
|
+
this.rolodexRootPath = state.rootPath;
|
|
1324
|
+
if (state.activePath) {
|
|
1325
|
+
checkRefMap(state.activePath);
|
|
1326
|
+
}
|
|
1327
|
+
// ensure the session has a root selected
|
|
1328
|
+
ModelService.selectRootPath(state.rootPath).then(() => {
|
|
1329
|
+
// nothing to do.
|
|
1330
|
+
}).catch((e) => {
|
|
1331
|
+
console.error('could not select the root path on boot bro', e);
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
if (state.rootHash)
|
|
1335
|
+
this.rolodexRootHash = state.rootHash;
|
|
1336
|
+
if (state.activePath) {
|
|
1337
|
+
this.rolodexTree.pendingNavigationPath = state.activePath;
|
|
1338
|
+
this.rolodexTree.requestUpdate();
|
|
1339
|
+
}
|
|
1340
|
+
if (state.activeNode) {
|
|
1341
|
+
// load the content of the active node into the editor
|
|
1342
|
+
if (state.activeLanguage) {
|
|
1343
|
+
this.editor.switchLanguage(state.activeLanguage);
|
|
1344
|
+
}
|
|
1345
|
+
this.editor.setValue(state.activeNode.instance, true);
|
|
1346
|
+
skipDocBag = true;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
else {
|
|
1350
|
+
this.rolodexActivePath = "root";
|
|
1351
|
+
// refresh the refmap.
|
|
1352
|
+
checkRefMap(this.rolodexActivePath);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
if (this.docBag && !skipDocBag) {
|
|
633
1356
|
const doc = this.docBag.get(DefaultDocument);
|
|
634
1357
|
if (doc) {
|
|
635
1358
|
this.editor.setValue(doc, true);
|
|
@@ -640,10 +1363,16 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
640
1363
|
const markers = this.problemBag.get(DocumentProblems);
|
|
641
1364
|
if (markers) {
|
|
642
1365
|
this.problems = markers;
|
|
643
|
-
this.editor.setMarkers(markers);
|
|
644
1366
|
for (let i = 0; i < markers.length; i++) {
|
|
645
1367
|
markers[i] = Problem.reconstruct(markers[i]);
|
|
646
1368
|
}
|
|
1369
|
+
this.buildRolodexResultMap(markers);
|
|
1370
|
+
if (this.rolodexProblemMap.size > 0 && this.rolodexProblemMap.has(this.rolodexActivePath)) {
|
|
1371
|
+
const probs = this.rolodexProblemMap.get(this.rolodexActivePath);
|
|
1372
|
+
if (probs) {
|
|
1373
|
+
this.editor.setMarkers(probs);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
647
1376
|
this.problemList.problems = markers;
|
|
648
1377
|
this.problemsOverview.problems = this.problemList.problemItems;
|
|
649
1378
|
}
|
|
@@ -663,11 +1392,33 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
663
1392
|
this.extractGraph(graph);
|
|
664
1393
|
}
|
|
665
1394
|
}
|
|
1395
|
+
// extract panel state
|
|
1396
|
+
if (this.panelStateBag) {
|
|
1397
|
+
const panelState = this.panelStateBag.get(PanelStateBag);
|
|
1398
|
+
if (panelState && panelState.explorerPanel) {
|
|
1399
|
+
this.splitPanelExplorer.position = panelState.explorerPanel;
|
|
1400
|
+
}
|
|
1401
|
+
if (panelState && panelState.rolodexPanel) {
|
|
1402
|
+
if (this.splitPanelRolodex) {
|
|
1403
|
+
this.splitPanelRolodex.position = panelState.rolodexPanel;
|
|
1404
|
+
}
|
|
1405
|
+
this.rolodexDividerPosition = panelState.rolodexPanel;
|
|
1406
|
+
}
|
|
1407
|
+
if (panelState && panelState.inspectorPanel) {
|
|
1408
|
+
this.splitPanelInspector.position = panelState.inspectorPanel;
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
if (!this.rolodexRoot) {
|
|
1412
|
+
this.importDisabled = false;
|
|
1413
|
+
}
|
|
1414
|
+
else {
|
|
1415
|
+
this.importDisabled = true;
|
|
1416
|
+
}
|
|
666
1417
|
// extract rulesets from bags
|
|
667
1418
|
const promises = [];
|
|
668
|
-
this.
|
|
669
|
-
if (this.
|
|
670
|
-
const ruleset = this.
|
|
1419
|
+
this.defaultRulesetBag = this.bagManager.getBag(DefaultRulesetBag);
|
|
1420
|
+
if (this.defaultRulesetBag) {
|
|
1421
|
+
const ruleset = this.defaultRulesetBag.get(DefaultRulesetBag);
|
|
671
1422
|
if (ruleset) {
|
|
672
1423
|
this.defaultRuleset = ruleset;
|
|
673
1424
|
}
|
|
@@ -687,21 +1438,21 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
687
1438
|
}
|
|
688
1439
|
}
|
|
689
1440
|
// All ruleset
|
|
690
|
-
this.
|
|
691
|
-
if (this.
|
|
692
|
-
const ruleset = this.
|
|
1441
|
+
this.allRulesetBag = this.bagManager.getBag(AllRulesetBag);
|
|
1442
|
+
if (this.allRulesetBag) {
|
|
1443
|
+
const ruleset = this.allRulesetBag.get(AllRulesetBag);
|
|
693
1444
|
if (ruleset) {
|
|
694
|
-
this.
|
|
1445
|
+
this.allRuleset = ruleset;
|
|
695
1446
|
}
|
|
696
1447
|
else {
|
|
697
1448
|
promises.push(this.fetchAllRuleset());
|
|
698
1449
|
}
|
|
699
1450
|
}
|
|
700
1451
|
// functions
|
|
701
|
-
this.
|
|
702
|
-
this.
|
|
703
|
-
if (this.
|
|
704
|
-
const functions = this.
|
|
1452
|
+
this.functionsBag = this.bagManager.getBag(FunctionsBag);
|
|
1453
|
+
this.functionSchemaBag = this.bagManager.getBag(FunctionsSchemaBag);
|
|
1454
|
+
if (this.functionsBag) {
|
|
1455
|
+
const functions = this.functionsBag.get(FunctionsBag);
|
|
705
1456
|
if (functions) {
|
|
706
1457
|
this.functions = functions;
|
|
707
1458
|
}
|
|
@@ -710,15 +1461,15 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
710
1461
|
}
|
|
711
1462
|
}
|
|
712
1463
|
// custom ruleset
|
|
713
|
-
this.
|
|
714
|
-
if (this.
|
|
715
|
-
const ruleset = this.
|
|
1464
|
+
this.customRulesetBag = this.bagManager.getBag(CustomRulesetBag);
|
|
1465
|
+
if (this.customRulesetBag) {
|
|
1466
|
+
const ruleset = this.customRulesetBag.get(CustomRulesetBag);
|
|
716
1467
|
if (ruleset) {
|
|
717
|
-
this.
|
|
1468
|
+
this.customRuleset = ruleset;
|
|
718
1469
|
}
|
|
719
1470
|
}
|
|
720
1471
|
// create rule configuration bag
|
|
721
|
-
this.
|
|
1472
|
+
this.ruleConfigBag = this.bagManager.getBag(RuleConfigurationBag);
|
|
722
1473
|
// create rule configuration bag
|
|
723
1474
|
this.sessionRulesetMapBag = this.bagManager.getBag(SessionRulesetMapBag);
|
|
724
1475
|
// fire off all network requests, then configure the ruleset management.
|
|
@@ -726,9 +1477,9 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
726
1477
|
// configure rule management
|
|
727
1478
|
this.manageRuleset.defaultRuleset = this.defaultRuleset;
|
|
728
1479
|
this.manageRuleset.owaspRuleset = this.OWASPRuleset;
|
|
729
|
-
this.manageRuleset.allRuleset = this.
|
|
1480
|
+
this.manageRuleset.allRuleset = this.allRuleset;
|
|
730
1481
|
this.manageRuleset.functions = this.functions;
|
|
731
|
-
const config = this.
|
|
1482
|
+
const config = this.ruleConfigBag?.get(RuleConfigurationBag);
|
|
732
1483
|
if (config) {
|
|
733
1484
|
this.manageRuleset.rulesetConfig = config;
|
|
734
1485
|
}
|
|
@@ -737,8 +1488,8 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
737
1488
|
}
|
|
738
1489
|
setTimeout(() => {
|
|
739
1490
|
this.manageRuleset.buildRulesets();
|
|
740
|
-
if (this.
|
|
741
|
-
this.manageRuleset.customRuleset = this.
|
|
1491
|
+
if (this.customRuleset && this.customRuleset.rules.size > 0) {
|
|
1492
|
+
this.manageRuleset.customRuleset = this.customRuleset;
|
|
742
1493
|
}
|
|
743
1494
|
this.fetchSessionRulesetAsYaml().then((result) => {
|
|
744
1495
|
this.rulesetEditor?.setValue(result, true);
|
|
@@ -770,14 +1521,14 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
770
1521
|
this.nodeIdMap.clear();
|
|
771
1522
|
this.nodeIdHashMap.clear();
|
|
772
1523
|
const renderedNodes = new Map();
|
|
773
|
-
graph
|
|
1524
|
+
graph?.nodesRendered?.forEach((node) => {
|
|
774
1525
|
this.explorer.renderedNodeMap.set(node.id, node);
|
|
775
1526
|
renderedNodes.set(node.idHash, node);
|
|
776
1527
|
});
|
|
777
|
-
for (let i = 0; i < graph
|
|
1528
|
+
for (let i = 0; i < graph?.nodesRendered?.length; i++) {
|
|
778
1529
|
this.renderedNodeMap.set(graph.nodesRendered[i].idHash, graph.nodesRendered[i]);
|
|
779
1530
|
}
|
|
780
|
-
graph
|
|
1531
|
+
graph?.nodes?.forEach((node) => {
|
|
781
1532
|
this.nodeMap.set('model-' + node.idHash, node);
|
|
782
1533
|
this.nodeIdMap.set(node.id, node);
|
|
783
1534
|
this.nodeIdHashMap.set(node.idHash, node);
|
|
@@ -793,9 +1544,15 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
793
1544
|
});
|
|
794
1545
|
this.graphBag?.set(GraphBag, graph);
|
|
795
1546
|
this.explorer.updateGraphResponse(graph);
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
1547
|
+
if (graph && graph.nodes) {
|
|
1548
|
+
this.modelTree.node = graph?.nodes[0]; // update tree
|
|
1549
|
+
}
|
|
1550
|
+
if (!this.explorer.equalizer.isInitialized()) {
|
|
1551
|
+
this.explorer.equalizer.initializeEqualizer();
|
|
1552
|
+
}
|
|
1553
|
+
else {
|
|
1554
|
+
this.explorer.equalizer.runEQ(true);
|
|
1555
|
+
}
|
|
799
1556
|
}
|
|
800
1557
|
customRulesetEnabled(event) {
|
|
801
1558
|
const customRS = { rules: new Map() };
|
|
@@ -808,12 +1565,12 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
808
1565
|
customRS.rules.set(rule.ruleId, rule.rule);
|
|
809
1566
|
});
|
|
810
1567
|
// write state
|
|
811
|
-
this.
|
|
1568
|
+
this.customRulesetBag?.set(CustomRulesetBag, customRS);
|
|
812
1569
|
if (event.detail.ruleConfig) {
|
|
813
|
-
this.
|
|
1570
|
+
this.ruleConfigBag?.set(RuleConfigurationBag, event.detail.ruleConfig);
|
|
814
1571
|
}
|
|
815
1572
|
else {
|
|
816
|
-
this.
|
|
1573
|
+
this.ruleConfigBag?.reset();
|
|
817
1574
|
// reset session ruleset
|
|
818
1575
|
RulesetService.resetSessionRuleset(event.detail.rulesetReset).then(() => {
|
|
819
1576
|
this.sendToast({
|
|
@@ -824,15 +1581,14 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
824
1581
|
});
|
|
825
1582
|
if (this.docBag) {
|
|
826
1583
|
const doc = this.docBag.get(DefaultDocument);
|
|
827
|
-
this.
|
|
1584
|
+
let path = this.rolodexActivePath;
|
|
1585
|
+
if (path == 'root') {
|
|
1586
|
+
path = "";
|
|
1587
|
+
}
|
|
1588
|
+
this.lintSpec(doc, this.rolodexActivePath);
|
|
828
1589
|
}
|
|
829
1590
|
this.fetchSessionRulesetAsYaml().then((result) => {
|
|
830
1591
|
this.rulesetEditor?.setValue(result, true);
|
|
831
|
-
// if(event.detail.rulesetReset) {
|
|
832
|
-
// this.manageRuleset.switchRuleset(event.detail.rulesetReset);
|
|
833
|
-
// } else {
|
|
834
|
-
// this.manageRuleset.switchRuleset("default");
|
|
835
|
-
// }
|
|
836
1592
|
});
|
|
837
1593
|
}).catch((e) => {
|
|
838
1594
|
this.sendToast({
|
|
@@ -858,7 +1614,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
858
1614
|
return new Promise(async (resolve) => {
|
|
859
1615
|
RulesetService.getFunctions().then((result) => {
|
|
860
1616
|
this.functions = result;
|
|
861
|
-
this.
|
|
1617
|
+
this.functionsBag?.set(FunctionsBag, result);
|
|
862
1618
|
// extract schemas for each function
|
|
863
1619
|
const promises = [];
|
|
864
1620
|
result.forEach((functionId) => {
|
|
@@ -873,12 +1629,12 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
873
1629
|
async fetchFunctionSchema(functionId) {
|
|
874
1630
|
return new Promise(async (resolve) => {
|
|
875
1631
|
RulesetService.getFunctionSchema(functionId).then((result) => {
|
|
876
|
-
let m = this.
|
|
1632
|
+
let m = this.functionSchemaBag?.get(FunctionsSchemaBag);
|
|
877
1633
|
if (!m) {
|
|
878
1634
|
m = new Map();
|
|
879
1635
|
}
|
|
880
1636
|
m.set(functionId, result);
|
|
881
|
-
this.
|
|
1637
|
+
this.functionSchemaBag?.set(FunctionsSchemaBag, m);
|
|
882
1638
|
resolve(result);
|
|
883
1639
|
});
|
|
884
1640
|
});
|
|
@@ -887,7 +1643,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
887
1643
|
return new Promise(async (resolve) => {
|
|
888
1644
|
RulesetService.getDefaultRuleset().then((result) => {
|
|
889
1645
|
this.defaultRuleset = result;
|
|
890
|
-
this.
|
|
1646
|
+
this.defaultRulesetBag?.set(DefaultRulesetBag, result);
|
|
891
1647
|
resolve(result);
|
|
892
1648
|
});
|
|
893
1649
|
});
|
|
@@ -904,8 +1660,8 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
904
1660
|
async fetchAllRuleset() {
|
|
905
1661
|
return new Promise(async (resolve) => {
|
|
906
1662
|
RulesetService.getAllRuleset().then((result) => {
|
|
907
|
-
this.
|
|
908
|
-
this.
|
|
1663
|
+
this.allRuleset = result;
|
|
1664
|
+
this.allRulesetBag?.set(AllRulesetBag, result);
|
|
909
1665
|
resolve(result);
|
|
910
1666
|
});
|
|
911
1667
|
});
|
|
@@ -915,10 +1671,13 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
915
1671
|
// the first this we need to do is start a session
|
|
916
1672
|
LintingService.startSession().then((session) => {
|
|
917
1673
|
this.session = session;
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1674
|
+
if (this.session.creditsRemaining) {
|
|
1675
|
+
this.creditTicker.credits = this.session.creditsRemaining;
|
|
1676
|
+
}
|
|
1677
|
+
else {
|
|
1678
|
+
this.creditTicker.credits = this.session.creditsRemaining;
|
|
1679
|
+
}
|
|
1680
|
+
this.creditTicker.visible = true;
|
|
922
1681
|
LintingService.fetchAllHowToFix().then((result) => {
|
|
923
1682
|
if (result) {
|
|
924
1683
|
result.forEach((howToFix) => {
|
|
@@ -935,6 +1694,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
935
1694
|
this.ruleDocsWorker.addEventListener("message", (event) => {
|
|
936
1695
|
const data = event.data;
|
|
937
1696
|
if (data) {
|
|
1697
|
+
this.docExpirationBag?.set(DocumentationExpirationBag, new Date().toISOString());
|
|
938
1698
|
data.forEach((doc) => {
|
|
939
1699
|
if (doc.ruleId) {
|
|
940
1700
|
this.ruleDocsBag?.set(doc.ruleId, doc);
|
|
@@ -946,7 +1706,43 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
946
1706
|
this.activitySpinner.hide();
|
|
947
1707
|
}
|
|
948
1708
|
});
|
|
949
|
-
|
|
1709
|
+
let ruleDocs = [];
|
|
1710
|
+
let functionDocs = [];
|
|
1711
|
+
if (this.ruleDocsBag) {
|
|
1712
|
+
ruleDocs = Array.from(this.ruleDocsBag.export().keys());
|
|
1713
|
+
}
|
|
1714
|
+
if (this.functionDocsBag) {
|
|
1715
|
+
functionDocs = Array.from(this.functionDocsBag.export().keys());
|
|
1716
|
+
}
|
|
1717
|
+
const fetchDocs = () => {
|
|
1718
|
+
this.ruleDocsWorker.postMessage({
|
|
1719
|
+
start: true,
|
|
1720
|
+
endpoint: this.doctorEndpoint,
|
|
1721
|
+
existingRules: ruleDocs,
|
|
1722
|
+
existingFunctions: functionDocs
|
|
1723
|
+
});
|
|
1724
|
+
};
|
|
1725
|
+
// check expiration
|
|
1726
|
+
if (this.docExpirationBag) {
|
|
1727
|
+
const expiration = this.docExpirationBag.get(DocumentationExpirationBag);
|
|
1728
|
+
// if the docs are older than 15 days, refresh them.
|
|
1729
|
+
if (expiration) {
|
|
1730
|
+
const now = new Date().getTime();
|
|
1731
|
+
const then = new Date(expiration).getTime();
|
|
1732
|
+
if (now - then > 1296000000) {
|
|
1733
|
+
fetchDocs();
|
|
1734
|
+
}
|
|
1735
|
+
else {
|
|
1736
|
+
this.activitySpinner.hide();
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
else {
|
|
1740
|
+
fetchDocs();
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
else {
|
|
1744
|
+
fetchDocs();
|
|
1745
|
+
}
|
|
950
1746
|
}).catch((e) => {
|
|
951
1747
|
this.platformUnavailable(e);
|
|
952
1748
|
console.error("cannot start session");
|
|
@@ -997,8 +1793,8 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
997
1793
|
rule.id = id; // set the id to the key
|
|
998
1794
|
});
|
|
999
1795
|
// write state
|
|
1000
|
-
this.
|
|
1001
|
-
this.
|
|
1796
|
+
this.customRulesetBag?.set(CustomRulesetBag, customRS);
|
|
1797
|
+
this.customRuleset = customRS;
|
|
1002
1798
|
if (customRS.rules.size > 0) {
|
|
1003
1799
|
// rebuild the ruleset management
|
|
1004
1800
|
this.manageRuleset.customRulesetManual = customRS;
|
|
@@ -1039,7 +1835,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1039
1835
|
if (rule.id != id)
|
|
1040
1836
|
rule.id = id; // set the id to the key
|
|
1041
1837
|
});
|
|
1042
|
-
this.
|
|
1838
|
+
this.customRuleset = customRS;
|
|
1043
1839
|
if (customRS.rules.size > 0) {
|
|
1044
1840
|
// rebuild the ruleset management
|
|
1045
1841
|
this.manageRuleset.customRulesetManual = customRS;
|
|
@@ -1059,7 +1855,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1059
1855
|
}
|
|
1060
1856
|
specChanged(event) {
|
|
1061
1857
|
const editor = this.editorMap.get(event.detail.id);
|
|
1062
|
-
if (editor && event.detail.id === 'ruleset') {
|
|
1858
|
+
if (editor && event.detail.id === 'ruleset-editor') {
|
|
1063
1859
|
this.rulesetManuallyChanged();
|
|
1064
1860
|
return;
|
|
1065
1861
|
}
|
|
@@ -1077,12 +1873,14 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1077
1873
|
const urlParam = url.searchParams.get('url');
|
|
1078
1874
|
if (urlParam) {
|
|
1079
1875
|
this.urlInput.value = urlParam;
|
|
1876
|
+
this.activeURL = urlParam;
|
|
1080
1877
|
this.lintSpec('', urlParam);
|
|
1081
1878
|
return;
|
|
1082
1879
|
}
|
|
1083
|
-
if (this.editor.getValue() === '') {
|
|
1880
|
+
if (this.editor.getValue() === '' || !this.problems) {
|
|
1084
1881
|
LintingService.bootstrapEditor().then((result) => {
|
|
1085
1882
|
this.editor.setValue(result, true);
|
|
1883
|
+
this.rolodexActivePath = "";
|
|
1086
1884
|
this.specChanged(new CustomEvent(EditorUpdated, {
|
|
1087
1885
|
detail: {
|
|
1088
1886
|
content: result,
|
|
@@ -1094,8 +1892,8 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1094
1892
|
}
|
|
1095
1893
|
exportJSON() {
|
|
1096
1894
|
let jsonRS;
|
|
1097
|
-
if (this.
|
|
1098
|
-
const config = this.
|
|
1895
|
+
if (this.ruleConfigBag) {
|
|
1896
|
+
const config = this.ruleConfigBag.get(RuleConfigurationBag);
|
|
1099
1897
|
if (config && config.returnedRuleset) {
|
|
1100
1898
|
jsonRS = config.returnedRuleset;
|
|
1101
1899
|
}
|
|
@@ -1188,17 +1986,21 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1188
1986
|
this.sidebarClosed = !this.sidebarClosed;
|
|
1189
1987
|
}
|
|
1190
1988
|
toggleExplorer() {
|
|
1191
|
-
this.explorerVisible =
|
|
1192
|
-
if (this.explorerVisible) {
|
|
1989
|
+
this.explorerVisible = !this.explorerVisible;
|
|
1990
|
+
if (this.explorerVisible && this.activeNode) {
|
|
1193
1991
|
this.explorer.moveToNode(this.activeNode);
|
|
1194
1992
|
}
|
|
1195
|
-
|
|
1196
|
-
this.explorer.equalizer.initializeEqualizer();
|
|
1197
|
-
this.explorerBooted = true;
|
|
1198
|
-
}
|
|
1993
|
+
this.explorerBooted = true;
|
|
1199
1994
|
}
|
|
1200
1995
|
closeExplorer() {
|
|
1201
1996
|
this.explorerVisible = false;
|
|
1997
|
+
setTimeout(() => {
|
|
1998
|
+
if (this.pendingLine > 0) {
|
|
1999
|
+
this.editor.editor?.setPosition({ lineNumber: this.pendingLine, column: 1 });
|
|
2000
|
+
this.editor.editor?.revealLineInCenter(this.pendingLine);
|
|
2001
|
+
this.pendingLine = 0;
|
|
2002
|
+
}
|
|
2003
|
+
}, 20);
|
|
1202
2004
|
}
|
|
1203
2005
|
render() {
|
|
1204
2006
|
let overlay = html ``;
|
|
@@ -1224,6 +2026,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1224
2026
|
<sl-badge pulse></sl-badge>`;
|
|
1225
2027
|
}
|
|
1226
2028
|
let mainPanelView = html `
|
|
2029
|
+
|
|
1227
2030
|
<div class="problems" slot="end">
|
|
1228
2031
|
<div class="problems-data">
|
|
1229
2032
|
<sl-tab-group class="tab-group" id="manager-controls"
|
|
@@ -1244,8 +2047,25 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1244
2047
|
<sl-icon-button class="collapse-side" name="chevron-bar-right"
|
|
1245
2048
|
@click="${this.toggleSidebar}"></sl-icon-button>
|
|
1246
2049
|
</div>`;
|
|
1247
|
-
let
|
|
2050
|
+
let modelTree = html `${this.modelTree}`;
|
|
2051
|
+
if (this.rolodexTree.node && this.rolodexTree.node.nodes?.length > 0) {
|
|
2052
|
+
modelTree = html `
|
|
2053
|
+
<sl-split-panel id="rolodex-split-panel" vertical class="split-panel-rolodex"
|
|
2054
|
+
position="${this.rolodexDividerPosition}" @sl-reposition="${this.updateRolodexDivider}"
|
|
2055
|
+
style="height: calc(100% - 60px);">
|
|
2056
|
+
<sl-icon id="split-rolodex-tree" slot="divider" name="grip-horizontal"
|
|
2057
|
+
class="divider-horiz"></sl-icon>
|
|
2058
|
+
<div slot="start" class="model-tree">
|
|
2059
|
+
${this.modelTree}
|
|
2060
|
+
</div>
|
|
2061
|
+
<div slot="end" class="model-tree">
|
|
2062
|
+
${this.rolodexTree}
|
|
2063
|
+
</div>
|
|
2064
|
+
</sl-split-panel>`;
|
|
2065
|
+
}
|
|
1248
2066
|
return html `
|
|
2067
|
+
${this.uploadArchive}
|
|
2068
|
+
${this.nukeWorkspace}
|
|
1249
2069
|
${welcomeBox}
|
|
1250
2070
|
${this.toastManager}
|
|
1251
2071
|
<sl-dialog open id="loading-overlay" class="dialog-overview"
|
|
@@ -1276,15 +2096,46 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1276
2096
|
${this.errorBanner}
|
|
1277
2097
|
${overlay}
|
|
1278
2098
|
|
|
1279
|
-
<sl-split-panel class="split-panel-explorer" position="12"
|
|
1280
|
-
|
|
2099
|
+
<sl-split-panel id="explorer-split-panel" class="split-panel-explorer" position="12"
|
|
2100
|
+
@sl-reposition="${this.updateExplorerDivider}">
|
|
2101
|
+
<sl-icon id="split-divider-tree" slot="divider" name="grip-vertical" class="divider-vert"></sl-icon>
|
|
1281
2102
|
<div slot="start" class="model-tree">
|
|
1282
|
-
|
|
2103
|
+
<div class="controls">
|
|
2104
|
+
|
|
2105
|
+
<sl-tooltip content="Upload zip file or tar.gz (tarball)" placement="top">
|
|
2106
|
+
<sl-button ?disabled=${this.importDisabled} class="import-button" variant="text"
|
|
2107
|
+
size="small" @click="${() => {
|
|
2108
|
+
this.uploadArchive.show();
|
|
2109
|
+
}}">
|
|
2110
|
+
Import
|
|
2111
|
+
</sl-button>
|
|
2112
|
+
</sl-tooltip>
|
|
2113
|
+
<sl-tooltip content="Nuke / reset workspace" placement="top">
|
|
2114
|
+
<sl-icon-button style="${!this.importDisabled ? 'display: none' : ''}"
|
|
2115
|
+
class="nuke-session-button" name="radioactive" @click="${() => {
|
|
2116
|
+
this.nukeWorkspace.show();
|
|
2117
|
+
}}">
|
|
2118
|
+
</sl-icon-button>
|
|
2119
|
+
</sl-tooltip>
|
|
2120
|
+
|
|
2121
|
+
</div>
|
|
2122
|
+
${modelTree}
|
|
2123
|
+
${this.creditTicker}
|
|
1283
2124
|
</div>
|
|
1284
2125
|
<div slot="end">
|
|
1285
|
-
<sl-split-panel
|
|
1286
|
-
|
|
2126
|
+
<sl-split-panel id="inspector-split-panel"
|
|
2127
|
+
@sl-reposition="${this.updateInspectorDivider}"
|
|
2128
|
+
class="split-panel ${this.unavailable ? 'unavailable' : ''}">
|
|
2129
|
+
<sl-icon id="split-divider" slot="divider" name="grip-vertical"
|
|
2130
|
+
class="divider-vert"></sl-icon>
|
|
1287
2131
|
<div class="editor" slot="start">
|
|
2132
|
+
|
|
2133
|
+
<sl-tooltip class="minimap-tip" content="Toggle source mini-map" hoist>
|
|
2134
|
+
<sl-icon-button @click="${this.minimapToggled}"
|
|
2135
|
+
name="map"
|
|
2136
|
+
class="minimap-toggle ${this.minimapVisible ? 'active' : ''}"></sl-icon-button>
|
|
2137
|
+
</sl-tooltip>
|
|
2138
|
+
|
|
1288
2139
|
${this.detailsDrawer}
|
|
1289
2140
|
<sl-tab-group class="tab-group" @sl-tab-show="${this.selectEditorTab}"
|
|
1290
2141
|
id="editor-controls">
|
|
@@ -1302,26 +2153,18 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1302
2153
|
</sl-tab>
|
|
1303
2154
|
|
|
1304
2155
|
<sl-tab-panel name="spec" class="tab-panel">
|
|
1305
|
-
|
|
1306
|
-
<div class="controls">
|
|
1307
|
-
<div style="margin-top: 8px; margin-right: 5px;">URL:</div>
|
|
1308
|
-
<sl-input id="url-input" class="url-input"
|
|
1309
|
-
placeholder="https://api.pb33f.io/train-travel.yaml" size="small"
|
|
1310
|
-
@keydown="${this.validateUrl}"
|
|
1311
|
-
@keyup="${this.validateUrl}"></sl-input>
|
|
1312
|
-
<sl-button id="url-input-button" class="url-input-button close-button"
|
|
1313
|
-
size="small" variant="neutral" disabled
|
|
1314
|
-
@click="${this.fetchUrl}">Fetch
|
|
1315
|
-
</sl-button>
|
|
1316
|
-
</div>
|
|
1317
2156
|
<div class="main-view">
|
|
2157
|
+
${this.statusBar}
|
|
1318
2158
|
<div id="editor-url-overlay" class="editor-url-overlay">
|
|
2159
|
+
|
|
2160
|
+
|
|
1319
2161
|
<div id="url-spinner">
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
</div>
|
|
2162
|
+
<sl-icon name="arrow-repeat" class="url-spinner-icon"></sl-icon>
|
|
2163
|
+
<h3>Fetching URL</h3>
|
|
2164
|
+
<p>${this.activeURL}</p>
|
|
1324
2165
|
</div>
|
|
2166
|
+
|
|
2167
|
+
|
|
1325
2168
|
<div id="url-problem" class="url-problem">
|
|
1326
2169
|
<pb33f-attention-box type="warning" headerText="Problem with URL">
|
|
1327
2170
|
<h4>Error: ${this.urlErrorCode}</h4>
|
|
@@ -1331,10 +2174,19 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1331
2174
|
</pb33f-attention-box>
|
|
1332
2175
|
</div>
|
|
1333
2176
|
</div>
|
|
1334
|
-
|
|
2177
|
+
|
|
2178
|
+
|
|
2179
|
+
<!-- EDITOR -->
|
|
2180
|
+
<slot name="spec-editor"></slot>
|
|
2181
|
+
<!-- EDITOR -->
|
|
1335
2182
|
</div>
|
|
1336
2183
|
</sl-tab-panel>
|
|
1337
|
-
<sl-tab-panel name="ruleset" class="tab-panel"
|
|
2184
|
+
<sl-tab-panel name="ruleset" class="tab-panel">
|
|
2185
|
+
|
|
2186
|
+
<!-- RULESET EDITOR -->
|
|
2187
|
+
<slot name="ruleset-editor"></slot>
|
|
2188
|
+
<!-- RULESET EDITOR -->
|
|
2189
|
+
</sl-tab-panel>
|
|
1338
2190
|
<sl-tab-panel name="explorer" class="tab-panel"
|
|
1339
2191
|
@mouseleave="${this.ungrabExplorer}">${this.explorer}
|
|
1340
2192
|
</sl-tab-panel>
|
|
@@ -1345,8 +2197,9 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1345
2197
|
</sl-split-panel>
|
|
1346
2198
|
</div>
|
|
1347
2199
|
</sl-split-panel>
|
|
1348
|
-
|
|
2200
|
+
|
|
1349
2201
|
</div>`;
|
|
2202
|
+
//
|
|
1350
2203
|
// docs <iframe src="/docs.html" width="100%" height="100%"
|
|
1351
2204
|
// style="border: none"></iframe>
|
|
1352
2205
|
// <sl-tab slot="nav" panel="docs" class="tab" id="docs">
|
|
@@ -1355,14 +2208,17 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1355
2208
|
// <sl-tab-panel name="docs" class="tab-panel">
|
|
1356
2209
|
// </sl-tab-panel>
|
|
1357
2210
|
}
|
|
1358
|
-
fetchUrl() {
|
|
1359
|
-
this.activeURL =
|
|
1360
|
-
this.
|
|
2211
|
+
fetchUrl(event) {
|
|
2212
|
+
this.activeURL = event.detail.url;
|
|
2213
|
+
this.rolodexNeedsReset = true;
|
|
2214
|
+
this.rolodexActivePath = "/";
|
|
2215
|
+
this.lintSpec('', event.detail.url);
|
|
1361
2216
|
}
|
|
1362
2217
|
hideUrlError() {
|
|
1363
2218
|
this.urlProblem.style.display = 'none';
|
|
1364
2219
|
this.urlOverlay.style.display = 'none';
|
|
1365
2220
|
this.urlSpinner.style.display = 'none';
|
|
2221
|
+
this.editor.toggleMinimap();
|
|
1366
2222
|
}
|
|
1367
2223
|
showUrlError(e) {
|
|
1368
2224
|
this.urlErrorCode = e.status;
|
|
@@ -1370,27 +2226,14 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
1370
2226
|
this.urlSpinner.style.display = 'none';
|
|
1371
2227
|
this.urlOverlay.style.display = 'block';
|
|
1372
2228
|
this.urlProblem.style.display = 'block';
|
|
2229
|
+
this.editor.toggleMinimap();
|
|
1373
2230
|
this.requestUpdate();
|
|
1374
2231
|
}
|
|
1375
|
-
validateUrl(evt) {
|
|
1376
|
-
if (evt.key === "Enter") {
|
|
1377
|
-
this.fetchUrl();
|
|
1378
|
-
}
|
|
1379
|
-
const urlValue = this.urlInput.value;
|
|
1380
|
-
if (urlValue.match(urlRegex)) {
|
|
1381
|
-
this.urlInputButton.disabled = false;
|
|
1382
|
-
this.urlInputButton.classList.remove('close-button');
|
|
1383
|
-
}
|
|
1384
|
-
else {
|
|
1385
|
-
this.urlInputButton.disabled = true;
|
|
1386
|
-
this.urlInputButton.classList.add('close-button');
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
2232
|
ungrabExplorer() {
|
|
1390
2233
|
this.explorer.grabbed = false;
|
|
1391
2234
|
}
|
|
1392
2235
|
};
|
|
1393
|
-
TheDoctor.styles = [theDoctorCss, linksCss, dialogCss, buttonCss, radioGroupsCss, tabsCss, formsCss, spinnerCss];
|
|
2236
|
+
TheDoctor.styles = [theDoctorCss, linksCss, dialogCss, buttonCss, radioGroupsCss, tabsCss, formsCss, spinnerCss, tooltipCss];
|
|
1394
2237
|
__decorate([
|
|
1395
2238
|
query('#overviewPanel')
|
|
1396
2239
|
], TheDoctor.prototype, "overviewPanel", void 0);
|
|
@@ -1433,6 +2276,15 @@ __decorate([
|
|
|
1433
2276
|
__decorate([
|
|
1434
2277
|
property({ type: Boolean })
|
|
1435
2278
|
], TheDoctor.prototype, "unavailable", void 0);
|
|
2279
|
+
__decorate([
|
|
2280
|
+
query('#editor-url-overlay')
|
|
2281
|
+
], TheDoctor.prototype, "urlOverlay", void 0);
|
|
2282
|
+
__decorate([
|
|
2283
|
+
query('#url-problem')
|
|
2284
|
+
], TheDoctor.prototype, "urlProblem", void 0);
|
|
2285
|
+
__decorate([
|
|
2286
|
+
query('#url-spinner')
|
|
2287
|
+
], TheDoctor.prototype, "urlSpinner", void 0);
|
|
1436
2288
|
__decorate([
|
|
1437
2289
|
property()
|
|
1438
2290
|
], TheDoctor.prototype, "doctorEndpoint", void 0);
|
|
@@ -1448,6 +2300,15 @@ __decorate([
|
|
|
1448
2300
|
__decorate([
|
|
1449
2301
|
query('sl-split-panel.split-panel')
|
|
1450
2302
|
], TheDoctor.prototype, "splitPanel", void 0);
|
|
2303
|
+
__decorate([
|
|
2304
|
+
query('#explorer-split-panel')
|
|
2305
|
+
], TheDoctor.prototype, "splitPanelExplorer", void 0);
|
|
2306
|
+
__decorate([
|
|
2307
|
+
query('#rolodex-split-panel')
|
|
2308
|
+
], TheDoctor.prototype, "splitPanelRolodex", void 0);
|
|
2309
|
+
__decorate([
|
|
2310
|
+
query('#inspector-split-panel')
|
|
2311
|
+
], TheDoctor.prototype, "splitPanelInspector", void 0);
|
|
1451
2312
|
__decorate([
|
|
1452
2313
|
state()
|
|
1453
2314
|
], TheDoctor.prototype, "rulesetPulse", void 0);
|
|
@@ -1456,18 +2317,14 @@ __decorate([
|
|
|
1456
2317
|
], TheDoctor.prototype, "explorerVisible", void 0);
|
|
1457
2318
|
__decorate([
|
|
1458
2319
|
state()
|
|
1459
|
-
], TheDoctor.prototype, "
|
|
1460
|
-
__decorate([
|
|
1461
|
-
query('#editor-url-overlay')
|
|
1462
|
-
], TheDoctor.prototype, "urlOverlay", void 0);
|
|
2320
|
+
], TheDoctor.prototype, "minimapVisible", void 0);
|
|
1463
2321
|
__decorate([
|
|
1464
|
-
|
|
1465
|
-
], TheDoctor.prototype, "
|
|
2322
|
+
state()
|
|
2323
|
+
], TheDoctor.prototype, "activeURL", void 0);
|
|
1466
2324
|
__decorate([
|
|
1467
|
-
|
|
1468
|
-
], TheDoctor.prototype, "
|
|
2325
|
+
state()
|
|
2326
|
+
], TheDoctor.prototype, "rolodexNeedsReset", void 0);
|
|
1469
2327
|
TheDoctor = __decorate([
|
|
1470
2328
|
customElement("pb33f-doctor")
|
|
1471
2329
|
], TheDoctor);
|
|
1472
2330
|
export { TheDoctor };
|
|
1473
|
-
const urlRegex = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/;
|