parent
ebcafcc71b
commit
cd70b8ffc4
@ -173,7 +173,6 @@ SheetMarking: Hinweise für Korrektoren
|
|||||||
SheetMarkingFiles: Korrektur
|
SheetMarkingFiles: Korrektur
|
||||||
SheetType: Wertung
|
SheetType: Wertung
|
||||||
SheetInvisible: Dieses Übungsblatt ist für Teilnehmer momentan unsichtbar!
|
SheetInvisible: Dieses Übungsblatt ist für Teilnehmer momentan unsichtbar!
|
||||||
SheetInvisibleUntil date@Text: Dieses Übungsblatt ist für Teilnehmer momentan unsichtbar bis #{date}!
|
|
||||||
SheetName: Name
|
SheetName: Name
|
||||||
SheetDescription: Hinweise für Teilnehmer
|
SheetDescription: Hinweise für Teilnehmer
|
||||||
SheetGroup: Gruppenabgabe
|
SheetGroup: Gruppenabgabe
|
||||||
@ -519,9 +518,9 @@ CorrectorMissing: Abwesend
|
|||||||
CorrectorExcused: Entschuldigt
|
CorrectorExcused: Entschuldigt
|
||||||
CorrectorStateTip: Abwesende Korrektoren bekommen bei späteren Übungsblättern mehr Korrekturen zum Ausgleich zugewiesen. Entschuldigte Korrektoren müssen nicht nacharbeiten.
|
CorrectorStateTip: Abwesende Korrektoren bekommen bei späteren Übungsblättern mehr Korrekturen zum Ausgleich zugewiesen. Entschuldigte Korrektoren müssen nicht nacharbeiten.
|
||||||
|
|
||||||
DayIsAHoliday tid@TermId name@Text date@Text: Datum für "#{name}" ist ein Feiertag: #{date}
|
DayIsAHoliday tid@TermId name@Text date@Text: "#{name}" (#{date}) ist ein Feiertag
|
||||||
DayIsOutOfLecture tid@TermId name@Text date@Text: Datum für "#{name}" ist außerhalb der Vorlesungszeit des #{display tid}: #{date}
|
DayIsOutOfLecture tid@TermId name@Text date@Text: "#{name}" (#{date}) ist außerhalb der Vorlesungszeit des #{display tid}
|
||||||
DayIsOutOfTerm tid@TermId name@Text date@Text: Datum für "#{name}" liegt nicht im Semester #{display tid}: #{date}
|
DayIsOutOfTerm tid@TermId name@Text date@Text: "#{name}" (#{date}) liegt nicht im Semester #{display tid}
|
||||||
|
|
||||||
UploadModeNone: Kein Upload
|
UploadModeNone: Kein Upload
|
||||||
UploadModeAny: Upload, beliebige Datei(en)
|
UploadModeAny: Upload, beliebige Datei(en)
|
||||||
@ -547,7 +546,7 @@ CorrectorSubmissions: Abgabe extern mit Pseudonym
|
|||||||
UserSubmissions: Direkte Abgabe
|
UserSubmissions: Direkte Abgabe
|
||||||
BothSubmissions: Abgabe direkt & extern mit Pseudonym
|
BothSubmissions: Abgabe direkt & extern mit Pseudonym
|
||||||
|
|
||||||
SheetCorrectorSubmissionsTip: Abgabe erfolgt über ein Uni2work-externes Verfahren (zumeist in Papierform durch Einwurf) unter Angabe eines persönlichen Pseudonyms. Korrektorn können mithilfe des Pseudonyms später Korrekturergebnisse in Uni2work eintragen, damit Sie sie einsehen können.
|
SheetCorrectorSubmissionsTip: Abgabe erfolgt über ein Uni2work-externes Verfahren (zumeist in Papierform durch Einwurf) unter Angabe eines persönlichen Pseudonyms. Korrektoren können mithilfe des Pseudonyms später Korrekturergebnisse in Uni2work eintragen, damit Sie sie einsehen können.
|
||||||
|
|
||||||
SubmissionNoUploadExpected: Es ist keine Abgabe von Dateien vorgesehen.
|
SubmissionNoUploadExpected: Es ist keine Abgabe von Dateien vorgesehen.
|
||||||
SubmissionReplace: Abgabe ersetzen
|
SubmissionReplace: Abgabe ersetzen
|
||||||
|
|||||||
6102
package-lock.json
generated
6102
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -71,6 +71,7 @@
|
|||||||
"webpack-cli": "^3.3.2"
|
"webpack-cli": "^3.3.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"flatpickr": "^4.5.7"
|
"flatpickr": "^4.5.7",
|
||||||
|
"npm": "^6.9.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -447,7 +447,10 @@ correctionsR whereClause displayColumns dbtFilterUI psValidator actions = do
|
|||||||
unless (null unassignedUnauth) $ do
|
unless (null unassignedUnauth) $ do
|
||||||
let submissionEncrypt = encrypt :: SubmissionId -> DB CryptoFileNameSubmission
|
let submissionEncrypt = encrypt :: SubmissionId -> DB CryptoFileNameSubmission
|
||||||
unassignedUnauth' <- mapM submissionEncrypt $ Set.toList unassignedUnauth
|
unassignedUnauth' <- mapM submissionEncrypt $ Set.toList unassignedUnauth
|
||||||
$(addMessageFile Warning "templates/messages/submissionsAssignUnauthorized.hamlet")
|
let numUnassignedUnauth = fromIntegral $ length unassignedUnauth'
|
||||||
|
trigger = [whamlet|_{MsgSubmissionsAssignUnauthorized numUnassignedUnauth}|]
|
||||||
|
content = Right $(widgetFile "messages/submissionsAssignUnauthorized")
|
||||||
|
addMessageModal Warning trigger content
|
||||||
unless (null unassignedAuth) $ do
|
unless (null unassignedAuth) $ do
|
||||||
num <- updateWhereCount [SubmissionId <-. Set.toList unassignedAuth]
|
num <- updateWhereCount [SubmissionId <-. Set.toList unassignedAuth]
|
||||||
[ SubmissionRatingBy =. Just uid
|
[ SubmissionRatingBy =. Just uid
|
||||||
@ -497,7 +500,10 @@ correctionsR whereClause displayColumns dbtFilterUI psValidator actions = do
|
|||||||
unless (null unassignedUnauth) $ do
|
unless (null unassignedUnauth) $ do
|
||||||
let submissionEncrypt = encrypt :: SubmissionId -> DB CryptoFileNameSubmission
|
let submissionEncrypt = encrypt :: SubmissionId -> DB CryptoFileNameSubmission
|
||||||
unassignedUnauth' <- mapM submissionEncrypt $ Set.toList unassignedUnauth
|
unassignedUnauth' <- mapM submissionEncrypt $ Set.toList unassignedUnauth
|
||||||
$(addMessageFile Warning "templates/messages/submissionsAssignUnauthorized.hamlet")
|
let numUnassignedUnauth = fromIntegral $ length unassignedUnauth'
|
||||||
|
trigger = [whamlet|_{MsgSubmissionsAssignUnauthorized numUnassignedUnauth}|]
|
||||||
|
content = Right $(widgetFile "messages/submissionsAssignUnauthorized")
|
||||||
|
addMessageModal Warning trigger content
|
||||||
unless (null unassignedAuth) $ do
|
unless (null unassignedAuth) $ do
|
||||||
(assigned, stillUnassigned) <- assignSubmissions shid (Just unassignedAuth)
|
(assigned, stillUnassigned) <- assignSubmissions shid (Just unassignedAuth)
|
||||||
unless (null assigned) $
|
unless (null assigned) $
|
||||||
@ -881,8 +887,8 @@ postCorrectionsCreateR = do
|
|||||||
, submissionRatingAssigned = Just now
|
, submissionRatingAssigned = Just now
|
||||||
, submissionRatingTime = Nothing
|
, submissionRatingTime = Nothing
|
||||||
}
|
}
|
||||||
unless (null duplicate)
|
unless (null duplicate) $
|
||||||
$(addMessageFile Warning "templates/messages/submissionCreateDuplicates.hamlet")
|
addMessageModal Warning [whamlet|_{MsgSheetDuplicatePseudonym}|] $ Right $(widgetFile "messages/submissionCreateDuplicates")
|
||||||
existingSubUsers <- E.select . E.from $ \(submissionUser `E.InnerJoin` submission) -> do
|
existingSubUsers <- E.select . E.from $ \(submissionUser `E.InnerJoin` submission) -> do
|
||||||
E.on $ submission E.^. SubmissionId E.==. submissionUser E.^. SubmissionUserSubmission
|
E.on $ submission E.^. SubmissionId E.==. submissionUser E.^. SubmissionUserSubmission
|
||||||
E.where_ $ submissionUser E.^. SubmissionUserUser `E.in_` E.valList (sheetPseudonymUser <$> concat sps')
|
E.where_ $ submissionUser E.^. SubmissionUserUser `E.in_` E.valList (sheetPseudonymUser <$> concat sps')
|
||||||
@ -890,7 +896,9 @@ postCorrectionsCreateR = do
|
|||||||
return submissionUser
|
return submissionUser
|
||||||
unless (null existingSubUsers) . mapReaderT lift $ do
|
unless (null existingSubUsers) . mapReaderT lift $ do
|
||||||
(Map.toList -> subs) <- foldrM (\(Entity _ SubmissionUser{..}) mp -> Map.insertWith (<>) <$> (encrypt submissionUserSubmission :: DB CryptoFileNameSubmission) <*> pure (Set.fromList . map sheetPseudonymPseudonym . filter (\SheetPseudonym{..} -> sheetPseudonymUser == submissionUserUser) $ concat sps') <*> pure mp) Map.empty existingSubUsers
|
(Map.toList -> subs) <- foldrM (\(Entity _ SubmissionUser{..}) mp -> Map.insertWith (<>) <$> (encrypt submissionUserSubmission :: DB CryptoFileNameSubmission) <*> pure (Set.fromList . map sheetPseudonymPseudonym . filter (\SheetPseudonym{..} -> sheetPseudonymUser == submissionUserUser) $ concat sps') <*> pure mp) Map.empty existingSubUsers
|
||||||
$(addMessageFile Warning "templates/messages/submissionCreateExisting.hamlet")
|
let trigger = [whamlet|_{MsgSheetCreateExisting}|]
|
||||||
|
content = Right $(widgetFile "messages/submissionCreateExisting")
|
||||||
|
addMessageModal Warning trigger content
|
||||||
let sps'' = filter (not . null) $ filter (\spGroup -> not . flip any spGroup $ \SheetPseudonym{sheetPseudonymUser} -> sheetPseudonymUser `elem` map (submissionUserUser . entityVal) existingSubUsers) sps'
|
let sps'' = filter (not . null) $ filter (\spGroup -> not . flip any spGroup $ \SheetPseudonym{sheetPseudonymUser} -> sheetPseudonymUser `elem` map (submissionUserUser . entityVal) existingSubUsers) sps'
|
||||||
forM_ sps'' $ \spGroup
|
forM_ sps'' $ \spGroup
|
||||||
-> let
|
-> let
|
||||||
|
|||||||
@ -406,10 +406,6 @@ getSShowR tid ssh csh shn = do
|
|||||||
hasHints <- (/= 0) <$> count [ SheetFileSheet ==. sid, SheetFileType ==. SheetHint ]
|
hasHints <- (/= 0) <$> count [ SheetFileSheet ==. sid, SheetFileType ==. SheetHint ]
|
||||||
hasSolution <- (/= 0) <$> count [ SheetFileSheet ==. sid, SheetFileType ==. SheetSolution ]
|
hasSolution <- (/= 0) <$> count [ SheetFileSheet ==. sid, SheetFileType ==. SheetSolution ]
|
||||||
return (hasHints, hasSolution)
|
return (hasHints, hasSolution)
|
||||||
cTime <- Just <$> liftIO getCurrentTime
|
|
||||||
visibleFrom <- traverse (formatTime SelFormatDateTime) $ sheetVisibleFrom sheet
|
|
||||||
when (NTop (sheetVisibleFrom sheet) >= NTop cTime) $ addMessageI Warning $
|
|
||||||
maybe MsgSheetInvisible MsgSheetInvisibleUntil visibleFrom
|
|
||||||
mPseudonym <- runMaybeT $ do
|
mPseudonym <- runMaybeT $ do
|
||||||
uid <- MaybeT maybeAuthId
|
uid <- MaybeT maybeAuthId
|
||||||
Entity _ SheetPseudonym{sheetPseudonymPseudonym} <- MaybeT . runDB . getBy $ UniqueSheetPseudonymUser sid uid
|
Entity _ SheetPseudonym{sheetPseudonymPseudonym} <- MaybeT . runDB . getBy $ UniqueSheetPseudonymUser sid uid
|
||||||
@ -421,12 +417,14 @@ getSShowR tid ssh csh shn = do
|
|||||||
, formEncoding = generateEnctype
|
, formEncoding = generateEnctype
|
||||||
, formSubmit = FormNoSubmit
|
, formSubmit = FormNoSubmit
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultLayout $ do
|
defaultLayout $ do
|
||||||
setTitleI $ prependCourseTitle tid ssh csh $ SomeMessage shn
|
setTitleI $ prependCourseTitle tid ssh csh $ SomeMessage shn
|
||||||
sheetFrom <- formatTime SelFormatDateTime $ sheetActiveFrom sheet
|
let visibleFrom = visibleUTCTime SelFormatDateTime <$> sheetVisibleFrom sheet
|
||||||
sheetTo <- formatTime SelFormatDateTime $ sheetActiveTo sheet
|
sheetFrom <- formatTime SelFormatDateTime $ sheetActiveFrom sheet
|
||||||
hintsFrom <- traverse (formatTime SelFormatDateTime) $ sheetHintFrom sheet
|
sheetTo <- formatTime SelFormatDateTime $ sheetActiveTo sheet
|
||||||
solutionFrom <- traverse (formatTime SelFormatDateTime) $ sheetSolutionFrom sheet
|
hintsFrom <- traverse (formatTime SelFormatDateTime) $ sheetHintFrom sheet
|
||||||
|
solutionFrom <- traverse (formatTime SelFormatDateTime) $ sheetSolutionFrom sheet
|
||||||
markingText <- runMaybeT $ assertM_ (Authorized ==) (evalAccessCorrector tid ssh csh) >> hoistMaybe (sheetMarkingText sheet)
|
markingText <- runMaybeT $ assertM_ (Authorized ==) (evalAccessCorrector tid ssh csh) >> hoistMaybe (sheetMarkingText sheet)
|
||||||
$(widgetFile "sheetShow")
|
$(widgetFile "sheetShow")
|
||||||
|
|
||||||
@ -702,11 +700,14 @@ correctorForm shid = wFormToAForm $ do
|
|||||||
| applyDefaultLoads = defaultLoads'
|
| applyDefaultLoads = defaultLoads'
|
||||||
| otherwise = currentLoads'
|
| otherwise = currentLoads'
|
||||||
|
|
||||||
when (not (Map.null loads) && applyDefaultLoads) $
|
|
||||||
addMessageI Warning MsgCorrectorsDefaulted
|
|
||||||
|
|
||||||
countTutRes <- wreq checkBoxField (fslI MsgCountTutProp & setTooltip MsgCountTutPropTip) . Just . any (\(_, Load{..}) -> fromMaybe False byTutorial) $ Map.elems loads
|
countTutRes <- wreq checkBoxField (fslI MsgCountTutProp & setTooltip MsgCountTutPropTip) . Just . any (\(_, Load{..}) -> fromMaybe False byTutorial) $ Map.elems loads
|
||||||
|
|
||||||
|
-- when (not (Map.null loads) && applyDefaultLoads) $ -- Alert Message
|
||||||
|
-- addMessageI Warning MsgCorrectorsDefaulted
|
||||||
|
when (not (Map.null loads) && applyDefaultLoads) $ -- Alert Notification
|
||||||
|
wformMessage =<< messageI Warning MsgCorrectorsDefaulted
|
||||||
|
|
||||||
|
|
||||||
let
|
let
|
||||||
previousCorrectors :: E.SqlQuery (E.SqlExpr (Entity User))
|
previousCorrectors :: E.SqlQuery (E.SqlExpr (Entity User))
|
||||||
previousCorrectors = E.from $ \(user `E.InnerJoin` sheetCorrector `E.InnerJoin` sheet `E.InnerJoin` course `E.InnerJoin` lecturer) -> do
|
previousCorrectors = E.from $ \(user `E.InnerJoin` sheetCorrector `E.InnerJoin` sheet `E.InnerJoin` course `E.InnerJoin` lecturer) -> do
|
||||||
|
|||||||
@ -533,6 +533,11 @@ renderWForm formLayout = renderAForm formLayout . wFormToAForm
|
|||||||
idFormSectionNoinput :: Text
|
idFormSectionNoinput :: Text
|
||||||
idFormSectionNoinput = "form-section-noinput"
|
idFormSectionNoinput = "form-section-noinput"
|
||||||
|
|
||||||
|
-- | special id to identify form messages, see 'aformMessage' and 'formMessage'
|
||||||
|
-- currently only treated by form generation through 'renderAForm'
|
||||||
|
idFormMessageNoinput :: Text
|
||||||
|
idFormMessageNoinput = "form-message-noinput"
|
||||||
|
|
||||||
-- | Generates a form having just a form-section-header and no input title.
|
-- | Generates a form having just a form-section-header and no input title.
|
||||||
-- Currently only correctly rendered by 'renderAForm' and mforms using 'widget/form.hamlet'
|
-- Currently only correctly rendered by 'renderAForm' and mforms using 'widget/form.hamlet'
|
||||||
-- Usage:
|
-- Usage:
|
||||||
@ -550,7 +555,7 @@ aformSection = formToAForm . fmap (second pure) . formSection
|
|||||||
wformSection :: (MonadHandler m, RenderMessage (HandlerSite m) msg) => msg -> WForm m ()
|
wformSection :: (MonadHandler m, RenderMessage (HandlerSite m) msg) => msg -> WForm m ()
|
||||||
wformSection = void . aFormToWForm . aformSection
|
wformSection = void . aFormToWForm . aformSection
|
||||||
|
|
||||||
formSection :: (MonadHandler m, site ~ HandlerSite m, RenderMessage site msg) => msg -> MForm m (FormResult (), FieldView site) -- TODO: WIP, delete
|
formSection :: (MonadHandler m, site ~ HandlerSite m, RenderMessage site msg) => msg -> MForm m (FormResult (), FieldView site)
|
||||||
formSection formSectionTitle = do
|
formSection formSectionTitle = do
|
||||||
mr <- getMessageRender
|
mr <- getMessageRender
|
||||||
return (FormSuccess (), FieldView
|
return (FormSuccess (), FieldView
|
||||||
@ -562,8 +567,6 @@ formSection formSectionTitle = do
|
|||||||
, fvInput = mempty
|
, fvInput = mempty
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-------------------
|
-------------------
|
||||||
-- Special Forms --
|
-- Special Forms --
|
||||||
-------------------
|
-------------------
|
||||||
@ -582,6 +585,33 @@ formSection' formSectionTitleSettings = mreq noinputField sectionSettings Nothin
|
|||||||
sectionSettings = formSectionTitleSettings { fsId = Just idFormSectionNoinput }
|
sectionSettings = formSectionTitleSettings { fsId = Just idFormSectionNoinput }
|
||||||
|
|
||||||
|
|
||||||
|
-- | Similar to aformSection, generates a form having just a view widget, but no input.
|
||||||
|
-- Currently only correctly rendered by 'renderAForm' and mforms using 'widget/form.hamlet'
|
||||||
|
-- Usage:
|
||||||
|
-- @
|
||||||
|
-- (,) <$ formMessage (Message Info html1)
|
||||||
|
-- <*> areq intField "int here" Nothing
|
||||||
|
-- <* formSection (Message Warning html2)
|
||||||
|
-- <*> areq doubleField "double there " Nothing
|
||||||
|
-- <* submitButton
|
||||||
|
-- @
|
||||||
|
|
||||||
|
aformMessage :: (MonadHandler m) => Message -> AForm m ()
|
||||||
|
aformMessage = formToAForm . fmap (second pure) . formMessage
|
||||||
|
|
||||||
|
wformMessage :: (MonadHandler m) => Message -> WForm m ()
|
||||||
|
wformMessage = void . aFormToWForm . aformMessage
|
||||||
|
|
||||||
|
formMessage :: (MonadHandler m) => Message -> MForm m (FormResult (), FieldView site)
|
||||||
|
formMessage Message{..} = do
|
||||||
|
return (FormSuccess (), FieldView
|
||||||
|
{ fvLabel = mempty
|
||||||
|
, fvTooltip = Nothing
|
||||||
|
, fvId = idFormMessageNoinput
|
||||||
|
, fvErrors = Nothing
|
||||||
|
, fvRequired = False
|
||||||
|
, fvInput = [whamlet|<div .notification .notification-#{toPathPiece messageStatus}>#{messageContent}|]
|
||||||
|
})
|
||||||
|
|
||||||
---------------------
|
---------------------
|
||||||
-- Form evaluation --
|
-- Form evaluation --
|
||||||
|
|||||||
@ -554,3 +554,55 @@ section {
|
|||||||
.headline-one {
|
.headline-one {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Notification style used as requested by @hamanf in #298, but class was not globally available. Copied from dead-code. For @hamanf to clean up: */
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
position: relative;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 10px 20px 20px;
|
||||||
|
margin: 40px 0;
|
||||||
|
color: var(--color-dark);
|
||||||
|
box-shadow: 0 0 4px 2px inset currentColor;
|
||||||
|
padding-left: 20%;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: 'i';
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 20%;
|
||||||
|
font-size: 100px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
|
||||||
|
padding-left: 40px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
height: auto;
|
||||||
|
width: 45px;
|
||||||
|
font-size: 40px;
|
||||||
|
top: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-danger {
|
||||||
|
color: #c51919 ;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '!';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification__content {
|
||||||
|
color: var(--color-font);
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
_{MsgSubmissionsAssignUnauthorized (fromIntegral (length unassignedUnauth'))}
|
_{MsgSubmissionsAssignUnauthorized numUnassignedUnauth}
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
$forall cID <- unassignedUnauth'
|
$forall cID <- unassignedUnauth'
|
||||||
|
|||||||
@ -7,6 +7,13 @@ $maybe descr <- sheetDescription sheet
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<dl .deflist>
|
<dl .deflist>
|
||||||
|
<dt .deflist__dt>_{MsgAccessibleSince}
|
||||||
|
<dd .deflist__dd>
|
||||||
|
$maybe invisible <- visibleFrom
|
||||||
|
^{invisible}
|
||||||
|
$nothing
|
||||||
|
#{isVisible False}
|
||||||
|
_{MsgSheetInvisible}
|
||||||
<dt .deflist__dt>_{MsgSheetActiveFrom}
|
<dt .deflist__dt>_{MsgSheetActiveFrom}
|
||||||
<dd .deflist__dd>#{sheetFrom}
|
<dd .deflist__dd>#{sheetFrom}
|
||||||
<dt .deflist__dt>_{MsgSheetActiveTo}
|
<dt .deflist__dt>_{MsgSheetActiveTo}
|
||||||
|
|||||||
Reference in New Issue
Block a user