web: Resurrect ImportForm and EditForm
This commit is contained in:
		
							parent
							
								
									c24c8f1c99
								
							
						
					
					
						commit
						4faf0d8b4a
					
				| @ -17,9 +17,9 @@ import Yesod.Default.Config | ||||
| import Yesod.Default.Main (defaultDevelApp) | ||||
| import Yesod.Default.Handlers (getFaviconR, getRobotsR) | ||||
| 
 | ||||
| -- Import all relevant handler modules here. | ||||
| -- Don't forget to add new modules to your cabal file! | ||||
| import Handler.AddR (postAddR) | ||||
| import Handler.EditR (postEditR) | ||||
| import Handler.ImportR (postImportR) | ||||
| import Handler.JournalR (getJournalR) | ||||
| import Handler.RegisterR (getRegisterR) | ||||
| import Handler.RootR (getRootR) | ||||
| @ -41,30 +41,29 @@ mkYesodDispatch "App" resourcesApp | ||||
| -- place to put your migrate statements to have automatic database | ||||
| -- migrations handled by Yesod. | ||||
| makeApplication :: WebOpts -> Journal -> AppConfig DefaultEnv Extra -> IO Application | ||||
| makeApplication opts j conf = do | ||||
|     foundation <- makeFoundation conf opts | ||||
|     writeIORef (appJournal foundation) j | ||||
|     app <- toWaiAppPlain foundation | ||||
|     return $ logWare app | ||||
| makeApplication opts' j' conf' = do | ||||
|     foundation <- makeFoundation conf' opts' | ||||
|     writeIORef (appJournal foundation) j' | ||||
|     logWare <$> toWaiAppPlain foundation | ||||
|   where | ||||
|     logWare | development  = logStdoutDev | ||||
|             | serve_ opts  = logStdout | ||||
|             | serve_ opts'  = logStdout | ||||
|             | otherwise    = id | ||||
| 
 | ||||
| makeFoundation :: AppConfig DefaultEnv Extra -> WebOpts -> IO App | ||||
| makeFoundation conf opts = do | ||||
| makeFoundation conf opts' = do | ||||
|     manager <- newManager defaultManagerSettings | ||||
|     s <- staticSite | ||||
|     jref <- newIORef nulljournal | ||||
|     return $ App conf s manager opts jref | ||||
|     return $ App conf s manager opts' jref | ||||
| 
 | ||||
| -- for yesod devel | ||||
| -- uses the journal specified by the LEDGER_FILE env var, or ~/.hledger.journal | ||||
| getApplicationDev :: IO (Int, Application) | ||||
| getApplicationDev = do | ||||
|   f <- head `fmap` journalFilePathFromOpts defcliopts -- XXX head should be safe for now | ||||
|   j <- either error' id `fmap` readJournalFile def f | ||||
|   defaultDevelApp loader (makeApplication defwebopts j) | ||||
|   j' <- either error' id <$> readJournalFile def f | ||||
|   defaultDevelApp loader (makeApplication defwebopts j') | ||||
|   where | ||||
|     loader = Yesod.Default.Config.loadConfig (configSettings Development) | ||||
|         { csParseExtra = parseExtra | ||||
|  | ||||
| @ -114,52 +114,6 @@ searchform VD{q, here} = [hamlet| | ||||
|       <button .btn .btn-default type=button data-toggle="modal" data-target="#helpmodal" title="Show search and general help">? | ||||
| |] | ||||
| 
 | ||||
| -- -- | Edit journal form. | ||||
| -- editform :: ViewData -> HtmlUrl AppRoute | ||||
| -- editform VD{..} = [hamlet| | ||||
| -- <form#editform method=POST style=display:none;> | ||||
| --  <h2#contenttitle>#{title}> | ||||
| --  <table.form> | ||||
| --   $if manyfiles | ||||
| --    <tr> | ||||
| --     <td colspan=2> | ||||
| --      Editing ^{journalselect $ files j} | ||||
| --   <tr> | ||||
| --    <td colspan=2> | ||||
| --     <!-- XXX textarea ids are unquoted journal file paths here, not valid html --> | ||||
| --     $forall f <- files j | ||||
| --      <textarea id=#{fst f}_textarea name=text rows=25 cols=80 style=display:none; disabled=disabled> | ||||
| --       \#{snd f} | ||||
| --   <tr#addbuttonrow> | ||||
| --    <td> | ||||
| --     <span.help>^{formathelp} | ||||
| --    <td> | ||||
| --     <span.help> | ||||
| --      Are you sure ? This will overwrite the journal. # | ||||
| --     <input type=hidden name=action value=edit> | ||||
| --     <input type=submit name=submit value="save journal"> | ||||
| --     \ or # | ||||
| --     <a href="#" onclick="return editformToggle(event)">cancel | ||||
| -- |] | ||||
| --   where | ||||
| --     title = "Edit journal" :: String | ||||
| --     manyfiles = length (files j) > 1 | ||||
| --     formathelp = helplink "file-format" "file format help" | ||||
| 
 | ||||
| -- -- | Import journal form. | ||||
| -- importform :: HtmlUrl AppRoute | ||||
| -- importform = [hamlet| | ||||
| -- <form#importform method=POST style=display:none;> | ||||
| --  <table.form> | ||||
| --   <tr> | ||||
| --    <td> | ||||
| --     <input type=file name=file> | ||||
| --     <input type=hidden name=action value=import> | ||||
| --     <input type=submit name=submit value="import from file"> | ||||
| --     \ or # | ||||
| --     <a href="#" onclick="return importformToggle(event)">cancel | ||||
| -- |] | ||||
| 
 | ||||
| -- | Link to a topic in the manual. | ||||
| helplink :: Text -> Text -> HtmlUrl AppRoute | ||||
| helplink topic label = [hamlet| | ||||
|  | ||||
| @ -1,75 +0,0 @@ | ||||
| -- -- | Handle a post from the journal edit form. | ||||
| -- handleEdit :: Handler Html | ||||
| -- handleEdit = do | ||||
| --   VD{..} <- getViewData | ||||
| --   -- get form input values, or validation errors. | ||||
| --   -- getRequest >>= liftIO (reqRequestBody req) >>= mtrace | ||||
| --   mtext <- lookupPostParam "text" | ||||
| --   mtrace "--------------------------" | ||||
| --   mtrace (journalFilePaths j) | ||||
| --   mjournalpath <- lookupPostParam "journal" | ||||
| --   let etext = maybe (Left "No value provided") (Right . unpack) mtext | ||||
| --       ejournalpath = maybe | ||||
| --                        (Right $ journalFilePath j) | ||||
| --                        (\f -> let f' = unpack f in | ||||
| --                               if f' `elem` dbg0 "paths2" (journalFilePaths j) | ||||
| --                               then Right f' | ||||
| --                               else Left ("unrecognised journal file path"::String)) | ||||
| --                        mjournalpath | ||||
| --       estrs = [etext, ejournalpath] | ||||
| --       errs = lefts estrs | ||||
| --       [text,journalpath] = rights estrs | ||||
| --   -- display errors or perform edit | ||||
| --   if not $ null errs | ||||
| --    then do | ||||
| --     setMessage $ toHtml (intercalate "; " errs :: String) | ||||
| --     redirect JournalR | ||||
| 
 | ||||
| -- -- | Handle a post from the journal edit form. | ||||
| -- handleEdit :: Handler Html | ||||
| -- handleEdit = do | ||||
| --   VD{..} <- getViewData | ||||
| --   -- get form input values, or validation errors. | ||||
| --   -- getRequest >>= liftIO (reqRequestBody req) >>= mtrace | ||||
| --   mtext <- lookupPostParam "text" | ||||
| --   mjournalpath <- lookupPostParam "journal" | ||||
| --   let etext = maybe (Left "No value provided") (Right . unpack) mtext | ||||
| --       ejournalpath = maybe | ||||
| --                        (Right $ journalFilePath j) | ||||
| --                        (\f -> let f' = unpack f in | ||||
| --                               if f' `elem` journalFilePaths j | ||||
| --                               then Right f' | ||||
| --                               else Left ("unrecognised journal file path"::String)) | ||||
| --                        mjournalpath | ||||
| --       estrs = [etext, ejournalpath] | ||||
| --       errs = lefts estrs | ||||
| --       [text,journalpath] = rights estrs | ||||
| --   -- display errors or perform edit | ||||
| --   if not $ null errs | ||||
| --    then do | ||||
| --     setMessage $ toHtml (intercalate "; " errs :: String) | ||||
| --     redirect JournalR | ||||
| 
 | ||||
| --    else do | ||||
| --     -- try to avoid unnecessary backups or saving invalid data | ||||
| --     filechanged' <- liftIO $ journalSpecifiedFileIsNewer j journalpath | ||||
| --     told <- liftIO $ readFileStrictly journalpath | ||||
| --     let tnew = filter (/= '\r') text | ||||
| --         changed = tnew /= told || filechanged' | ||||
| --     if not changed | ||||
| --      then do | ||||
| --        setMessage "No change" | ||||
| --        redirect JournalR | ||||
| --      else do | ||||
| --       jE <- liftIO $ readJournal def (Just journalpath) tnew | ||||
| --       either | ||||
| --        (\e -> do | ||||
| --           setMessage $ toHtml e | ||||
| --           redirect JournalR) | ||||
| --        (const $ do | ||||
| --           liftIO $ writeFileWithBackup journalpath tnew | ||||
| --           setMessage $ toHtml (printf "Saved journal %s\n" (show journalpath) :: String) | ||||
| --           redirect JournalR) | ||||
| --        jE | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										46
									
								
								hledger-web/Handler/EditR.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								hledger-web/Handler/EditR.hs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| {-# LANGUAGE LambdaCase #-} | ||||
| {-# LANGUAGE NamedFieldPuns #-} | ||||
| {-# LANGUAGE OverloadedStrings #-} | ||||
| 
 | ||||
| module Handler.EditR | ||||
|   ( postEditR | ||||
|   ) where | ||||
| 
 | ||||
| import Import | ||||
| 
 | ||||
| import Control.Monad.Trans (lift) | ||||
| import Control.Monad.Trans.Except | ||||
| import qualified Data.Text as T | ||||
| import Text.Printf (printf) | ||||
| 
 | ||||
| import Handler.Common (showErrors) | ||||
| 
 | ||||
| import Hledger | ||||
| import Hledger.Cli.Utils | ||||
| 
 | ||||
| -- | Handle a post from the journal edit form. | ||||
| postEditR :: Handler () | ||||
| postEditR = runE $ do | ||||
|   VD {j} <- lift getViewData | ||||
|   -- get form input values, or validation errors. | ||||
|   text <- ExceptT $ maybe (Left "No value provided") Right <$> lookupPostParam "text" | ||||
|   journalpath <- ExceptT $ maybe | ||||
|     (Right . T.pack $ journalFilePath j) | ||||
|     (\f -> | ||||
|        if T.unpack f `elem` journalFilePaths j | ||||
|          then Right f | ||||
|          else Left "unrecognised journal file path") <$> | ||||
|     lookupPostParam "journal" | ||||
|   -- try to avoid unnecessary backups or saving invalid data | ||||
|   let tnew = T.filter (/= '\r') text | ||||
| 
 | ||||
|   jE <- liftIO $ readJournal def (Just $ T.unpack journalpath) tnew | ||||
|   _ <- ExceptT . pure $ first T.pack jE | ||||
|   _ <- liftIO $ writeFileWithBackupIfChanged (T.unpack journalpath) tnew | ||||
|   setMessage $ toHtml (printf "Saved journal %s\n" (show journalpath) :: String) | ||||
|   redirect JournalR | ||||
|   where | ||||
|     runE :: ExceptT Text Handler () -> Handler () | ||||
|     runE f = runExceptT f >>= \case | ||||
|       Left e -> showErrors [e] >> redirect JournalR | ||||
|       Right x -> pure x | ||||
| @ -1,18 +0,0 @@ | ||||
| -- -- | Handle a post from the journal import form. | ||||
| -- handleImport :: Handler Html | ||||
| -- handleImport = do | ||||
| --   setMessage "can't handle file upload yet" | ||||
| --   redirect JournalR | ||||
| --   -- -- get form input values, or basic validation errors. E means an Either value. | ||||
| --   -- fileM <- runFormPost $ maybeFileInput "file" | ||||
| --   -- let fileE = maybe (Left "No file provided") Right fileM | ||||
| --   -- -- display errors or import transactions | ||||
| --   -- case fileE of | ||||
| --   --  Left errs -> do | ||||
| --   --   setMessage errs | ||||
| --   --   redirect JournalR | ||||
| 
 | ||||
| --   --  Right s -> do | ||||
| --   --    setMessage s | ||||
| --   --    redirect JournalR | ||||
| 
 | ||||
							
								
								
									
										29
									
								
								hledger-web/Handler/ImportR.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								hledger-web/Handler/ImportR.hs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| {-# LANGUAGE LambdaCase #-} | ||||
| {-# LANGUAGE OverloadedStrings #-} | ||||
| 
 | ||||
| module Handler.ImportR | ||||
|   ( postImportR | ||||
|   ) where | ||||
| 
 | ||||
| import Import | ||||
| 
 | ||||
| import Control.Monad.Trans (lift) | ||||
| import Control.Monad.Trans.Except | ||||
| 
 | ||||
| import Handler.Common (showErrors) | ||||
| 
 | ||||
| -- | Handle a post from the journal import form. | ||||
| postImportR :: Handler () | ||||
| postImportR = runE $ do | ||||
|   ((res, _), _) <- lift . runFormPost . renderDivs $ areq fileField "file" Nothing | ||||
|   case res of | ||||
|     FormMissing -> throwE ["No file provided"] | ||||
|     FormFailure es -> throwE es | ||||
|     FormSuccess _ -> do | ||||
|      setMessage "File uploaded successfully" | ||||
|      redirect JournalR | ||||
|   where | ||||
|     runE :: ExceptT [Text] Handler () -> Handler () | ||||
|     runE f = runExceptT f >>= \case | ||||
|       Left e -> showErrors e >> redirect JournalR | ||||
|       Right x -> pure x | ||||
| @ -9,6 +9,7 @@ import           Yesod                as Import hiding (Route (..)) | ||||
| 
 | ||||
| import           Control.Monad        as Import (when, unless, void) | ||||
| import           Data.Bifunctor       as Import (first, second, bimap) | ||||
| import           Data.Default         as Import (Default(def)) | ||||
| import           Data.Either          as Import (lefts, rights, partitionEithers) | ||||
| import           Data.Maybe           as Import (fromMaybe, maybeToList, mapMaybe, isJust) | ||||
| import           Data.Text            as Import (Text) | ||||
|  | ||||
| @ -6,6 +6,8 @@ | ||||
| /register        RegisterR       GET | ||||
| /sidebar         SidebarR        GET | ||||
| /add             AddR            POST | ||||
| /edit            EditR           POST | ||||
| /import          ImportR         POST | ||||
| 
 | ||||
| -- /accounts        AccountsR       GET | ||||
| -- /api/accounts    AccountsJsonR   GET | ||||
|  | ||||
| @ -125,6 +125,8 @@ library | ||||
|       Handler.AddForm | ||||
|       Handler.AddR | ||||
|       Handler.Common | ||||
|       Handler.EditR | ||||
|       Handler.ImportR | ||||
|       Handler.JournalR | ||||
|       Handler.RegisterR | ||||
|       Handler.RootR | ||||
|  | ||||
| @ -118,8 +118,10 @@ library: | ||||
|   - Application | ||||
|   - Foundation | ||||
|   - Handler.AddForm | ||||
|   - Handler.Common | ||||
|   - Handler.AddR | ||||
|   - Handler.Common | ||||
|   - Handler.EditR | ||||
|   - Handler.ImportR | ||||
|   - Handler.JournalR | ||||
|   - Handler.RegisterR | ||||
|   - Handler.RootR | ||||
|  | ||||
							
								
								
									
										24
									
								
								hledger-web/templates/edit-form.hamlet
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								hledger-web/templates/edit-form.hamlet
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| <form#editform method=POST style=display:none;> | ||||
|   <h2#contenttitle>Edit journal | ||||
|   <table.form> | ||||
|     $if length (jfiles j) > 1 | ||||
|      <tr> | ||||
|        <td colspan=2> | ||||
|          Editing ^{journalselect (fmap (T.unpack . snd) (jfiles j))} | ||||
|     <tr> | ||||
|       <td colspan=2> | ||||
|         <!-- XXX textarea ids are unquoted journal file paths here, not valid html --> | ||||
|          $forall f <- jfiles j | ||||
|           <textarea id=#{fst f}_textarea name=text rows=25 cols=80 style=display:none; disabled=disabled> | ||||
|             \#{snd f} | ||||
|     <tr#addbuttonrow> | ||||
|       <td> | ||||
|         <span.help> | ||||
|           ^{helplink "file-format" "file format help"} | ||||
|       <td> | ||||
|         <span.help> | ||||
|           Are you sure ? This will overwrite the journal. # | ||||
|         <input type=hidden name=action value=edit> | ||||
|         <input type=submit name=submit value="save journal"> | ||||
|         \ or # | ||||
|         <a href="#" onclick="return editformToggle(event)">cancel | ||||
							
								
								
									
										9
									
								
								hledger-web/templates/import-form.hamlet
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								hledger-web/templates/import-form.hamlet
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| <form#importform method=POST style=display:none;> | ||||
|  <table.form> | ||||
|   <tr> | ||||
|    <td> | ||||
|     <input type=file name=file> | ||||
|     <input type=hidden name=action value=import> | ||||
|     <input type=submit name=submit value="import from file"> | ||||
|     \ or # | ||||
|     <a href="#" onclick="return importformToggle(event)">cancel | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user