REF - Divorce API4SelectQuery from base class SelectQuery
[civicrm-core.git] / ang / api4Explorer / Explorer.html
CommitLineData
19b53e5b
C
1<div id="bootstrap-theme" class="api4-explorer-page">
2 <div crm-ui-debug="availableParams"></div>
3
4 <h1 crm-page-title>
f9c5f498 5 {{:: ts('CiviCRM APIv4') }}{{ entity ? (' (' + entity + '::' + action + ')') : '' }}
19b53e5b
C
6 </h1>
7
8 <!--This warning will show if bootstrap is unavailable. Normally it will be hidden by the bootstrap .collapse class.-->
9 <div class="messages warning no-popup collapse">
10 <p>
13a3d214 11 <i class="crm-i fa-exclamation-triangle" aria-hidden="true"></i>
f9c5f498 12 <strong>{{:: ts('Bootstrap theme not found.') }}</strong>
19b53e5b 13 </p>
f9c5f498 14 <p>{{:: ts('This screen may not work correctly without a bootstrap-based theme such as Shoreditch installed.') }}</p>
19b53e5b
C
15 </div>
16
17 <div class="api4-explorer-row">
18 <form name="api4-explorer" class="panel panel-default explorer-params-panel">
19 <div class="panel-heading">
20 <div class="form-inline">
9cea3619 21 <span ng-mouseenter="help('entity', paramDoc('$entity'))" ng-mouseleave="help()">
4cd69277 22 <input class="collapsible-optgroups form-control" ng-model="entity" ng-disabled="!entities.length" ng-class="{loading: !entities.length}" crm-ui-select="::{placeholder: ts('Entity'), data: entities}" />
9cea3619
CW
23 </span>
24 <span ng-mouseenter="help('action', paramDoc('$action'))" ng-mouseleave="help()">
4cd69277 25 <input class="collapsible-optgroups form-control" ng-model="action" ng-disabled="!entity || !actions.length" ng-class="{loading: entity && !actions.length}" crm-ui-select="::{placeholder: ts('Action'), data: actions}" />
9cea3619 26 </span>
f9c5f498
CW
27 <input class="form-control api4-index" type="search" ng-model="index" ng-mouseenter="help('index', paramDoc('$index'))" ng-mouseleave="help()" placeholder="{{:: ts('Index') }}" />
28 <button class="btn btn-success pull-right" crm-icon="fa-bolt" ng-disabled="!entity || !action || loading" ng-click="execute()" ng-mouseenter="help(ts('Execute'), executeDoc())" ng-mouseleave="help()">{{:: ts('Execute') }}</button>
48102254 29 <button class="btn btn-primary pull-right" crm-icon="fa-save" ng-show="perm.editGroups && action === 'get'" ng-click="save()" ng-mouseenter="help(ts('Save smart group'), saveDoc())" ng-mouseleave="help()">{{:: ts('Save...') }}</button>
19b53e5b
C
30 </div>
31 </div>
32 <div class="panel-body">
33 <div class="api4-input form-inline">
8f38d9e9 34 <label class="form-control" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-class="{'api4-option-selected': params[name]}" ng-repeat="(name, param) in ::getGenericParams(['bool'], false)">
4cd69277
CW
35 <input type="checkbox" id="api4-param-{{:: name }}" ng-model="params[name]"/>
36 {{:: name }}<span class="crm-marker" ng-if="::param.required"> *</span>
e730bd39 37 </label>
4cd69277 38 <label class="form-control" ng-mouseenter="help('selectRowCount', availableParams.select)" ng-mouseleave="help()" ng-class="{'api4-option-selected': isSelectRowCount()}" ng-if="::availableParams.select">
19b53e5b 39 <input type="checkbox" id="api4-param-selectRowCount" ng-checked="isSelectRowCount()" ng-click="selectRowCount()" />
0c8e6f1e
CW
40 SelectRowCount
41 </label>
19b53e5b 42 </div>
8f38d9e9 43 <div class="api4-input form-inline" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-repeat="(name, param) in ::getGenericParams(['bool'], true)">
f28caa2c 44 <label>{{ name }}<span class="crm-marker" ng-if="::param.required"> *</span></label>
19b53e5b
C
45 <label class="radio-inline">
46 <input type="radio" ng-model="params[name]" ng-value="true" />true
47 </label>
48 <label class="radio-inline">
49 <input type="radio" ng-model="params[name]" ng-value="false" />false
50 </label>
13a3d214 51 <a href class="crm-hover-button" title="Clear" ng-click="clearParam(name)" ng-show="params[name] !== null"><i class="crm-i fa-times" aria-hidden="true"></i></a>
19b53e5b 52 </div>
292c1648 53 <fieldset class="api4-input form-inline" ng-mouseenter="help('select', availableParams.select)" ng-mouseleave="help()" ng-if="availableParams.select && !isSelectRowCount()">
4cd69277 54 <legend>select<span class="crm-marker" ng-if="::availableParams.select.required"> *</span></legend>
292c1648 55 <div ng-model="params.select" ui-sortable="{axis: 'y'}">
a26e006b 56 <div class="api4-input form-inline" ng-repeat="item in params.select track by $index">
13a3d214 57 <i class="crm-i fa-arrows" aria-hidden="true"></i>
a26e006b 58 <input class="form-control huge" type="text" ng-model="params.select[$index]" />
13a3d214 59 <a href class="crm-hover-button" title="Clear" ng-click="clearParam('select', $index)"><i class="crm-i fa-times" aria-hidden="true"></i></a>
292c1648
CW
60 </div>
61 </div>
62 <div class="api4-input form-inline">
a26e006b 63 <input class="collapsible-optgroups form-control huge" ng-model="controls.select" crm-ui-select="{data: fieldsAndJoinsAndFunctionsAndWildcards}" placeholder="Add select" />
292c1648
CW
64 </div>
65 </fieldset>
af6f5ac8 66 <fieldset id="api4-join-fieldset" class="api4-input form-inline" ng-mouseenter="help('join', availableParams.join)" ng-mouseleave="help()" ng-if="::availableParams.join">
c2d3af50 67 <legend>join<span class="crm-marker" ng-if="::availableParams.join.required"> *</span></legend>
af6f5ac8
CW
68 <div ng-model="params.join" ui-sortable="{axis: 'y', containment: '#api4-join-fieldset'}">
69 <fieldset ng-repeat="item in params.join track by $index">
70 <div class="api4-input form-inline">
71 <i class="crm-i fa-arrows"></i>
f54beb1e 72 <input class="form-control twenty" type="text" ng-model="params.join[$index][0]" ng-model-options="{updateOn: 'blur'}" ng-change="$ctrl.buildFieldList()"/>
af6f5ac8
CW
73 <select class="form-control" ng-model="params.join[$index][1]" ng-options="o.k as o.v for o in ::joinTypes" ></select>
74 <a href class="crm-hover-button" title="Clear" ng-click="clearParam('join', $index)"><i class="crm-i fa-times"></i></a>
75 </div>
76 <fieldset class="api4-clause-fieldset" crm-api4-clause="{skip: 2, clauses: params.join[$index], op: 'AND', label: 'On', fields: fieldsAndJoins, format: 'plain'}">
77 </fieldset>
78 </fieldset>
c2d3af50
CW
79 </div>
80 <div class="api4-input form-inline">
81 <input class="collapsible-optgroups form-control huge" ng-model="controls.join" crm-ui-select="{data: entities}" placeholder="Add join" />
82 </div>
83 </fieldset>
f28caa2c 84 <div class="api4-input form-inline" ng-mouseenter="help('fields', availableParams.fields)" ng-mouseleave="help()" ng-if="::availableParams.fields">
4cd69277
CW
85 <label for="api4-param-fields">fields<span class="crm-marker" ng-if="::availableParams.fields.required"> *</span></label>
86 <input class="form-control" ng-list crm-ui-select="::{data: fields, multiple: true}" id="api4-param-fields" ng-model="params.fields" style="width: 85%;"/>
19b53e5b 87 </div>
4cd69277
CW
88 <div class="api4-input form-inline" ng-mouseenter="help('action', availableParams.action)" ng-mouseleave="help()"ng-if="::availableParams.action">
89 <label for="api4-param-action">action<span class="crm-marker" ng-if="::availableParams.action.required"> *</span></label>
19b53e5b
C
90 <input class="form-control" crm-ui-select="{data: actions, allowClear: true, placeholder: 'None'}" id="api4-param-action" ng-model="params.action"/>
91 </div>
8f38d9e9 92 <div class="api4-input form-inline" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-repeat="(name, param) in ::getGenericParams(['string', 'int'])">
4cd69277
CW
93 <label for="api4-param-{{:: name }}">{{:: name }}<span class="crm-marker" ng-if="::param.required"> *</span></label>
94 <input class="form-control" ng-if="::!param.options" type="{{:: param.type[0] === 'int' && param.type.length === 1 ? 'number' : 'text' }}" id="api4-param-{{:: name }}" ng-model="params[name]"/>
95 <select class="form-control" ng-if="::param.options" ng-options="o for o in ::param.options" id="api4-param-{{:: name }}" ng-model="params[name]"></select>
13a3d214 96 <a href class="crm-hover-button" title="Clear" ng-click="clearParam(name)" ng-show="!!params[name]"><i class="crm-i fa-times" aria-hidden="true"></i></a>
19b53e5b 97 </div>
8f38d9e9 98 <div class="api4-input" ng-mouseenter="help(name, param)" ng-mouseleave="help()" ng-repeat="(name, param) in ::getGenericParams(['array', 'mixed'])">
4cd69277
CW
99 <label for="api4-param-{{:: name }}">{{:: name }}<span class="crm-marker" ng-if="::param.required"> *</span></label>
100 <textarea class="form-control" type="{{:: param.type[0] === 'int' && param.type.length === 1 ? 'number' : 'text' }}" id="api4-param-{{:: name }}" ng-model="params[name]">
19b53e5b
C
101 </textarea>
102 </div>
af6f5ac8 103 <fieldset ng-if="::availableParams.where" class="api4-clause-fieldset" ng-mouseenter="help('where', availableParams.where)" ng-mouseleave="help()" crm-api4-clause="{type: 'where', clauses: params.where, required: availableParams.where.required, op: 'AND', label: 'Where', fields: fieldsAndJoins}">
19b53e5b 104 </fieldset>
4cd69277 105 <fieldset ng-repeat="name in ['values', 'defaults']" ng-if="::availableParams[name]" ng-mouseenter="help(name, availableParams[name])" ng-mouseleave="help()">
f28caa2c 106 <legend>{{:: name }}<span class="crm-marker" ng-if="::availableParams[name].required"> *</span></legend>
bb3786d2 107 <div class="api4-input form-inline" ng-repeat="clause in params[name]" ng-mouseenter="help('value: ' + clause[0], fieldHelp(clause[0]))" ng-mouseleave="help(name, availableParams[name])">
37d82abe 108 <input class="collapsible-optgroups form-control twenty" ng-model="clause[0]" crm-ui-select="{formatResult: formatSelect2Item, formatSelection: formatSelect2Item, data: fieldList(name), allowClear: true, placeholder: 'Field'}" />
c752d94b 109 <input class="form-control" ng-model="clause[1]" api4-exp-value="{field: clause[0], action: action === 'getFields' ? params.action || 'get' : action}" />
19b53e5b
C
110 </div>
111 <div class="api4-input form-inline">
37d82abe 112 <input class="collapsible-optgroups form-control twenty" ng-model="controls[name]" crm-ui-select="{formatResult: formatSelect2Item, formatSelection: formatSelect2Item, data: fieldList(name), placeholder: ts('Add %1', {1: name.slice(0, -1)})}"/>
19b53e5b 113 </div>
b578f063 114 </fieldset>
f0acec37
CW
115 <fieldset ng-if="::availableParams.groupBy" ng-mouseenter="help('groupBy', availableParams.groupBy)" ng-mouseleave="help()">
116 <legend>groupBy<span class="crm-marker" ng-if="::availableParams.groupBy.required"> *</span></legend>
117 <div ng-model="params.groupBy" ui-sortable="{axis: 'y'}">
118 <div class="api4-input form-inline" ng-repeat="item in params.groupBy track by $index">
13a3d214 119 <i class="crm-i fa-arrows" aria-hidden="true"></i>
f0acec37 120 <input class="form-control huge" type="text" ng-model="params.groupBy[$index]" />
13a3d214 121 <a href class="crm-hover-button" title="Clear" ng-click="clearParam('groupBy', $index)"><i class="crm-i fa-times" aria-hidden="true"></i></a>
f0acec37
CW
122 </div>
123 </div>
124 <div class="api4-input form-inline">
125 <input class="collapsible-optgroups form-control huge" ng-model="controls.groupBy" crm-ui-select="{data: fieldsAndJoinsAndFunctions}" placeholder="Add groupBy" />
126 </div>
127 </fieldset>
af6f5ac8 128 <fieldset ng-if="::availableParams.having" class="api4-clause-fieldset" ng-mouseenter="help('having', availableParams.having)" ng-mouseleave="help()" crm-api4-clause="{clauses: params.having, required: availableParams.having.required, op: 'AND', label: 'Having', fields: havingOptions}">
f0acec37
CW
129 </fieldset>
130 <fieldset ng-if="::availableParams.orderBy" ng-mouseenter="help('orderBy', availableParams.orderBy)" ng-mouseleave="help()">
131 <legend>orderBy<span class="crm-marker" ng-if="::availableParams.orderBy.required"> *</span></legend>
132 <div ng-model="params.orderBy" ui-sortable="{axis: 'y'}">
133 <div class="api4-input form-inline" ng-repeat="clause in params.orderBy">
13a3d214 134 <i class="crm-i fa-arrows" aria-hidden="true"></i>
f0acec37
CW
135 <input class="form-control huge" type="text" ng-model="clause[0]" />
136 <select class="form-control" ng-model="clause[1]">
137 <option value="ASC">ASC</option>
138 <option value="DESC">DESC</option>
139 </select>
13a3d214 140 <a href class="crm-hover-button" title="Clear" ng-click="clearParam('orderBy', $index)"><i class="crm-i fa-times" aria-hidden="true"></i></a>
f0acec37 141 </div>
19b53e5b
C
142 </div>
143 <div class="api4-input form-inline">
a4499ec5 144 <input class="collapsible-optgroups form-control huge" ng-model="controls.orderBy" crm-ui-select="{data: fieldsAndJoinsAndFunctionsWithSuffixes}" placeholder="Add orderBy" />
19b53e5b
C
145 </div>
146 </fieldset>
f0acec37
CW
147 <fieldset ng-if="::availableParams.limit && availableParams.offset">
148 <div class="api4-input form-inline">
149 <span ng-mouseenter="help('limit', availableParams.limit)" ng-mouseleave="help()">
150 <label for="api4-param-limit">limit<span class="crm-marker" ng-if="::availableParams.limit.required"> *</span></label>
151 <input class="form-control" type="number" min="0" id="api4-param-limit" ng-model="params.limit"/>
152 </span>
153 <span ng-mouseenter="help('offset', availableParams.offset)" ng-mouseleave="help()">
154 <label for="api4-param-offset">offset<span class="crm-marker" ng-if="::availableParams.offset.required"> *</span></label>
155 <input class="form-control" type="number" min="0" id="api4-param-offset" ng-model="params.offset"/>
156 </span>
13a3d214 157 <a href class="crm-hover-button" title="Clear" ng-click="clearParam('limit');clearParam('offset');" ng-show="!!params.limit || !!params.offset"><i class="crm-i fa-times" aria-hidden="true"></i></a>
f0acec37
CW
158 </div>
159 </fieldset>
160 <fieldset ng-if="::availableParams.chain" ng-mouseenter="help('chain', availableParams.chain)" ng-mouseleave="help()">
19b53e5b 161 <legend>chain</legend>
4cd69277 162 <div class="api4-input form-inline" ng-repeat="clause in params.chain" api4-exp-chain="clause" entities="::entities" main-entity="::entity" >
19b53e5b
C
163 </div>
164 <div class="api4-input form-inline">
4cd69277 165 <input class="form-control" ng-model="controls.chain" crm-ui-select="::{data: entities}" placeholder="Add chain" />
19b53e5b
C
166 </div>
167 </fieldset>
168 </div>
169 </form>
170 <div class="panel panel-info explorer-help-panel">
171 <div class="panel-heading">
172 <h3 class="panel-title" crm-icon="fa-info-circle">{{ helpTitle }}</h3>
173 </div>
174 <div class="panel-body">
136ca5bb
CW
175 <h4 ng-bind-html="helpContent.description"></h4>
176 <div ng-bind-html="helpContent.comment"></div>
0493ec47 177 <p ng-repeat="(key, item) in helpContent" ng-if="key !== 'description' && key !== 'comment' && key !== 'see'">
19b53e5b
C
178 <strong>{{ key }}:</strong> {{ item }}
179 </p>
0493ec47
CW
180 <div ng-if="helpContent.see">
181 <strong>See:</strong>
182 <ul>
fc95d9a5 183 <li ng-repeat="ref in helpContent.see" ng-bind-html="ref"> </li>
0493ec47
CW
184 </ul>
185 </div>
19b53e5b
C
186 </div>
187 </div>
188 </div>
189 <div class="api4-explorer-row">
2aafb0fc 190 <div class="panel panel-info explorer-code-panel">
19d01932 191 <ul class="panel-heading nav nav-tabs">
f28caa2c
CW
192 <li role="presentation" ng-repeat="lang in ::langs" ng-class="{active: selectedTab.code === lang}">
193 <a href ng-click="selectLang(lang)">
194 {{:: lang }}
19d01932
CW
195 </a>
196 </li>
197 </ul>
19b53e5b 198 <div class="panel-body">
f28caa2c
CW
199 <table>
200 <tr ng-repeat="style in code[selectedTab.code]">
201 <td>{{:: style.label }}</td>
19d01932 202 <td><pre class="prettyprint" ng-bind-html="style.code"></pre></td>
19b53e5b
C
203 </tr>
204 </table>
205 </div>
206 </div>
207 <div class="panel explorer-result-panel panel-{{ status }}" >
b65fa6dc 208 <ul class="panel-heading nav nav-tabs">
19d01932
CW
209 <li role="presentation" ng-class="{active: selectedTab.result === 'result'}">
210 <a href ng-click="selectedTab.result = 'result'">
f28caa2c
CW
211 <span ng-switch="status">
212 <i class="fa fa-fw fa-circle-o" ng-switch-when="default"></i>
213 <i class="fa fa-fw fa-check-circle" ng-switch-when="success"></i>
2aafb0fc 214 <i class="fa fa-fw fa-check-circle" ng-switch-when="warning"></i>
f28caa2c 215 <i class="fa fa-fw fa-minus-circle" ng-switch-when="danger"></i>
2aafb0fc 216 <i class="fa fa-fw fa-spinner fa-pulse" ng-switch-when="info"></i>
f28caa2c 217 </span>
f9c5f498 218 <span>{{:: ts('Result') }}</span>
b65fa6dc
CW
219 </a>
220 </li>
4cd69277 221 <li role="presentation" ng-if="::perm.accessDebugOutput" ng-class="{active: selectedTab.result === 'debug'}">
19d01932 222 <a href ng-click="selectedTab.result = 'debug'">
2aafb0fc 223 <i class="fa fa-fw fa-{{ debug ? (status === 'warning' || status === 'danger' ? 'warning' : 'bug') : 'circle-o' }}"></i>
f9c5f498 224 <span>{{:: ts('Debug') }}</span>
b65fa6dc
CW
225 </a>
226 </li>
227 </ul>
19b53e5b 228 <div class="panel-body">
19d01932 229 <div ng-show="selectedTab.result === 'result'">
b65fa6dc
CW
230 <pre class="prettyprint" ng-repeat="code in result" ng-bind-html="code"></pre>
231 </div>
4cd69277 232 <div ng-if="::perm.accessDebugOutput" ng-show="selectedTab.result === 'debug'">
b65fa6dc 233 <pre ng-if="debug" class="prettyprint" ng-bind-html="debug"></pre>
f28caa2c
CW
234 <div ng-if="!debug">
235 <p>
236 {{:: ts('To view debugging output, enable the debug param before executing.') }}
237 </p>
238 <p>
239 {{:: ts('Enable backtrace in system settings to see error backtraces.') }}
240 </p>
241 </div>
b65fa6dc 242 </div>
19b53e5b
C
243 </div>
244 </div>
245 </div>
19b53e5b 246</div>