Add domain alias UI
This commit is contained in:
@@ -211,6 +211,9 @@ angular.module('Application').controller('ActivityController', ['$scope', '$loca
|
||||
} else if (!angular.equals(data.alternateDomains, data.app.alternateDomains)) {
|
||||
var altFqdns = data.alternateDomains.map(function (a) { return a.fqdn; });
|
||||
return 'Alternate domains of ' + appName(app) + ' was ' + (altFqdns.length ? 'set to ' + altFqdns.join(', ') : 'reset');
|
||||
} else if (!angular.equals(data.aliasDomains, data.app.aliasDomains)) {
|
||||
var aliasDomains = data.aliasDomains.map(function (a) { return a.fqdn; });
|
||||
return 'Alias domains of ' + appName(app) + ' was ' + (aliasDomains.length ? 'set to ' + aliasDomains.join(', ') : 'reset');
|
||||
} else if (!angular.equals(data.portBindings, data.app.portBindings)) {
|
||||
return 'Port bindings of ' + appName(app) + ' was changed';
|
||||
}
|
||||
|
||||
+40
-2
@@ -106,6 +106,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="repair.aliasDomains.length">
|
||||
<p ng-repeat="aliasDomain in repair.aliasDomains">
|
||||
<label class="control-label"><input type="checkbox" ng-model="aliasDomain.enabled">
|
||||
{{ aliasDomain.subdomain + (!aliasDomain.subdomain ? '' : '.') + aliasDomain.domain.domain }}
|
||||
</label>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div ng-show="repair.alternateDomains.length">
|
||||
<p ng-repeat="alternateDomain in repair.alternateDomains">
|
||||
<label class="control-label"><input type="checkbox" ng-model="alternateDomain.enabled">
|
||||
@@ -533,6 +541,36 @@
|
||||
</ng-form>
|
||||
</div>
|
||||
|
||||
<div class="form-group alias-domains" ng-show="app.manifest.multiDomain">
|
||||
<label class="control-label">{{ 'app.location.aliases' | tr }} <sup><a ng-href="https://docs.cloudron.io/apps/#aliases" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
|
||||
<div class="has-error" ng-show="location.error.aliasDomains">{{ location.error.aliasDomains }}</div>
|
||||
|
||||
<div class="row" ng-repeat="aliasDomain in location.aliasDomains">
|
||||
<div class="col col-lg-11">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" ng-model="aliasDomain.subdomain" placeholder="{{ 'app.location.aliasesPlaceholder' | tr }}">
|
||||
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<span>{{ (!aliasDomain.subdomain ? '' : '.') + aliasDomain.domain.domain }}</span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right" role="menu">
|
||||
<li ng-repeat="domain in domains">
|
||||
<a href="" ng-click="aliasDomain.domain = domain">{{ domain.domain }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-lg-1">
|
||||
<button class="btn btn-danger btn-sm" ng-click="location.delAliasDomain($event, $index)"><i class="far fa-trash-alt"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="location.aliasDomains.length === 0">{{ 'app.location.noAliases' | tr }}</div>
|
||||
<div style="margin-top: 5px;"><a href="" ng-click="location.addAliasDomain($event)">{{ 'app.location.addAliasAction' | tr }}</a></div>
|
||||
</div>
|
||||
|
||||
<div class="form-group alternate-domains">
|
||||
<label class="control-label">{{ 'app.location.redirections' | tr }} <sup><a ng-href="https://docs.cloudron.io/apps/#redirections" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
|
||||
<div class="has-error" ng-show="location.error.alternateDomains">{{ location.error.alternateDomains }}</div>
|
||||
@@ -585,8 +623,8 @@
|
||||
</div>
|
||||
<div ng-show="!access.ssoAuth">
|
||||
<label class="control-label">{{ 'app.accessControl.userManagement.dashboardVisibility' | tr }}</label>
|
||||
<p ng-show="!access.app.manifest.addons.email" class="text-small">{{ 'appstore.installDialog.userManagementNone' | tr }} <span ng-show="access.ftp">{{ 'app.accessControl.userManagement.sftpAccessControl' | tr }}</span></p>
|
||||
<p ng-show="access.app.manifest.addons.email" class="text-small">{{ 'appstore.installDialog.configuredForCloudronEmail' | tr:{ emailDocsLink: 'https://docs.cloudron.io/email/' } }}</p>
|
||||
<p ng-show="!app.manifest.addons.email" class="text-small">{{ 'appstore.installDialog.userManagementNone' | tr }} <span ng-show="access.ftp">{{ 'app.accessControl.userManagement.sftpAccessControl' | tr }}</span></p>
|
||||
<p ng-show="app.manifest.addons.email" class="text-small">{{ 'appstore.installDialog.configuredForCloudronEmail' | tr:{ emailDocsLink: 'https://docs.cloudron.io/email/' } }}</p>
|
||||
</div>
|
||||
|
||||
<div class="radio">
|
||||
|
||||
+41
-5
@@ -268,6 +268,7 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
domain: null,
|
||||
location: '',
|
||||
alternateDomains: [],
|
||||
aliasDomains: [],
|
||||
portBindings: {},
|
||||
portBindingsEnabled: {},
|
||||
portBindingsInfo: {},
|
||||
@@ -285,6 +286,19 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
$scope.location.alternateDomains.splice(index, 1);
|
||||
},
|
||||
|
||||
addAliasDomain: function (event) {
|
||||
event.preventDefault();
|
||||
$scope.location.aliasDomains.push({
|
||||
domain: $scope.domains.filter(function (d) { return d.domain === $scope.app.domain; })[0], // pre-select app's domain by default
|
||||
subdomain: ''
|
||||
});
|
||||
},
|
||||
|
||||
delAliasDomain: function (event, index) {
|
||||
event.preventDefault();
|
||||
$scope.location.aliasDomains.splice(index, 1);
|
||||
},
|
||||
|
||||
show: function () {
|
||||
var app = $scope.app;
|
||||
|
||||
@@ -294,6 +308,7 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
$scope.location.domain = $scope.domains.filter(function (d) { return d.domain === app.domain; })[0];
|
||||
$scope.location.portBindingsInfo = angular.extend({}, app.manifest.tcpPorts, app.manifest.udpPorts); // Portbinding map only for information
|
||||
$scope.location.alternateDomains = app.alternateDomains.map(function (a) { return { subdomain: a.subdomain, domain: $scope.domains.filter(function (d) { return d.domain === a.domain; })[0] };});
|
||||
$scope.location.aliasDomains = app.aliasDomains.map(function (a) { return { subdomain: a.subdomain, domain: $scope.domains.filter(function (d) { return d.domain === a.domain; })[0] };});
|
||||
|
||||
// fill the portBinding structures. There might be holes in the app.portBindings, which signalizes a disabled port
|
||||
for (var env in $scope.location.portBindingsInfo) {
|
||||
@@ -327,15 +342,20 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
location: $scope.location.location,
|
||||
domain: $scope.location.domain.domain,
|
||||
portBindings: portBindings,
|
||||
alternateDomains: $scope.location.alternateDomains.map(function (a) { return { subdomain: a.subdomain, domain: a.domain.domain };})
|
||||
alternateDomains: $scope.location.alternateDomains.map(function (a) { return { subdomain: a.subdomain, domain: a.domain.domain };}),
|
||||
aliasDomains: $scope.location.aliasDomains.map(function (a) { return { subdomain: a.subdomain, domain: a.domain.domain };})
|
||||
};
|
||||
|
||||
// pre-flight only for changed domains
|
||||
var domains = [];
|
||||
if ($scope.app.domain !== data.domain || $scope.app.location !== data.location) domains.push({ subdomain: data.location, domain: data.domain });
|
||||
if ($scope.app.domain !== data.domain || $scope.app.location !== data.location) domains.push({ subdomain: data.location, domain: data.domain, type: 'main' });
|
||||
data.alternateDomains.forEach(function (a) {
|
||||
if ($scope.app.alternateDomains.some(function (d) { return d.domain === a.domain && d.subdomain === a.subdomain; })) return;
|
||||
domains.push({ subdomain: a.subdomain, domain: a.domain });
|
||||
domains.push({ subdomain: a.subdomain, domain: a.domain, type: 'redirect' });
|
||||
});
|
||||
data.aliasDomains.forEach(function (a) {
|
||||
if ($scope.app.aliasDomains.some(function (d) { return d.domain === a.domain && d.subdomain === a.subdomain; })) return;
|
||||
domains.push({ subdomain: a.subdomain, domain: a.domain, type: 'alias' });
|
||||
});
|
||||
|
||||
async.eachSeries(domains, function (domain, callback) {
|
||||
@@ -344,8 +364,10 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
Client.checkDNSRecords(domain.domain, domain.subdomain, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
if (result.error) {
|
||||
if (data.domain === domain.domain && data.location === domain.subdomain) {
|
||||
if (domain.type === 'main') {
|
||||
$scope.location.error.location = domain.domain + ' ' + result.error.message;
|
||||
} else if (domain.type === 'alias') {
|
||||
$scope.location.error.aliasDomains = domain.domain + ' ' + result.error.message;
|
||||
} else {
|
||||
$scope.location.error.alternateDomains = domain.domain + ' ' + result.error.message;
|
||||
}
|
||||
@@ -374,7 +396,7 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
if (data.domain === error.domain && data.location === error.subdomain) { // the primary
|
||||
$scope.location.error.location = error.message;
|
||||
$scope.locationForm.$setPristine();
|
||||
} else {
|
||||
} else { // FIXME: check error in aliasDomains
|
||||
$scope.location.error.alternateDomains = error.message;
|
||||
}
|
||||
} else if (error.portName || error.field === 'portBindings') {
|
||||
@@ -1287,6 +1309,7 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
location: null,
|
||||
domain: null,
|
||||
alternateDomains: [],
|
||||
aliasDomains: [],
|
||||
backups: [],
|
||||
|
||||
backupId: '',
|
||||
@@ -1300,6 +1323,7 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
$scope.repair.location = null;
|
||||
$scope.repair.domain = null;
|
||||
$scope.repair.alternateDomains = [];
|
||||
$scope.repair.aliasDomains = [];
|
||||
$scope.repair.backupId = '';
|
||||
|
||||
var app = $scope.app;
|
||||
@@ -1309,6 +1333,16 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
if (errorState === ISTATES.PENDING_LOCATION_CHANGE) {
|
||||
$scope.repair.location = app.location;
|
||||
$scope.repair.domain = $scope.domains.filter(function (d) { return d.domain === app.domain; })[0];
|
||||
|
||||
$scope.repair.aliasDomains = $scope.app.aliasDomains;
|
||||
$scope.repair.aliasDomains = $scope.app.aliasDomains.map(function (aliasDomain) {
|
||||
return {
|
||||
subdomain: aliasDomain.subdomain,
|
||||
enabled: true,
|
||||
domain: $scope.domains.filter(function (d) { return d.domain === aliasDomain.domain; })[0]
|
||||
};
|
||||
});
|
||||
|
||||
$scope.repair.alternateDomains = $scope.app.alternateDomains;
|
||||
$scope.repair.alternateDomains = $scope.app.alternateDomains.map(function (altDomain) {
|
||||
return {
|
||||
@@ -1351,6 +1385,8 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
case ISTATES.PENDING_LOCATION_CHANGE:
|
||||
data.location = $scope.repair.location;
|
||||
data.domain = $scope.repair.domain.domain;
|
||||
data.aliasDomains = $scope.repair.aliasDomains.filter(function (a) { return a.enabled; })
|
||||
.map(function (d) { return { subdomain: d.subdomain, domain: d.domain.domain }; });
|
||||
data.alternateDomains = $scope.repair.alternateDomains.filter(function (a) { return a.enabled; })
|
||||
.map(function (d) { return { subdomain: d.subdomain, domain: d.domain.domain }; });
|
||||
data.overwriteDns = true; // always overwriteDns. user can anyway check and uncheck above
|
||||
|
||||
Reference in New Issue
Block a user