Add domain alias UI

This commit is contained in:
Girish Ramakrishnan
2021-01-18 17:55:48 -08:00
parent 7835785aac
commit 2e17e444aa
5 changed files with 101 additions and 8 deletions
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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