feat(csv): add column explanations
BREAKING CHANGE: CsvColumnsExplained now required
This commit is contained in:
parent
e9b86cd3fb
commit
c8dca945cf
@ -83,6 +83,10 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.modal__trigger {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.modal__trigger-label {
|
.modal__trigger-label {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
|||||||
@ -1195,3 +1195,17 @@ BtnCsvExport: CSV-Datei exportieren
|
|||||||
BtnCsvImport: CSV-Datei importieren
|
BtnCsvImport: CSV-Datei importieren
|
||||||
|
|
||||||
Proportion c@Text of@Text prop@Rational: #{c}/#{of} (#{rationalToFixed2 (100 * prop)}%)
|
Proportion c@Text of@Text prop@Rational: #{c}/#{of} (#{rationalToFixed2 (100 * prop)}%)
|
||||||
|
|
||||||
|
CsvColumnsExplanationsLabel: Spalten
|
||||||
|
CsvColumnsExplanationsTip: Bedeutung der in der CSV-Datei enthaltenen Spalten
|
||||||
|
CsvColumnExamUserSurname: Nachname des Teilnehmers
|
||||||
|
CsvColumnExamUserName: Voller Name des Teilnehmers (inkl. Nachname)
|
||||||
|
CsvColumnExamUserMatriculation: Matrikelnummer des Teilnehmers
|
||||||
|
CsvColumnExamUserField: Hauptfach, mit dem der Teilnehmer seine Kursanmeldung assoziiert hat
|
||||||
|
CsvColumnExamUserDegree: Abschluss, den der Teilnehmer im assoziierten Hauptfach anstrebt
|
||||||
|
CsvColumnExamUserSemester: Fachsemester des Teilnehmers im assoziierten Hauptfach
|
||||||
|
CsvColumnExamUserOccurrence: Prüfungstermin/-Raum, zu dem der Teilnehmer angemeldet ist
|
||||||
|
CsvColumnExamUserExercisePoints: Anzahl von Punkten, die der Teilnehmer im Übungsbetrieb erreicht hat
|
||||||
|
CsvColumnExamUserExercisePointsMax: Maximale Anzahl von Punkten, die der Teilnehmer im Übungsbetrieb bis zu seinem Klausurtermin erreichen hätte können
|
||||||
|
CsvColumnExamUserExercisePasses: Anzahl von Übungsblättern, die der Teilnehmer bestanden hat
|
||||||
|
CsvColumnExamUserExercisePassesMax: Maximale Anzahl von Übungsblättern, die der Teilnehmer bis zu seinem Klausurtermin bestehen hätte können
|
||||||
@ -832,9 +832,9 @@ data ExamUserTableCsv = ExamUserTableCsv
|
|||||||
, csvEUserDegree :: Maybe Text
|
, csvEUserDegree :: Maybe Text
|
||||||
, csvEUserSemester :: Maybe Int
|
, csvEUserSemester :: Maybe Int
|
||||||
, csvEUserOccurrence :: Maybe (CI Text)
|
, csvEUserOccurrence :: Maybe (CI Text)
|
||||||
, csvEUserExercisePoints, csvEUserExercisePassPoints :: Maybe Points
|
, csvEUserExercisePoints :: Maybe Points
|
||||||
, csvEUserExercisePasses :: Maybe Int
|
, csvEUserExercisePasses :: Maybe Int
|
||||||
, csvEUserExercisePointsMax, csvEUserExercisePassPointsMax :: Maybe Points
|
, csvEUserExercisePointsMax :: Maybe Points
|
||||||
, csvEUserExercisePassesMax :: Maybe Int
|
, csvEUserExercisePassesMax :: Maybe Int
|
||||||
}
|
}
|
||||||
deriving (Generic)
|
deriving (Generic)
|
||||||
@ -851,6 +851,21 @@ instance FromNamedRecord ExamUserTableCsv where
|
|||||||
instance DefaultOrdered ExamUserTableCsv where
|
instance DefaultOrdered ExamUserTableCsv where
|
||||||
headerOrder = Csv.genericHeaderOrder examUserTableCsvOptions
|
headerOrder = Csv.genericHeaderOrder examUserTableCsvOptions
|
||||||
|
|
||||||
|
instance CsvColumnsExplained ExamUserTableCsv where
|
||||||
|
csvColumnsExplanations = genericCsvColumnsExplanations examUserTableCsvOptions $ Map.fromList
|
||||||
|
[ ('csvEUserSurname , MsgCsvColumnExamUserSurname )
|
||||||
|
, ('csvEUserName , MsgCsvColumnExamUserName )
|
||||||
|
, ('csvEUserMatriculation , MsgCsvColumnExamUserMatriculation )
|
||||||
|
, ('csvEUserField , MsgCsvColumnExamUserField )
|
||||||
|
, ('csvEUserDegree , MsgCsvColumnExamUserDegree )
|
||||||
|
, ('csvEUserSemester , MsgCsvColumnExamUserSemester )
|
||||||
|
, ('csvEUserOccurrence , MsgCsvColumnExamUserOccurrence )
|
||||||
|
, ('csvEUserExercisePoints , MsgCsvColumnExamUserExercisePoints )
|
||||||
|
, ('csvEUserExercisePasses , MsgCsvColumnExamUserExercisePasses )
|
||||||
|
, ('csvEUserExercisePointsMax, MsgCsvColumnExamUserExercisePointsMax )
|
||||||
|
, ('csvEUserExercisePassesMax, MsgCsvColumnExamUserExercisePassesMax )
|
||||||
|
]
|
||||||
|
|
||||||
getEUsersR, postEUsersR :: TermId -> SchoolId -> CourseShorthand -> ExamName -> Handler Html
|
getEUsersR, postEUsersR :: TermId -> SchoolId -> CourseShorthand -> ExamName -> Handler Html
|
||||||
getEUsersR = postEUsersR
|
getEUsersR = postEUsersR
|
||||||
postEUsersR tid ssh csh examn = do
|
postEUsersR tid ssh csh examn = do
|
||||||
@ -861,8 +876,7 @@ postEUsersR tid ssh csh examn = do
|
|||||||
let
|
let
|
||||||
allBoni = (mappend <$> normalSummary <*> bonusSummary) $ fold bonus
|
allBoni = (mappend <$> normalSummary <*> bonusSummary) $ fold bonus
|
||||||
showPasses = numSheetsPasses allBoni /= 0
|
showPasses = numSheetsPasses allBoni /= 0
|
||||||
showPoints = getSum (numSheetsPoints allBoni) - getSum (numSheetsPassPoints allBoni) /= 0
|
showPoints = getSum (numSheetsPoints allBoni) /= 0
|
||||||
showPassPoints = numSheetsPassPoints allBoni /= 0
|
|
||||||
|
|
||||||
let
|
let
|
||||||
examUsersDBTable = DBTable{..}
|
examUsersDBTable = DBTable{..}
|
||||||
@ -891,14 +905,10 @@ postEUsersR tid ssh csh examn = do
|
|||||||
SheetGradeSummary{achievedPasses} <- examBonusAchieved uid bonus
|
SheetGradeSummary{achievedPasses} <- examBonusAchieved uid bonus
|
||||||
SheetGradeSummary{numSheetsPasses} <- examBonusPossible uid bonus
|
SheetGradeSummary{numSheetsPasses} <- examBonusPossible uid bonus
|
||||||
return $ propCell (getSum achievedPasses) (getSum numSheetsPasses)
|
return $ propCell (getSum achievedPasses) (getSum numSheetsPasses)
|
||||||
, guardOn showPassPoints $ sortable Nothing (i18nCell MsgAchievedPassPoints) $ \(view $ resultUser . _entityKey -> uid) -> fromMaybe mempty $ do
|
|
||||||
SheetGradeSummary{achievedPassPoints} <- examBonusAchieved uid bonus
|
|
||||||
SheetGradeSummary{sumSheetsPassPoints} <- examBonusPossible uid bonus
|
|
||||||
return $ propCell (getSum achievedPassPoints) (getSum sumSheetsPassPoints)
|
|
||||||
, guardOn showPoints $ sortable Nothing (i18nCell MsgAchievedPoints) $ \(view $ resultUser . _entityKey -> uid) -> fromMaybe mempty $ do
|
, guardOn showPoints $ sortable Nothing (i18nCell MsgAchievedPoints) $ \(view $ resultUser . _entityKey -> uid) -> fromMaybe mempty $ do
|
||||||
SheetGradeSummary{achievedPoints, achievedPassPoints} <- examBonusAchieved uid bonus
|
SheetGradeSummary{achievedPoints} <- examBonusAchieved uid bonus
|
||||||
SheetGradeSummary{sumSheetsPoints, sumSheetsPassPoints} <- examBonusPossible uid bonus
|
SheetGradeSummary{sumSheetsPoints} <- examBonusPossible uid bonus
|
||||||
return $ propCell (getSum achievedPoints - getSum achievedPassPoints) (getSum sumSheetsPoints - getSum sumSheetsPassPoints)
|
return $ propCell (getSum achievedPoints) (getSum sumSheetsPoints)
|
||||||
]
|
]
|
||||||
dbtSorting = Map.fromList
|
dbtSorting = Map.fromList
|
||||||
[ sortUserNameLink queryUser
|
[ sortUserNameLink queryUser
|
||||||
@ -940,10 +950,8 @@ postEUsersR tid ssh csh examn = do
|
|||||||
<*> preview (resultStudyFeatures . _entityVal . _studyFeaturesSemester)
|
<*> preview (resultStudyFeatures . _entityVal . _studyFeaturesSemester)
|
||||||
<*> preview (resultExamOccurrence . _entityVal . _examOccurrenceName)
|
<*> preview (resultExamOccurrence . _entityVal . _examOccurrenceName)
|
||||||
<*> preview (resultUser . _entityKey . to (examBonusAchieved ?? bonus) . _Just . _achievedPoints . _Wrapped)
|
<*> preview (resultUser . _entityKey . to (examBonusAchieved ?? bonus) . _Just . _achievedPoints . _Wrapped)
|
||||||
<*> preview (resultUser . _entityKey . to (examBonusAchieved ?? bonus) . _Just . _achievedPassPoints . _Wrapped)
|
|
||||||
<*> preview (resultUser . _entityKey . to (examBonusAchieved ?? bonus) . _Just . _achievedPasses . _Wrapped . integral)
|
<*> preview (resultUser . _entityKey . to (examBonusAchieved ?? bonus) . _Just . _achievedPasses . _Wrapped . integral)
|
||||||
<*> preview (resultUser . _entityKey . to (examBonusPossible ?? bonus) . _Just . _sumSheetsPoints . _Wrapped)
|
<*> preview (resultUser . _entityKey . to (examBonusPossible ?? bonus) . _Just . _sumSheetsPoints . _Wrapped)
|
||||||
<*> preview (resultUser . _entityKey . to (examBonusPossible ?? bonus) . _Just . _sumSheetsPassPoints . _Wrapped)
|
|
||||||
<*> preview (resultUser . _entityKey . to (examBonusPossible ?? bonus) . _Just . _numSheetsPasses . _Wrapped . integral)
|
<*> preview (resultUser . _entityKey . to (examBonusPossible ?? bonus) . _Just . _numSheetsPasses . _Wrapped . integral)
|
||||||
dbtCsvDecode = Nothing
|
dbtCsvDecode = Nothing
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ module Handler.Utils.Table.Pagination
|
|||||||
, FilterColumn(..), IsFilterColumn
|
, FilterColumn(..), IsFilterColumn
|
||||||
, DBRow(..), _dbrOutput, _dbrIndex, _dbrCount
|
, DBRow(..), _dbrOutput, _dbrIndex, _dbrCount
|
||||||
, DBStyle(..), defaultDBSFilterLayout, DBEmptyStyle(..)
|
, DBStyle(..), defaultDBSFilterLayout, DBEmptyStyle(..)
|
||||||
|
, module Handler.Utils.Table.Pagination.CsvColumnExplanations
|
||||||
, DBTCsvEncode, DBTCsvDecode
|
, DBTCsvEncode, DBTCsvDecode
|
||||||
, DBTable(..), noCsvEncode, IsDBTable(..), DBCell(..)
|
, DBTable(..), noCsvEncode, IsDBTable(..), DBCell(..)
|
||||||
, singletonFilter
|
, singletonFilter
|
||||||
@ -34,6 +35,7 @@ module Handler.Utils.Table.Pagination
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Handler.Utils.Table.Pagination.Types
|
import Handler.Utils.Table.Pagination.Types
|
||||||
|
import Handler.Utils.Table.Pagination.CsvColumnExplanations
|
||||||
import Handler.Utils.Form
|
import Handler.Utils.Form
|
||||||
import Handler.Utils.Csv
|
import Handler.Utils.Csv
|
||||||
import Handler.Utils.ContentDisposition
|
import Handler.Utils.ContentDisposition
|
||||||
@ -439,7 +441,7 @@ instance PathPiece x => PathPiece (WithIdent x) where
|
|||||||
WithIdent <$> pure ident <*> fromPathPiece rest
|
WithIdent <$> pure ident <*> fromPathPiece rest
|
||||||
|
|
||||||
|
|
||||||
type DBTCsvEncode r' csv = DictMaybe (ToNamedRecord csv, DefaultOrdered csv) (Conduit r' (YesodDB UniWorX) csv)
|
type DBTCsvEncode r' csv = DictMaybe (ToNamedRecord csv, DefaultOrdered csv, CsvColumnsExplained csv) (Conduit r' (YesodDB UniWorX) csv)
|
||||||
type DBTCsvDecode csv = DictMaybe (FromNamedRecord csv) (Sink csv (YesodDB UniWorX) ())
|
type DBTCsvDecode csv = DictMaybe (FromNamedRecord csv) (Sink csv (YesodDB UniWorX) ())
|
||||||
|
|
||||||
data DBTable m x = forall a r r' h i t k k' csv.
|
data DBTable m x = forall a r r' h i t k k' csv.
|
||||||
@ -462,7 +464,7 @@ data DBTable m x = forall a r r' h i t k k' csv.
|
|||||||
, dbtIdent :: i
|
, dbtIdent :: i
|
||||||
}
|
}
|
||||||
|
|
||||||
noCsvEncode :: DictMaybe (ToNamedRecord Void, DefaultOrdered Void) (Conduit r' (YesodDB UniWorX) Void)
|
noCsvEncode :: DictMaybe (ToNamedRecord Void, DefaultOrdered Void, CsvColumnsExplained Void) (Conduit r' (YesodDB UniWorX) Void)
|
||||||
noCsvEncode = Nothing
|
noCsvEncode = Nothing
|
||||||
|
|
||||||
class (MonadHandler m, HandlerSite m ~ UniWorX, Monoid' x, Monoid' (DBCell m x), Default (DBParams m x)) => IsDBTable (m :: * -> *) (x :: *) where
|
class (MonadHandler m, HandlerSite m ~ UniWorX, Monoid' x, Monoid' (DBCell m x), Default (DBParams m x)) => IsDBTable (m :: * -> *) (x :: *) where
|
||||||
@ -768,7 +770,7 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db
|
|||||||
{ formMethod = GET
|
{ formMethod = GET
|
||||||
, formAction = Just $ tblLink id
|
, formAction = Just $ tblLink id
|
||||||
, formEncoding = csvExportEnctype
|
, formEncoding = csvExportEnctype
|
||||||
, formAttrs = [("target", "_blank")]
|
, formAttrs = [("target", "_blank"), ("class", "form--inline")]
|
||||||
, formSubmit = FormNoSubmit
|
, formSubmit = FormNoSubmit
|
||||||
, formAnchor = Nothing :: Maybe Text
|
, formAnchor = Nothing :: Maybe Text
|
||||||
}
|
}
|
||||||
@ -780,6 +782,12 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db
|
|||||||
, formSubmit = FormSubmit
|
, formSubmit = FormSubmit
|
||||||
, formAnchor = Nothing :: Maybe Text
|
, formAnchor = Nothing :: Maybe Text
|
||||||
}
|
}
|
||||||
|
csvColExplanations = case dbtCsvEncode of
|
||||||
|
(Just (Dict, _) :: DBTCsvEncode _ csv) -> assertM' (not . null) . Map.toList . csvColumnsExplanations $ Proxy @csv
|
||||||
|
Nothing -> Nothing
|
||||||
|
csvColExplanations' = case csvColExplanations of
|
||||||
|
Just csvColExplanations'' -> modal [whamlet|_{MsgCsvColumnsExplanationsLabel}|] $ Right $(widgetFile "table/csv-column-explanations")
|
||||||
|
Nothing -> mempty
|
||||||
|
|
||||||
|
|
||||||
rows' <- E.select . E.from $ \t -> do
|
rows' <- E.select . E.from $ \t -> do
|
||||||
|
|||||||
70
src/Handler/Utils/Table/Pagination/CsvColumnExplanations.hs
Normal file
70
src/Handler/Utils/Table/Pagination/CsvColumnExplanations.hs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
module Handler.Utils.Table.Pagination.CsvColumnExplanations
|
||||||
|
( CsvColumnsExplained(..)
|
||||||
|
, genericCsvColumnsExplanations
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Import
|
||||||
|
|
||||||
|
import qualified Data.Csv as Csv
|
||||||
|
import GHC.Generics
|
||||||
|
import qualified GHC.Generics as Generics
|
||||||
|
|
||||||
|
import Language.Haskell.TH
|
||||||
|
-- import Language.Haskell.TH.Datatype
|
||||||
|
-- import Language.Haskell.TH.Lib
|
||||||
|
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
import qualified Data.ByteString.Char8 as B8
|
||||||
|
|
||||||
|
|
||||||
|
class CsvColumnsExplained csv where
|
||||||
|
csvColumnsExplanations :: forall p. p csv -> Map Csv.Name Widget
|
||||||
|
csvColumnsExplanations _ = Map.empty
|
||||||
|
|
||||||
|
genericCsvColumnsExplanations :: forall msg p csv.
|
||||||
|
( Generic csv
|
||||||
|
, GCsvColumnsExplained (Rep csv)
|
||||||
|
, RenderMessage UniWorX msg
|
||||||
|
)
|
||||||
|
=> Csv.Options
|
||||||
|
-> Map Name msg
|
||||||
|
-> p csv
|
||||||
|
-> Map Csv.Name Widget
|
||||||
|
genericCsvColumnsExplanations opts msgMap' _ = Map.mapMaybe (fmap (toWidget <=< ap getMessageRender . pure) . flip Map.lookup msgMap) headerNames
|
||||||
|
where
|
||||||
|
msgMap :: Map String msg
|
||||||
|
msgMap = Map.mapKeys nameBase msgMap'
|
||||||
|
headerNames :: Map Csv.Name String
|
||||||
|
headerNames = gCsvColumnsExplanations opts $ Generics.from (error "proxy" :: csv)
|
||||||
|
|
||||||
|
class GCsvColumnsExplained a where
|
||||||
|
gCsvColumnsExplanations :: Csv.Options -> a p -> Map Csv.Name String
|
||||||
|
|
||||||
|
instance GCsvColumnsExplained U1 where
|
||||||
|
gCsvColumnsExplanations _ _ = Map.empty
|
||||||
|
|
||||||
|
instance (GCsvColumnsExplained a, GCsvColumnsExplained b) => GCsvColumnsExplained (a :*: b) where
|
||||||
|
gCsvColumnsExplanations opts _ = Map.unionWithKey (\h f1 f2 -> error $ "Column header ‘" ++ B8.unpack h ++ "’ is produced by both ‘" ++ f1 ++ "’ and ‘" ++ f2 ++ "’")
|
||||||
|
(gCsvColumnsExplanations opts (error "proxy" :: a p))
|
||||||
|
(gCsvColumnsExplanations opts (error "proxy" :: b p))
|
||||||
|
|
||||||
|
|
||||||
|
instance GCsvColumnsExplained a => GCsvColumnsExplained (M1 D c a) where
|
||||||
|
gCsvColumnsExplanations opts _ = gCsvColumnsExplanations opts (error "proxy" :: a p)
|
||||||
|
|
||||||
|
instance GCsvColumnsExplained a => GCsvColumnsExplained (M1 C c a) where
|
||||||
|
gCsvColumnsExplanations opts _ = gCsvColumnsExplanations opts (error "proxy" :: a p)
|
||||||
|
|
||||||
|
-- | Instance to ensure that you cannot derive DefaultOrdered for
|
||||||
|
-- constructors without selectors.
|
||||||
|
instance CsvColumnsExplained (M1 S ('MetaSel 'Nothing srcpk srcstr decstr) a ())
|
||||||
|
=> GCsvColumnsExplained (M1 S ('MetaSel 'Nothing srcpk srcstr decstr) a)
|
||||||
|
where
|
||||||
|
gCsvColumnsExplanations _ _ =
|
||||||
|
error "You cannot derive CsvColumnsExplanations for constructors without selectors."
|
||||||
|
|
||||||
|
instance Selector s => GCsvColumnsExplained (M1 S s a) where
|
||||||
|
gCsvColumnsExplanations (Csv.fieldLabelModifier -> f) m
|
||||||
|
| null name = error "Cannot derive CsvColumnsExplanations for constructors without selectors"
|
||||||
|
| otherwise = Map.singleton (B8.pack $ f name) name
|
||||||
|
where name = selName m
|
||||||
@ -329,7 +329,22 @@ input[type="button"].btn-info:hover,
|
|||||||
.scrolltable {
|
.scrolltable {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
box-shadow: 0 0 1px 1px var(--color-grey-light);
|
box-shadow: 0 0 1px 1px var(--color-grey-light);
|
||||||
margin-bottom: 15px;
|
}
|
||||||
|
|
||||||
|
.csv-export, .csv-import {
|
||||||
|
box-shadow: 0 0 1px 1px var(--color-grey);
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
|
||||||
|
&.modal__trigger {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 425px) {
|
@media (max-width: 425px) {
|
||||||
@ -642,3 +657,8 @@ section {
|
|||||||
.uuid {
|
.uuid {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.form--inline {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|||||||
7
templates/table/csv-column-explanations.hamlet
Normal file
7
templates/table/csv-column-explanations.hamlet
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<h3>_{MsgCsvColumnsExplanationsTip}
|
||||||
|
<dl .deflist>
|
||||||
|
$forall (colName, colExplanation) <- csvColExplanations''
|
||||||
|
<dt .deflist__dt>#{decodeUtf8 colName}
|
||||||
|
<dd .deflist__dd>^{colExplanation}
|
||||||
|
<div>
|
||||||
|
^{csvExportWdgt'}
|
||||||
@ -5,3 +5,4 @@ $if is _Just dbtCsvDecode
|
|||||||
$if is _Just dbtCsvEncode
|
$if is _Just dbtCsvEncode
|
||||||
<div .csv-export>
|
<div .csv-export>
|
||||||
^{csvExportWdgt'}
|
^{csvExportWdgt'}
|
||||||
|
^{csvColExplanations'}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row-reverse;
|
flex-flow: row-reverse;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TABLE FOOTER */
|
/* TABLE FOOTER */
|
||||||
@ -10,6 +11,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row-reverse;
|
flex-flow: row-reverse;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PAGINATION */
|
/* PAGINATION */
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
$newline never
|
$newline never
|
||||||
<div uw-modal data-modal-trigger=#{triggerId'} data-modal-closeable>
|
<div .modal uw-modal data-modal-trigger=#{triggerId'} data-modal-closeable>
|
||||||
$case modalContent
|
$case modalContent
|
||||||
$of Right content
|
$of Right content
|
||||||
<div .modal__content>
|
<div .modal__content>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user