1
1
mirror of https://github.com/aelve/guide.git synced 2024-12-23 21:02:13 +03:00

Rename pros/cons to traits

This commit is contained in:
Artyom 2016-02-20 16:12:45 +03:00
parent 88ad776ae4
commit dd47e83637
2 changed files with 78 additions and 77 deletions

View File

@ -50,26 +50,26 @@ type Uid = Int
randomUid :: MonadIO m => m Uid randomUid :: MonadIO m => m Uid
randomUid = liftIO $ randomRIO (0, 10^(9::Int)) randomUid = liftIO $ randomRIO (0, 10^(9::Int))
data ProCon = ProCon { data Trait = Trait {
_proConUid :: Uid, _traitUid :: Uid,
_proConContent :: Text } _traitContent :: Text }
makeFields ''ProCon makeFields ''Trait
data ItemKind = HackageLibrary | Library | Unknown data ItemKind = HackageLibrary | Library | Unknown
data Item = Item { data Item = Item {
_itemUid :: Uid, _itemUid :: Uid,
_itemName :: Text, _itemName :: Text,
_itemPros :: [ProCon], _itemPros :: [Trait],
_itemCons :: [ProCon], _itemCons :: [Trait],
_itemLink :: Maybe Url, _itemLink :: Maybe Url,
_itemKind :: ItemKind } _itemKind :: ItemKind }
makeFields ''Item makeFields ''Item
proConById :: Uid -> Lens' Item ProCon traitById :: Uid -> Lens' Item Trait
proConById uid' = singular $ traitById uid' = singular $
(pros.each . filtered ((== uid') . view uid)) `failing` (pros.each . filtered ((== uid') . view uid)) `failing`
(cons.each . filtered ((== uid') . view uid)) (cons.each . filtered ((== uid') . view uid))
@ -103,17 +103,17 @@ sampleState = do
let lensItem = Item { let lensItem = Item {
_itemUid = 12, _itemUid = 12,
_itemName = "lens", _itemName = "lens",
_itemPros = [ProCon 121 "the standard lenses library", _itemPros = [Trait 121 "the standard lenses library",
ProCon 122 "batteries included"], Trait 122 "batteries included"],
_itemCons = [ProCon 123 "huge"], _itemCons = [Trait 123 "huge"],
_itemLink = Nothing, _itemLink = Nothing,
_itemKind = HackageLibrary } _itemKind = HackageLibrary }
let microlensItem = Item { let microlensItem = Item {
_itemUid = 13, _itemUid = 13,
_itemName = "microlens", _itemName = "microlens",
_itemPros = [ProCon 131 "very small", _itemPros = [Trait 131 "very small",
ProCon 132 "good for libraries"], Trait 132 "good for libraries"],
_itemCons = [ProCon 133 "doesn't have advanced features"], _itemCons = [Trait 133 "doesn't have advanced features"],
_itemLink = Just "https://github.com/aelve/microlens", _itemLink = Just "https://github.com/aelve/microlens",
_itemKind = HackageLibrary } _itemKind = HackageLibrary }
let lensesCategory = Category { let lensesCategory = Category {
@ -130,6 +130,9 @@ itemVar = "item" <//> var
categoryVar :: Path '[Uid] categoryVar :: Path '[Uid]
categoryVar = "category" <//> var categoryVar = "category" <//> var
traitVar :: Path '[Uid]
traitVar = "trait" <//> var
main :: IO () main :: IO ()
main = runSpock 8080 $ spockT id $ do main = runSpock 8080 $ spockT id $ do
middleware (staticPolicy (addBase "static")) middleware (staticPolicy (addBase "static"))
@ -163,17 +166,17 @@ main = runSpock 8080 $ spockT id $ do
item <- withGlobal $ use (itemById itemId) item <- withGlobal $ use (itemById itemId)
renderMode <- param' "mode" renderMode <- param' "mode"
lucid $ renderItemInfo renderMode item lucid $ renderItemInfo renderMode item
-- Item pros-cons -- All item traits
Spock.get (itemVar <//> "pros-cons") $ \itemId -> do Spock.get (itemVar <//> "traits") $ \itemId -> do
item <- withGlobal $ use (itemById itemId) item <- withGlobal $ use (itemById itemId)
renderMode <- param' "mode" renderMode <- param' "mode"
lucid $ renderItemProsCons renderMode item lucid $ renderItemTraits renderMode item
-- Pro/con -- A single trait
Spock.get (itemVar <//> "pro-con" <//> var) $ Spock.get (itemVar <//> traitVar) $
\itemId thingId -> do \itemId traitId -> do
thing <- withGlobal $ use (itemById itemId . proConById thingId) trait <- withGlobal $ use (itemById itemId . traitById traitId)
renderMode <- param' "mode" renderMode <- param' "mode"
lucid $ renderProCon renderMode itemId thing lucid $ renderTrait renderMode itemId trait
-- The add/set methods return rendered parts of the structure (added -- The add/set methods return rendered parts of the structure (added
-- categories, changed items, etc) so that the Javascript part could take -- categories, changed items, etc) so that the Javascript part could take
@ -196,14 +199,14 @@ main = runSpock 8080 $ spockT id $ do
categoryById catId . description .= content' categoryById catId . description .= content'
use (categoryById catId) use (categoryById catId)
lucid $ renderCategoryDescription Editable changedCategory lucid $ renderCategoryDescription Editable changedCategory
-- Pro/con -- Trait
Spock.post (itemVar <//> "pro-con" <//> var) $ Spock.post (itemVar <//> traitVar) $
\itemId thingId -> do \itemId traitId -> do
content' <- param' "content" content' <- param' "content"
changedThing <- withGlobal $ do changedTrait <- withGlobal $ do
itemById itemId . proConById thingId . content .= content' itemById itemId . traitById traitId . content .= content'
use (itemById itemId . proConById thingId) use (itemById itemId . traitById traitId)
lucid $ renderProCon Editable itemId changedThing lucid $ renderTrait Editable itemId changedTrait
-- Add methods -- Add methods
Spock.subcomponent "add" $ do Spock.subcomponent "add" $ do
@ -237,16 +240,16 @@ main = runSpock 8080 $ spockT id $ do
Spock.post (itemVar <//> "pro") $ \itemId -> do Spock.post (itemVar <//> "pro") $ \itemId -> do
content' <- param' "content" content' <- param' "content"
uid' <- randomUid uid' <- randomUid
let newThing = ProCon uid' content' let newTrait = Trait uid' content'
withGlobal $ itemById itemId . pros %= (++ [newThing]) withGlobal $ itemById itemId . pros %= (++ [newTrait])
lucid $ renderProCon Editable itemId newThing lucid $ renderTrait Editable itemId newTrait
-- Con (argument against a library) -- Con (argument against a library)
Spock.post (itemVar <//> "con") $ \itemId -> do Spock.post (itemVar <//> "con") $ \itemId -> do
content' <- param' "content" content' <- param' "content"
uid' <- randomUid uid' <- randomUid
let newThing = ProCon uid' content' let newTrait = Trait uid' content'
withGlobal $ itemById itemId . cons %= (++ [newThing]) withGlobal $ itemById itemId . cons %= (++ [newTrait])
lucid $ renderProCon Editable itemId newThing lucid $ renderTrait Editable itemId newTrait
renderRoot :: GlobalState -> HtmlT IO () renderRoot :: GlobalState -> HtmlT IO ()
renderRoot globalState = do renderRoot globalState = do
@ -278,7 +281,7 @@ renderCategoryTitle editable category =
textButton "cancel" $ textButton "cancel" $
js_setCategoryTitleMode (titleNode, category^.uid, Editable) js_setCategoryTitleMode (titleNode, category^.uid, Editable)
-- TODO: render descriptions and pros/cons as Markdown -- TODO: render descriptions and traits as Markdown
renderCategoryDescription :: Editable -> Category -> HtmlT IO () renderCategoryDescription :: Editable -> Category -> HtmlT IO ()
renderCategoryDescription editable category = renderCategoryDescription editable category =
@ -311,7 +314,7 @@ renderItem :: Item -> HtmlT IO ()
renderItem item = renderItem item =
div_ [class_ "item"] $ do div_ [class_ "item"] $ do
renderItemInfo Normal item renderItemInfo Normal item
renderItemProsCons Normal item renderItemTraits Normal item
renderItemInfo :: Editable -> Item -> HtmlT IO () renderItemInfo :: Editable -> Item -> HtmlT IO ()
renderItemInfo editable item = renderItemInfo editable item =
@ -336,52 +339,52 @@ renderItemInfo editable item =
where where
hackageLink = "https://hackage.haskell.org/package/" <> item^.name hackageLink = "https://hackage.haskell.org/package/" <> item^.name
renderItemProsCons :: Editable -> Item -> HtmlT IO () renderItemTraits :: Editable -> Item -> HtmlT IO ()
renderItemProsCons editable item = renderItemTraits editable item =
div_ [class_ "pros-cons"] $ do div_ [class_ "traits"] $ do
this <- thisNode this <- thisNode
case editable of case editable of
Normal -> textButton "edit" $ Normal -> textButton "edit" $
js_setItemProsConsMode (this, item^.uid, Editable) js_setItemTraitsMode (this, item^.uid, Editable)
Editable -> textButton "edit off" $ Editable -> textButton "edit off" $
js_setItemProsConsMode (this, item^.uid, Normal) js_setItemTraitsMode (this, item^.uid, Normal)
div_ [class_ "pros"] $ do div_ [class_ "traits-group"] $ do
p_ "Pros:" p_ "Pros:"
case editable of case editable of
Normal -> Normal ->
ul_ $ mapM_ (renderProCon Normal (item^.uid)) (item^.pros) ul_ $ mapM_ (renderTrait Normal (item^.uid)) (item^.pros)
Editable -> do Editable -> do
listNode <- ul_ $ do listNode <- ul_ $ do
mapM_ (renderProCon Editable (item^.uid)) (item^.pros) mapM_ (renderTrait Editable (item^.uid)) (item^.pros)
thisNode thisNode
let handler s = js_addPro (listNode, item^.uid, s) let handler s = js_addPro (listNode, item^.uid, s)
input_ [type_ "text", placeholder_ "add pro", submitFunc handler] input_ [type_ "text", placeholder_ "add pro", submitFunc handler]
div_ [class_ "cons"] $ do div_ [class_ "traits-group"] $ do
p_ "Cons:" p_ "Cons:"
case editable of case editable of
Normal -> Normal ->
ul_ $ mapM_ (renderProCon Normal (item^.uid)) (item^.cons) ul_ $ mapM_ (renderTrait Normal (item^.uid)) (item^.cons)
Editable -> do Editable -> do
listNode <- ul_ $ do listNode <- ul_ $ do
mapM_ (renderProCon Editable (item^.uid)) (item^.cons) mapM_ (renderTrait Editable (item^.uid)) (item^.cons)
thisNode thisNode
let handler s = js_addCon (listNode, item^.uid, s) let handler s = js_addCon (listNode, item^.uid, s)
input_ [type_ "text", placeholder_ "add con", submitFunc handler] input_ [type_ "text", placeholder_ "add con", submitFunc handler]
renderProCon :: Editable -> Uid -> ProCon -> HtmlT IO () renderTrait :: Editable -> Uid -> Trait -> HtmlT IO ()
renderProCon Normal _ proCon = li_ (toHtml (proCon^.content)) renderTrait Normal _ trait = li_ (toHtml (trait^.content))
renderProCon Editable itemId proCon = li_ $ do renderTrait Editable itemId trait = li_ $ do
this <- thisNode this <- thisNode
toHtml (proCon^.content) toHtml (trait^.content)
textButton "edit" $ textButton "edit" $
js_setProConMode (this, itemId, proCon^.uid, InEdit) js_setTraitMode (this, itemId, trait^.uid, InEdit)
renderProCon InEdit itemId thing = li_ $ do renderTrait InEdit itemId trait = li_ $ do
this <- thisNode this <- thisNode
let handler s = js_submitProConEdit let handler s = js_submitTraitEdit
(this, itemId, thing^.uid, s) (this, itemId, trait^.uid, s)
input_ [type_ "text", value_ (thing^.content), submitFunc handler] input_ [type_ "text", value_ (trait^.content), submitFunc handler]
textButton "cancel" $ textButton "cancel" $
js_setProConMode (this, itemId, thing^.uid, Editable) js_setTraitMode (this, itemId, trait^.uid, Editable)
-- Utils -- Utils
@ -423,8 +426,6 @@ instance JSParams a => JSFunction (a -> JS) where
makeJSFunction fName _ = \args -> makeJSFunction fName _ = \args ->
fName <> "(" <> T.intercalate "," (jsParams args) <> ");" fName <> "(" <> T.intercalate "," (jsParams args) <> ");"
-- TODO: rename pros/cons to traits
allJSFunctions :: JSFunction a => [a] allJSFunctions :: JSFunction a => [a]
allJSFunctions = [ allJSFunctions = [
-- Utilities -- Utilities
@ -434,11 +435,11 @@ allJSFunctions = [
js_addPro, js_addCon, js_addPro, js_addCon,
-- Render-as-editable methods -- Render-as-editable methods
js_setCategoryTitleMode, js_setCategoryDescriptionMode, js_setCategoryTitleMode, js_setCategoryDescriptionMode,
js_setItemInfoMode, js_setItemProsConsMode, js_setItemInfoMode, js_setItemTraitsMode,
js_setProConMode, js_setTraitMode,
-- Set methods -- Set methods
js_submitCategoryTitleEdit, js_submitCategoryTitleEdit,
js_submitProConEdit, js_submitTraitEdit,
js_submitCategoryDescriptionEdit ] js_submitCategoryDescriptionEdit ]
js_replaceWithData :: JSFunction a => a js_replaceWithData :: JSFunction a => a
@ -539,26 +540,26 @@ js_setItemInfoMode = makeJSFunction "setItemInfoMode" [text|
} }
|] |]
js_setItemProsConsMode :: JSFunction a => a js_setItemTraitsMode :: JSFunction a => a
js_setItemProsConsMode = makeJSFunction "setItemProsConsMode" [text| js_setItemTraitsMode = makeJSFunction "setItemTraitsMode" [text|
function setItemProsConsMode(node, itemId, mode) { function setItemTraitsMode(node, itemId, mode) {
$.get("/render/item/"+itemId+"/pros-cons", {mode: mode}) $.get("/render/item/"+itemId+"/traits", {mode: mode})
.done(replaceWithData(node)); .done(replaceWithData(node));
} }
|] |]
js_setProConMode :: JSFunction a => a js_setTraitMode :: JSFunction a => a
js_setProConMode = makeJSFunction "setProConMode" [text| js_setTraitMode = makeJSFunction "setTraitMode" [text|
function setProConMode(node, itemId, thingId, mode) { function setTraitMode(node, itemId, traitId, mode) {
$.get("/render/item/"+itemId+"/pro-con/"+thingId, {mode: mode}) $.get("/render/item/"+itemId+"/trait/"+traitId, {mode: mode})
.done(replaceWithData(node)); .done(replaceWithData(node));
} }
|] |]
js_submitProConEdit :: JSFunction a => a js_submitTraitEdit :: JSFunction a => a
js_submitProConEdit = makeJSFunction "submitProConEdit" [text| js_submitTraitEdit = makeJSFunction "submitTraitEdit" [text|
function submitProConEdit(node, itemId, thingId, s) { function submitTraitEdit(node, itemId, traitId, s) {
$.post("/set/item/"+itemId+"/pro-con/"+thingId, {content: s}) $.post("/set/item/"+itemId+"/trait/"+traitId, {content: s})
.done(replaceWithData(node)); .done(replaceWithData(node));
} }
|] |]

View File

@ -5,10 +5,10 @@
border: 1px solid; border: 1px solid;
margin: 5px; } margin: 5px; }
.pros-cons { .traits {
display: flex } display: flex }
.pros, .cons { .traits-group {
margin: 0px 5px; } margin: 0px 5px; }
.anchor { .anchor {