Adds a predefined "Panel Pane" style, for creating dashboards.
'element' => [
'#tag' => 'fieldset',
'af-fieldset' => NULL,
+ 'class' => 'af-container',
'af-title' => E::ts('Enter title'),
'#children' => [],
],
margin-top: 10px;
}
+/* Card style */
+#afGuiEditor .af-gui-container.af-container-style-pane {
+ box-shadow: 1px 2px 8px 1px rgb(0, 0, 0, .3);
+ background: linear-gradient(to bottom, #f2f2f2 0 22px, transparent 22px 100%) no-repeat;
+ border-radius: 4px;
+}
+
#afGuiEditor af-gui-container,
#afGuiEditor af-gui-markup,
#afGuiEditor af-gui-field,
--- /dev/null
+// https://civicrm.org/licensing
+(function(angular, $, _) {
+ "use strict";
+
+ // Menu item to control the border property of a node
+ angular.module('afGuiEditor').component('afGuiMenuItemStyle', {
+ templateUrl: '~/afGuiEditor/afGuiMenuItemStyle.html',
+ bindings: {
+ node: '='
+ },
+ controller: function($scope, afGui) {
+ var ts = $scope.ts = CRM.ts('org.civicrm.afform_admin'),
+ ctrl = this;
+
+ // Todo: Make this an option group so other extensions can add to it
+ this.styles = [
+ {name: 'af-container-style-pane', label: ts('Panel Pane')}
+ ];
+
+ $scope.getSetStyle = function(style) {
+ var options = _.map(ctrl.styles, 'name');
+ if (arguments.length) {
+ afGui.modifyClasses(ctrl.node, options, style);
+ }
+ return _.intersection(afGui.splitClass(ctrl.node['class']), options)[0] || '';
+ };
+
+ }
+ });
+
+})(angular, CRM.$, CRM._);
--- /dev/null
+<div class="af-gui-field-select-in-dropdown form-inline" ng-click="$event.stopPropagation()">
+ <label>{{:: ts('Style:') }}</label>
+ <select class="form-control" ng-model="getSetStyle" ng-model-options="{getterSetter: true}">
+ <option value="">{{:: ts('None') }}</option>
+ <option ng-repeat="style in $ctrl.styles" value="{{:: style.name }}">{{:: style.label }}</option>
+ </select>
+</div>
</div>
</li>
<li><af-gui-menu-item-collapsible ng-if="!block" node="$ctrl.node" class="af-gui-field-select-in-dropdown form-inline"></af-gui-menu-item-collapsible></li>
+<li><af-gui-menu-item-style node="$ctrl.node"></af-gui-menu-item-style></li>
<li><af-gui-menu-item-border node="$ctrl.node"></af-gui-menu-item-border></li>
<li><af-gui-menu-item-background node="$ctrl.node"></af-gui-menu-item-background></li>
<li role="separator" class="divider"></li>
<div ng-if="!$ctrl.loading" ui-sortable="$ctrl.sortableOptions" ui-sortable-update="$ctrl.editor.onDrop" ng-model="getSetChildren" ng-model-options="{getterSetter: true}" class="af-gui-layout {{ getLayout() }}">
<div ng-repeat="item in getSetChildren()" >
<div ng-switch="$ctrl.getNodeType(item)">
- <af-gui-container ng-switch-when="fieldset" node="item" delete-this="$ctrl.removeElement(item)" style="{{ item.style }}" class="af-gui-container af-gui-fieldset af-gui-container-type-{{ item['#tag'] }}" ng-class="{'af-entity-selected': isSelectedFieldset(item['af-fieldset'])}" entity-name="item['af-fieldset']" data-entity="{{ item['af-fieldset'] }}" ></af-gui-container>
- <af-gui-container ng-switch-when="container" node="item" delete-this="$ctrl.removeElement(item)" style="{{ item.style }}" class="af-gui-container af-gui-container-type-{{ item['#tag'] }}" entity-name="$ctrl.entityName" data-entity="{{ $ctrl.getDataEntity() }}" ></af-gui-container>
+ <af-gui-container ng-switch-when="fieldset" node="item" delete-this="$ctrl.removeElement(item)" style="{{ item.style }}" class="af-gui-container af-gui-fieldset af-gui-container-type-{{ item['#tag'] + ' ' + item['class'] }}" ng-class="{'af-entity-selected': isSelectedFieldset(item['af-fieldset'])}" entity-name="item['af-fieldset']" data-entity="{{ item['af-fieldset'] }}" ></af-gui-container>
+ <af-gui-container ng-switch-when="container" node="item" delete-this="$ctrl.removeElement(item)" style="{{ item.style }}" class="af-gui-container af-gui-container-type-{{ item['#tag'] + ' ' + item['class'] }}" entity-name="$ctrl.entityName" data-entity="{{ $ctrl.getDataEntity() }}" ></af-gui-container>
<af-gui-container ng-switch-when="join" node="item" delete-this="$ctrl.removeElement(item)" style="{{ item.style }}" class="af-gui-container" join="item['af-join']" entity-name="$ctrl.entityName + '-join-' + item['af-join']" data-entity="{{ $ctrl.entityName + '-join-' + item['af-join'] }}" ></af-gui-container>
<af-gui-field ng-switch-when="field" node="item" delete-this="$ctrl.removeElement(item)" ></af-gui-field>
<af-gui-text ng-switch-when="text" node="item" delete-this="$ctrl.removeElement(item)" class="af-gui-element af-gui-text" ></af-gui-text>
<af-gui-markup ng-switch-when="markup" node="item" delete-this="$ctrl.removeElement(item)" class="af-gui-markup" ></af-gui-markup>
<af-gui-button ng-switch-when="button" node="item" delete-this="$ctrl.removeElement(item)" class="af-gui-element af-gui-button" ></af-gui-button>
- <af-gui-container ng-switch-when="searchFieldset" node="item" delete-this="$ctrl.removeElement(item)" style="{{ item.style }}" class="af-gui-container af-gui-fieldset af-gui-container-type-{{ item['#tag'] }}" ng-class="{'af-entity-selected': isSelectedSearchFieldset(item)}" data-entity="{{ getSearchKey(item) }}" ></af-gui-container>
+ <af-gui-container ng-switch-when="searchFieldset" node="item" delete-this="$ctrl.removeElement(item)" style="{{ item.style }}" class="af-gui-container af-gui-fieldset af-gui-container-type-{{ item['#tag'] + ' ' + item['class'] }}" ng-class="{'af-entity-selected': isSelectedSearchFieldset(item)}" data-entity="{{ getSearchKey(item) }}" ></af-gui-container>
<af-gui-search-display ng-switch-when="searchDisplay" node="item" class="af-gui-element"></af-gui-search-display>
</div>
</div>
</div>
</li>
<li><af-gui-menu-item-collapsible node="$ctrl.node" class="af-gui-field-select-in-dropdown form-inline"></af-gui-menu-item-collapsible></li>
+<li><af-gui-menu-item-style node="$ctrl.node"></af-gui-menu-item-style></li>
<li><af-gui-menu-item-border node="$ctrl.node"></af-gui-menu-item-border></li>
<li><af-gui-menu-item-background node="$ctrl.node"></af-gui-menu-item-background></li>
<li role="separator" class="divider"></li>
.af-container.af-layout-cols {
display: flex;
+ flex-wrap: wrap;
}
.af-container.af-layout-cols > * {
flex: 1;
margin-right: .5em;
vertical-align: top;
}
+.af-container.af-layout-cols > .af-title {
+ flex: 0 0 100%;
+}
+.af-container.af-layout-inline > .af-title {
+ display: block;
+ width: 100%;
+}
+
af-form {
display: block;
}
.af-collapsible.af-collapsed > .af-title + * {
display: none;
}
+
+/* Card style */
+#bootstrap-theme .af-container-style-pane {
+ background-color: white;
+ border-radius: 4px;
+ box-shadow: 1px 2px 8px 1px rgba(0, 0, 0, 0.3);
+ margin: 10px;
+ padding: 5px;
+}
+#bootstrap-theme .af-container-style-pane > .af-title {
+ background-color: #70716b;
+ color: white;
+ padding: 5px;
+ border-radius: 4px 4px 0 0;
+ position: relative;
+ top: -5px;
+ left: -5px;
+ width: calc(100% + 10px);
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+#bootstrap-theme .af-container-style-pane.af-collapsed > .af-title {
+ margin-bottom: 0;
+}