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