From 6c7bb9eff49be6dda72a96234926a2b2dcd76da9 Mon Sep 17 00:00:00 2001 From: Josh Date: Sat, 2 Jul 2022 14:22:52 +1000 Subject: [PATCH] Order Screen fully ported to Giraffe View Engine --- Core/Browser.module.fs | 3 +- DredgePos.fsproj | 1 + Entities/Buttons/Model.fs | 19 ++++ Floorplan/Model.fs | 12 ++- Global/View.fs | 13 +++ OrderScreen/Controller.fs | 135 +++++++++------------------- OrderScreen/Model.fs | 118 ------------------------ OrderScreen/Router.fs | 1 - OrderScreen/View.fs | 40 +++++---- sass/dredgepos.orderScreen.sass | 3 + typescript/dredgepos.orderScreen.ts | 9 +- typescript/types.ts | 2 +- 12 files changed, 117 insertions(+), 239 deletions(-) create mode 100644 Entities/Buttons/Model.fs diff --git a/Core/Browser.module.fs b/Core/Browser.module.fs index 07cb33d..b76830f 100644 --- a/Core/Browser.module.fs +++ b/Core/Browser.module.fs @@ -25,5 +25,4 @@ let setCookie name value (expiry: DateTimeOffset) (context: HttpContext) = options.Expires <- expiry context.Response.Cookies.Append(name, value, options); -let redirect url (context: HttpContext) = - context.Response.Redirect url \ No newline at end of file +let redirect url (context: HttpContext) = context.Response.Redirect url \ No newline at end of file diff --git a/DredgePos.fsproj b/DredgePos.fsproj index a5df94d..21966c6 100644 --- a/DredgePos.fsproj +++ b/DredgePos.fsproj @@ -20,6 +20,7 @@ + diff --git a/Entities/Buttons/Model.fs b/Entities/Buttons/Model.fs new file mode 100644 index 0000000..5680079 --- /dev/null +++ b/Entities/Buttons/Model.fs @@ -0,0 +1,19 @@ +module DredgePos.Entities.Buttons.Model + +open DredgePos.Types +open DredgeFramework + +let attr = Giraffe.ViewEngine.HtmlElements.attr + +let getItemActionAttributes (itemCode: string) = + let item = Entity.GetFirstByColumn "code" (StringTrim itemCode) + [(attr "data-item") <| jsonEncode item] + +let getGridActionAttributes (gridId: int) = [(attr "data-grid") <| jsonEncode gridId] + +let getActionAttributes (action: string) (actionValue: string) = + + match action with + | "item" -> getItemActionAttributes actionValue + | "grid" -> actionValue |> int |> getGridActionAttributes + | _ -> [] \ No newline at end of file diff --git a/Floorplan/Model.fs b/Floorplan/Model.fs index f7ac2db..98a6239 100644 --- a/Floorplan/Model.fs +++ b/Floorplan/Model.fs @@ -87,14 +87,20 @@ let saveOrderToTable orderXML tableNumber = File.WriteAllText(tableFile, tableXML) -let getTable (tableNumber : int) = +let getTableSafely (tableNumber: int) = let query = select { table "floorplan_tables" where (eq "table_number" tableNumber + eq "venue_id" (getCurrentVenue())) } - let result = query |> Database.Select - result |> first + query + |> Database.Select + |> Array.tryItem 0 + +let getTable (tableNumber : int) = + match getTableSafely tableNumber with + | None -> failwith $"Table {tableNumber} not found in current venue" + | Some table -> table let getTableById (id : int) = select { diff --git a/Global/View.fs b/Global/View.fs index 9a63587..a20d283 100644 --- a/Global/View.fs +++ b/Global/View.fs @@ -101,6 +101,19 @@ let posButton (extraClasses: string) attrs content = let allAttrs = [_class $"posButton {extraClasses}"] |> List.append attrs a allAttrs content +let PosButton classes (attrs: Map) text = + let attrArray = + attrs + |> Map.map (fun key value -> + (attr key) (string value) + ) + |> Map.values + |> Array.ofSeq + + posButton classes [ + yield! attrArray + ] [str text] + let HtmlPage pageTitle scripts styles tags content = html [] [ head [] [ diff --git a/OrderScreen/Controller.fs b/OrderScreen/Controller.fs index 6cd3835..f1db196 100644 --- a/OrderScreen/Controller.fs +++ b/OrderScreen/Controller.fs @@ -4,6 +4,7 @@ open DredgePos open DredgeFramework open DredgePos.Types open DredgePos.Global.Controller +open Saturn.CSRF open Thoth.Json.Net open Giraffe open Microsoft.AspNetCore.Http @@ -20,14 +21,6 @@ let getOrderScreenData (tableNumber: int) = |> ajaxSuccess |> json -let loadGrid (gridId: int) = - let grid = Entity.GetById gridId - let gridHtml = Model.loadGrid gridId - if gridHtml = "Error" then ajaxFail gridHtml - else ajaxSuccess {|grid=grid;gridHtml=gridHtml|} - |> json - - let renderGrid (grid: grid) = let gridData = grid.data |> Decode.Auto.fromString> match gridData with @@ -44,96 +37,54 @@ let renderGrid (grid: grid) = |> View.gridPage grid ) +let loadGrid (gridId: int) = + let grid = Entity.GetById gridId + let gridNodes = (renderGrid grid) |> List.ofArray + let gridHtml = Giraffe.ViewEngine.RenderView.AsString.htmlNodes gridNodes + + if gridHtml = "Error" then ajaxFail gridHtml + else ajaxSuccess {|grid=grid;gridHtml=gridHtml|} + |> json let loadOrderScreenView (ctx: HttpContext) (tableNumber: int) = Authenticate.Model.RequireClerkAuthentication ctx - let currentClerk = Authenticate.Model.getCurrentClerk ctx - let styles = [|"dredgepos.orderScreen.css"|] |> addDefaultStyles - let scripts = [|"dredgepos.tables.js";"./external/currency.min.js";"dredgepos.orderScreen.js"; |] |> addDefaultScripts - let metaTags = [|"viewport", "user-scalable = no, initial-scale=0.8,maximum-scale=0.8 ,shrink-to-fit=yes"|] |> addDefaultMetaTags + let tableOption = DredgePos.Floorplan.Model.getTableSafely tableNumber + let attr = Giraffe.ViewEngine.HtmlElements.attr - let printGroupButtons = - Entity.GetAllInVenue - |> Array.map View.printGroupButton + match tableOption with + | None -> + Browser.redirect "/" ctx + View.posButtonTemplate + | Some table -> + let currentClerk = Authenticate.Model.getCurrentClerk ctx + let styles = [|"dredgepos.orderScreen.css"|] |> addDefaultStyles + let scripts = [|"dredgepos.tables.js";"./external/currency.min.js";"dredgepos.orderScreen.js"; |] |> addDefaultScripts + let metaTags = [|"viewport", "user-scalable = no, initial-scale=0.8,maximum-scale=0.8 ,shrink-to-fit=yes"|] |> addDefaultMetaTags - let orderScreenPageGroupButtons = - Entity.GetAllInVenue - |> Array.filter (fun page_group -> page_group.id <> 0) - |> Array.sortBy (fun {order=order} -> order) - |> Array.map View.pageGroupButton + let printGroupButtons = + Entity.GetAllInVenue + |> Array.map View.printGroupButton - let grids = Model.getAllPageGridsInVenue () - let pageGroupNodes = - grids - |> Array.map(fun (grid, page_group) -> - renderGrid grid - |> View.pageGroup page_group - ) + let orderScreenPageGroupButtons = + Entity.GetAllInVenue + |> Array.filter (fun page_group -> page_group.id <> 0) + |> Array.sortBy (fun {order=order} -> order) + |> Array.map View.pageGroupButton + let grids = Model.getAllPageGridsInVenue () + let pageGroupNodes = + grids + |> Array.map(fun (grid, page_group) -> + renderGrid grid + |> View.pageGroup page_group + ) + let coverSelectorButtons = + Array.init (table.default_covers + 1) id + |> Array.map(fun coverNumber -> + let text = if coverNumber > 0 then language.getAndReplace "selected_cover" [coverNumber] + else language.get "cover_zero" + Global.View.PosButton "coverSelectorButton" (map ["data-cover", coverNumber]) text + ) - View.index tableNumber styles scripts metaTags currentClerk printGroupButtons orderScreenPageGroupButtons pageGroupNodes - -let loadOrderScreen (ctx: HttpContext) (tableNumber: int) : HttpHandler = - Authenticate.Model.RequireClerkAuthentication ctx - - let table = Floorplan.Model.getTable tableNumber - - let covers = if tableNumber > 0 then table.default_covers else 0 - let coverString = language.getAndReplace "covers" [covers] - - let changeCoverNumberButton = if tableNumber > 0 then Theme.loadTemplateWithVars "orderScreen/change_cover_number_button" (map ["covers", coverString]) else "" - - let orderNumber = - if tableNumber > 0 then language.getAndReplace "active_table" [tableNumber] - else language.get "new_order" - - let containerAttributes = - if tableNumber > 0 then - map ["data-table", jsonEncode table] - |> Theme.htmlAttributes - else "" - - let categoryList = - Entity.GetAllInVenue - |> Array.filter (fun page_group -> page_group.id <> 0) - |> Array.sortBy (fun {order=order} -> order) - |> Array.map (fun category -> - let categoryMap = recordToMap category - let categoryArray = map ["page", categoryMap] - Theme.loadTemplateWithArrays "orderScreen/page_group_button" categoryArray - ) - |> joinWithNewLine - - let grids = - Model.getAllPageGridsInVenue () - |> Array.map Model.getPagesHTML - |> joinWithNewLine - - let coverSelectorButtons = - Array.init (covers+1) id - |> Array.map(fun coverNumber -> - let text = if coverNumber > 0 then language.getAndReplace "selected_cover" [coverNumber] - else language.get "cover_zero" - Theme.PosButton text "coverSelectorButton" $"""data-cover="{coverNumber}" """) - |> String.concat "\n" - - let variables = map [ - "title", "Order" - "containerAttributes", containerAttributes - "categoryList", categoryList - "pageGroups", grids - "orderNumber", orderNumber - "changeCoverNumberButton", changeCoverNumberButton - "covers", coverString - "salesCategoryOverrideButtons", Model.generateSalesCategoryOverrideButtons () - "coverSelectorButtons", coverSelectorButtons - ] - - let styles = ["dredgepos.orderScreen.css"] - let scripts = ["dredgepos.tables.js";"./external/currency.min.js";"dredgepos.orderScreen.js"; ] - let currentClerk = recordToMap <| Authenticate.Model.getCurrentClerk ctx - let arrays = map ["clerk", currentClerk] - - Theme.loadTemplateWithVarsArraysScriptsAndStyles "orderScreen" variables arrays scripts styles - |> htmlString + View.index tableNumber styles scripts metaTags currentClerk printGroupButtons orderScreenPageGroupButtons pageGroupNodes coverSelectorButtons \ No newline at end of file diff --git a/OrderScreen/Model.fs b/OrderScreen/Model.fs index 646e8ce..aa8fa98 100644 --- a/OrderScreen/Model.fs +++ b/OrderScreen/Model.fs @@ -13,124 +13,6 @@ let getAllPageGridsInVenue () = |> Array.filter(fun pageGroup -> pageGroup.grid_id <> 0) |> Array.map(fun pageGroup -> (Entity.GetById pageGroup.grid_id), pageGroup) -let getImageButtonData (button: button) = - let itemCode = - if button.primary_action = "item" then button.primary_action_value - else button.secondary_action_value - - let item = Entity.GetAllByColumn "code" itemCode - |> first - - let extraData = - map [ - "data-item", jsonEncode item - ] |> htmlAttributes - - {| - extra_data = extraData - text = item.name - |} - -let getGridButtonData (button: button) = - let gridId = - if button.primary_action = "grid" then button.primary_action_value - else button.secondary_action_value - |> int - - let grid = Entity.GetById gridId - {| - extra_data = map ["data-grid", jsonEncode gridId] |> htmlAttributes - text = grid.name - |} - -let getActionData (button: button) (action: string) = - let actionValue = - if action = "primary" then button.primary_action - else button.secondary_action - - match actionValue with - | "item" -> getImageButtonData button - | "grid" -> getGridButtonData button - | "spacer" -> {|extra_data=""; text=""|} - | _ -> {|extra_data=""; text=""|} - -let renderButton (buttonId: int) = - let button = Entity.GetById