summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2017-03-15 18:11:47 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2017-03-15 18:11:47 +0100
commit3cd4169e33c07b71129aafcecfb81a3b5007fa39 (patch)
tree261de0303273cc1a861977dc9aebce235d0afe51
parent37f0dac79707a0de81ec6364d2704007eefd9289 (diff)
downloadbar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.tar
bar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.tar.gz
bar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.tar.bz2
bar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.tar.xz
bar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.zip
Autocomplete types
-rw-r--r--Application.hs1
-rw-r--r--Handler/Common.hs126
-rw-r--r--Handler/Types.hs15
-rw-r--r--Settings.hs2
-rw-r--r--bar.cabal1
-rw-r--r--config/routes3
6 files changed, 97 insertions, 51 deletions
diff --git a/Application.hs b/Application.hs
index 85ceb2f..3a16e88 100644
--- a/Application.hs
+++ b/Application.hs
@@ -41,6 +41,7 @@ import Handler.ReferenceListing
41import Handler.ReferenceItem 41import Handler.ReferenceItem
42import Handler.DeleteRefItem 42import Handler.DeleteRefItem
43import Handler.Kinds 43import Handler.Kinds
44import Handler.Types
44import Handler.List 45import Handler.List
45 46
46-- This line actually creates our YesodDispatch instance. It is the second half 47-- This line actually creates our YesodDispatch instance. It is the second half
diff --git a/Handler/Common.hs b/Handler/Common.hs
index 65988da..a1ae34b 100644
--- a/Handler/Common.hs
+++ b/Handler/Common.hs
@@ -26,6 +26,8 @@ import Control.Lens
26 26
27import Handler.Common.Types 27import Handler.Common.Types
28 28
29import Text.Julius (RawJS(..))
30
29dayFormat :: Day -> String 31dayFormat :: Day -> String
30dayFormat = formatTime defaultTimeLocale "%e. %b %y" 32dayFormat = formatTime defaultTimeLocale "%e. %b %y"
31 33
@@ -36,8 +38,12 @@ itemForm proto identView = do
36 38
37 t <- lift . runDB $ maybe (return Nothing) (fmap (Just . kindType) . getType) proto 39 t <- lift . runDB $ maybe (return Nothing) (fmap (Just . kindType) . getType) proto
38 40
39 (kindRes, kindWidget) <- kindField $ itemKind <$> proto 41 let kt kWidget tWidget =
40 (typeRes, typeWidget) <- typeField $ t 42 [whamlet|
43 <div .td>^{kWidget}
44 <div .td>^{tWidget}
45 |]
46 ((kindRes, typeRes), typedKindWidget) <- typedKindField kt ((itemKind <$> proto), t)
41 (boughtRes, boughtWidget) <- dayForm (maybe (Just $ Just today) Just $ fmap itemBought proto) "Unknown" 47 (boughtRes, boughtWidget) <- dayForm (maybe (Just $ Just today) Just $ fmap itemBought proto) "Unknown"
42 (expiresRes, expiresWidget) <- dayForm (fmap itemExpires proto) "Never" 48 (expiresRes, expiresWidget) <- dayForm (fmap itemExpires proto) "Never"
43 (openedRes, openedWidget) <- dayForm (fmap itemOpened proto) "Never" 49 (openedRes, openedWidget) <- dayForm (fmap itemOpened proto) "Never"
@@ -54,8 +60,7 @@ itemForm proto identView = do
54 [whamlet| 60 [whamlet|
55 $newline never 61 $newline never
56 #{identView} 62 #{identView}
57 <div .td>^{kindWidget} 63 ^{typedKindWidget}
58 <div .td>^{typeWidget}
59 <div .td>^{boughtWidget} 64 <div .td>^{boughtWidget}
60 <div .td>^{expiresWidget} 65 <div .td>^{expiresWidget}
61 <div .td>^{openedWidget} 66 <div .td>^{openedWidget}
@@ -93,9 +98,14 @@ referenceForm :: Maybe Reference -- ^ Update existing item or insert new?
93 -> Html -> MForm Handler (FormResult (WithType Reference), Widget) 98 -> Html -> MForm Handler (FormResult (WithType Reference), Widget)
94referenceForm proto identView = do 99referenceForm proto identView = do
95 t <- lift . runDB $ maybe (return Nothing) (fmap (Just . kindType) . getType) proto 100 t <- lift . runDB $ maybe (return Nothing) (fmap (Just . kindType) . getType) proto
101
102 let kt kWidget tWidget =
103 [whamlet|
104 <div .td>^{kWidget}
105 <div .td>^{tWidget}
106 |]
96 107
97 (kindRes, kindWidget) <- kindField $ referenceKind <$> proto 108 ((kindRes, typeRes), typedKindWidget) <- typedKindField kt ((referenceKind <$> proto), t)
98 (typeRes, typeWidget) <- typeField $ t
99 109
100 let referenceRes = do 110 let referenceRes = do
101 referenceKind <- kindRes 111 referenceKind <- kindRes
@@ -106,63 +116,79 @@ referenceForm proto identView = do
106 [whamlet| 116 [whamlet|
107 $newline never 117 $newline never
108 #{identView} 118 #{identView}
109 <div .td>^{kindWidget} 119 ^{typedKindWidget}
110 <div .td>^{typeWidget}
111 |] 120 |]
112 121
113referenceListing :: ReferenceState -> Widget 122referenceListing :: ReferenceState -> Widget
114referenceListing ReferenceState{ refFormState = formState, ..} = $(widgetFile "referenceListing") 123referenceListing ReferenceState{ refFormState = formState, ..} = $(widgetFile "referenceListing")
115 124
116kindField :: Maybe Text -> MForm Handler (FormResult Text, Widget) 125typedKindField :: (Widget -> Widget -> Widget) -- ^ `\kindWidget typeWidget -> _`
117kindField proto = do 126 -> (Maybe Text, Maybe Text) -- ^ `(kindProto, typeProto)`
118 optionId <- ("options" <>) . tshow . hashUnique <$> liftIO newUnique 127 -> MForm Handler ((FormResult Text, FormResult Text), Widget) -- ^ `((kindRes, typeRes), typedKindWidget)`
119 128typedKindField collate (kindProto, typeProto) = do
129 tOptionId <- ("options" <>) . tshow . hashUnique <$> liftIO newUnique
120 let 130 let
121 attrs = [ ("list", optionId) 131 tAttrs = [ ("list", tOptionId)
122 , ("autocomplete", "off") 132 , ("autocomplete", "off")
123 ] 133 ]
124 134 kOptionId <- ("options" <>) . tshow . hashUnique <$> liftIO newUnique
125 (kindRes, kindView) <- mreq textField ("" { fsAttrs = attrs }) proto
126
127 options <- lift kinds
128
129 return . (kindRes, ) $
130 [whamlet|
131 $newline never
132 ^{fvInput kindView}
133 <datalist ##{optionId}>
134 $forall opt <- options
135 <option value=#{opt}>
136 |]
137
138typeField :: Maybe Text -> MForm Handler (FormResult Text, Widget)
139typeField proto = do
140 optionId <- ("options" <>) . tshow . hashUnique <$> liftIO newUnique
141 135
142 let 136 let
143 attrs = [ ("list", optionId) 137 kAttrs = [ ("list", kOptionId)
144 , ("autocomplete", "off") 138 , ("autocomplete", "off")
145 ] 139 ]
146 140
147 (typeRes, typeView) <- mreq textField ("" { fsAttrs = attrs }) proto 141 (kindRes, kindView) <- mreq textField ("" { fsAttrs = kAttrs }) kindProto
148 142 (typeRes, typeView) <- mreq textField ("" { fsAttrs = tAttrs }) typeProto
149 (Set.fromList . map (kindType . entityVal) -> options) <- lift . runDB $ selectList [] [] 143
150 144 kOptions <- lift kinds
151 return . (typeRes, ) $ 145 (Set.fromList . map (kindType . entityVal) -> tOptions) <- lift . runDB $ selectList [] []
152 [whamlet| 146
153 $newline never 147 return . ((kindRes, typeRes), ) $ do
154 ^{fvInput typeView} 148 toWidget $
155 <datalist ##{optionId}> 149 [julius|
156 $forall opt <- Set.toList options 150 $(function () {
157 <option value=#{opt}> 151 $("##{rawJS $ fvId kindView}").change(function () {
158 |] 152 $.ajax({
153 url: '@{TypeR}',
154 type: 'GET',
155 contentType: 'application/json',
156 data: {
157 kind: $(this).val()
158 },
159 success: function (answer) {
160 $("##{rawJS $ fvId typeView}").val(answer);
161 typeChanged = false;
162 }
163 });
164 }) ;
165 });
166 |]
167 let
168 kindWidget =
169 [whamlet|
170 $newline never
171 ^{fvInput kindView}
172 <datalist ##{kOptionId}>
173 $forall opt <- kOptions
174 <option value=#{opt}>
175 |]
176 typeWidget =
177 [whamlet|
178 $newline never
179 ^{fvInput typeView}
180 <datalist ##{tOptionId}>
181 $forall opt <- tOptions
182 <option value=#{opt}>
183 |]
184 collate kindWidget typeWidget
159 185
160kinds :: Handler [Text] 186kinds :: Handler (Set Text)
161kinds = do 187kinds = do
162 stock <- runDB $ selectList [] [] 188 stock <- runDB $ selectList [] []
163 reference <- runDB $ selectList [] [] 189 reference <- runDB $ selectList [] []
164 190
165 return $ concat 191 return . Set.fromList $ concat
166 [ [ itemKind | Entity _ Item{..} <- stock ] 192 [ [ itemKind | Entity _ Item{..} <- stock ]
167 , [ referenceKind | Entity _ Reference{..} <- reference ] 193 , [ referenceKind | Entity _ Reference{..} <- reference ]
168 ] 194 ]
diff --git a/Handler/Types.hs b/Handler/Types.hs
new file mode 100644
index 0000000..04055ad
--- /dev/null
+++ b/Handler/Types.hs
@@ -0,0 +1,15 @@
1module Handler.Types where
2
3import Import
4
5import Data.Set (Set)
6import qualified Data.Set as Set
7
8getTypesR :: Handler Value
9getTypesR = returnJson <=< runDB $ do
10 Set.fromList . map (kindType . entityVal) <$> selectList [] []
11
12getTypeR :: Handler Value
13getTypeR = do
14 kind <- maybe (invalidArgs ["kind"]) return =<< lookupGetParam "kind"
15 returnJson <=< runDB $ kindType . entityVal <$> getBy404 (UniqueKind $ normalizeKind kind)
diff --git a/Settings.hs b/Settings.hs
index d0e16ea..a15fb03 100644
--- a/Settings.hs
+++ b/Settings.hs
@@ -19,7 +19,7 @@ import Yesod.Default.Config2 (applyEnvValue, configSettingsYml)
19import Yesod.Default.Util (WidgetFileSettings, widgetFileNoReload, 19import Yesod.Default.Util (WidgetFileSettings, widgetFileNoReload,
20 widgetFileReload) 20 widgetFileReload)
21 21
22import Thermoprint.Client (BaseUrl(..), Scheme(..), InvalidBaseUrlException, parseBaseUrl) 22import Thermoprint.Client (BaseUrl(..), parseBaseUrl)
23 23
24#ifdef DEVELOPMENT 24#ifdef DEVELOPMENT
25#define DEV_BOOL True 25#define DEV_BOOL True
diff --git a/bar.cabal b/bar.cabal
index 1d25e21..112a89d 100644
--- a/bar.cabal
+++ b/bar.cabal
@@ -31,6 +31,7 @@ library
31 Handler.ReferenceItem 31 Handler.ReferenceItem
32 Handler.DeleteRefItem 32 Handler.DeleteRefItem
33 Handler.Kinds 33 Handler.Kinds
34 Handler.Types
34 Handler.List 35 Handler.List
35 36
36 if flag(dev) || flag(library-only) 37 if flag(dev) || flag(library-only)
diff --git a/config/routes b/config/routes
index 6ed3204..5024ab1 100644
--- a/config/routes
+++ b/config/routes
@@ -11,4 +11,7 @@
11/ref/#ReferenceId/delete DeleteRefItemR POST 11/ref/#ReferenceId/delete DeleteRefItemR POST
12 12
13/kinds KindsR GET 13/kinds KindsR GET
14/types TypesR GET
15/type TypeR GET
16
14/list ListR GET POST 17/list ListR GET POST