| //- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| include /app/helpers/jade/mixins |
| |
| mixin btn-toolbar(btn, click, tip, focusId) |
| i.btn.btn-default.fa(class=btn ng-click=click bs-tooltip='' data-title=tip ignite-on-click-focus=focusId data-trigger='hover' data-placement='bottom') |
| |
| mixin btn-toolbar-data(btn, kind, tip) |
| i.btn.btn-default.fa(class=btn ng-click=`setResult(paragraph, '${kind}')` ng-class=`{active: resultEq(paragraph, '${kind}')}` bs-tooltip='' data-title=tip data-trigger='hover' data-placement='bottom') |
| |
| mixin result-toolbar |
| .btn-group(ng-model='paragraph.result' ng-click='$event.stopPropagation()' style='left: 50%; margin: 0 0 0 -70px;display: block;') |
| +btn-toolbar-data('fa-table', 'table', 'Show data in tabular form') |
| +btn-toolbar-data('fa-bar-chart', 'bar', 'Show bar chart<br/>By default first column - X values, second column - Y values<br/>In case of one column it will be treated as Y values') |
| +btn-toolbar-data('fa-pie-chart', 'pie', 'Show pie chart<br/>By default first column - pie labels, second column - pie values<br/>In case of one column it will be treated as pie values') |
| +btn-toolbar-data('fa-line-chart', 'line', 'Show line chart<br/>By default first column - X values, second column - Y values<br/>In case of one column it will be treated as Y values') |
| +btn-toolbar-data('fa-area-chart', 'area', 'Show area chart<br/>By default first column - X values, second column - Y values<br/>In case of one column it will be treated as Y values') |
| |
| mixin chart-settings |
| .total.row |
| .col-xs-7 |
| .chart-settings-link(ng-show='paragraph.chart && paragraph.chartColumns.length > 0') |
| a(title='Click to show chart settings dialog' ng-click='$event.stopPropagation()' bs-popover data-template-url='{{ $ctrl.chartSettingsTemplateUrl }}' data-placement='bottom' data-auto-close='1' data-trigger='click') |
| i.fa.fa-bars |
| | Chart settings |
| div(ng-show='paragraphTimeSpanVisible(paragraph)') |
| label Show |
| button.select-manual-caret.btn.btn-default(ng-model='paragraph.timeLineSpan' ng-change='applyChartSettings(paragraph)' bs-options='item for item in timeLineSpans' bs-select data-caret-html='<span class="caret"></span>') |
| label min |
| |
| div |
| label Duration: #[b {{paragraph.duration | duration}}] |
| label.margin-left-dflt(ng-show='paragraph.localQueryMode') NodeID8: #[b {{paragraph.resNodeId | id8}}] |
| .col-xs-2 |
| +result-toolbar |
| |
| mixin notebook-rename |
| .notebooks-top |
| breadcrumbs |
| a.link-success(ui-sref='^.') Notebooks |
| span(ui-sref='.' ui-sref-active) Notebook '{{notebook.name}}' |
| cluster-selector |
| |
| .docs-header.notebook-header |
| h1.col-sm-6(ng-hide='notebook.edit') |
| label(style='max-width: calc(100% - 60px)') {{notebook.name}} |
| .btn-group(ng-if='!demo') |
| +btn-toolbar('fa-pencil', 'notebook.edit = true;notebook.editName = notebook.name', 'Rename notebook') |
| +btn-toolbar('fa-trash', 'removeNotebook(notebook)', '{{$ctrl.isDemo ? "Demo notebook cannot be deleted" : "Remove notebook"}}') |
| h1.col-sm-6(ng-show='notebook.edit') |
| i.btn.fa.fa-floppy-o(ng-show='notebook.editName' ng-click='renameNotebook(notebook.editName)' bs-tooltip data-title='Save notebook name' data-trigger='hover') |
| .input-tip |
| input.form-control(ng-model='notebook.editName' required ignite-on-enter='renameNotebook(notebook.editName)' ignite-on-escape='notebook.edit = false;') |
| h1.pull-right |
| a.dropdown-toggle(style='margin-right: 20px' data-toggle='dropdown' bs-dropdown='scrollParagraphs' data-placement='bottom-right') Scroll to query |
| span.caret |
| button.btn.btn-default(style='margin-top: 2px' ng-click='addQuery()' ignite-on-click-focus=focusId) |
| i.fa.fa-fw.fa-plus |
| | Add query |
| |
| button.btn.btn-default(style='margin-top: 2px' ng-click='addScan()' ignite-on-click-focus=focusId) |
| i.fa.fa-fw.fa-plus |
| | Add scan |
| |
| mixin notebook-error |
| h2 Failed to load notebook |
| label.col-sm-12 Notebook not accessible any more. Go back to configuration or open to another notebook. |
| button.h3.btn.btn-primary(ui-sref='default-state') Back to configuration |
| |
| mixin paragraph-rename |
| .col-sm-6(ng-hide='paragraph.edit') |
| i.fa(ng-class='paragraphExpanded(paragraph) ? "fa-chevron-circle-down" : "fa-chevron-circle-right"') |
| label {{paragraph.name}} |
| |
| .btn-group(ng-hide='notebook.paragraphs.length > 1') |
| +btn-toolbar('fa-pencil', 'paragraph.edit = true; paragraph.editName = paragraph.name; $event.stopPropagation();', 'Rename query', 'paragraph-name-{{paragraph.id}}') |
| |
| .btn-group(ng-show='notebook.paragraphs.length > 1' ng-click='$event.stopPropagation();') |
| +btn-toolbar('fa-pencil', 'paragraph.edit = true; paragraph.editName = paragraph.name;', 'Rename query', 'paragraph-name-{{paragraph.id}}') |
| +btn-toolbar('fa-remove', 'removeParagraph(paragraph)', 'Remove query') |
| |
| .col-sm-6(ng-show='paragraph.edit') |
| i.tipLabel.fa(style='float: left;' ng-class='paragraphExpanded(paragraph) ? "fa-chevron-circle-down" : "fa-chevron-circle-right"') |
| i.tipLabel.fa.fa-floppy-o(style='float: right;' ng-show='paragraph.editName' ng-click='renameParagraph(paragraph, paragraph.editName); $event.stopPropagation();' bs-tooltip data-title='Save query name' data-trigger='hover') |
| .input-tip |
| input.form-control(id='paragraph-name-{{paragraph.id}}' ng-model='paragraph.editName' required ng-click='$event.stopPropagation();' ignite-on-enter='renameParagraph(paragraph, paragraph.editName)' ignite-on-escape='paragraph.edit = false') |
| |
| mixin query-settings |
| .panel-top-align |
| label.tipLabel(bs-tooltip data-placement='bottom' data-title='Configure periodical execution of last successfully executed query') Refresh rate: |
| button.btn.btn-default.fa.fa-clock-o.tipLabel(ng-class='{"btn-info": paragraph.rate && paragraph.rate.installed}' bs-popover data-template-url='{{ $ctrl.paragraphRateTemplateUrl }}' data-placement='left' data-auto-close='1' data-trigger='click') {{rateAsString(paragraph)}} |
| |
| label.tipLabel(bs-tooltip data-placement='bottom' data-title='Max number of rows to show in query result as one page') Page size: |
| button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.pageSize' bs-select bs-options='item for item in pageSizes') |
| |
| label.tipLabel(bs-tooltip data-placement='bottom' data-title='Limit query max results to specified number of pages') Max pages: |
| button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.maxPages' bs-select bs-options='item.value as item.label for item in maxPages') |
| |
| .panel-tip-container |
| .row(ng-if='nonCollocatedJoinsAvailable(paragraph)') |
| label.tipLabel(bs-tooltip data-placement='bottom' data-title='Non-collocated joins is a special mode that allow to join data across cluster without collocation.<br/>\ |
| Nested joins are not supported for now.<br/>\ |
| <b>NOTE</b>: In some cases it may consume more heap memory or may take a long time than collocated joins.' data-trigger='hover') |
| input(type='checkbox' ng-model='paragraph.nonCollocatedJoins') |
| span Allow non-collocated joins |
| .row(ng-if='enforceJoinOrderAvailable(paragraph)') |
| label.tipLabel(bs-tooltip data-placement='bottom' data-title='Enforce join order of tables in the query.<br/>\ |
| If <b>set</b>, then query optimizer will not reorder tables within join.<br/>\ |
| <b>NOTE:</b> It is not recommended to enable this property unless you have verified that\ |
| indexes are not selected in optimal order.' data-trigger='hover') |
| input(type='checkbox' ng-model='paragraph.enforceJoinOrder') |
| span Enforce join order |
| .row(ng-if='lazyQueryAvailable(paragraph)') |
| label.tipLabel(bs-tooltip data-placement='bottom' data-title='By default Ignite attempts to fetch the whole query result set to memory and send it to the client.<br/>\ |
| For small and medium result sets this provides optimal performance and minimize duration of internal database locks, thus increasing concurrency.<br/>\ |
| If result set is too big to fit in available memory this could lead to excessive GC pauses and even OutOfMemoryError.<br/>\ |
| Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing memory consumption at the cost of moderate performance hit.' data-trigger='hover') |
| input(type='checkbox' ng-model='paragraph.lazy') |
| span Lazy result set |
| |
| mixin query-actions |
| button.btn.btn-primary(ng-disabled='!queryAvailable(paragraph)' ng-click='execute(paragraph)') |
| div |
| i.fa.fa-fw.fa-play(ng-hide='paragraph.executionInProgress(false)') |
| i.fa.fa-fw.fa-refresh.fa-spin(ng-show='paragraph.executionInProgress(false)') |
| span.tipLabelExecute Execute |
| button.btn.btn-primary(ng-disabled='!queryAvailable(paragraph)' ng-click='execute(paragraph, true)') |
| div |
| i.fa.fa-fw.fa-play(ng-hide='paragraph.executionInProgress(true)') |
| i.fa.fa-fw.fa-refresh.fa-spin(ng-show='paragraph.executionInProgress(true)') |
| span.tipLabelExecute Execute on selected node |
| |
| |
| a.btn.btn-default(ng-disabled='!queryAvailable(paragraph)' ng-click='explain(paragraph)' data-placement='bottom' bs-tooltip='' data-title='{{queryTooltip(paragraph, "explain query")}}') Explain |
| |
| mixin table-result-heading-query |
| .total.row |
| .col-xs-7 |
| grid-column-selector(grid-api='paragraph.gridOptions.api') |
| .fa.fa-bars.icon |
| label Page: #[b {{paragraph.page}}] |
| label.margin-left-dflt Results so far: #[b {{paragraph.rows.length + paragraph.total}}] |
| label.margin-left-dflt Duration: #[b {{paragraph.duration | duration}}] |
| label.margin-left-dflt(ng-show='paragraph.localQueryMode') NodeID8: #[b {{paragraph.resNodeId | id8}}] |
| .col-xs-2 |
| div(ng-if='paragraph.qryType === "query"') |
| +result-toolbar |
| .col-xs-3 |
| .pull-right |
| .btn-group.panel-tip-container |
| button.btn.btn-primary.btn--with-icon( |
| ng-click='exportCsv(paragraph)' |
| |
| ng-disabled='paragraph.loading' |
| |
| bs-tooltip='' |
| ng-attr-title='{{ queryTooltip(paragraph, "export query results") }}' |
| |
| data-trigger='hover' |
| data-placement='bottom' |
| ) |
| svg(ignite-icon='csv' ng-if='!paragraph.csvIsPreparing') |
| i.fa.fa-fw.fa-refresh.fa-spin(ng-if='paragraph.csvIsPreparing') |
| span Export |
| |
| -var options = [{ text: 'Export', click: 'exportCsv(paragraph)' }, { text: 'Export all', click: 'exportCsvAll(paragraph)' }, { divider: true }, { text: '<span title="Copy current result page to clipboard">Copy to clipboard</span>', click: 'exportCsvToClipBoard(paragraph)' }] |
| button.btn.dropdown-toggle.btn-primary( |
| ng-disabled='paragraph.loading' |
| |
| bs-dropdown=`${JSON.stringify(options)}` |
| |
| data-toggle='dropdown' |
| data-container='body' |
| data-placement='bottom-right' |
| data-html='true' |
| ) |
| span.caret |
| |
| |
| |
| mixin table-result-heading-scan |
| .total.row |
| .col-xs-7 |
| grid-column-selector(grid-api='paragraph.gridOptions.api') |
| .fa.fa-bars.icon |
| label Page: #[b {{paragraph.page}}] |
| label.margin-left-dflt Results so far: #[b {{paragraph.rows.length + paragraph.total}}] |
| label.margin-left-dflt Duration: #[b {{paragraph.duration | duration}}] |
| label.margin-left-dflt(ng-show='paragraph.localQueryMode') NodeID8: #[b {{paragraph.resNodeId | id8}}] |
| .col-xs-2 |
| div(ng-if='paragraph.qryType === "query"') |
| +result-toolbar |
| .col-xs-3 |
| .pull-right |
| .btn-group.panel-tip-container |
| // TODO: replace this logic for exporting under one component |
| button.btn.btn-primary.btn--with-icon( |
| ng-click='exportCsv(paragraph)' |
| |
| ng-disabled='paragraph.loading || paragraph.csvIsPreparing' |
| |
| bs-tooltip='' |
| ng-attr-title='{{ scanTooltip(paragraph) }}' |
| |
| data-trigger='hover' |
| data-placement='bottom' |
| ) |
| svg(ignite-icon='csv' ng-if='!paragraph.csvIsPreparing') |
| i.fa.fa-fw.fa-refresh.fa-spin(ng-if='paragraph.csvIsPreparing') |
| span Export |
| |
| -var options = [{ text: "Export", click: 'exportCsv(paragraph)' }, { text: 'Export all', click: 'exportCsvAll(paragraph)' }, { divider: true }, { text: '<span title="Copy current result page to clipboard">Copy to clipboard</span>', click: 'exportCsvToClipBoard(paragraph)' }] |
| button.btn.dropdown-toggle.btn-primary( |
| ng-disabled='paragraph.loading || paragraph.csvIsPreparing' |
| |
| bs-dropdown=`${JSON.stringify(options)}` |
| |
| data-toggle='dropdown' |
| data-container='body' |
| data-placement='bottom-right' |
| data-html='true' |
| ) |
| span.caret |
| |
| mixin table-result-body |
| .grid(ui-grid='paragraph.gridOptions' ui-grid-resize-columns ui-grid-exporter) |
| |
| mixin chart-result |
| div(ng-hide='paragraph.scanExplain()') |
| +chart-settings |
| .empty(ng-show='paragraph.chartColumns.length > 0 && !paragraph.chartColumnsConfigured()') Cannot display chart. Please configure axis using #[b Chart settings] |
| .empty(ng-show='paragraph.chartColumns.length == 0') Cannot display chart. Result set must contain Java build-in type columns. Please change query and execute it again. |
| div(ng-show='paragraph.chartColumnsConfigured()') |
| div(ng-show='paragraph.timeLineSupported() || !paragraph.chartTimeLineEnabled()') |
| div(ng-repeat='chart in paragraph.charts') |
| nvd3(options='chart.options' data='chart.data' api='chart.api') |
| .empty(ng-show='!paragraph.timeLineSupported() && paragraph.chartTimeLineEnabled()') Pie chart does not support 'TIME_LINE' column for X-axis. Please use another column for X-axis or switch to another chart. |
| .empty(ng-show='paragraph.scanExplain()') |
| .row |
| .col-xs-4.col-xs-offset-4 |
| +result-toolbar |
| label.margin-top-dflt Charts do not support #[b Explain] and #[b Scan] query |
| |
| mixin paragraph-scan |
| .panel-heading(bs-collapse-toggle) |
| .row |
| +paragraph-rename |
| .panel-collapse(role='tabpanel' bs-collapse-target) |
| .col-sm-12.sql-controls |
| .col-sm-3 |
| +dropdown-required('Cache:', 'paragraph.cacheName', '"cache"', 'true', 'false', 'Choose cache', 'caches') |
| .col-sm-3 |
| +text-enabled('Filter:', 'paragraph.filter', '"filter"', true, false, 'Enter filter') |
| label.btn.btn-default.ignite-form-field__btn(ng-click='paragraph.caseSensitive = !paragraph.caseSensitive') |
| input(type='checkbox' ng-model='paragraph.caseSensitive') |
| span(bs-tooltip data-title='Select this checkbox for case sensitive search') Cs |
| label.tipLabel(bs-tooltip data-placement='bottom' data-title='Max number of rows to show in query result as one page') Page size: |
| button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.pageSize' bs-select bs-options='item for item in pageSizes') |
| |
| .col-sm-12.sql-controls |
| button.btn.btn-primary(ng-disabled='!scanAvailable(paragraph)' ng-click='scan(paragraph)') |
| div |
| i.fa.fa-fw.fa-play(ng-hide='paragraph.checkScanInProgress(false)') |
| i.fa.fa-fw.fa-refresh.fa-spin(ng-show='paragraph.checkScanInProgress(false)') |
| span.tipLabelExecute Scan |
| |
| button.btn.btn-primary(ng-disabled='!scanAvailable(paragraph)' ng-click='scan(paragraph, true)') |
| i.fa.fa-fw.fa-play(ng-hide='paragraph.checkScanInProgress(true)') |
| i.fa.fa-fw.fa-refresh.fa-spin(ng-show='paragraph.checkScanInProgress(true)') |
| span.tipLabelExecute Scan on selected node |
| |
| .col-sm-12.sql-result(ng-if='paragraph.queryExecuted() && !paragraph.scanningInProgress' ng-switch='paragraph.resultType()') |
| .error(ng-switch-when='error') Error: {{paragraph.error.message}} |
| .empty(ng-switch-when='empty') Result set is empty. Duration: #[b {{paragraph.duration | duration}}] |
| .table(ng-switch-when='table') |
| +table-result-heading-scan |
| +table-result-body |
| .footer.clearfix() |
| .pull-left |
| | Showing results for scan of #[b {{ paragraph.queryArgs.cacheName | defaultName }}] |
| span(ng-if='paragraph.queryArgs.filter') with filter: #[b {{ paragraph.queryArgs.filter }}] |
| span(ng-if='paragraph.queryArgs.localNid') on node: #[b {{ paragraph.queryArgs.localNid | limitTo:8 }}] |
| |
| -var nextVisibleCondition = 'paragraph.resultType() != "error" && paragraph.queryId && paragraph.nonRefresh() && (paragraph.table() || paragraph.chart() && !paragraph.scanExplain())' |
| |
| .pull-right(ng-show=`${nextVisibleCondition}` ng-class='{disabled: paragraph.loading}' ng-click='!paragraph.loading && nextPage(paragraph)') |
| i.fa.fa-chevron-circle-right |
| a Next |
| |
| mixin paragraph-query |
| .row.panel-heading(bs-collapse-toggle) |
| +paragraph-rename |
| .panel-collapse(role='tabpanel' bs-collapse-target) |
| .col-sm-12 |
| .col-xs-8.col-sm-9(style='border-right: 1px solid #eee') |
| .sql-editor(ignite-ace='{onLoad: aceInit(paragraph), theme: "chrome", mode: "sql", require: ["ace/ext/language_tools"],' + |
| 'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}' |
| ng-model='paragraph.query') |
| .col-xs-4.col-sm-3 |
| div(ng-show='caches.length > 0' style='padding: 5px 10px' st-table='displayedCaches' st-safe-src='caches') |
| lable.labelField.labelFormField Caches: |
| i.fa.fa-database.tipField(title='Click to show cache types metadata dialog' bs-popover data-template-url='{{ $ctrl.cacheMetadataTemplateUrl }}' data-placement='bottom' data-trigger='click' data-container='#{{ paragraph.id }}') |
| .input-tip |
| input.form-control(type='text' st-search='label' placeholder='Filter caches...') |
| table.links |
| tbody.scrollable-y(style='max-height: 15em; display: block;') |
| tr(ng-repeat='cache in displayedCaches track by cache.name') |
| td(style='width: 100%') |
| input.labelField(id='cache_{{ [paragraph.id, $index].join("_") }}' type='radio' value='{{cache.name}}' ng-model='paragraph.cacheName') |
| label(for='cache_{{ [paragraph.id, $index].join("_") }} ' ng-bind-html='cache.label') |
| .settings-row |
| .row(ng-if='ddlAvailable(paragraph)') |
| label.tipLabel.use-cache(bs-tooltip data-placement='bottom' |
| data-title= |
| 'Use selected cache as default schema name.<br/>\ |
| This will allow to execute query on specified cache without specify schema name.<br/>\ |
| <b>NOTE:</b> In future version of Ignite this feature will be removed.' |
| data-trigger='hover') |
| input(type='checkbox' ng-model='paragraph.useAsDefaultSchema') |
| span Use selected cache as default schema name |
| .empty-caches(ng-show='displayedCaches.length == 0 && caches.length != 0') |
| label Wrong caches filter |
| .empty-caches(ng-show='caches.length == 0') |
| label No caches |
| .col-sm-12.sql-controls |
| +query-actions |
| |
| .pull-right |
| +query-settings |
| .col-sm-12.sql-result(ng-if='paragraph.queryExecuted()' ng-switch='paragraph.resultType()') |
| .error(ng-switch-when='error') |
| label Error: {{paragraph.error.message}} |
| br |
| a(ng-show='paragraph.resultType() === "error"' ng-click='showStackTrace(paragraph)') Show more |
| .empty(ng-switch-when='empty') Result set is empty. Duration: #[b {{paragraph.duration | duration}}] |
| .table(ng-switch-when='table') |
| +table-result-heading-query |
| +table-result-body |
| .chart(ng-switch-when='chart') |
| +chart-result |
| .footer.clearfix(ng-show='paragraph.resultType() !== "error"') |
| a.pull-left(ng-click='showResultQuery(paragraph)') Show query |
| |
| -var nextVisibleCondition = 'paragraph.resultType() !== "error" && paragraph.queryId && paragraph.nonRefresh() && (paragraph.table() || paragraph.chart() && !paragraph.scanExplain())' |
| |
| .pull-right(ng-show=`${nextVisibleCondition}` ng-class='{disabled: paragraph.loading}' ng-click='!paragraph.loading && nextPage(paragraph)') |
| i.fa.fa-chevron-circle-right |
| a Next |
| |
| .row |
| .docs-content |
| .row(ng-if='notebook' bs-affix style='margin-bottom: 20px;') |
| +notebook-rename |
| |
| -var example = `CREATE TABLE Person(ID INTEGER PRIMARY KEY, NAME VARCHAR(100));\nINSERT INTO Person(ID, NAME) VALUES (1, 'Ed'), (2, 'Ann'), (3, 'Emma');\nSELECT * FROM Person;`; |
| |
| ignite-information( |
| data-title='With query notebook you can' |
| style='margin-bottom: 30px' |
| ng-init=`example = "${example}"` |
| ) |
| ul |
| li Create any number of queries |
| li Execute and explain SQL queries |
| li Execute scan queries |
| li View data in tabular form and as charts |
| .example |
| .group |
| .group-legend |
| label Examples: |
| .group-content |
| .sql-editor(ignite-ace='{\ |
| onLoad: aceInit({}),\ |
| theme: "chrome",\ |
| mode: "sql",\ |
| require: ["ace/ext/language_tools"],\ |
| showGutter: false,\ |
| advanced: {\ |
| enableSnippets: false,\ |
| enableBasicAutocompletion: true,\ |
| enableLiveAutocompletion: true\ |
| }}' |
| ng-model='example' |
| readonly='true' |
| ) |
| |
| div(ng-if='notebookLoadFailed' style='text-align: center') |
| +notebook-error |
| |
| div(ng-if='notebook' ignite-loading='sqlLoading' ignite-loading-text='{{ loadingText }}' ignite-loading-position='top') |
| .docs-body.paragraphs |
| .panel-group(bs-collapse ng-model='notebook.expandedParagraphs' data-allow-multiple='true' data-start-collapsed='false') |
| |
| .panel-paragraph(ng-repeat='paragraph in notebook.paragraphs' id='{{paragraph.id}}' ng-form='form_{{paragraph.id}}') |
| .panel.panel-default(ng-if='paragraph.qryType === "scan"') |
| +paragraph-scan |
| .panel.panel-default(ng-if='paragraph.qryType === "query"') |
| +paragraph-query |