diff options
| author | Ben Sima <ben@bensima.com> | 2025-11-28 02:08:50 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-11-28 02:08:50 -0500 |
| commit | 717fd14986fea45f2a539068be67a7f132cdedad (patch) | |
| tree | e2bbabb5c841a31a697370a7fb2b9a3d2955a1d3 /Omni/Jr/Web.hs | |
| parent | db102cb5206acb6008ea80a6c920dd6f320abe2d (diff) | |
Add create fact form in web UI
All tests pass. The create fact form has been added to the web
UI. Here'
1. **Added `FactCreateForm` data type** - New form type to handle the
cr 2. **Added API route** - `POST /kb/create` endpoint that accepts
the for 3. **Added handler** - `factCreateHandler` that creates a
new fact using 4. **Added form UI** - A collapsible form on the KB
page with fields for
- Project (required) - Fact Content (required textarea) - Related
Files (optional, comma-separated) - Confidence level (0.0-1.0,
default 0.8)
5. **Added CSS styles** - Styling for the create fact section in
both li
Task-Id: t-158.6
Diffstat (limited to 'Omni/Jr/Web.hs')
| -rw-r--r-- | Omni/Jr/Web.hs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/Omni/Jr/Web.hs b/Omni/Jr/Web.hs index eb8a751..e58992c 100644 --- a/Omni/Jr/Web.hs +++ b/Omni/Jr/Web.hs @@ -62,6 +62,7 @@ type API = :> QueryParam "type" Text :> Get '[Lucid.HTML] TaskListPage :<|> "kb" :> Get '[Lucid.HTML] KBPage + :<|> "kb" :> "create" :> ReqBody '[FormUrlEncoded] FactCreateForm :> PostRedirect :<|> "kb" :> Capture "id" Int :> Get '[Lucid.HTML] FactDetailPage :<|> "kb" :> Capture "id" Int :> "edit" :> ReqBody '[FormUrlEncoded] FactEditForm :> PostRedirect :<|> "kb" :> Capture "id" Int :> "delete" :> PostRedirect @@ -148,6 +149,16 @@ instance FromForm FactEditForm where let confidence = fromRight "0.8" (lookupUnique "confidence" form) Right (FactEditForm content files confidence) +data FactCreateForm = FactCreateForm Text Text Text Text + +instance FromForm FactCreateForm where + fromForm form = do + project <- parseUnique "project" form + content <- parseUnique "content" form + let files = fromRight "" (lookupUnique "files" form) + let confidence = fromRight "0.8" (lookupUnique "confidence" form) + Right (FactCreateForm project content files confidence) + data EpicsPage = EpicsPage [TaskCore.Task] [TaskCore.Task] newtype RecentActivityPartial = RecentActivityPartial [TaskCore.Task] @@ -570,6 +581,60 @@ instance Lucid.ToHtml KBPage where Lucid.div_ [Lucid.class_ "container"] <| do Lucid.h1_ "Knowledge Base" Lucid.p_ [Lucid.class_ "info-msg"] "Facts learned during task execution." + + Lucid.details_ [Lucid.class_ "create-fact-section"] <| do + Lucid.summary_ [Lucid.class_ "btn btn-primary create-fact-toggle"] "Create New Fact" + Lucid.form_ + [ Lucid.method_ "POST", + Lucid.action_ "/kb/create", + Lucid.class_ "fact-create-form" + ] + <| do + Lucid.div_ [Lucid.class_ "form-group"] <| do + Lucid.label_ [Lucid.for_ "project"] "Project:" + Lucid.input_ + [ Lucid.type_ "text", + Lucid.name_ "project", + Lucid.id_ "project", + Lucid.class_ "form-input", + Lucid.required_ "required", + Lucid.placeholder_ "e.g., Omni/Jr" + ] + Lucid.div_ [Lucid.class_ "form-group"] <| do + Lucid.label_ [Lucid.for_ "content"] "Fact Content:" + Lucid.textarea_ + [ Lucid.name_ "content", + Lucid.id_ "content", + Lucid.class_ "form-textarea", + Lucid.rows_ "4", + Lucid.required_ "required", + Lucid.placeholder_ "Describe the fact or knowledge..." + ] + "" + Lucid.div_ [Lucid.class_ "form-group"] <| do + Lucid.label_ [Lucid.for_ "files"] "Related Files (comma-separated):" + Lucid.input_ + [ Lucid.type_ "text", + Lucid.name_ "files", + Lucid.id_ "files", + Lucid.class_ "form-input", + Lucid.placeholder_ "path/to/file1.hs, path/to/file2.hs" + ] + Lucid.div_ [Lucid.class_ "form-group"] <| do + Lucid.label_ [Lucid.for_ "confidence"] "Confidence (0.0 - 1.0):" + Lucid.input_ + [ Lucid.type_ "number", + Lucid.name_ "confidence", + Lucid.id_ "confidence", + Lucid.class_ "form-input", + Lucid.step_ "0.1", + Lucid.min_ "0", + Lucid.max_ "1", + Lucid.value_ "0.8" + ] + Lucid.div_ [Lucid.class_ "form-actions"] <| do + Lucid.button_ [Lucid.type_ "submit", Lucid.class_ "btn btn-primary"] "Create Fact" + if null facts then Lucid.p_ [Lucid.class_ "empty-msg"] "No facts recorded yet." else Lucid.div_ [Lucid.class_ "task-list"] <| traverse_ renderFactCard facts @@ -1614,6 +1679,7 @@ server = :<|> statsHandler :<|> taskListHandler :<|> kbHandler + :<|> factCreateHandler :<|> factDetailHandler :<|> factEditHandler :<|> factDeleteHandler @@ -1682,6 +1748,13 @@ server = facts <- liftIO Fact.getAllFacts pure (KBPage facts) + factCreateHandler :: FactCreateForm -> Servant.Handler (Headers '[Header "Location" Text] NoContent) + factCreateHandler (FactCreateForm project content filesText confText) = do + let files = filter (not <. Text.null) (Text.splitOn "," (Text.strip filesText)) + confidence = fromMaybe 0.8 (readMaybe (Text.unpack confText)) + fid <- liftIO (Fact.createFact project content files Nothing confidence) + pure <| addHeader ("/kb/" <> tshow fid) NoContent + factDetailHandler :: Int -> Servant.Handler FactDetailPage factDetailHandler fid = do maybeFact <- liftIO (Fact.getFact fid) |
