server/admin/static/views/settings.html

518 lines
33 KiB
HTML

<div class="row mb-4">
<div class="col-9">
<form ng-submit="saveSettings()" class="card my-3">
<div class="card-header">
<button type="submit" class="float-right btn btn-success"><span class="glyphicon glyphicon-save" aria-hidden="true"></span> Propager ces paramètres</button>
<div class="form-group float-right mr-2 mb-0">
<div class="input-group mt-1">
<div class="input-group-prepend">
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" ng-class="{'btn-outline-secondary': !activateTimeCountDown, 'btn-warning': activateTimeCountDown && activateTime == settings.activateTime, 'btn-outline-warning': activateTime && activateTime != settings.activateTime}"><span class="glyphicon glyphicon-record" aria-hidden="true"></span> Propager plus tard</button>
<div class="dropdown-menu">
<a class="dropdown-item" ng-click="updActivateTime(2)">modulo 2 minutes</a>
<a class="dropdown-item" ng-click="updActivateTime(5)">modulo 5 minutes</a>
<a class="dropdown-item" ng-click="updActivateTime(10)">modulo 10 minutes</a>
<a class="dropdown-item" ng-click="updActivateTime(15)">modulo 15 minutes</a>
<a class="dropdown-item" ng-click="updActivateTime(20)">modulo 20 minutes</a>
<a class="dropdown-item" ng-click="updActivateTime(30)">modulo 30 minutes</a>
<a class="dropdown-item" ng-click="updActivateTime(60)">modulo 60 minutes</a>
<a class="dropdown-item" ng-click="updActivateTime(90)">modulo 90 minutes</a>
<a class="dropdown-item" ng-click="updActivateTime(null)" ng-show="activateTimeCountDown">annuler la propagation</a>
</div>
</div>
<input type="datetime-local" class="form-control form-control-sm" id="activateTime" ng-model="activateTime" ng-change="updateActivateTime()">
</div>
<small ng-if="activateTimeCountDown">
Propagation dans : {{ activateTimeCountDown | timer }}.
Il restera : {{ timeRemaining - activateTimeCountDown | timer }}
</small>
</div>
<h2 class="mb-0">
Paramètres
</h2>
</div>
<div class="card-body pb-1">
<div class="form-group row">
<label for="startTime" class="col-sm-3 col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.start != dist_config.start}">Début du challenge</label>
<div class="col-sm-9">
<div class="input-group">
<input type="datetime-local" class="form-control form-control-sm" id="startTime" ng-model="config.start" ng-class="{'border-primary': config.start != dist_config.start}">
<div class="input-group-append">
<button ng-click="launchChallenge()" class="btn btn-sm btn-secondary" type="button"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Lancer le challenge</button>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="endTime" class="col-sm-3 col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.end != dist_config.end}">Fin du challenge</label>
<div class="col-sm-6">
<input type="datetime-local" class="form-control form-control-sm" id="endTime" ng-model="config.end" ng-class="{'border-primary': config.end != dist_config.end}">
</div>
<div class="col-sm-1 text-right">
<label for="duration" class="col-form-label col-form-label-sm">Durée</label>
</div>
<div class="col-sm-2">
<div class="input-group input-group-sm">
<input type="text" class="form-control form-control-sm" id="duration" ng-model="duration" integer>
<div class="input-group-append">
<span class="input-group-text">min</span>
</div>
</div>
</div>
</div>
<hr>
<div class="form-group row">
<label for="globalScoreCoefficient" class="col-sm-2 col-form-label col-form-label-sm" ng-class="{'text-primary': config.globalScoreCoefficient != dist_config.globalScoreCoefficient}"><strong>Coefficients</strong></label>
<div class="col-sm-1">
<input type="text" class="form-control form-control-sm" id="globalScoreCoefficient" ng-model="config.globalScoreCoefficient" float title="Coefficient multiplicateur global du score final (le coefficient est appliqué dans la fonction et vaut pour tout le challenge, présent/passé/futur, sans effet de bord)" ng-class="{'border-primary': config.globalScoreCoefficient != dist_config.globalScoreCoefficient}">
</div>
<label for="hintcoefficient" class="col-sm-2 col-form-label col-form-label-sm text-right" ng-class="{'text-primary font-weight-bold': config.hintCurrentCoefficient != dist_config.hintCurrentCoefficient}">incides</label>
<div class="col-sm-1">
<input type="text" class="form-control form-control-sm" id="hintcoefficient" ng-model="config.hintCurrentCoefficient" float title="Coefficient multiplicateur temporaire du nombre de points que fait perdre un indice (le coefficient est enregistré au moment où l'équipe demande un indice, ce n'est pas global)" ng-class="{'border-primary': config.hintCurrentCoefficient != dist_config.hintCurrentCoefficient}">
</div>
<label for="wchoicescoefficient" class="col-sm-2 col-form-label col-form-label-sm text-right" ng-class="{'text-primary font-weight-bold': config.wchoiceCurrentCoefficient != dist_config.wchoiceCurrentCoefficient}">WChoices</label>
<div class="col-sm-1">
<input type="text" class="form-control form-control-sm" id="wchoicescoefficient" ng-model="config.wchoiceCurrentCoefficient" float title="Coefficient multiplicateur temporaire du nombre de points que fait perdre une demande de liste de choix (le coefficient est enregistré au moment où l'équipe demande la liste de choix, ce n'est pas global)" ng-class="{'border-primary': config.wchoiceCurrentCoefficient != dist_config.wchoiceCurrentCoefficient}">
</div>
<label for="exercicecurcoefficient" class="col-sm-2 col-form-label col-form-label-sm text-right" ng-class="{'text-primary font-weight-bold': config.exerciceCurrentCoefficient != dist_config.exerciceCurrentCoefficient}">défis</label>
<div class="col-sm-1">
<input type="text" class="form-control form-control-sm" id="exercicecurcoefficient" ng-model="config.exerciceCurrentCoefficient" float title="Coefficient multiplicateur temporaire du nombre de points que fait gagner un exercice validé (le coefficient est enregistré au moment où l'équipe valide l'exercice, ce n'est pas global)" ng-class="{'border-primary': config.exerciceCurrentCoefficient != dist_config.exerciceCurrentCoefficient}">
</div>
</div>
<div class="form-group row">
<div class="col-sm row">
<label for="firstBlood" class="col-sm-8 col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.firstBlood != dist_config.firstBlood}">Bonus premier sang</label>
<div class="col-sm-4">
<input type="text" class="form-control form-control-sm" id="firstBlood" ng-model="config.firstBlood" float ng-class="{'border-primary': config.firstBlood != dist_config.firstBlood}">
</div>
</div>
<div class="col-sm row">
<label for="discountFactor" class="col-sm-8 col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.discountedFactor != dist_config.discountedFactor}">Décote des exercices</label>
<div class="col-sm-4">
<input type="text" class="form-control form-control-sm" id="discountFactor" ng-model="config.discountedFactor" float ng-class="{'border-primary': config.discountedFactor != dist_config.discountedFactor}">
</div>
</div>
<div class="col-sm row">
<label for="submissionCostBase" class="col-sm-8 col-form-label col-form-label-sm text-right" ng-class="{'text-primary font-weight-bold': config.submissionCostBase != dist_config.submissionCostBase}">Coût de base tentative</label>
<div class="col-sm-4">
<input type="text" class="form-control form-control-sm" id="submissionCostBase" ng-model="config.submissionCostBase" float ng-class="{'border-primary': config.submissionCostBase != dist_config.submissionCostBase}">
</div>
</div>
</div>
<hr>
<div class="form-group row">
<label for="globalTopMessage" class="col-sm-3 col-form-label col-form-label-sm">Message global (top)</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-sm" id="globalTopMessage" ng-model="config.globaltopmessage">
</div>
</div>
<div class="form-group row">
<label for="globalTopMessageVariant" class="col-sm-3 col-form-label col-form-label-sm">Variant message global</label>
<div class="col-sm-9">
<select class="form-control form-control-sm" id="globalTopMessage" ng-model="config.globaltopmessagevariant">
<option value=""></option>
<option value="primary">primary</option>
<option value="secondary">secondary</option>
<option value="info">info</option>
<option value="success">success</option>
<option value="danger">danger</option>
<option value="warning">warning</option>
<option value="light">light</option>
<option value="dark">dark</option>
</select>
</div>
</div>
</div>
<div class="card-body pb-2 border-top">
<div class="row">
<div class="col">
<div class="form-group row">
<label for="unlockedStandaloneExercices" class="col-sm-auto col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.unlockedStandaloneExercices != dist_config.unlockedStandaloneExercices}">Exercices indépendants débloqués</label>
<div class="col-sm">
<input type="number" class="form-control form-control-sm" id="unlockedStandaloneExercices" ng-model="config.unlockedStandaloneExercices" ng-class="{'border-primary': config.unlockedStandaloneExercices != dist_config.unlockedStandaloneExercices}" min="0">
</div>
</div>
</div>
<div class="col">
<div class="form-group row">
<label for="unlockedStandaloneExercicesByThemeStepValidation" class="col-sm-auto col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.unlockedStandaloneExercicesByThemeStepValidation != dist_config.unlockedStandaloneExercicesByThemeStepValidation}">Débloqués par étape validée</label>
<div class="col-sm">
<input type="number" class="form-control form-control-sm" id="unlockedStandaloneExercicesByThemeStepValidation" ng-model="config.unlockedStandaloneExercicesByThemeStepValidation" ng-class="{'border-primary': config.unlockedStandaloneExercicesByThemeStepValidation != dist_config.unlockedStandaloneExercicesByThemeStepValidation}" min="0" step="0.01">
</div>
</div>
<div class="form-group row">
<label for="unlockedStandaloneExercicesByStandaloneExerciceValidation" class="col-sm-auto col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.unlockedStandaloneExercicesByStandaloneExerciceValidation != dist_config.unlockedStandaloneExercicesByStandaloneExerciceValidation}">Débloqués par exercice indépendant validé</label>
<div class="col-sm">
<input type="number" class="form-control form-control-sm" id="unlockedStandaloneExercicesByStandaloneExerciceValidation" ng-model="config.unlockedStandaloneExercicesByStandaloneExerciceValidation" ng-class="{'border-primary': config.unlockedStandaloneExercicesByStandaloneExerciceValidation != dist_config.unlockedStandaloneExercicesByStandaloneExerciceValidation}" min="0" step="0.01">
</div>
</div>
</div>
</div>
</div>
<div class="card-body pl-0 pt-3 border-top" style="columns: 2;">
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.allowRegistration">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.allowRegistration != !dist_config.allowRegistration}">Activer les inscriptions</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.canJoinTeam" ng-disabled="!config.allowRegistration">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.canJoinTeam != !dist_config.canJoinTeam}">Les participants sans équipe peuvent en rejoindre une</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.denyTeamCreation" ng-disabled="!config.allowRegistration && !config.canJoinTeam">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.denyTeamCreation != !dist_config.denyTeamCreation}">Interdire la création de nouvelles équipes</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.denyNameChange">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.denyNameChange != !dist_config.denyNameChange}">Interdire les changements de nom d'équipe</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.ignoreTeamMembers">
<span class="custom-control-label" title="Un message d'avertissement est affiché aux équipes dont la liste des membres n'est pas connue, afin qu'ils viennent se présenter à l'équipe serveur. Cocher cette case pour que le message ne s'affiche pas, lorsque la composition de l'équipe n'intéresse pas." ng-class="{'text-primary font-weight-bold': !config.ignoreTeamMembers != !dist_config.ignoreTeamMembers}">Ne pas avertir les équipes sans membre</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.acceptNewIssue">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.acceptNewIssue != !dist_config.acceptNewIssue}">Activer le rapport d'anomalies par les équipes</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.QAenabled">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.QAenabled != !dist_config.QAenabled}">Activer les rapports QA</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.canResetProgress" ng-disabled="!config.wip">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.canResetProgress != !dist_config.canResetProgress}">Autoriser les équipes à auto-effacer leur progression</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.enableExerciceDepend" ng-change="exerciceDependChange()">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': config.unlockedChallengeDepth != dist_config.unlockedChallengeDepth}">Activer les dépendances des exercices</span>
<input type="number" class="form-control form-control-sm" ng-model="config.unlockedChallengeDepth" ng-disabled="!config.enableExerciceDepend" title="-1 : Désactivé ; 0: activé ; 1,2,3 : débloque 1,2,3,... exercices supplémentaires après un challenge validé" min="0" integer ng-class="{'border-primary': config.unlockedChallengeDepth != dist_config.unlockedChallengeDepth}">
</label>
</div>
<div class="form-group row px-3">
<label class="col-form-label col-form-label-sm col-8" ng-class="{'text-primary': !config.unlockedChallengeUpTo != !dist_config.unlockedChallengeUpTo}" for="unlockedChallengeUpTo">
Débloquer jusqu'au niveau :
</label>
<input type="number" class="form-control form-control-sm col-4" id="unlockedChallengeUpTo" ng-model="config.unlockedChallengeUpTo" min="0" integer ng-class="{'border-primary': config.unlockedChallengeUpTo != dist_config.unlockedChallengeUpTo}">
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.enableResolutionRoute">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.enableResolutionRoute != !dist_config.enableResolutionRoute}">Activer la route montrant les solutions</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.partialValidation">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.partialValidation != !dist_config.partialValidation}">Activer la validation partielle des challenges</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.displayAllFlags">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.displayAllFlags != !dist_config.displayAllFlags}">Désactiver les dépendances des flags</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.hideCaseSensitivity">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.hideCaseSensitivity != !dist_config.hideCaseSensitivity}">Ne pas informer sur la sensibilité à la casse des flags</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.submissionUniqueness">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.submissionUniqueness != !dist_config.submissionUniqueness}">Ne pas comptabiliser les tentatives identiques dans le score</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.countOnlyNotGoodTries">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.countOnlyNotGoodTries != !dist_config.countOnlyNotGoodTries}">Comptabiliser seulement les tentatives sans bonne réponse dans le score</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.displayMCQBadCount">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.displayMCQBadCount != !dist_config.displayMCQBadCount}">Afficher le décompte de mauvaises réponses des QCM</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.eventKindness">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.eventKindness != !dist_config.eventKindness}">Réduire la relève d'évènements côté navigateur</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.hide_header">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.hide_header != !dist_config.hide_header}">Cacher l'en-tête du compte à rebours</span>
</label>
</div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox"ng-model="config.disabledsubmitbutton" ng-change="submitButtonStateChange()">
<span class="custom-control-label" ng-class="{'text-primary font-weight-bold': !config.disablesubmitbutton != !dist_config.disablesubmitbutton}">Désactiver les boutons de soumission (pour indiquer une indisponibilité)</span>
<input class="form-control form-control-sm" ng-model="config.disablesubmitbutton" ng-disabled="!config.disabledsubmitbutton" title="Message qui sera indiqué aux participants" ng-class="{'border-primary': !config.disablesubmitbutton != !dist_config.disablesubmitbutton}">
</label>
</div>
</div>
</form>
<div class="card my-3">
<div class="card-header">
<h3>Managers QA</h3>
</div>
<div class="card-body">
<ul>
<li ng-repeat="m in config.delegated_qa">
{{ m }}
<button class="btn btn-sm btn-danger" type="button" ng-click="dropDelegatedQA(m)">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</li>
</ul>
<form class="row" ng-controller="AllTeamAssociationsController" ng-submit="addDelegatedQA()">
<div class="col">
<select class="form-control form-control-sm" ng-model="newdqa">
<option ng-selected="newdqa == m" ng-repeat="(i,m) in allAssociations" ng-value="m">{{ m }}</option>
</select>
</div>
<div class="col input-group">
<input type="text" class="form-control form-control-sm" ng-model="newdqa" placeholder="Nouveau manager QA">
<span class="input-group-append">
<button class="btn btn-sm btn-success" ng-disabled="!newdqa.length"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</span>
</div>
</form>
</div>
</div>
<form ng-submit="saveChallengeInfo()" class="card my-3">
<div class="card-header">
<button type="submit" class="btn btn-success float-right" title="Enregistrer les modifications aux infos du challenge"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
<button ng-show="config.wip || !timeProgression || displayDangerousActions" ng-click="reset('challengeInfo');" type="button" class="mx-3 btn btn-danger float-right" title="Remettre les infos du challenge à zéro"><span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span></button>
<h3 class="mb-0">Infos challenge</h3>
</div>
<div class="card-body">
<div class="form-group row">
<label for="challengeTitle" class="col-sm-3 col-form-label col-form-label-sm">Nom du challenge</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-sm" id="challengeTitle" ng-model="challenge.title">
</div>
</div>
<div class="form-group row">
<label for="challengeSubtitle" class="col-sm-3 col-form-label col-form-label-sm">Sous-titre du challenge</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-sm" id="challengeSubtitle" ng-model="challenge.subtitle">
</div>
</div>
<div class="form-group row">
<label for="challengeAuthors" class="col-sm-3 col-form-label col-form-label-sm">Auteur du challenge</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-sm" id="challengeAuthors" ng-model="challenge.authors">
</div>
</div>
<div class="form-group row">
<label for="challengeVideoslink" class="col-sm-3 col-form-label col-form-label-sm">Liens solutions</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-sm" id="challengeVideoslink" ng-model="challenge.videoslink">
</div>
</div>
<div class="form-group row">
<label for="challengeDescription" class="col-sm-3 col-form-label col-form-label-sm">Description</label>
<div class="col-sm-9">
<textarea class="form-control form-control-sm" id="challengeDescription" ng-model="challenge.description">
</textarea>
</div>
</div>
<div class="form-group row">
<label for="challengeRules" class="col-sm-3 col-form-label col-form-label-sm">Règles</label>
<div class="col-sm-9">
<textarea class="form-control form-control-sm" id="challengeRules" ng-model="challenge.rules">
</textarea>
</div>
</div>
<div class="form-group row">
<label for="challengeYourMission" class="col-sm-3 col-form-label col-form-label-sm">Mission</label>
<div class="col-sm-9">
<textarea class="form-control form-control-sm" id="challengeYourMission" ng-model="challenge.your_mission">
</textarea>
</div>
</div>
<div class="form-group row">
<label for="main_logo" class="col-sm-3 col-form-label col-form-label-sm">Logo principal</label>
<div class="col-sm-9">
<div ng-repeat="(i, v) in challenge.main_logo track by $index" class="input-group">
<input type="text" class="form-control form-control-sm" id="main_logo" ng-model="challenge.main_logo[i]">
<div class="input-group-append">
<button class="btn btn-sm btn-outline-success" type="button" ng-if="$last" ng-click="challenge.main_logo.push('')">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
<button class="btn btn-sm btn-outline-danger" type="button" ng-click="challenge.main_logo.splice($index, 1)">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="challengeParentLink" class="col-sm-3 col-form-label col-form-label-sm">Lien site parent</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-sm" id="challengeParentLink" ng-model="challenge.main_link">
</div>
</div>
<div class="form-group row">
<label for="dashboard_back" class="col-sm-3 col-form-label col-form-label-sm">Fond dashboard</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-sm" id="dashboard_back" ng-model="challenge.dashboard_back">
</div>
</div>
<div class="form-group row">
<label for="partner_0_alt" class="col-sm-3 col-form-label col-form-label-sm">Partenaires</label>
<div class="col-sm-9">
<div ng-repeat="(i, v) in challenge.partners track by $index" class="d-flex justify-content-between">
<input type="text" class="form-control form-control-sm" id="partner_{{$index}}_alt" ng-model="challenge.partners[i].alt" placeholder="Titre">
<input type="text" class="form-control form-control-sm" id="partner_{{$index}}_img" ng-model="challenge.partners[i].img" placeholder="Lien image">
<input type="text" class="form-control form-control-sm" id="partner_{{$index}}_href" ng-model="challenge.partners[i].href" placeholder="Lien site">
<div class="d-flex">
<button class="btn btn-sm btn-outline-success" type="button" ng-if="$last" ng-click="challenge.partners.push({})">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
<button class="btn btn-sm btn-outline-danger" type="button" ng-click="challenge.partners.splice($index, 1)">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="col-3 pt-2 d-flex flex-column justify-content-between">
<div>
<div class="d-flex flex-column">
<button ng-click="regenerateStaticFiles()" class="btn btn-info my-1" type="button" ng-disabled="staticRegenerationInProgress">
<span class="glyphicon glyphicon-share" aria-hidden="true" ng-show="!staticRegenerationInProgress"></span>
<div class="spinner-border spinner-border-sm" role="status" ng-show="staticRegenerationInProgress">
<span class="sr-only">Loading...</span>
</div>
Regénérer les fichiers statiques
</button>
<button ng-if="settings.wip" ng-click="switchToProd()" class="btn btn-danger my-1" type="button"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span> Activer le mode challenge</button>
<a href="api/archive.zip" class="btn btn-secondary my-1" type="button" target="_self"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Télécharger l'archive pour publication</a>
</div>
<hr>
<h4>Changements anticipés</h4>
<div class="card mb-2" ng-repeat="ns in nextsettings">
<div class="card-header d-flex justify-content-between">
<h4 class="text-truncate mb-0 align-self-center" title="{{ ns.date }}">
{{ ns.date }}
</h4>
<div class="d-flex">
<button class="btn btn-sm btn-primary mr-1" ng-click="editNextSettings(ns)">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
</button>
<button class="btn btn-sm btn-danger" ng-click="deleteNextSettings(ns)">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
</div>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item" ng-repeat="(k,v) in ns.values">
{{ k }} &rarr; {{ v }}
</li>
</ul>
</div>
</div>
<div class="card" ng-show="!config.wip && timeProgression && !displayDangerousActions">
<div class="card-header bg-secondary text-light">
<h5 class="mb-0">
Synchronisation et suppressions de masse
</h5>
</div>
<div class="card-body pl-0 pr-3 pt-3">
<div class="form-check pl-2">
<label class="custom-control custom-checkbox text-justify">
<input class="custom-control-input" type="checkbox" ng-model="displayDangerousActions">
<strong class="custom-control-label">Je sais ce que le challenge a démarré ET <span style="text-decoration: underline red;">j'ai réalisé une sauvegarde de la base de données il y a moins d'une minute</span> ET je sais que c'est <span style="text-decoration: underline yellow;">une très mauvaise idée de cocher cette case</span>, mais j'y suis obligé pour de bonnes raisons.</strong>
</label>
</div>
</div>
</div>
<div class="row mb-2" ng-show="settings.wip || !timeProgression || displayDangerousActions">
<div class="d-flex flex-column">
<a href="sync" class="btn btn-primary my-1" type="button"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Paramètres de synchronisation</a>
<button ng-click="reset('settings');" class="btn btn-secondary mt-2 mb-1" type="button"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Revenir aux paramètres par défaut</button>
<button ng-click="reset('challenges')" class="btn btn-secondary mt-2 mb-1" type="button"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Effacer les challenges et les thèmes</button>
<button ng-click="reset('teams');" class="btn btn-secondary mt-1 mb-1" type="button"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Effacer les équipes</button>
<button ng-click="reset('game');" class="btn btn-secondary mt-1 mb-2" type="button"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Effacer la partie (tentatives, indices, ...)</button>
<button ng-click="reset('annexes');" class="btn btn-secondary mt-1 mb-2" type="button"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Effacer les annexes (events, issues, QA)</button>
</div>
</div>
</div>
</div>