xref: /6.6.0/cbas-ui/cbas-ui/cbas.html (revision ad9512b9)
1<style>
2  .tooltip-custom-wide .tooltip-inner {
3    max-width: 1024px;
4    width: auto;
5  }
6</style>
7<div ng-show="qc.validated.valid()" class="wb-wrapper">
8
9  <mn-element-cargo depot="actions" ng-if="qc.validated.valid()">
10    <div class="header-controls">
11      <a ng-if="qc.showOptions"
12         ng-click="qc.options()">
13        <span class="icon fa-cog fa-lg"></span>
14      </a>
15      <input type="file" id="loadQuery" name="files" style="display:none" accept="text/plain">
16      <a ng-if="qc.fileSupport"
17         id="loadQueryButton"
18         ng-click="qc.load_query()"
19         onchange="console.log('changed files')">
20        IMPORT
21      </a>
22      <a ng-click="qc.unified_save()">
23        EXPORT
24      </a>
25    </div>
26  </mn-element-cargo>
27
28<!-- wrapper for query editor and results ------------------------------------->
29  <div mn-spinner="queryInProgress" class="wb-main-wrapper width-9 resp-small">
30<!-- query editor header, main editor area, and results footer ---------------->
31    <div class="wb-query-editor">
32<!-- Editor "header row" ------------------------------------------------------>
33      <div class="wb-query-editor-header" ng-click="qc.handleClick('editor')">
34        <h4>Analytics Query Editor</h4>
35        <span>
36          <button
37             title="View previous queries/results"
38             ng-click="qc.prev()"
39             qw-long-press="qc.historyMenu"
40             class="outline btn-small"
41             ng-disabled="!qc.hasPrev()">
42            &larr;
43          </button>
44          <span class="wb-history-controls-inner">
45            <a ng-click="qc.historyMenu()">history</a>
46            <small>({{qc.getCurrentIndex()}})</small>
47          </span>
48          <button
49             title="View subsequent queries/results"
50             ng-click="qc.next()"
51             qw-long-press="qc.historyMenu"
52             class="outline btn-small"
53             ng-disabled="!qc.hasNext()">
54            &rarr;
55          </button>
56        </span>
57        <div class="wb-fullscreen resp-hide-sml" ng-click="qc.toggleFullscreen()">
58          <span ng-if="!qc.fullscreen" class="icon fa-expand" title="expand"></span>
59          <span ng-if="qc.fullscreen" class="icon fa-compress" title="contract"></span>
60        </div>
61      </div>
62
63<!-- Ace editor --------------------------------------------------------------->
64      <div
65         class="wb-ace-editor" ng-click="qc.handleClick('editor')"
66         ui-ace="qc.aceInputOptions"
67         ng-disabled="qc.executingQuery.busy"
68         ng-model="qc.lastResult.query">{{qc.renderPage()}}
69      </div>
70
71<!-- wrapper under query editor for button and stats -------------------------->
72      <div class="wb-query-editor-footer">
73        <span class="wb-button-wrapper nowrap">
74          <button ng-click="qc.query()" class="wb-button-execute">
75            <div ng-if="!qc.executingQuery.busy">
76              Execute
77            </div>
78            <div ng-if="qc.executingQuery.busy" class="icon-button">
79              Cancel <span class="icon fa-spinner fa-spin fa-pulse"></span>
80            </div>
81          </button>
82          <button
83             ng-disabled="qc.executingQuery.busy"
84             ng-click="qc.query(true)"
85             class="outline tight">
86            Explain
87            <span ng-if="qc.executingQuery.busy" class="icon fa-spinner fa-spin fa-pulse"></span>
88          </button>
89        </span>
90
91<!-- query execution summary stats -------------------------------------------->
92        <div class="wb-result-summary">
93          <span
94             class="nowrap wb-result-status padding-right-half"
95             ng-class="{success: qc.status_success(), error: qc.status_fail()}">
96            {{qc.lastResult.status}}
97          </span>
98          <span ng-if="qc.lastResult.elapsedTime" class="nowrap pipe">
99            elapsed: {{qc.lastResult.elapsedTime}}
100          </span>
101          <span ng-if="qc.lastResult.executionTime" class="nowrap pipe">
102            execution: {{qc.lastResult.executionTime}}
103          </span>
104          <span ng-if="qc.lastResult.processedObjects == 0 || qc.lastResult.processedObjects" class="nowrap pipe">
105            docs scanned: {{qc.lastResult.processedObjects}}
106          </span>
107          <span ng-if="qc.lastResult.resultCount" class="nowrap pipe">
108            docs returned: {{qc.lastResult.resultCount}}
109          </span>
110          <span ng-if="qc.lastResult.resultSize" class="nowrap pipe">
111            size: {{qc.lastResult.resultSize}} bytes
112          </span>
113          <span ng-if="qc.lastResult.warningCount == 0 || qc.lastResult.warningCount" class="nowrap pipe">
114            warnings: {{qc.lastResult.warningCount}}
115          </span>
116        </div>
117
118<!-- run-time preferences ----------------------------------------------------->
119        <a ng-disabled="qc.executingQuery.busy"
120           ng-click="qc.format()"
121           class="text-smallish nowrap resp-hide-xsml">
122          <span class="icon fa-align-right"></span>
123          format
124        </a>
125      </div>
126    </div>
127
128<!-- query results ------------------------------------------------------------>
129    <div class="wb-results-header" ng-click="qc.handleClick('results')">
130      <h4>Analytics Query Results
131        <a
132           ng-click="qc.copyResultAsCSV()"
133           class="margin-left-half"
134           title="Copy results in tabular format">
135          <span class="icon fa-copy"></span>
136        </a>
137        <span ng-if="qc.lastResult.warnings"
138              tooltip-trigger="'mouseenter'"
139              tooltip-append-to-body="true"
140              tooltip-class="tooltip-custom-wide"
141              class="fa-warning icon force-orange-3 cursor-pointer"
142              uib-tooltip-html="'Showing {{qc.lastResult.limitedWarningsCount}} of {{qc.lastResult.warningCount}} warnings:<br/>'
143                                 + '{{qc.lastResultWarnings()}}'">
144          </span>
145      </h4>
146      <span class="pills">
147        <a ng-click="qc.selectTab(1)"
148           ng-class="{selected: qc.isSelected(1)}">JSON</a>
149        <a ng-click="qc.selectTab(2)"
150           ng-class="{selected: qc.isSelected(2)}">Table</a>
151        <a ng-click="qc.selectTab(3)"
152           ng-class="{selected: qc.isSelected(3)}">Tree</a>
153        <a ng-click="qc.selectTab(4)" ng-if="qc.isEnterprise"
154           ng-class="{selected: qc.isSelected(4)}">Plan</a>
155        <a ng-click="qc.selectTab(5)"
156           ng-class="{selected: qc.isSelected(5)}">Plan Text</a>
157      </span>
158    </div>
159
160    <div class="wb-results-wrapper" ng-click="qc.handleClick('results')">
161      <div class="wb-results-show-anyway" ng-if="!qc.showBigDatasets && qc.dataTooBig()">
162        <div ng-bind-html="qc.getBigDataMessage()"></div>
163        <a ng-click="qc.setShowBigData(true)" class="text-medium link-heavy">
164          Show anyway <span class="icon fa-angle-right"></span>
165        </a>
166      </div>
167      <div class="wb-results-json" ui-ace="qc.aceOutputOptions"
168           ng-if="qc.isSelected(1) && (!qc.dataTooBig() || qc.showBigDatasets)"
169           ng-model="qc.lastResult.result"></div>
170
171      <div class="wb-results-table"
172           ng-if="qc.isSelected(2) && (!qc.dataTooBig() || qc.showBigDatasets)"
173           qw-json-data-table="qc.lastResult.data"></div>
174
175      <div class="wb-results-tree"
176           ng-if="qc.isSelected(3) && (!qc.dataTooBig() || qc.showBigDatasets)"
177           qw-json-tree="qc.lastResult.data"></div>
178
179      <div class="wb-results-explain" ng-if="qc.isSelected(4)"
180           qw-explain-viz-d3="qc.lastResult.explainResult"></div>
181
182      <div class="wb-results-explain-text"
183           ng-if="qc.isSelected(5)"
184           ui-ace="qc.acePlanOptions"
185           ng-model="qc.lastResult.explainResultText"></div>
186    </div>
187  </div>
188
189<!-- datasets  sidebar -------------------------------------------------------->
190  <div class="insights-sidebar width-3 show-scrollbar resp-hide-sml">
191    <div class="insights-sidebar-body">
192      <div class="row margin-bottom-half">
193        <h4>Datasets</h4>
194        <div class="insights-sidebar-expand" ng-click="qc.toggleAnalysisSize()">
195          <span ng-if="!qc.analysisExpanded" class="icon fa-expand" title="expand"></span>
196          <span ng-if="qc.analysisExpanded" class="icon fa-compress" title="contract"></span>
197        </div>
198      </div>
199
200      <div mn-spinner="qc.qqs.loadingBuckets">
201        <div ng-if="qc.qqs.bucket_errors">
202          <br>
203          <p style="white-space:pre-wrap;" class="text-small">
204            {{qc.qqs.bucket_errors}}
205          </p>
206        </div>
207        <div ng-if="!qc.qqs.bucket_errors">
208          <section class="text-small" ng-repeat="dataverse in qc.dataverses">
209            <p class="margin-bottom-0 margin-top-half">
210              Dataverse: {{dataverse.DataverseName}}
211            </p>
212            <span ng-repeat="shadow in qc.shadows">
213              <div ng-if="shadow.DataverseName === dataverse.DataverseName" ng-init="shadow.expanded = false">
214                <span class="row margin-bottom-0">
215                  <span ng-click="changeExpandShadow(shadow)" class="cursor-pointer">
216                    <span class="icon fa-caret-down fa-fw" ng-class="{'fa-caret-right': !shadow.expanded}"></span>
217                    <strong ng-class="{error : shadow.remaining === qc.datasetDisconnectedState}">
218                      {{shadow.id}}
219                    </strong>
220                  </span>
221                  <span
222                     ng-show="shadow.remaining === qc.datasetUnknownState"
223                     title="fetching dataset state..."
224                     class="icon fa-spinner fa-pulse grayblack-3">
225                  </span>
226                  <span
227                     ng-show="shadow.remaining === qc.datasetDisconnectedState"
228                     title="disconnected"
229                     class="icon fa-unlink red-3">
230                  </span>
231                  <span
232                     ng-show="shadow.remaining > 0 || shadow.remaining == 0"
233                     title="connected"
234                     class="icon fa-link grayblack-3">
235                  </span>
236                </span>
237
238                <div class="margin-bottom-half padding-left-half" ng-show="shadow.expanded">
239                  <p class="margin-bottom-half">
240                    Bucket:<br>
241                    {{shadow.LinkName}}.{{shadow.bucketName}}
242                    <span ng-show="shadow.filter">|</span> {{shadow.filter}}
243                  </p>
244                  <p class="margin-bottom-half" ng-show="shadow.indexes.length > 0">
245                    Index<span ng-show="shadow.indexes.length > 1">es</span>:<br>
246                    <span ng-repeat="idx in shadow.indexes">
247                      {{idx.IndexName}} <span ng-repeat="key in idx.keys">({{key}})<br></span>
248                    </span>
249                  </p>
250                </div>
251
252                <div class="margin-bottom-1 padding-left-half" ng-show="shadow.remaining > 0">
253                  <em class="text-smaller">
254                    remaining mutations: {{shadow.remaining}}
255                  </em>
256                </div>
257              </div>
258            </span>
259            <span
260               ng-show="shadow.remaining === qc.datasetDisconnectedState"
261               title="disconnected"
262               class="icon fa-unlink"
263               style="color: #e07f82">
264            </span>
265            <span
266               ng-show="shadow.remaining > 0 || shadow.remaining == 0"
267               title="connected"
268               class="icon fa-link">
269            </span>
270          </section>
271
272          <section class="margin-top-1">
273            <h5>Couchbase Buckets</h5>
274            <span class="text-small" ng-repeat="bucket in qc.clusterBuckets">
275              {{bucket}}<br>
276            </span>
277          </section>
278
279<!-- datasets refresh button -------------------------------------------------->
280          <div class="row flex-right fix-position-br wb-refresh-btn">
281            <button
282               title="Refresh dataset insights"
283               ng-click="qc.updateBuckets()"
284               class="outline"
285               ng-disabled="qc.qqs.loadingBuckets">
286              Refresh &nbsp;
287              <span ng-if="qc.qqs.loadingBuckets" class="icon fa-refresh"></span>
288              <span ng-if="!qc.qqs.loadingBuckets" class="icon fa-refresh"></span>
289            </button>
290          </div>
291        </div>
292      </div>
293    </div>
294  </div>
295</div>
296