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