summaryrefslogtreecommitdiff
path: root/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn
diff options
context:
space:
mode:
Diffstat (limited to 'www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn')
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AboutCtrl.html14
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AboutCtrl.js5
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AdvTable.html18
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AdvTable.js20
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/CheckAddress.js33
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmConnectCtrl.html15
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmConnectCtrl.js5
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmReconnectCtrl.html23
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmReconnectCtrl.js5
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/Connectivity.html4
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/LinkDialogCtrl.html3
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/LinkDialogCtrl.js11
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ManageCtrl.html120
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ManageCtrl.js153
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/PermTable.html42
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/PermTable.js27
16 files changed, 498 insertions, 0 deletions
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AboutCtrl.html b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AboutCtrl.html
new file mode 100644
index 00000000..8757449d
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AboutCtrl.html
@@ -0,0 +1,14 @@
+<div ng-controller="CrmCxnConfirmAboutCtrl">
+ <div crm-ui-accordion="{title: ts('About'), collapsed: false}">
+ <div ng-bind-html="appMeta.desc"></div>
+ </div>
+ <div crm-ui-accordion="{title: ts('Permissions: Summary'), collapsed: true}">
+ <div ng-bind-html="appMeta.perm.desc"></div>
+ </div>
+ <div crm-ui-accordion="{title: ts('Permissions: Details'), collapsed: true}">
+ <div crm-cxn-perm-table="{perm: appMeta.perm}"></div>
+ </div>
+ <div crm-ui-accordion="{title: ts('Advanced'), collapsed: true}">
+ <div crm-cxn-adv-table="{appMeta: appMeta}"></div>
+ </div>
+</div>
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AboutCtrl.js b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AboutCtrl.js
new file mode 100644
index 00000000..f9b9491e
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AboutCtrl.js
@@ -0,0 +1,5 @@
+(function(angular, $, _) {
+ angular.module('crmCxn').controller('CrmCxnConfirmAboutCtrl', function($scope) {
+ $scope.ts = CRM.ts(null);
+ });
+})(angular, CRM.$, CRM._);
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AdvTable.html b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AdvTable.html
new file mode 100644
index 00000000..7080fdd7
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AdvTable.html
@@ -0,0 +1,18 @@
+<table>
+ <thead>
+ <tr>
+ <th>{{ts('Property')}}</th>
+ <th>{{ts('Value')}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr class="odd-row odd">
+ <td>App ID</td>
+ <td>{{appMeta.appId}}</td>
+ </tr>
+ <tr class="even-row even">
+ <td>App URL</td>
+ <td><code>{{appMeta.appUrl}}</code></td>
+ </tr>
+ </tbody>
+</table>
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AdvTable.js b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AdvTable.js
new file mode 100644
index 00000000..3ea2bc39
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/AdvTable.js
@@ -0,0 +1,20 @@
+(function(angular, $, _) {
+
+ // This directive formats the data in appMeta as a nice table.
+ // example: <div crm-cxn-perm-table="{appMeta: cxn.app_meta}"></div>
+ angular.module('crmCxn').directive('crmCxnAdvTable', function crmCxnAdvTable() {
+ return {
+ restrict: 'EA',
+ scope: {
+ crmCxnAdvTable: '='
+ },
+ templateUrl: '~/crmCxn/AdvTable.html',
+ link: function(scope, element, attrs) {
+ scope.ts = CRM.ts(null);
+ scope.$watch('crmCxnAdvTable', function(crmCxnAdvTable){
+ scope.appMeta = crmCxnAdvTable.appMeta;
+ });
+ }
+ };
+ });
+})(angular, CRM.$, CRM._);
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/CheckAddress.js b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/CheckAddress.js
new file mode 100644
index 00000000..2313ddd0
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/CheckAddress.js
@@ -0,0 +1,33 @@
+(function (angular, $, _) {
+
+ angular.module('crmCxn').factory('crmCxnCheckAddr', function($q, $timeout) {
+ var TIMEOUT = 6000, CHECK_ADDR = 'https://mycivi.org/check-addr';
+ return function(url) {
+ var dfr = $q.defer(), result = null;
+
+ function onErr() {
+ if (result !== null) return;
+ result = {url: url, valid: false};
+ dfr.resolve(result);
+ }
+
+ $.ajax({
+ url: CHECK_ADDR,
+ data: {url: url},
+ jsonp: "callback",
+ dataType: "jsonp"
+ }).fail(onErr)
+ .done(function(response) {
+ if (result !== null) return;
+ result = {url: url, valid: response.result};
+ dfr.resolve(result);
+ }
+ );
+ // JSONP may not provide errors directly.
+ $timeout(onErr, TIMEOUT);
+
+ return dfr.promise;
+ };
+ });
+
+})(angular, CRM.$, CRM._);
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmConnectCtrl.html b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmConnectCtrl.html
new file mode 100644
index 00000000..eadee337
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmConnectCtrl.html
@@ -0,0 +1,15 @@
+<div ng-controller="CrmCxnConfirmConnectCtrl">
+ <p>{{ts('The application, \"%1\", requests permission to access your system.', {1: appMeta.title})}}</p>
+ <div crm-ui-accordion="{title: ts('About'), collapsed: true}">
+ <div ng-bind-html="appMeta.desc"></div>
+ </div>
+ <div crm-ui-accordion="{title: ts('Permissions: Summary'), collapsed: true}">
+ <div ng-bind-html="appMeta.perm.desc"></div>
+ </div>
+ <div crm-ui-accordion="{title: ts('Permissions: Details'), collapsed: true}">
+ <div crm-cxn-perm-table="{perm: appMeta.perm}"></div>
+ </div>
+ <div crm-ui-accordion="{title: ts('Advanced'), collapsed: true}">
+ <div crm-cxn-adv-table="{appMeta: appMeta}"></div>
+ </div>
+</div>
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmConnectCtrl.js b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmConnectCtrl.js
new file mode 100644
index 00000000..c303d5e9
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmConnectCtrl.js
@@ -0,0 +1,5 @@
+(function(angular, $, _) {
+ angular.module('crmCxn').controller('CrmCxnConfirmConnectCtrl', function($scope) {
+ $scope.ts = CRM.ts(null);
+ });
+})(angular, CRM.$, CRM._);
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmReconnectCtrl.html b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmReconnectCtrl.html
new file mode 100644
index 00000000..0b60bd87
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmReconnectCtrl.html
@@ -0,0 +1,23 @@
+<div ng-controller="CrmCxnConfirmReconnectCtrl">
+ <p>{{ts('Are you sure you want to reconnect \"%1\"?', {1: appMeta.title})}}</p>
+
+ <p>{{ts('Reconnecting will change the connection details (such as callback URLs and permissions). This can be useful in a few cases, such as:')}}</p>
+
+ <ul>
+ <li>{{ts('After your site has migrated to a new URL.')}}</li>
+ <li>{{ts('After the application has migrated to a new URL.')}}</li>
+ <li>{{ts('After the application has changed permission requirements.')}}</li>
+ <li>{{ts('After the application has a major failure or reset.')}}</li>
+ </ul>
+
+ <div crm-ui-accordion="{title: ts('Permissions: Summary'), collapsed: true}">
+ <div ng-bind-html="appMeta.perm.desc"></div>
+ </div>
+ <div crm-ui-accordion="{title: ts('Permissions: Details'), collapsed: true}">
+ <div crm-cxn-perm-table="{perm: appMeta.perm}"></div>
+ </div>
+ <div crm-ui-accordion="{title: ts('Advanced'), collapsed: true}">
+ <div crm-cxn-adv-table="{appMeta: appMeta}"></div>
+ </div>
+
+</div>
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmReconnectCtrl.js b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmReconnectCtrl.js
new file mode 100644
index 00000000..211d415d
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ConfirmReconnectCtrl.js
@@ -0,0 +1,5 @@
+(function(angular, $, _) {
+ angular.module('crmCxn').controller('CrmCxnConfirmReconnectCtrl', function($scope) {
+ $scope.ts = CRM.ts(null);
+ });
+})(angular, CRM.$, CRM._);
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/Connectivity.html b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/Connectivity.html
new file mode 100644
index 00000000..e8a14d8a
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/Connectivity.html
@@ -0,0 +1,4 @@
+<p>{{ts('There was a problem verifying that this site is available on the public Internet.')}}</p>
+<p>{{ts('See also:')}}
+ <a href="https://civicrm.org/inapp/civiconnect-firewall" target="_blank">{{ts('Firewalls and Proxies')}}</a>
+</p> \ No newline at end of file
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/LinkDialogCtrl.html b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/LinkDialogCtrl.html
new file mode 100644
index 00000000..ad656409
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/LinkDialogCtrl.html
@@ -0,0 +1,3 @@
+<div ng-controller="CrmCxnLinkDialogCtrl">
+ <iframe crm-ui-iframe crm-ui-iframe-src="model.url"></iframe>
+</div>
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/LinkDialogCtrl.js b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/LinkDialogCtrl.js
new file mode 100644
index 00000000..d1672d83
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/LinkDialogCtrl.js
@@ -0,0 +1,11 @@
+(function(angular, $, _) {
+
+ // Controller for the "Open Link" dialog
+ // Scope members:
+ // - [input] "model": Object
+ // - "url": string
+ angular.module('crmCxn').controller('CrmCxnLinkDialogCtrl', function CrmCxnLinkDialogCtrl($scope, dialogService) {
+ var ts = $scope.ts = CRM.ts(null);
+ });
+
+})(angular, CRM.$, CRM._);
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ManageCtrl.html b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ManageCtrl.html
new file mode 100644
index 00000000..891942e6
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ManageCtrl.html
@@ -0,0 +1,120 @@
+<div crm-ui-debug="appMetas"></div>
+<div crm-ui-debug="cxns"></div>
+<div crm-ui-debug="alerts"></div>
+
+<!--
+ The merits of this layout:
+ * On a fresh install, the available connections show up first.
+ * Once you've made a connection, the extant connections bubble up.
+ * Extant connections can be portrayed as enabled or disabled.
+-->
+
+<div class="help">
+ <p>{{ts('Connections provide a simplified way to link your CiviCRM installation to an external service.')}}</p>
+</div>
+
+<div ng-show="cxns.length > 0">
+ <span crm-ui-order="{var: 'cxnOrder', defaults: ['-created_date']}"></span>
+ <h3>{{ts('Existing Connections')}}</h3>
+ <table class="display">
+ <thead>
+ <tr>
+ <th>{{ts('Title')}}</th> <!-- <a crm-ui-order-by="[cxnOrder, 'app_meta.appId']"> -->
+ <th>{{ts('Description')}}</th> <!-- <a crm-ui-order-by="[cxnOrder, 'desc']"> -->
+ <th>{{ts('Status')}}</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="cxn in cxns | orderBy:cxnOrder.get()" ng-class-even="'even-row even'" ng-class-odd="'odd-row odd'">
+ <td>
+ <a class="action-item"
+ crm-confirm='{width: "65%", resizable: true, title:ts("%1: About", {1: cxn.app_meta.title}), templateUrl: "~/crmCxn/AboutCtrl.html", export: {appMeta: cxn.app_meta}}'
+ >{{cxn.app_meta.title}}</a>
+ </td>
+ <td><div ng-bind-html="cxn.app_meta.desc"></div></td>
+ <td>{{cxn.is_active=="1" ? ts('Enabled') : ts('Disabled')}}</td>
+ <td>
+ <span>
+ <a class="action-item crm-hover-button" ng-click="openLink(cxn.app_meta, 'settings', {title: ts('%1: Settings (External)', {1: cxn.app_meta.title})})" ng-show="cxn.app_meta.links.settings">{{ts('Settings')}}</a>
+ <span class="btn-slide crm-hover-button">{{ts('more')}}
+ <ul class="panel" style="display: none;">
+ <li ng-show="cxn.app_meta.links.logs">
+ <a class="action-item crm-hover-button" ng-click="openLink(cxn.app_meta, 'logs', {title: ts('%1: Logs (External)', {1: cxn.app_meta.title})})">
+ {{ts('Logs')}}
+ </a>
+ </li>
+ <li ng-show="cxn.app_meta.links.docs">
+ <a class="action-item crm-hover-button" ng-click="openLink(cxn.app_meta, 'docs', {title: ts('%1: Documentation (External)', {1: cxn.app_meta.title})})">
+ {{ts('Docs')}}
+ </a>
+ </li>
+ <li ng-show="cxn.app_meta.links.support">
+ <a class="action-item crm-hover-button" ng-click="openLink(cxn.app_meta, 'support', {title: ts('%1: Support (External)', {1: cxn.app_meta.title})})">
+ {{ts('Support')}}
+ </a>
+ </li>
+ <li>
+ <a class="action-item crm-hover-button" ng-click="toggleCxn(cxn)">{{ cxn.is_active=="1" ? ts('Disable') : ts('Enable')}}</a>
+ </li>
+ <li>
+ <a class="action-item crm-hover-button"
+ crm-confirm='{width: "65%", resizable: true, title:ts("%1: Reconnect", {1: cxn.app_meta.title}), templateUrl: "~/crmCxn/ConfirmReconnectCtrl.html", export: {cxn: cxn, appMeta: findAppByAppId(cxn.app_guid)}}'
+ on-yes="reregister(cxn.app_meta)"
+ >{{ts('Reconnect')}}</a>
+ </li>
+ <li>
+ <a class="action-item crm-hover-button"
+ crm-confirm='{width: "65%", resizable: true, title: ts("%1: Disconnect", {1: cxn.app_meta.title}), message: ts("Are you sure you want to disconnect \"%1?\". Doing so may permanently destroy data linkage.", {1: cxn.app_meta.title})}'
+ on-yes="unregister(cxn.app_meta)">
+ {{ts('Disconnect')}}
+ </a>
+ </li>
+ </ul>
+ </span>
+
+ </span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <br/>
+</div>
+
+<div ng-show="hasAvailApps()">
+ <span crm-ui-order="{var: 'availOrder', defaults: ['title']}"></span>
+
+<div class="crm-content-block crm-block crm-connection-block">
+ <h3>{{ts('New Connections')}}</h3>
+ <table class="display">
+ <thead>
+ <tr>
+ <th><a crm-ui-order-by="[availOrder, 'title']">{{ts('Title')}}</a></th>
+ <th><a crm-ui-order-by="[availOrder, 'desc']">{{ts('Description')}}</a></th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="appMeta in appMetas | orderBy:availOrder.get()" ng-show="!findCxnByAppId(appMeta.appId)" ng-class-even="'even-row even'" ng-class-odd="'odd-row odd'">
+ <td>
+ <a crm-confirm='{width: "65%", resizable: true, title:ts("%1: About", {1: appMeta.title}), templateUrl: "~/crmCxn/AboutCtrl.html", export: {appMeta: appMeta}}'
+ >{{appMeta.title}}</a>
+ </td>
+ <td><div ng-bind-html="appMeta.desc"></div></td>
+ <td>
+ <a class="action-item crm-hover-button"
+ crm-confirm='{width: "65%", resizable: true, title:ts("%1: Connect", {1: appMeta.title}), templateUrl: "~/crmCxn/ConfirmConnectCtrl.html", export: {appMeta: appMeta}}'
+ on-yes="register(appMeta)"
+ >{{ts('Connect')}}</a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+
+</div>
+
+<div ng-show="appMetas.length === 0" class="messages status no-popup">
+ <i class="crm-i fa-info-circle"></i>
+ {{ts('No available applications')}}
+</div>
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ManageCtrl.js b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ManageCtrl.js
new file mode 100644
index 00000000..cd843c33
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/ManageCtrl.js
@@ -0,0 +1,153 @@
+(function(angular, $, _) {
+
+ angular.module('crmCxn').controller('CrmCxnManageCtrl', function CrmCxnManageCtrl($scope, apiCalls, crmApi, crmUiAlert, crmBlocker, crmStatus, $timeout, dialogService, crmCxnCheckAddr) {
+ var ts = $scope.ts = CRM.ts(null);
+ if (apiCalls.appMetas.is_error) {
+ $scope.appMetas = [];
+ CRM.alert(apiCalls.appMetas.error_message, ts('Application List Unavailable'), 'error');
+ }
+ else {
+ $scope.appMetas = apiCalls.appMetas.values;
+ }
+ $scope.cxns = apiCalls.cxns.values;
+ $scope.alerts = _.where(apiCalls.sysCheck.values, {name: 'checkCxnOverrides'});
+
+ crmCxnCheckAddr(apiCalls.cfg.values.siteCallbackUrl).then(function(response) {
+ if (response.valid) return;
+ crmUiAlert({
+ type: 'warning',
+ title: ts('Internet Access Required'),
+ templateUrl: '~/crmCxn/Connectivity.html',
+ scope: $scope.$new(),
+ options: {expires: false}
+ });
+ });
+
+ $scope.filter = {};
+ var block = $scope.block = crmBlocker();
+
+ _.each($scope.alerts, function(alert){
+ crmUiAlert({text: alert.message, title: alert.title, type: 'error'});
+ });
+
+ // Convert array [x] to x|null|error
+ function asOne(result, msg) {
+ switch (result.length) {
+ case 0:
+ return null;
+ case 1:
+ return result[0];
+ default:
+ throw msg;
+ }
+ }
+
+ $scope.findCxnByAppId = function(appId) {
+ var result = _.where($scope.cxns, {
+ app_guid: appId
+ });
+ return asOne(result, "Error: Too many connections for appId: " + appId);
+ };
+
+ $scope.findAppByAppId = function(appId) {
+ var result = _.where($scope.appMetas, {
+ appId: appId
+ });
+ return asOne(result, "Error: Too many apps for appId: " + appId);
+ };
+
+ $scope.hasAvailApps = function() {
+ // This should usu return after the 1st or 2nd item, but in testing with small# apps, we may exhaust the list.
+ for (var i = 0; i< $scope.appMetas.length; i++) {
+ if (!$scope.findCxnByAppId($scope.appMetas[i].appId)) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ $scope.refreshCxns = function() {
+ crmApi('Cxn', 'get', {sequential: 1}).then(function(result) {
+ $timeout(function(){
+ $scope.cxns = result.values;
+ });
+ });
+ };
+
+ $scope.register = function(appMeta) {
+ var reg = crmApi('Cxn', 'register', {app_guid: appMeta.appId}).then($scope.refreshCxns).then(function() {
+ if (appMeta.links.welcome) {
+ return $scope.openLink(appMeta, 'welcome', {title: ts('%1: Welcome (External)', {1: appMeta.title})});
+ }
+ });
+ return block(crmStatus({start: ts('Connecting...'), success: ts('Connected')}, reg));
+ };
+
+ $scope.reregister = function(appMeta) {
+ var reg = crmApi('Cxn', 'register', {app_guid: appMeta.appId}).then($scope.refreshCxns).then(function() {
+ if (appMeta.links.welcome) {
+ return $scope.openLink(appMeta, 'welcome', {title: ts('%1: Welcome (External)', {1: appMeta.title})});
+ }
+ });
+ return block(crmStatus({start: ts('Reconnecting...'), success: ts('Reconnected')}, reg));
+ };
+
+ $scope.unregister = function(appMeta) {
+ var reg = crmApi('Cxn', 'unregister', {app_guid: appMeta.appId, debug: 1}).then($scope.refreshCxns);
+ return block(crmStatus({start: ts('Disconnecting...'), success: ts('Disconnected')}, reg));
+ };
+
+ $scope.toggleCxn = function toggleCxn(cxn) {
+ var is_active = (cxn.is_active=="1" ? 0 : 1); // we switch the flag
+ var reg = crmApi('Cxn', 'create', {id: cxn.id, app_guid: cxn.app_meta.appId, is_active: is_active, debug: 1}).then(function(){
+ cxn.is_active = is_active;
+ });
+ return block(crmStatus({start: ts('Saving...'), success: ts('Saved')}, reg));
+ };
+
+ $scope.openLink = function openLink(appMeta, page, options) {
+ var promise = crmApi('Cxn', 'getlink', {app_guid: appMeta.appId, page_name: page}).then(function(result) {
+ var mode = result.values.mode ? result.values.mode : 'popup';
+ switch (result.values.mode) {
+ case 'iframe':
+ var passThrus = ['height', 'width']; // Options influenced by remote server.
+ options = angular.extend(_.pick(result.values, passThrus), options);
+ $scope.openIframe(result.values.url, options);
+ break;
+ case 'popup':
+ CRM.alert(ts('The page "%1" will open in a popup. If it does not appear automatically, check your browser for notifications.', {1: options.title}), '', 'info');
+ window.open(result.values.url, 'cxnSettings', 'resizable,scrollbars,status');
+ break;
+ case 'redirect':
+ window.location = result.values.url;
+ break;
+ default:
+ CRM.alert(ts('Cannot open link. Unrecognized mode.'), '', 'error');
+ }
+ });
+ return block(crmStatus({start: ts('Opening...'), success: ''}, promise));
+ };
+
+ // @param Object options -- see dialogService.open
+ $scope.openIframe = function openIframe(url, options) {
+ var model = {
+ url: url
+ };
+ options = CRM.utils.adjustDialogDefaults(angular.extend(
+ {
+ autoOpen: false,
+ height: 'auto',
+ width: '40%',
+ title: ts('External Link')
+ },
+ options
+ ));
+ return dialogService.open('cxnLinkDialog', '~/crmCxn/LinkDialogCtrl.html', model, options)
+ .then(function(item) {
+ mailing.msg_template_id = item.id;
+ return item;
+ });
+ };
+ });
+
+})(angular, CRM.$, CRM._);
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/PermTable.html b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/PermTable.html
new file mode 100644
index 00000000..d2a1eabf
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/PermTable.html
@@ -0,0 +1,42 @@
+<table>
+ <thead>
+ <tr>
+ <th>{{ts('Entity')}}</th>
+ <th>{{ts('Action(s)')}}</th>
+ <th>{{ts('Filter(s)')}}</th>
+ <th>{{ts('Field(s)')}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="api in perm.api"
+ ng-class-even="'even-row even'"
+ ng-class-odd="'odd-row odd'">
+ <td>
+ <em ng-show="api.entity == '*'">{{ts('Any')}}</em>
+ <code ng-hide="api.entity == '*'">{{api.entity}}</code>
+ </td>
+ <td>
+ <div ng-switch="isString(api.actions)">
+ <span ng-switch-when="true">
+ <em ng-show="api.actions == '*'">{{ts('Any')}}</em>
+ <code ng-hide="api.actions == '*'">{{api.actions}}</code>
+ </span>
+ <span ng-switch-default="">
+ <span ng-repeat="action in api.actions"><code>{{action}}</code><span ng-show="!$last">, </span></span>
+ </span>
+ </div>
+ </td>
+ <td>
+ <em ng-show="!hasRequiredFilters(api)">{{ts('Any')}}</em>
+ <div ng-repeat="(field,value) in api.required"><code>{{field}}</code> = "<code>{{value}}</code>"<span ng-show="!$last">, </span></div>
+ </td>
+ <td>
+ <em ng-show="api.fields == '*'">{{ts('Any')}}</em>
+ <span ng-hide="api.fields == '*'" ng-repeat="field in api.fields"><code>{{field}}</code><span ng-show="!$last">, </span></span>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<div class="crmCxn-footer">
+ <em ng-bind-html="ts('For in-depth details about entities and actions, see the <a href=\'%1\' target=\'%2\'>API Explorer</a>.', {1: apiExplorerUrl, 2: '_blank'})"></em>
+</div>
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/PermTable.js b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/PermTable.js
new file mode 100644
index 00000000..eb7da355
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmCxn/PermTable.js
@@ -0,0 +1,27 @@
+(function(angular, $, _) {
+
+ // This directive formats the data in appMeta.perm as a nice table.
+ // example: <div crm-cxn-perm-table="{perm: cxn.app_meta.perm}"></div>
+ angular.module('crmCxn').directive('crmCxnPermTable', function crmCxnPermTable() {
+ return {
+ restrict: 'EA',
+ scope: {
+ crmCxnPermTable: '='
+ },
+ templateUrl: '~/crmCxn/PermTable.html',
+ link: function(scope, element, attrs) {
+ scope.ts = CRM.ts(null);
+ scope.hasRequiredFilters = function(api) {
+ return !_.isEmpty(api.required);
+ };
+ scope.isString = function(v) {
+ return _.isString(v);
+ };
+ scope.apiExplorerUrl = CRM.url('civicrm/api');
+ scope.$watch('crmCxnPermTable', function(crmCxnPermTable){
+ scope.perm = crmCxnPermTable.perm;
+ });
+ }
+ };
+ });
+})(angular, CRM.$, CRM._);