chore(users-add): confirm stub, migrate buttons
This commit is contained in:
parent
e65d38898e
commit
dfc017b10a
@ -121,6 +121,8 @@ CourseParticipantsAlreadyRegistered n@Int: #{n} #{pluralDE n "Teinehmer:in" "Tei
|
||||
CourseParticipantsAlreadyTutorialMember n@Int: #{n} #{pluralDE n "Teinehmer:in" "Teilnehmer:innen"} #{pluralDE n "ist" "sind"} bereits in dieser Übungsgruppe angemeldet
|
||||
CourseParticipantsRegistered n@Int: #{n} #{pluralDE n "Teinehmer:in" "Teilnehmer:innen"} erfolgreich angemeldet
|
||||
CourseParticipantsRegisteredTutorial n@Int: #{n} #{pluralDE n "Teinehmer:in" "Teilnehmer:innen"} erfolgreich zur Übungsgruppe angemeldet
|
||||
CourseParticipantsRegisterConfirmationHeading: Teilnehmer:innen hinzufügen
|
||||
|
||||
CourseApplicationText: Text-Bewerbung
|
||||
CourseApplicationFollowInstructions: Beachten Sie die Anweisungen zur Bewerbung!
|
||||
CourseRegistrationText: Text zur Anmeldung
|
||||
|
||||
@ -121,6 +121,8 @@ CourseParticipantsAlreadyRegistered n: #{n} #{pluralEN n "participant is" "parti
|
||||
CourseParticipantsAlreadyTutorialMember n: #{n} #{pluralEN n "participant is" "participants are"} already registered for this tutorial
|
||||
CourseParticipantsRegistered n: Successfully registered #{n} #{pluralEN n "participant" "participants"}
|
||||
CourseParticipantsRegisteredTutorial n: Successfully registered #{n} #{pluralEN n "participant" "participants"} for tutorial
|
||||
CourseParticipantsRegisterConfirmationHeading: Register participants
|
||||
|
||||
CourseApplicationText: Application text
|
||||
CourseApplicationFollowInstructions: Please follow the instructions for applications!
|
||||
CourseRegistrationText: Registration text
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -65,4 +65,7 @@ BtnNotifyNewCourseForceOff: Nicht benachrichtigen
|
||||
BtnUserAssimilate: Assimilieren
|
||||
BtnCloseExam: Prüfung abschließen
|
||||
BtnFinishExam: Prüfungsergebnisse sichtbar schalten
|
||||
BtnConfirm: Bestätigen
|
||||
BtnConfirm: Bestätigen
|
||||
BtnCourseRegisterAdd: Personen suchen
|
||||
BtnCourseRegisterConfirm: Ausgewählte Personen anmelden
|
||||
BtnCourseRegisterAbort: Abbrechen
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
||||
# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
@ -65,4 +65,7 @@ BtnNotifyNewCourseForceOff: Do not notify me
|
||||
BtnUserAssimilate: Assimilate
|
||||
BtnCloseExam: Close exam
|
||||
BtnFinishExam: Make results visible
|
||||
BtnConfirm: Confirm
|
||||
BtnConfirm: Confirm
|
||||
BtnCourseRegisterAdd: Search persons
|
||||
BtnCourseRegisterConfirm: Register selected persons
|
||||
BtnCourseRegisterAbort: Abort
|
||||
@ -13,9 +13,7 @@ import Handler.Utils.Avs
|
||||
|
||||
import Jobs.Queue
|
||||
|
||||
--import Data.Aeson hiding (Result(..))
|
||||
import qualified Data.CaseInsensitive as CI
|
||||
--import qualified Data.HashSet as HashSet
|
||||
import Data.List (genericLength)
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Text as Text
|
||||
@ -26,6 +24,26 @@ import Control.Monad.Except (MonadError(..))
|
||||
import Generics.Deriving.Monoid (memptydefault, mappenddefault)
|
||||
|
||||
|
||||
data ButtonCourseRegisterMode = BtnCourseRegisterAdd | BtnCourseRegisterConfirm | BtnCourseRegisterAbort
|
||||
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
|
||||
instance Universe ButtonCourseRegisterMode
|
||||
instance Finite ButtonCourseRegisterMode
|
||||
|
||||
embedRenderMessage ''UniWorX ''ButtonCourseRegisterMode id
|
||||
|
||||
nullaryPathPiece ''ButtonCourseRegisterMode $ camelToPathPiece' 1
|
||||
|
||||
instance Button UniWorX ButtonCourseRegisterMode where
|
||||
btnLabel x = [whamlet|_{x}|]
|
||||
|
||||
btnClasses BtnCourseRegisterAdd = [BCIsButton, BCPrimary]
|
||||
btnClasses BtnCourseRegisterConfirm = [BCIsButton, BCPrimary]
|
||||
btnClasses BtnCourseRegisterAbort = [BCIsButton, BCDanger]
|
||||
|
||||
btnValidate _ BtnCourseRegisterAbort = False
|
||||
btnValidate _ _ = True
|
||||
|
||||
|
||||
data AddUsers = AddUsers
|
||||
{ auUsers :: Set Text
|
||||
, auTutorial :: Maybe (CI Text)
|
||||
@ -120,11 +138,32 @@ postCAddUserR tid ssh csh = do
|
||||
}
|
||||
|
||||
|
||||
--confirmAddUser :: ()
|
||||
--confirmAddUser = do
|
||||
-- siteLayoutMsg MsgCourseParticipantsRegisterConfirmationHeading $ do
|
||||
-- setTitleI MsgCourseParticipantsRegisterConfirmationHeading
|
||||
|
||||
confirmAddUser :: Handler Html
|
||||
confirmAddUser = do
|
||||
siteLayoutMsg MsgCourseParticipantsRegisterConfirmationHeading $ do
|
||||
setTitleI MsgCourseParticipantsRegisterConfirmationHeading
|
||||
let
|
||||
confirmCheckBox :: Widget
|
||||
confirmCheckBox = do
|
||||
let sJsonField :: Field (HandlerFor UniWorX) a
|
||||
sJsonField = secretJsonField' $ \theId name attrs val _isReq ->
|
||||
[whamlet|
|
||||
$newline never
|
||||
<input id=#{theId} *{attrs} type=checkbox name=#{name} value=#{either id id val} checked>
|
||||
|]
|
||||
fieldView sJsonField act mempty vAttrs (Right act) False
|
||||
availableActs :: Widget
|
||||
availableActs = fieldView (secretJsonField :: Field Handler (Set csvAction)) "" mempty [] (Right . Set.empty) False
|
||||
(confirmForm', confirmEnctype) <- liftHandler . generateFormPost . withButtonForm' [BtnCourseRegisterConfirm, BtnCourseRegisterAbort] . identifyForm FIDCourseRegisterConfirm $ \csrf -> return (error "No meaningful FormResult", $(widgetFile "course/add-user/confirmation"))
|
||||
let confirmForm = wrapForm confirmForm' FormSettings
|
||||
{ formMethod = POST
|
||||
, formAction = Just $ tblLink id
|
||||
, formEncoding = confirmEnctype
|
||||
, formAttrs = []
|
||||
, formSubmit = FormNoSubmit
|
||||
, formAnchor = Nothing :: Maybe Text
|
||||
}
|
||||
$(widgetFile "course/add-user/confirmation-wrapper")
|
||||
|
||||
|
||||
registerUsers :: CourseId -> Map Text (Maybe UserId) -> WriterT [Message] (YesodJobDB UniWorX) ()
|
||||
|
||||
@ -283,7 +283,7 @@ data FormIdentifier
|
||||
| FIDDBTableCsvImportConfirm Text
|
||||
| FIDDelete
|
||||
| FIDPrintAcknowledge
|
||||
| FIDCourseRegister
|
||||
| FIDCourseRegister | FIDCourseRegisterConfirm
|
||||
| FIDuserRights
|
||||
| FIDUserSystemFunctions
|
||||
| FIDcUserNote
|
||||
|
||||
10
templates/course/add-user/confirmation-wrapper.hamlet
Normal file
10
templates/course/add-user/confirmation-wrapper.hamlet
Normal file
@ -0,0 +1,10 @@
|
||||
$newline never
|
||||
|
||||
$# SPDX-FileCopyrightText: 2022 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>
|
||||
$#
|
||||
$# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
<section>
|
||||
<p>_{MsgCourseAddUserConfirmationTip}
|
||||
<section>
|
||||
^{confirmForm}
|
||||
27
templates/course/add-user/confirmation.hamlet
Normal file
27
templates/course/add-user/confirmation.hamlet
Normal file
@ -0,0 +1,27 @@
|
||||
$newline never
|
||||
|
||||
$# SPDX-FileCopyrightText: 2022 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>
|
||||
$#
|
||||
$# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
#{csrf}
|
||||
^{availableActs}
|
||||
<div .actions>
|
||||
$forall actionClass <- sortOn dbtCsvCoarsenActionClass (Map.keys actionMap)
|
||||
<div .action>
|
||||
<input type=checkbox id=#{actionClassIdent actionClass} .action__checkbox :defaultChecked actionClass:checked>
|
||||
<label .action__label for=#{actionClassIdent actionClass}>
|
||||
^{dbtCsvRenderActionClass actionClass}
|
||||
|
||||
<fieldset .action__fieldset uw-interactive-fieldset .interactive-fieldset__target data-conditional-input=#{actionClassIdent actionClass}>
|
||||
<div .action__checked-counter>
|
||||
<div .action__toggle-all>
|
||||
<input type=checkbox id=#{actionClassIdent actionClass}-toggle-all>
|
||||
<label for=#{actionClassIdent actionClass}-toggle-all .action__option-label>
|
||||
_{MsgDBCsvImportActionToggleAll}
|
||||
<div .action__options>
|
||||
$forall action <- Set.toList (actionMap ! actionClass)
|
||||
<div .action__option>
|
||||
^{csvActionCheckBox [] action}
|
||||
<label .action__option-label for=#{actionIdent action}>
|
||||
^{dbtCsvRenderKey existing action}
|
||||
85
templates/course/add-user/confirmation.julius
Normal file
85
templates/course/add-user/confirmation.julius
Normal file
@ -0,0 +1,85 @@
|
||||
// SPDX-FileCopyrightText: 2022 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
(function() {
|
||||
|
||||
var IMPORT_ACTIONS_SELECTOR = '.actions';
|
||||
var IMPORT_ACTION_SELECTOR = '.action';
|
||||
var IMPORT_ACTION_CHECKBOX_SELECTOR = '.action__checkbox ';
|
||||
var IMPORT_ACTION_OPTIONS_SELECTOR = '.action__options';
|
||||
var IMPORT_ACTION_TOGGLE_ALL_SELECTOR = '.action__toggle-all [type="checkbox"]';
|
||||
var IMPORT_ACTION_CHECKED_COUNTER_SELECTOR = '.action__checked-counter';
|
||||
|
||||
var importActionsElement;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
importActionsElement = document.querySelector(IMPORT_ACTIONS_SELECTOR);
|
||||
|
||||
setupActions();
|
||||
});
|
||||
|
||||
function setupActions() {
|
||||
var actionElements = Array.from(importActionsElement.querySelectorAll(IMPORT_ACTION_SELECTOR));
|
||||
|
||||
actionElements.forEach(function(element) {
|
||||
setupAction(element);
|
||||
});
|
||||
}
|
||||
|
||||
function setupAction(actionElement) {
|
||||
var actionCheckbox = actionElement.querySelector(IMPORT_ACTION_CHECKBOX_SELECTOR);
|
||||
var actionOptions = actionElement.querySelector(IMPORT_ACTION_OPTIONS_SELECTOR);
|
||||
if (actionOptions) {
|
||||
var actionCheckboxes = Array.from(actionOptions.querySelectorAll('[type="checkbox"]'));
|
||||
var toggleAllCheckbox = actionElement.querySelector(IMPORT_ACTION_TOGGLE_ALL_SELECTOR);
|
||||
|
||||
// setup action checkbox to toggle all child checkboxes if changed
|
||||
actionCheckbox.addEventListener('change', function() {
|
||||
actionCheckboxes.forEach(function(checkbox) {
|
||||
checkbox.checked = actionCheckbox.checked;
|
||||
});
|
||||
updateCheckedCounter(actionElement, actionCheckboxes);
|
||||
updateToggleAllCheckbox(toggleAllCheckbox, actionCheckboxes);
|
||||
});
|
||||
|
||||
// update counter and toggle checkbox initially
|
||||
updateCheckedCounter(actionElement, actionCheckboxes);
|
||||
updateToggleAllCheckbox(toggleAllCheckbox, actionCheckboxes);
|
||||
|
||||
// register change listener for individual checkboxes
|
||||
actionCheckboxes.forEach(function(checkbox) {
|
||||
checkbox.addEventListener('change', function() {
|
||||
updateCheckedCounter(actionElement, actionCheckboxes);
|
||||
updateToggleAllCheckbox(toggleAllCheckbox, actionCheckboxes);
|
||||
});
|
||||
});
|
||||
|
||||
// register change listener for toggle all checkbox
|
||||
if (toggleAllCheckbox) {
|
||||
toggleAllCheckbox.addEventListener('change', function() {
|
||||
actionCheckboxes.forEach(function(checkbox) {
|
||||
checkbox.checked = toggleAllCheckbox.checked;
|
||||
});
|
||||
updateCheckedCounter(actionElement, actionCheckboxes);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update checked state of toggle all checkbox based on all other checkboxes
|
||||
function updateToggleAllCheckbox(toggleAllCheckbox, actionCheckboxes) {
|
||||
var allChecked = actionCheckboxes.reduce(function(acc, checkbox) {
|
||||
return acc && checkbox.checked;
|
||||
}, true);
|
||||
toggleAllCheckbox.checked = allChecked;
|
||||
}
|
||||
|
||||
// update value of checked counter
|
||||
function updateCheckedCounter(actionElement, actionCheckboxes) {
|
||||
var checkedCounter = actionElement.querySelector(IMPORT_ACTION_CHECKED_COUNTER_SELECTOR);
|
||||
var checkedCheckboxes = actionCheckboxes.reduce(function(acc, checkbox) { return checkbox.checked ? acc + 1 : acc; }, 0);
|
||||
checkedCounter.innerHTML = checkedCheckboxes + '/' + actionCheckboxes.length;
|
||||
}
|
||||
|
||||
})();
|
||||
Loading…
Reference in New Issue
Block a user