Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Check if the authorities are online #416

Merged
merged 22 commits into from
Apr 12, 2024
43 changes: 43 additions & 0 deletions avAdmin/admin-directives/create/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,48 @@ angular.module('avAdmin')
}
});

function checkTrustees(el) {
logInfo($i18next.t('avAdmin.create.checkingTrustees', {title: el.title}));
var deferred = $q.defer();
var auths = el.authorities && Array.from(el.authorities) || [];
if (el.director) {
auths.push(el.director);
}

if (0 === auths.length) {
logError($i18next.t('avAdmin.create.errors.election-auths-missing', {eltitle: el.title}));
deferred.reject();
} else {
ElectionsApi
.authoritiesStatus()
.then(function (trustees) {
var hasError = false;
for (var i = 0; i < auths.length; i++) {
var auth = auths[i];
if (!trustees[auth]) {
logError($i18next.t('avAdmin.create.errors.election-auth-not-found', {eltitle: el.title, auth: auth}));
hasError = true;
continue;
}
if ('ok' !== trustees[auth].state) {
logError($i18next.t('avAdmin.create.errors.election-auth-error', {eltitle: el.title, auth: auth, message: trustees[auth].message}));
hasError = true;
continue;
}
}
if (hasError) {
deferred.reject();
} else {
deferred.resolve(el);
}
})
.catch(deferred.reject);
}


return deferred.promise;
}

function createAuthEvent(el) {
console.log("creating auth event for election " + el.title);
var deferred = $q.defer();
Expand Down Expand Up @@ -1264,6 +1306,7 @@ angular.module('avAdmin')

var promise = deferred.promise;
promise = promise
.then(checkTrustees)
.then(createAuthEvent)
.then(registerElection)
.then(function(election) {
Expand Down
10 changes: 8 additions & 2 deletions avAdmin/admin-directives/dashboard/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,14 @@ <h4>

<ul class="list-group">
<li class="authority list-group-item" ng-repeat="auth in election.auths">
<span class="badge" ng-if="auth == election.director"><i class="fa fa-sitemap"></i></span>
{{ auth }}
<span class="auth-name-container">{{ auth }}</span>
<div class="auth-badge" ng-class="{'auth-badge-green': isTrusteeOk(auth)}">
<div class="auth-tooltip" ng-if="getTrusteeMsg(auth)">
{{ getTrusteeMsg(auth) }}
</div>
</div>
<span class="badge" ng-if="auth === election.director"><i class="fa fa-sitemap"></i></span>
<span ng-if="auth !== election.director" style="width: 30px;"></span>
</li>
</ul>
</div>
Expand Down
90 changes: 82 additions & 8 deletions avAdmin/admin-directives/dashboard/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ angular.module('avAdmin')
$q,
$window,
$state,
$i18next,
Authmethod,
Plugins,
ElectionsApi,
Expand All @@ -37,6 +38,7 @@ angular.module('avAdmin')
function link(scope, element, attrs)
{
scope.reloadTimeout = null;
scope.trusteesState = {};

scope.isWriteInResult = function(answer)
{
Expand Down Expand Up @@ -81,8 +83,25 @@ angular.module('avAdmin')
}
}

function setTrusteesState() {
ElectionsApi
.authoritiesStatus()
.then(function (trustees) {
scope.trusteesState = trustees;
});
}

function isTrusteeOk(name) {
return scope.trusteesState && scope.trusteesState[name] && 'ok' === scope.trusteesState[name].state;
}

function getTrusteeMsg(name) {
return scope.trusteesState && scope.trusteesState[name] && scope.trusteesState && scope.trusteesState[name].message || '';
}

function waitElectionChange()
{
setTrusteesState();
ElectionsApi
.getElection(scope.id, /*ignorecache = */ true)
.then(function(el)
Expand Down Expand Up @@ -743,6 +762,46 @@ angular.module('avAdmin')
);
}

function checkTrustees() {
var deferred = $q.defer();

var errors = [];

var auths = scope.election.authorities && Array.from(scope.election.authorities) || [];
if (scope.election.director) {
auths.push(scope.election.director);
}

if (0 === auths.length) {
errors.push($i18next.t('avAdmin.create.errors.election-auths-missing', {eltitle: scope.election.title}));
deferred.reject(errors.join("\n"));
} else {
ElectionsApi
.authoritiesStatus()
.then(function (trustees) {
for (var i = 0; i < auths.length; i++) {
var auth = auths[i];
if (!trustees[auth]) {
errors.push($i18next.t('avAdmin.create.errors.election-auth-not-found', {eltitle: scope.election.title, auth: auth}));
continue;
}
if ('ok' !== trustees[auth].state) {
errors.push($i18next.t('avAdmin.create.errors.election-auth-error', {eltitle: scope.election.title, auth: auth, message: trustees[auth].message}));
continue;
}
}
if (errors.length > 0) {
deferred.reject(errors);
} else {
deferred.resolve();
}
})
.catch(deferred.reject);
}

return deferred.promise;
}

// performs all the initialization
function init()
{
Expand Down Expand Up @@ -895,13 +954,17 @@ angular.module('avAdmin')
scope.index = scope.getStatusIndex('stopped') + 1;
}
scope.nextaction = false;
Authmethod
.launchTally(
scope.election.id,
data.tallyElectionIds,
'force-all',
data.mode
)

checkTrustees()
.then(function () {
return Authmethod
.launchTally(
scope.election.id,
data.tallyElectionIds,
'force-all',
data.mode
);
})
.then(
function onSuccess()
{
Expand All @@ -915,7 +978,15 @@ angular.module('avAdmin')
scope.loading = false;
scope.error = error;
}
);
)
.catch(function(error)
{
if (scope.launchedTally) {
scope.launchedTally = false;
}
scope.loading = false;
scope.error = error;
});
},
enableFunc: function () {
return (
Expand Down Expand Up @@ -1460,6 +1531,7 @@ angular.module('avAdmin')
scope.prevStatus = null;
scope.percentVotes = PercentVotesService;

setTrusteesState();
// get the election at the begining
ElectionsApi
.getElection(scope.id)
Expand Down Expand Up @@ -1532,6 +1604,8 @@ angular.module('avAdmin')
launchKeyDistributionCeremony: launchKeyDistributionCeremony,
launchOpeningCeremony: launchOpeningCeremony,
configureScheduledEvents: configureScheduledEvents,
isTrusteeOk: isTrusteeOk,
getTrusteeMsg: getTrusteeMsg,
downloadTurnout: downloadTurnout
});

Expand Down
37 changes: 37 additions & 0 deletions avAdmin/admin-directives/dashboard/dashboard.less
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,43 @@
}
}

.authority {
display: flex;
flex-direction: row;
justify-content: space-between;
}

.auth-badge {
width: 25px;
height: 25px;
border-radius: 25px;
background-color: @error-primary-color;
margin: auto 0;
position: relative;

&.auth-badge-green {
background-color: @av-secondary-contrast;
}

.auth-tooltip {
visibility: hidden;
width: 240px;
background-color: @av-bg;
text-align: center;
padding: 5px 0;
border-radius: 6px;
position: absolute;
z-index: 1;
font-size: 1rem;
top: 25px;
left: 16px;
}
}

.auth-badge:hover .auth-tooltip {
visibility: visible;
}

/** descriptive radio buttons */
.descriptive-radio {
border: 2px solid transparent;
Expand Down
19 changes: 19 additions & 0 deletions avAdmin/elections-api-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,25 @@ angular.module('avAdmin')
return deferred.promise;
};

electionsapi.authoritiesStatus = function ()
{
var deferred = $q.defer();$http
.get(
backendUrl + 'authorities-state'
)
.then(
function (response) {
if (response && response.data && response.data.payload) {
deferred.resolve(response.data.payload);
} else {
deferred.reject(response);
}
},
deferred.reject
);
return deferred.promise;
};

electionsapi.parseElection = function(d) {
var election = d.payload;
var conf = electionsapi.templateEl();
Expand Down
4 changes: 4 additions & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@
"create": {
"summary": "Summary: creating __num__ elections",
"summary__plural": "Summary: creating __num__ elections",
"checkingTrustees": "Checking trustees status for election __title__",
"create": "Create the elections",
"creating": "Creating the authentication for election __title__",
"setChildrenElectionInfo": "Setting the children election info for election (id: __id__) __title__",
Expand All @@ -954,6 +955,9 @@
"confirmEdit": "Finish edit"
},
"errors": {
"election-auths-missing": "Election '__eltitle__': Missing trustees",
"election-auth-not-found": "Election '__eltitle__': Trustee not found '__auth__'",
"election-auth-error": "Election '__eltitle__': Trustee '__auth__' has invalid status '__message__'",
"lambda-live-preview-parent-children": "Missing election IDs for a parent-children election",
"election-is-array-questions": "Election '__eltitle__': list of questions is not an array",
"election-lambda-success-action-url-mode": "Election '__eltitle__': invalid success action url",
Expand Down
4 changes: 4 additions & 0 deletions locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@
"create": {
"summary": "Resumen: creando __num__ votaciones",
"summary__plural": "Resumen: creando __num__ votaciones",
"checkingTrustees": "Checking trustees status for election __title__",
"create": "Crear las votaciones",
"create__plural": "Crear las votaciones",
"creating": "Creando la autenticación de la votación __title__",
Expand All @@ -834,6 +835,9 @@
"livePreview": "Previsualización en vivo"
},
"errors": {
"election-auths-missing": "Election '__eltitle__': Faltan autoridades",
"election-auth-not-found": "Election '__eltitle__': Autoridad no encontrada '__auth__'",
"election-auth-error": "Election '__eltitle__': Autoridad '__auth__' tiene un estado inválido '__message__'",
"lambda-live-preview-parent-children": "Faltan ID de la votación para una votación padre-hijos",
"election-is-array-questions": "Votación '__eltitle__': la lista de pregunta no es un array",
"election-lambda-success-action-url-mode": "Votación '__eltitle__': url de redirección en 'Acción de éxito' inválida",
Expand Down
Loading