diff options
| -rw-r--r-- | Handler/Common.hs | 13 | ||||
| -rw-r--r-- | Handler/InventoryListing.hs | 17 | ||||
| -rw-r--r-- | Handler/List.hs | 2 | ||||
| -rw-r--r-- | bar.cabal | 3 | ||||
| -rw-r--r-- | bar.nix | 8 | ||||
| -rw-r--r-- | templates/default-layout.cassius | 27 | ||||
| -rw-r--r-- | templates/inventoryListing.hamlet | 4 | 
7 files changed, 64 insertions, 10 deletions
diff --git a/Handler/Common.hs b/Handler/Common.hs index 990732d..65e6ce1 100644 --- a/Handler/Common.hs +++ b/Handler/Common.hs  | |||
| @@ -11,13 +11,15 @@ module Handler.Common | |||
| 11 | , FormState(..) | 11 | , FormState(..) | 
| 12 | , HasFormState(..) | 12 | , HasFormState(..) | 
| 13 | , stockSort, referenceSort | 13 | , stockSort, referenceSort | 
| 14 | , humanId | ||
| 14 | ) where | 15 | ) where | 
| 15 | 16 | ||
| 16 | import Import | 17 | import Import hiding ((\\)) | 
| 17 | 18 | ||
| 18 | import Data.Unique | 19 | import Data.Unique | 
| 19 | 20 | ||
| 20 | import qualified Data.Text as Text | 21 | import qualified Data.Text as Text | 
| 22 | import qualified Data.ByteString.Char8 as CBS | ||
| 21 | 23 | ||
| 22 | import Data.Set (Set) | 24 | import Data.Set (Set) | 
| 23 | import qualified Data.Set as Set | 25 | import qualified Data.Set as Set | 
| @@ -28,10 +30,19 @@ import Handler.Common.Types | |||
| 28 | 30 | ||
| 29 | import Text.Julius (RawJS(..)) | 31 | import Text.Julius (RawJS(..)) | 
| 30 | 32 | ||
| 33 | import Database.Persist.Sql (fromSqlKey) | ||
| 34 | import qualified Web.Hashids as HID | ||
| 35 | import Data.List ((\\)) | ||
| 36 | |||
| 31 | import Data.List.NonEmpty (NonEmpty) | 37 | import Data.List.NonEmpty (NonEmpty) | 
| 32 | import Data.Semigroup hiding (First(..)) | 38 | import Data.Semigroup hiding (First(..)) | 
| 33 | import Data.Monoid (First(..)) | 39 | import Data.Monoid (First(..)) | 
| 34 | 40 | ||
| 41 | humanId :: ItemId -> Text | ||
| 42 | humanId = Text.pack . CBS.unpack . HID.encode ctx . fromIntegral . fromSqlKey | ||
| 43 | where | ||
| 44 | ctx = HID.createHashidsContext "ItemId" 3 $ (['0'..'9'] ++ ['a'..'z']) \\ ['0', 'l', 'v', '2'] | ||
| 45 | |||
| 35 | dayFormat :: Day -> String | 46 | dayFormat :: Day -> String | 
| 36 | dayFormat = formatTime defaultTimeLocale "%e. %b %y" | 47 | dayFormat = formatTime defaultTimeLocale "%e. %b %y" | 
| 37 | 48 | ||
diff --git a/Handler/InventoryListing.hs b/Handler/InventoryListing.hs index c2ec5d1..d87512a 100644 --- a/Handler/InventoryListing.hs +++ b/Handler/InventoryListing.hs  | |||
| @@ -11,8 +11,21 @@ postInventoryListingR = do | |||
| 11 | case insertResult of | 11 | case insertResult of | 
| 12 | FormSuccess (Item{..} `WithType` t) -> runDB $ do | 12 | FormSuccess (Item{..} `WithType` t) -> runDB $ do | 
| 13 | upsertBy (UniqueKind itemNormKind) (Kind itemNormKind t) [ KindType =. t ] | 13 | upsertBy (UniqueKind itemNormKind) (Kind itemNormKind t) [ KindType =. t ] | 
| 14 | insert Item{..} | 14 | newItem <- insert Item{..} | 
| 15 | return () | 15 | otherItems <- selectKeysList [ ItemNormKind ==. itemNormKind, ItemId !=. newItem ] [] | 
| 16 | when (not $ null otherItems) . addMessage "insertAmbiguous" $ | ||
| 17 | [shamlet| | ||
| 18 | $newline never | ||
| 19 | There are other items of the same kind. | ||
| 20 | <ul> | ||
| 21 | $forall other <- otherItems | ||
| 22 | <li .itemId>#{humanId other} | ||
| 23 | |] | ||
| 24 | addMessage "insertSuccess" [shamlet| | ||
| 25 | $newline never | ||
| 26 | Inserted new item as # | ||
| 27 | <span .itemId>#{humanId newItem} | ||
| 28 | |] | ||
| 16 | FormFailure errors -> mapM_ (addMessage "formError" . toHtml) errors | 29 | FormFailure errors -> mapM_ (addMessage "formError" . toHtml) errors | 
| 17 | _ -> return () | 30 | _ -> return () | 
| 18 | 31 | ||
diff --git a/Handler/List.hs b/Handler/List.hs index 4209651..7ab4ebe 100644 --- a/Handler/List.hs +++ b/Handler/List.hs  | |||
| @@ -64,7 +64,7 @@ postListR = do | |||
| 64 | case printResult of | 64 | case printResult of | 
| 65 | FormSuccess pId -> do | 65 | FormSuccess pId -> do | 
| 66 | (JobId jId) <- jobCreate (Just pId) $ mkPrintout list | 66 | (JobId jId) <- jobCreate (Just pId) $ mkPrintout list | 
| 67 | addMessage "printSuccess" . toHtml $ "List is printing as job #" <> tshow jId | 67 | addMessage "printSuccess" [shamlet|List is printing as job ##{jId}|] | 
| 68 | FormFailure errors -> mapM_ (addMessage "formError" . toHtml) errors | 68 | FormFailure errors -> mapM_ (addMessage "formError" . toHtml) errors | 
| 69 | _ -> return () | 69 | _ -> return () | 
| 70 | 70 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | name: bar | 1 | name: bar | 
| 2 | version: 0.1.0 | 2 | version: 0.2.0 | 
| 3 | cabal-version: >= 1.8 | 3 | cabal-version: >= 1.8 | 
| 4 | build-type: Simple | 4 | build-type: Simple | 
| 5 | 5 | ||
| @@ -106,6 +106,7 @@ library | |||
| 106 | , mtl | 106 | , mtl | 
| 107 | , lens | 107 | , lens | 
| 108 | , thermoprint-client | 108 | , thermoprint-client | 
| 109 | , hashids | ||
| 109 | 110 | ||
| 110 | executable bar | 111 | executable bar | 
| 111 | if flag(library-only) | 112 | if flag(library-only) | 
| @@ -1,7 +1,7 @@ | |||
| 1 | { mkDerivation, aeson, base, bytestring, case-insensitive | 1 | { mkDerivation, aeson, base, bytestring, case-insensitive | 
| 2 | , classy-prelude, classy-prelude-conduit, classy-prelude-yesod | 2 | , classy-prelude, classy-prelude-conduit, classy-prelude-yesod | 
| 3 | , conduit, containers, data-default, directory, fast-logger | 3 | , conduit, containers, data-default, directory, fast-logger | 
| 4 | , file-embed, hjsmin, http-conduit, lens, monad-control | 4 | , file-embed, hashids, hjsmin, http-conduit, lens, monad-control | 
| 5 | , monad-logger, mtl, persistent, persistent-postgresql | 5 | , monad-logger, mtl, persistent, persistent-postgresql | 
| 6 | , persistent-template, safe, shakespeare, stdenv, template-haskell | 6 | , persistent-template, safe, shakespeare, stdenv, template-haskell | 
| 7 | , text, thermoprint-client, time, unordered-containers, vector, wai | 7 | , text, thermoprint-client, time, unordered-containers, vector, wai | 
| @@ -10,15 +10,15 @@ | |||
| 10 | }: | 10 | }: | 
| 11 | mkDerivation { | 11 | mkDerivation { | 
| 12 | pname = "bar"; | 12 | pname = "bar"; | 
| 13 | version = "0.1.0"; | 13 | version = "0.2.0"; | 
| 14 | src = ./.; | 14 | src = ./.; | 
| 15 | isLibrary = true; | 15 | isLibrary = true; | 
| 16 | isExecutable = true; | 16 | isExecutable = true; | 
| 17 | libraryHaskellDepends = [ | 17 | libraryHaskellDepends = [ | 
| 18 | aeson base bytestring case-insensitive classy-prelude | 18 | aeson base bytestring case-insensitive classy-prelude | 
| 19 | classy-prelude-conduit classy-prelude-yesod conduit containers | 19 | classy-prelude-conduit classy-prelude-yesod conduit containers | 
| 20 | data-default directory fast-logger file-embed hjsmin http-conduit | 20 | data-default directory fast-logger file-embed hashids hjsmin | 
| 21 | lens monad-control monad-logger mtl persistent | 21 | http-conduit lens monad-control monad-logger mtl persistent | 
| 22 | persistent-postgresql persistent-template safe shakespeare | 22 | persistent-postgresql persistent-template safe shakespeare | 
| 23 | template-haskell text thermoprint-client time unordered-containers | 23 | template-haskell text thermoprint-client time unordered-containers | 
| 24 | vector wai wai-extra wai-logger warp yaml yesod yesod-auth | 24 | vector wai wai-extra wai-logger warp yaml yesod yesod-auth | 
diff --git a/templates/default-layout.cassius b/templates/default-layout.cassius index 50aab3f..bc64e8e 100644 --- a/templates/default-layout.cassius +++ b/templates/default-layout.cassius  | |||
| @@ -31,6 +31,13 @@ | |||
| 31 | text-align: center | 31 | text-align: center | 
| 32 | padding: 0.25em | 32 | padding: 0.25em | 
| 33 | color: #aaa | 33 | color: #aaa | 
| 34 | .itemId | ||
| 35 | font-family: monospace | ||
| 36 | div.itemId | ||
| 37 | display: table-cell | ||
| 38 | text-align: left | ||
| 39 | padding: 0.25em | ||
| 40 | color: #aaa | ||
| 34 | .table .table .td, .table .table .tc, .table .table .th, .table .table .kind | 41 | .table .table .td, .table .table .tc, .table .table .th, .table .table .kind | 
| 35 | padding: 0 | 42 | padding: 0 | 
| 36 | table table td, table table th, .table table td, .table table th | 43 | table table td, table table th, .table table td, .table table th | 
| @@ -41,10 +48,26 @@ table table td, table table th, .table table td, .table table th | |||
| 41 | padding: 0 | 48 | padding: 0 | 
| 42 | text-align: center | 49 | text-align: center | 
| 43 | font-weight: bold | 50 | font-weight: bold | 
| 51 | li | ||
| 52 | margin: 0 0 0.5em 0 | ||
| 53 | li:last-child | ||
| 54 | margin: 0 | ||
| 44 | .formError | 55 | .formError | 
| 45 | color: #800 | 56 | color: #800 | 
| 46 | .printSuccess | 57 | .printSuccess, .insertSuccess | 
| 47 | color: #080 | 58 | color: #080 | 
| 59 | .insertAmbiguous | ||
| 60 | color: inherit | ||
| 61 | ul | ||
| 62 | list-style-type: none | ||
| 63 | li | ||
| 64 | display: inline | ||
| 65 | margin: 0 0 0 0 | ||
| 66 | padding: 0 0 0 0 | ||
| 67 | li::before | ||
| 68 | content: ", " | ||
| 69 | li:first-child::before | ||
| 70 | content: "" | ||
| 48 | button | 71 | button | 
| 49 | width: 6em | 72 | width: 6em | 
| 50 | display: inline-block | 73 | display: inline-block | 
| @@ -94,3 +117,5 @@ label.checkbox | |||
| 94 | vertical-align: middle | 117 | vertical-align: middle | 
| 95 | span | 118 | span | 
| 96 | vertical-align: middle | 119 | vertical-align: middle | 
| 120 | .itemH | ||
| 121 | display: table-cell \ No newline at end of file | ||
diff --git a/templates/inventoryListing.hamlet b/templates/inventoryListing.hamlet index 39758bb..802905d 100644 --- a/templates/inventoryListing.hamlet +++ b/templates/inventoryListing.hamlet  | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | <div .table> | 1 | <div .table> | 
| 2 | <div .tr .sepBelow> | 2 | <div .tr .sepBelow> | 
| 3 | <div .itemH> | ||
| 3 | <div .th>Item | 4 | <div .th>Item | 
| 4 | <div .th>Type | 5 | <div .th>Type | 
| 5 | <div .th>Bought | 6 | <div .th>Bought | 
| @@ -9,6 +10,7 @@ | |||
| 9 | $if isJust (preview insertForm =<< formState) | 10 | $if isJust (preview insertForm =<< formState) | 
| 10 | $with Just InsertForm{..} <- formState | 11 | $with Just InsertForm{..} <- formState | 
| 11 | <form .tr .sepBelow action=@{InventoryListingR} method=post enctype=#{fsInsertEncoding}> | 12 | <form .tr .sepBelow action=@{InventoryListingR} method=post enctype=#{fsInsertEncoding}> | 
| 13 | <div .td> | ||
| 12 | ^{fsInsertForm} | 14 | ^{fsInsertForm} | 
| 13 | <div .td> | 15 | <div .td> | 
| 14 | <button type=submit> | 16 | <button type=submit> | 
| @@ -17,12 +19,14 @@ | |||
| 17 | $if Just itemId == (preview updateId =<< formState) | 19 | $if Just itemId == (preview updateId =<< formState) | 
| 18 | $with Just UpdateForm{..} <- formState | 20 | $with Just UpdateForm{..} <- formState | 
| 19 | <form .tr .color action=@{UpdateItemR fsUpdateId}##{toPathPiece fsUpdateId} method=post enctype=#{fsUpdateEncoding} ##{toPathPiece fsUpdateId}> | 21 | <form .tr .color action=@{UpdateItemR fsUpdateId}##{toPathPiece fsUpdateId} method=post enctype=#{fsUpdateEncoding} ##{toPathPiece fsUpdateId}> | 
| 22 | <div .itemId>#{humanId itemId} | ||
| 20 | ^{fsUpdateForm} | 23 | ^{fsUpdateForm} | 
| 21 | <div .td> | 24 | <div .td> | 
| 22 | <button type=submit> | 25 | <button type=submit> | 
| 23 | Save Changes | 26 | Save Changes | 
| 24 | $else | 27 | $else | 
| 25 | <div .tr .color ##{toPathPiece itemId}> | 28 | <div .tr .color ##{toPathPiece itemId}> | 
| 29 | <div .itemId>#{humanId itemId} | ||
| 26 | <div .kind>#{itemKind} | 30 | <div .kind>#{itemKind} | 
| 27 | <div .type>#{itemType} | 31 | <div .type>#{itemType} | 
| 28 | <div .td .day> | 32 | <div .td .day> | 
