Floorplan Updated
This commit is contained in:
1
.idea/.idea.DredgePos.dir/.idea/.name
generated
1
.idea/.idea.DredgePos.dir/.idea/.name
generated
@@ -1 +0,0 @@
|
||||
DredgePos
|
||||
11
.idea/config/applicationhost.config
generated
11
.idea/config/applicationhost.config
generated
@@ -156,7 +156,7 @@
|
||||
<virtualDirectoryDefaults allowSubDirConfig="true" />
|
||||
<site name="DredgePos" id="1">
|
||||
<application path="/" applicationPool="DredgePos AppPool">
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\dredgy\RiderProjects\WebApplication\WebApplication" />
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\dredgy\RiderProjects\DredgePos\DredgePos" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:55543:localhost" />
|
||||
@@ -984,10 +984,15 @@
|
||||
<handlers>
|
||||
<add name="aspNetCore" path="*" verb="*" resourceType="Unspecified" modules="aspnetcorev2" />
|
||||
</handlers>
|
||||
<modules><add name="aspnetcorev2" /><remove name="WebMatrixSupportModule" /></modules>
|
||||
<modules>
|
||||
<add name="aspnetcorev2" />
|
||||
<remove name="WebMatrixSupportModule" />
|
||||
</modules>
|
||||
<aspNetCore stdoutLogEnabled="false" startupTimeLimit="3600" requestTimeout="23:00:00" processPath="%ANCM_LAUNCHER_PATH%" hostingModel="InProcess" arguments="%ANCM_LAUNCHER_ARGS%" />
|
||||
<httpCompression>
|
||||
<dynamicTypes><add mimeType="text/event-stream" enabled="false" /></dynamicTypes>
|
||||
<dynamicTypes>
|
||||
<add mimeType="text/event-stream" enabled="false" />
|
||||
</dynamicTypes>
|
||||
</httpCompression>
|
||||
</system.webServer>
|
||||
</location>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
module AjaxController
|
||||
|
||||
open DredgeFramework
|
||||
open Floorplan
|
||||
open Microsoft.AspNetCore.Http
|
||||
open Reservations
|
||||
open language
|
||||
open Giraffe
|
||||
open Dapper.FSharp
|
||||
|
||||
let loginWithLoginCode (context: HttpContext) (login_code: int) =
|
||||
if Session.clerkLogin login_code context then ajaxSuccess "success"
|
||||
@@ -15,28 +18,50 @@ let getActiveTables venue = Floorplan.getActiveTables venue |> ajaxSuccess |> js
|
||||
|
||||
let getRoomData roomId = Floorplan.getRoom roomId |> ajaxSuccess |> json
|
||||
|
||||
let mergeTables (parent, child) =
|
||||
let mergeTables (tables: floorplan_table[]) =
|
||||
let status =
|
||||
if Floorplan.mergeTables parent child then "success"
|
||||
else "fail"
|
||||
|
||||
map [
|
||||
"status", status
|
||||
"data" , parent |> Floorplan.getTable |> jsonEncode
|
||||
if mergeTables tables.[0].table_number tables.[1].table_number then
|
||||
let outputTables = map [
|
||||
"parent", tables.[0];
|
||||
"child", tables.[1];
|
||||
"merged", getTable tables.[0].table_number;
|
||||
]
|
||||
|> json
|
||||
ajaxSuccess outputTables
|
||||
else ajaxFail "Could Not Merge Tables"
|
||||
status |> json
|
||||
|
||||
let unmergeTable tableNumber =
|
||||
let status =
|
||||
if Floorplan.unmergeTable tableNumber then "success"
|
||||
else "fail"
|
||||
let unmerged = Floorplan.unmergeTable tableNumber
|
||||
let unmergedTables =
|
||||
match unmerged with
|
||||
| Some (parent, child) ->
|
||||
map["parent", parent; "child", child] |> ajaxSuccess
|
||||
| None -> ajaxFail "Could not Unmerge Table"
|
||||
|
||||
map [
|
||||
"status", status
|
||||
"data" , "[true]"
|
||||
]
|
||||
unmergedTables |> json
|
||||
|
||||
|
||||
let getFloorplanData venue =
|
||||
let tableList = Floorplan.tableList venue
|
||||
let reservationList = getReservationList tableList
|
||||
{|
|
||||
tables = tableList
|
||||
decorations = Decorations.decorationList venue
|
||||
activeTableNumbers = Floorplan.getActiveTables venue
|
||||
rooms = Floorplan.getRoomList venue
|
||||
reservations = reservationList
|
||||
|}
|
||||
|> ajaxSuccess
|
||||
|> json
|
||||
|
||||
let getKeyboardLayout (language: string) =
|
||||
let layout = $"""wwwroot/languages/{language}/keyboardLayout.json""" |> GetFileContents
|
||||
map [
|
||||
"status", "success"
|
||||
"data", layout
|
||||
] |> json
|
||||
|
||||
|
||||
let getRoomTablesAndDecorations roomId =
|
||||
let tables = Floorplan.tablesInRoom roomId
|
||||
let decorations = Decorations.decorationsInRoom roomId
|
||||
@@ -53,50 +78,70 @@ let updateTableShape (table: Floorplan.floorplan_table_shape) =
|
||||
Floorplan.updateTableShape table |> ignore
|
||||
getTableData table.table_number
|
||||
|
||||
let transformTable (table: Floorplan.floorplan_table_transform) =
|
||||
let transformTable (table: Floorplan.floorplan_table) =
|
||||
Floorplan.updateTablePosition table |> ignore
|
||||
getTableData table.table_number
|
||||
|
||||
let createTable (tableData) =
|
||||
let newTableCreated = Floorplan.addNewTable tableData
|
||||
let createTable (tableData: floorplan_table) =
|
||||
let result =
|
||||
if newTableCreated then Floorplan.getTable tableData.table_number |> jsonEncode |> ajaxSuccess
|
||||
else Floorplan.tableExists tableData.table_number |> jsonEncode |> ajaxFail
|
||||
if tableExists tableData.table_number = "False" then
|
||||
ajaxSuccess (addNewTable tableData)
|
||||
else ajaxFail (tableExists tableData.table_number)
|
||||
|
||||
json result
|
||||
result |> json
|
||||
|
||||
let deleteTable (table: floorplan_table) =
|
||||
Floorplan.deleteTable table.table_number
|
||||
table |> ajaxSuccess |> json
|
||||
|
||||
let transferTable (origin, destination) =
|
||||
Floorplan.transferTable origin destination
|
||||
ajaxSuccess "true" |> json
|
||||
let data = map ["origin", getTable origin ; "destination", getTable destination]
|
||||
ajaxSuccess data |> json
|
||||
|
||||
let AddDecoration (data: Decorations.decoration_creator) =
|
||||
let AddDecoration (data: Decorations.floorplan_decoration) =
|
||||
let image = "wwwroot/images/decorations/" + data.decoration_image
|
||||
let width, height = image |> GetImageSize
|
||||
let aspectRatio = decimal width / decimal height
|
||||
|
||||
let decoration : Decorations.floorplan_decoration = {
|
||||
decoration_id = 0
|
||||
id = 0
|
||||
decoration_height = (200m / aspectRatio) |> int
|
||||
decoration_width = 200
|
||||
decoration_rotation = 0
|
||||
decoration_image = data.decoration_image
|
||||
decoration_pos_x = data.basis/2
|
||||
decoration_pos_y = data.basis/2
|
||||
decoration_pos_x = data.decoration_pos_x
|
||||
decoration_pos_y = data.decoration_pos_y
|
||||
decoration_room = data.decoration_room
|
||||
}
|
||||
|
||||
Decorations.CreateDecoration decoration |> ignore
|
||||
ajaxSuccess "true" |> json
|
||||
Decorations.CreateDecoration decoration |> ajaxSuccess |> json
|
||||
|
||||
let UpdateDecoration data =
|
||||
Decorations.UpdateDecoration data |> ignore
|
||||
ajaxSuccess "true" |> json
|
||||
|
||||
let DeleteDecoration id =
|
||||
Decorations.DeleteDecorationById id |> ignore
|
||||
ajaxSuccess "true" |> json
|
||||
let DeleteDecoration id = ajaxSuccess (Decorations.DeleteDecoration id) |> json
|
||||
|
||||
let newEmptyReservation tableNumber =
|
||||
Floorplan.createEmptyReservation tableNumber 2
|
||||
let newEmptyReservation (reservation: reservation) =
|
||||
let newReservation = {reservation with
|
||||
reservation_created_at = CurrentTime()
|
||||
reservation_time = CurrentTime()
|
||||
}
|
||||
|
||||
json <| ajaxSuccess "true"
|
||||
if reservation.reservation_table_id > 0 then
|
||||
let table = {(getTableById reservation.reservation_table_id) with
|
||||
status = 2
|
||||
default_covers = reservation.reservation_covers}
|
||||
updateTablePosition table |> ignore
|
||||
|
||||
let createdReservation = Floorplan.createEmptyReservation newReservation
|
||||
ajaxSuccess createdReservation |> json
|
||||
|
||||
let updateReservation (reservation: reservation) = updateReservation reservation |> ajaxSuccess |> json
|
||||
|
||||
let unreserveTable (table: floorplan_table) =
|
||||
let newTable = {table with status = 0}
|
||||
updateTablePosition newTable |> ignore
|
||||
DeleteReservation newTable.id
|
||||
newTable |> ajaxSuccess |> json
|
||||
|
||||
@@ -8,12 +8,12 @@ open Thoth.Json.Net
|
||||
|
||||
let mutable loginCookie = ""
|
||||
|
||||
type clerk = {clerk_id: int; clerk_name: string; clerk_login_code: int; clerk_usergroup: int}
|
||||
type clerk = {id: int; clerk_name: string; clerk_login_code: int; clerk_usergroup: int}
|
||||
let clerk_decoder : Decoder<clerk> =
|
||||
Decode.object
|
||||
(fun get ->
|
||||
{
|
||||
clerk_id = get.Required.Field "clerk_id" Decode.int
|
||||
id = get.Required.Field "clerk_id" Decode.int
|
||||
clerk_name = get.Required.Field "clerk_name" Decode.string
|
||||
clerk_login_code = get.Required.Field "clerk_login_code" Decode.int
|
||||
clerk_usergroup = get.Required.Field "clerk_usergroup" Decode.int
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
module db
|
||||
|
||||
open Dapper
|
||||
open Dapper.FSharp
|
||||
open Dapper.FSharp.MySQL
|
||||
open MySql.Data.MySqlClient
|
||||
open DredgeFramework
|
||||
@@ -24,6 +26,16 @@ let Insert<'a> asyncQuery =
|
||||
|> connection.InsertAsync<'a>
|
||||
|> RunSynchronously
|
||||
|
||||
let InsertOutput<'a> asyncQuery =
|
||||
asyncQuery
|
||||
|> connection.InsertAsync<'a>
|
||||
|> RunSynchronously
|
||||
|> ignore
|
||||
|
||||
let table = asyncQuery.Table
|
||||
connection.Query<'a>($"""Select * From {table} Where id = (select last_insert_id())""")
|
||||
|> EnumerableToArray
|
||||
|
||||
let Update<'a> asyncQuery =
|
||||
asyncQuery
|
||||
|> connection.UpdateAsync<'a>
|
||||
|
||||
@@ -6,10 +6,11 @@ open System.Text.RegularExpressions
|
||||
open DredgeFramework
|
||||
open Dapper
|
||||
open Dapper.FSharp
|
||||
open Floorplan
|
||||
|
||||
[<CLIMutable>]
|
||||
type floorplan_decoration = {
|
||||
decoration_id: int
|
||||
id: int
|
||||
decoration_room: int
|
||||
decoration_pos_x: int
|
||||
decoration_pos_y: int
|
||||
@@ -19,12 +20,14 @@ type floorplan_decoration = {
|
||||
decoration_image: string
|
||||
}
|
||||
|
||||
type decoration_creator = {
|
||||
decoration_room: int
|
||||
decoration_image: string
|
||||
basis: int
|
||||
let decorationList venue =
|
||||
select {
|
||||
table "floorplan_decorations"
|
||||
innerJoin "floorplan_rooms" "id" "decoration_room"
|
||||
}
|
||||
|
||||
|> db.SelectJoin<floorplan_decoration, floorplan_room>
|
||||
|> Array.filter (fun (_, room) -> room.venue_id = venue )
|
||||
|> Array.map fst
|
||||
|
||||
let decorationsInRoom (roomId: int) =
|
||||
select {
|
||||
@@ -43,8 +46,6 @@ let getImageName (image: string, path: string) =
|
||||
|
||||
imageName, path
|
||||
|
||||
|
||||
|
||||
let isImageFile (fileName: string) = Regex.IsMatch(fileName |> ToLowerCase, @"^.+\.(jpg|jpeg|png|gif)$")
|
||||
|
||||
let getImageHTML (imageName: string, imageUrl: string) =
|
||||
@@ -77,20 +78,21 @@ let CreateDecoration (decoration: floorplan_decoration) =
|
||||
insert {
|
||||
table "floorplan_decorations"
|
||||
value decoration
|
||||
} |> db.Insert
|
||||
}
|
||||
|> db.InsertOutput
|
||||
|> first
|
||||
|
||||
|
||||
let UpdateDecoration (decoration: floorplan_decoration) =
|
||||
let imageFile = GetFileName decoration.decoration_image
|
||||
let updatedDecoration = {decoration with decoration_image = imageFile}
|
||||
|
||||
update {
|
||||
table "floorplan_decorations"
|
||||
set updatedDecoration
|
||||
where (eq "decoration_id" decoration.decoration_id )
|
||||
set decoration
|
||||
where (eq "id" decoration.id )
|
||||
} |> db.Update
|
||||
|
||||
let DeleteDecorationById (id: int) =
|
||||
let DeleteDecoration (decoration: floorplan_decoration) =
|
||||
delete {
|
||||
table "floorplan_decorations"
|
||||
where (eq "decoration_id" id)
|
||||
} |> db.Delete
|
||||
where (eq "id" decoration.id)
|
||||
} |> db.Delete |> ignore
|
||||
decoration
|
||||
@@ -18,9 +18,7 @@ let (|?) lhs rhs = if lhs = null then rhs else lhs
|
||||
|
||||
let map list = list |> Map.ofList
|
||||
|
||||
let JoinArray (char: string) (array: string[]) = String.Join(char, array)
|
||||
|
||||
let first (array: 'a[]) = array.[0]
|
||||
let JoinArray (char: string) (array: 'a[]) = String.Join(char, array)
|
||||
|
||||
let StringReplace (search:string) (replace:string) (string:string) = (search, replace) |> string.Replace
|
||||
|
||||
@@ -37,6 +35,9 @@ let GetFileContents (file: string) = File.ReadAllText file
|
||||
let GetFileName (file: string) = Path.GetFileName file
|
||||
|
||||
let length (variable: 'T[]) = variable.Length
|
||||
let first (array: 'a[]) = array.[0]
|
||||
let last (array: 'a[]) = array.[array.Length-1]
|
||||
|
||||
|
||||
let removeFalseValues (variable: bool[]) = variable |> Array.filter id
|
||||
|
||||
@@ -67,14 +68,15 @@ let RunSynchronously task =
|
||||
|> Async.AwaitTask
|
||||
|> Async.RunSynchronously
|
||||
|
||||
let AppendToArray (element: 'T) (array : 'T[]) = Array.append [|element|] array
|
||||
|
||||
let ToLowerCase (string: string) = string.ToLower()
|
||||
let ToUpperCase (string: string) = string.ToUpper()
|
||||
let ToTitleCase (string: string) = CultureInfo.CurrentCulture.TextInfo.ToTitleCase <| string
|
||||
|
||||
let recordToMap (record: 'T) =
|
||||
seq {
|
||||
for prop in FSharpType.GetRecordFields(typeof<'T>) ->
|
||||
prop.Name, prop.GetValue(record) |> string
|
||||
for prop in FSharpType.GetRecordFields(typeof<'T>) -> prop.Name, prop.GetValue(record) |> string
|
||||
}
|
||||
|> Map.ofSeq
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<Compile Include="Browser.module.fs" />
|
||||
<Compile Include="Database.module.fs" />
|
||||
<Compile Include="Language.module.fs" />
|
||||
<Compile Include="GenericEntities.module.fs" />
|
||||
<Compile Include="Theme.module.fs" />
|
||||
<Compile Include="Reservations.module.fs" />
|
||||
<Compile Include="Floorplan.module.fs" />
|
||||
@@ -31,6 +32,7 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Remove="node_modules\**" />
|
||||
<Content Remove="wwwroot\scripts\ts\test.ts" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -38,13 +38,13 @@ type floorplan_table = {
|
||||
rotation: int
|
||||
merged_children: string
|
||||
previous_state: string
|
||||
status: string
|
||||
table_id: int
|
||||
status: int
|
||||
id: int
|
||||
}
|
||||
|
||||
[<CLIMutable>]
|
||||
type floorplan_room = {
|
||||
room_id: int
|
||||
id: int
|
||||
room_name: string
|
||||
background_image: string
|
||||
venue_id: int
|
||||
@@ -66,8 +66,8 @@ let floorplan_table_decoder : Decoder<floorplan_table> =
|
||||
rotation = get.Required.Field "rotation" Decode.int
|
||||
merged_children = get.Required.Field "merged_children" Decode.string
|
||||
previous_state = get.Required.Field "previous_state" Decode.string
|
||||
status = get.Required.Field "status" Decode.string
|
||||
table_id = get.Required.Field "table_id" Decode.int
|
||||
status = get.Required.Field "status" Decode.int
|
||||
id = get.Required.Field "id" Decode.int
|
||||
})
|
||||
|
||||
|
||||
@@ -78,10 +78,12 @@ let getTableFile (tableNumber: int) =
|
||||
let tableNumberString = tableNumber |> string
|
||||
activeTablePath + "table" + tableNumberString + ".table"
|
||||
|
||||
let tableIsOpen (tableNumber: int) =
|
||||
let tableNumberIsOpen (tableNumber: int) =
|
||||
let tableFile = getTableFile tableNumber
|
||||
File.Exists tableFile
|
||||
|
||||
let tableIsOpen (table: floorplan_table) = tableNumberIsOpen table.table_number
|
||||
|
||||
let fileNameToTableNumber (fileName: string) = //Takes a file name for a floorplan table and returns the table number
|
||||
if fileName.Contains ".table" then
|
||||
let fileName = (fileName.Split ".").[0]
|
||||
@@ -105,15 +107,14 @@ let tablesInRoom (roomId: int) = //Get a list of all tables in a particular room
|
||||
|> db.Select<floorplan_table>
|
||||
|
||||
|
||||
|
||||
let getActiveTables (venueId: int) =
|
||||
select{
|
||||
table "floorplan_tables"
|
||||
where (eq "venue_id" venueId)
|
||||
}
|
||||
|> db.Select
|
||||
|> Array.map getTableNumber
|
||||
|> Array.filter tableIsOpen
|
||||
|> Array.map (fun table -> table.table_number)
|
||||
|
||||
let openNewTable tableNumber = //Create a new table file pre-populated with skeleton data
|
||||
let tableFile = getTableFile tableNumber
|
||||
@@ -128,10 +129,10 @@ let transferTable origin destination = //Transfers a table from one to another
|
||||
let originFile = getTableFile origin
|
||||
let destinationFile = getTableFile destination
|
||||
|
||||
if tableIsOpen origin then
|
||||
if tableNumberIsOpen origin then
|
||||
(* If the destination is not an already open table,
|
||||
then we simply have to rename the origin to destination *)
|
||||
if not <| tableIsOpen destination then
|
||||
if not <| tableNumberIsOpen destination then
|
||||
let content = File.ReadAllText originFile
|
||||
let newContent = content.Replace($"number=\"{origin|>string}\">", $"number=\"{destination|>string}\">")
|
||||
File.WriteAllText(originFile, newContent)
|
||||
@@ -159,10 +160,18 @@ let getTable (tableNumber : int) =
|
||||
|> db.Select<floorplan_table>
|
||||
|> first
|
||||
|
||||
let getTableById (id : int) =
|
||||
select {
|
||||
table "floorplan_tables"
|
||||
where (eq "id" id)
|
||||
}
|
||||
|> db.Select<floorplan_table>
|
||||
|> first
|
||||
|
||||
let getRoom (roomId: int) =
|
||||
select {
|
||||
table "floorplan_rooms"
|
||||
where (eq "room_id" roomId)
|
||||
where (eq "id" roomId)
|
||||
} |> db.Select<floorplan_room> |> first
|
||||
|
||||
let getRoomList (venueId: int) =
|
||||
@@ -172,6 +181,7 @@ let getRoomList (venueId: int) =
|
||||
} |> db.Select<floorplan_room>
|
||||
|
||||
let updateFloorplanTable (tableNumber:int) (column: string) value =
|
||||
//TODO: Make update query venue specific
|
||||
let sql = "Update floorplan_tables Set @column = @value Where table_number = @tableNumber"
|
||||
let parameters = [("column", box column); ("value", box value); ("tableNumber", box tableNumber)]
|
||||
db.connection.Execute(sql, parameters) |> ignore
|
||||
@@ -185,25 +195,26 @@ let updateTableShape (floorplanTable: floorplan_table_shape) =
|
||||
where (eq "table_number" floorplanTable.table_number + eq "venue_id" currentVenue)
|
||||
} |> db.Update
|
||||
|
||||
let updateTablePosition (floorplanTable: floorplan_table_transform) =
|
||||
|
||||
let updateTablePosition (floorplanTable: floorplan_table) =
|
||||
update {
|
||||
table "floorplan_tables"
|
||||
set floorplanTable
|
||||
where (eq "table_number" floorplanTable.table_number + eq "venue_id" currentVenue)
|
||||
} |> db.Update
|
||||
|
||||
let createEmptyReservation tableNumber covers =
|
||||
let table = getTable tableNumber
|
||||
let status = if table.status = "" then "reserved" else table.status
|
||||
|
||||
//let res = newReservation "" 0 covers
|
||||
|
||||
let createEmptyReservation (reservation: reservation) =
|
||||
update {
|
||||
table "floorplan_tables"
|
||||
set {| status = status |}
|
||||
where(eq "table_number" tableNumber)
|
||||
set {| status = 2 |}
|
||||
where(eq "id" reservation.reservation_table_id)
|
||||
} |> db.Update |> ignore
|
||||
|
||||
insert{
|
||||
table "reservations"
|
||||
value reservation
|
||||
} |> db.InsertOutput |> first
|
||||
|
||||
|
||||
|
||||
let getChildTables tableNumber =
|
||||
@@ -217,7 +228,7 @@ let matchTable (tableNumberToMatch: int) (floorplanTableToCheck: floorplan_table
|
||||
|
||||
let findChildTable (childTable: int) (parentTable: floorplan_table) =
|
||||
let json = parentTable.merged_children
|
||||
let childTables = json |> Decode.fromString(Decode.array floorplan_table_decoder)
|
||||
let childTables = json |> Decode.Auto.fromString<floorplan_table[]>
|
||||
|
||||
let matchedTables =
|
||||
match childTables with
|
||||
@@ -262,16 +273,24 @@ let tableExists (tableNumber: int) =
|
||||
language.getAndReplace "error_table_exists" [room.room_name]
|
||||
|
||||
|
||||
let addNewTable newTable =
|
||||
if tableExists newTable.table_number = "False" then
|
||||
let addNewTableWithoutOutput (newTable: floorplan_table) =
|
||||
insert{
|
||||
table "floorplan_tables"
|
||||
value newTable
|
||||
} |> db.Insert |> ignore
|
||||
true
|
||||
else false
|
||||
}
|
||||
|> db.Insert
|
||||
|
||||
let deleteTable tableNumber =
|
||||
let addNewTable (newTable: floorplan_table) =
|
||||
let newTableList =
|
||||
insert{
|
||||
table "floorplan_tables"
|
||||
value newTable
|
||||
}
|
||||
|> db.InsertOutput
|
||||
|
||||
newTableList |> first
|
||||
|
||||
let deleteTable (tableNumber: int) =
|
||||
delete {
|
||||
table "floorplan_tables"
|
||||
where (eq "table_number" tableNumber + eq "venue_id" currentVenue)
|
||||
@@ -342,7 +361,7 @@ let updateUnmergedTables parentTable childTable =
|
||||
where(eq "table_number" parentTable.table_number + eq "venue_id" currentVenue)
|
||||
} |> db.Update |> ignore
|
||||
|
||||
addNewTable childTable |> ignore
|
||||
addNewTableWithoutOutput childTable |> ignore
|
||||
true
|
||||
|
||||
let processUnmerge originalTable unmergedChild =
|
||||
@@ -354,25 +373,35 @@ let processUnmerge originalTable unmergedChild =
|
||||
|
||||
let unmergeTable tableNumber = //Separates a merged table into itself and the last table merged into it.
|
||||
let currentTable = getTable tableNumber
|
||||
let mergedChildren = currentTable.merged_children |> Decode.fromString(Decode.list floorplan_table_decoder)
|
||||
let mergedChildren = currentTable.merged_children |> Decode.Auto.fromString<floorplan_table[]>
|
||||
|
||||
match mergedChildren with
|
||||
| Ok listOfChildTables ->
|
||||
let unmergedChild = listOfChildTables |> List.last
|
||||
processUnmerge currentTable unmergedChild
|
||||
| Error _ -> false
|
||||
let unmergedChild = listOfChildTables |> last
|
||||
processUnmerge currentTable unmergedChild |> ignore
|
||||
Some (getTable currentTable.table_number, unmergedChild)
|
||||
| Error _ -> None
|
||||
|
||||
let convertRoomListToLinks (room: floorplan_room) =
|
||||
let vars = map [
|
||||
"roomId", room.room_id |> string
|
||||
"roomId", room.id |> string
|
||||
"roomName", room.room_name
|
||||
]
|
||||
|
||||
Theme.loadTemplateWithVars "roomButton" vars
|
||||
|
||||
let getReservationList (tableList: floorplan_table[]) =
|
||||
let tableIds =
|
||||
tableList
|
||||
|> Array.map(fun table -> table.id)
|
||||
|> JoinArray ","
|
||||
|
||||
db.connection.Query<reservation>($"""Select * From reservations Where reservation_table_id In ({tableIds})""")
|
||||
|> EnumerableToArray
|
||||
|
||||
let newReservation name time covers =
|
||||
let reservation = {
|
||||
reservation_id = 0
|
||||
id = 0
|
||||
reservation_name = name
|
||||
reservation_time = time
|
||||
reservation_covers = covers
|
||||
@@ -385,12 +414,12 @@ let newReservation name time covers =
|
||||
value reservation
|
||||
} |> db.Insert
|
||||
|
||||
let unReserveTable tableNumber =
|
||||
let table = getTable tableNumber
|
||||
DeleteReservation table.table_id
|
||||
if table.status = "reserved" then
|
||||
update {
|
||||
table "floorplan_tables"
|
||||
set {| status = "" ; reservation_id = 0 |}
|
||||
} |> db.Update |> ignore
|
||||
|
||||
let tableList venueId =
|
||||
select{
|
||||
table "floorplan_tables"
|
||||
innerJoin "floorplan_rooms" "id" "floorplan_tables.room_id"
|
||||
}
|
||||
|> db.SelectJoin<floorplan_table, floorplan_room>
|
||||
|> Array.filter (fun (_, room) -> room.venue_id = venueId )
|
||||
|> Array.map fst
|
||||
|
||||
1
GenericEntities.module.fs
Normal file
1
GenericEntities.module.fs
Normal file
@@ -0,0 +1 @@
|
||||
module GenericEntities
|
||||
23
Program.fs
23
Program.fs
@@ -1,6 +1,7 @@
|
||||
namespace WebApplication
|
||||
|
||||
open Clerk
|
||||
open Floorplan
|
||||
open Microsoft.AspNetCore.Http
|
||||
open Microsoft.AspNetCore.Mvc.RazorPages
|
||||
open Microsoft.Extensions.Hosting;
|
||||
@@ -23,25 +24,28 @@ module Program =
|
||||
post "/authenticateClerk" (bindJson<int> (handlePostRoute AjaxController.loginWithLoginCode) )
|
||||
post "/getTableData" (bindJson<int> AjaxController.getTableData)
|
||||
post "/updateTableShape" (bindJson<Floorplan.floorplan_table_shape> AjaxController.updateTableShape)
|
||||
post "/transformTable" (bindJson<Floorplan.floorplan_table_transform> AjaxController.transformTable)
|
||||
post "/transformTable" (bindJson<Floorplan.floorplan_table> AjaxController.transformTable)
|
||||
post "/createTable" (bindJson<Floorplan.floorplan_table> AjaxController.createTable)
|
||||
post "/addDecoration" (bindJson<Decorations.decoration_creator> AjaxController.AddDecoration)
|
||||
post "/addDecoration" (bindJson<Decorations.floorplan_decoration> AjaxController.AddDecoration)
|
||||
post "/updateDecoration" (bindJson<Decorations.floorplan_decoration> AjaxController.UpdateDecoration)
|
||||
post "/deleteDecoration" (bindJson<int> AjaxController.DeleteDecoration)
|
||||
post "/newEmptyReservation" (bindJson<int> AjaxController.newEmptyReservation)
|
||||
post "/deleteDecoration" (bindJson<Decorations.floorplan_decoration> AjaxController.DeleteDecoration)
|
||||
post "/deleteTable" (bindJson<Floorplan.floorplan_table> AjaxController.deleteTable)
|
||||
post "/mergeTables" (bindJson<Floorplan.floorplan_table[]> AjaxController.mergeTables)
|
||||
post "/newEmptyReservation" (bindJson<reservation> AjaxController.newEmptyReservation)
|
||||
post "/updateReservation" (bindJson<reservation> AjaxController.updateReservation)
|
||||
post "/getReservation" (bindJson<int> (fun reservation -> json <| GetReservationById reservation) )
|
||||
post "/unreserveTable" (bindJson<int> (fun tableNumber -> json <| Floorplan.unReserveTable tableNumber) )
|
||||
post "/unreserveTable" (bindJson<floorplan_table> AjaxController.unreserveTable )
|
||||
getf "/getRoomData/%i" AjaxController.getRoomData
|
||||
getf "/getKeyboardLayout/%s" AjaxController.getKeyboardLayout
|
||||
getf "/getTablesAndDecorations/%i" AjaxController.getRoomTablesAndDecorations
|
||||
get "/languageVars" (json <| AjaxController.getLanguageVars)
|
||||
get "/getOpenTables" (json <| Floorplan.getActiveTables Floorplan.currentVenue)
|
||||
getf "/getActiveTables/%i" AjaxController.getActiveTables
|
||||
getf "/tableIsOpen/%i" (fun tableNumber -> json <| Floorplan.tableIsOpen tableNumber)
|
||||
getf "/transferTables/%i/%i" AjaxController.transferTable
|
||||
getf "/mergeTables/%i/%i" AjaxController.mergeTables
|
||||
getf "/getFloorplanData/%i" AjaxController.getFloorplanData
|
||||
getf "/tableIsOpen/%i" (fun tableNumber -> json <| Floorplan.tableNumberIsOpen tableNumber)
|
||||
getf "/transferTable/%i/%i" AjaxController.transferTable
|
||||
getf "/unmergeTable/%i" AjaxController.unmergeTable
|
||||
getf "/tableExists/%i" (fun tableNumber -> json <| Floorplan.tableExists tableNumber)
|
||||
getf "/deleteTable/%i" (fun tableNumber -> json <| Floorplan.deleteTable tableNumber)
|
||||
}
|
||||
|
||||
let pageRouter = router {
|
||||
@@ -56,6 +60,7 @@ module Program =
|
||||
let app = application {
|
||||
use_static "wwwroot"
|
||||
use_router pageRouter
|
||||
|
||||
}
|
||||
|
||||
run app
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
open System
|
||||
open DredgeFramework
|
||||
open Dapper.FSharp
|
||||
|
||||
[<CLIMutable>]
|
||||
type reservation = {
|
||||
reservation_id: int
|
||||
id: int
|
||||
reservation_name: string
|
||||
reservation_time: int
|
||||
reservation_covers: int
|
||||
@@ -16,13 +16,21 @@ type reservation = {
|
||||
let GetReservationById (id: int) =
|
||||
select {
|
||||
table "reservations"
|
||||
where (eq "reservation_id" id)
|
||||
where (eq "id" id)
|
||||
}
|
||||
|> db.Select<reservation>
|
||||
|> first
|
||||
|
||||
let updateReservation (reservation: reservation) =
|
||||
update{
|
||||
table "reservations"
|
||||
set reservation
|
||||
where(eq "id" reservation.id)
|
||||
} |> db.Update |> ignore
|
||||
reservation
|
||||
|
||||
let DeleteReservation (tableId: int) =
|
||||
delete {
|
||||
table "reservations"
|
||||
where (eq "table_id" tableId)
|
||||
where (eq "reservation_table_id" tableId)
|
||||
} |> db.Delete |> ignore
|
||||
@@ -6,7 +6,8 @@ open Dapper.FSharp
|
||||
open Clerk
|
||||
open Thoth.Json.Net
|
||||
|
||||
type session = {session_id: string; clerk_json: string; clerk_id: int; expires: int}
|
||||
[<CLIMutable>]
|
||||
type session = {id: int; session_id: string; clerk_json: string; clerk_id: int; expires: int}
|
||||
|
||||
let deleteSession sessionId context =
|
||||
delete {
|
||||
@@ -25,19 +26,22 @@ let deleteSessionByClerkId clerk_id context =
|
||||
|
||||
let createNewSession (clerk: clerk) context =
|
||||
if (getClerkByLoginCode clerk.clerk_login_code).IsSome then
|
||||
deleteSessionByClerkId clerk.clerk_id context
|
||||
deleteSessionByClerkId clerk.id context
|
||||
let newSessionId = (Guid.NewGuid().ToString "N") + (Guid.NewGuid().ToString "N")
|
||||
|
||||
let newSession = { session_id = newSessionId
|
||||
let newSession = {
|
||||
id = 0
|
||||
session_id = newSessionId
|
||||
clerk_json = clerk |> jsonEncode
|
||||
clerk_id = clerk.clerk_id
|
||||
clerk_id = clerk.id
|
||||
expires = int <| DateTimeOffset.Now.AddHours(24.0).ToUnixTimeSeconds()
|
||||
}
|
||||
|
||||
insert {
|
||||
table "sessions"
|
||||
value newSession
|
||||
} |> db.Insert |> ignore
|
||||
}
|
||||
|> db.Insert
|
||||
|> ignore
|
||||
|
||||
Browser.setCookie "dredgepos_clerk_logged_in" newSessionId (DateTimeOffset.UtcNow.AddHours(24.0)) context
|
||||
|
||||
@@ -63,7 +67,7 @@ let sessionExists (sessionId: string) context =
|
||||
let checkAuthentication clerk =
|
||||
let existingClerk = getClerkByLoginCode clerk.clerk_login_code
|
||||
if existingClerk.IsSome
|
||||
&& existingClerk.Value.clerk_id = clerk.clerk_id
|
||||
&& existingClerk.Value.id = clerk.id
|
||||
&& existingClerk.Value.clerk_name = clerk.clerk_name
|
||||
&& existingClerk.Value.clerk_login_code = clerk.clerk_login_code
|
||||
then true
|
||||
@@ -79,12 +83,12 @@ let getSession (sessionId: string) =
|
||||
} |> db.Select<session>
|
||||
|
||||
match sessions |> length with
|
||||
| 0 -> {session_id = ""; clerk_json = ""; clerk_id= 0; expires= 0}
|
||||
| 0 -> {session_id = ""; clerk_json = ""; clerk_id= 0; expires= 0; id=0}
|
||||
| _ -> sessions |> first
|
||||
|
||||
let getCurrentClerk context =
|
||||
let cookie = getLoginCookie context
|
||||
let emptyClerk = {clerk_id=0; clerk_login_code=0; clerk_usergroup=0; clerk_name=""}
|
||||
let emptyClerk = {id=0; clerk_login_code=0; clerk_usergroup=0; clerk_name=""}
|
||||
match cookie with
|
||||
| "" ->
|
||||
Browser.redirect "/login" context
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -7,7 +7,6 @@
|
||||
/ajax/getActiveTables/%i, GET,
|
||||
/ajax/tableIsOpen/%i, GET,
|
||||
/ajax/tableExists/%i, GET,
|
||||
/ajax/deleteTable/%i, GET,
|
||||
/ajax/authenticateClerk, POST,
|
||||
/ajax/getTableData, POST,
|
||||
/ajax/updateTableShape, POST,
|
||||
@@ -16,7 +15,10 @@
|
||||
/ajax/addDecoration, POST,
|
||||
/ajax/updateDecoration, POST,
|
||||
/ajax/deleteDecoration, POST,
|
||||
/ajax/deleteTable, POST,
|
||||
/ajax/mergeTables, POST,
|
||||
/ajax/newEmptyReservation, POST,
|
||||
/ajax/updateReservation, POST,
|
||||
/ajax/getReservation, POST,
|
||||
/ajax/unreserveTable, POST,
|
||||
, NotFoundHandler,
|
||||
@@ -14,7 +14,7 @@
|
||||
"logged_in_as":"Logged in as [1]",
|
||||
"covers":"[1] Covers",
|
||||
"selected_cover":"Cover [1]",
|
||||
"activeTable":"Table [1]",
|
||||
"active_table":"Table [1]",
|
||||
"totalPrice":"Total Price: [1]",
|
||||
"selectedPrice":"([1] Selected)",
|
||||
"next_page":"Next Page",
|
||||
@@ -60,7 +60,8 @@
|
||||
"delete_table":"Delete Table",
|
||||
"change_shape":"Change Shape",
|
||||
"new_table_number":"New Table Number",
|
||||
"transfer_table":"Transfer to New Table",
|
||||
"transfer_table":"Transfer to Other Table",
|
||||
"transfer_self_error":"Cannot transfer a table to itself.",
|
||||
"add_decoration":"Add Decoration",
|
||||
"choose_decoration":"Choose a Decoration",
|
||||
"delete_decoration":"Delete Decoration",
|
||||
@@ -68,9 +69,11 @@
|
||||
"reserved_for":"Reserved for [1]",
|
||||
"reserved":"Reserved",
|
||||
"confirm_delete_reservation":"Are you sure you want to delete the reservation on table [1]?",
|
||||
"confirm_reservation_name":"Who is this reservation for?",
|
||||
"error_table_exists":"Table already exists in room \"[1]\"",
|
||||
"error_table_exists_merged":"Table already exists in room \"[1]\", it is merged with table [2].",
|
||||
"error_delete_existing_table":"Can't delete a table that's currently active.",
|
||||
"error_self_merge" : "You can't merge a table with itself",
|
||||
"confirm_delete_table":"Are you sure you want to delete table [1]?",
|
||||
"orig_qty_header":"Original Qty",
|
||||
"selected_qty_header":"Selected Qty",
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
4ce3c2bb1d8bbd35c1b58d110118bb059ac6cd85
|
||||
6de23b71f021bbbc1f858685dc5809960956a0bb
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -14,7 +14,7 @@
|
||||
"logged_in_as":"Logged in as [1]",
|
||||
"covers":"[1] Covers",
|
||||
"selected_cover":"Cover [1]",
|
||||
"activeTable":"Table [1]",
|
||||
"active_table":"Table [1]",
|
||||
"totalPrice":"Total Price: [1]",
|
||||
"selectedPrice":"([1] Selected)",
|
||||
"next_page":"Next Page",
|
||||
@@ -60,7 +60,8 @@
|
||||
"delete_table":"Delete Table",
|
||||
"change_shape":"Change Shape",
|
||||
"new_table_number":"New Table Number",
|
||||
"transfer_table":"Transfer to New Table",
|
||||
"transfer_table":"Transfer to Other Table",
|
||||
"transfer_self_error":"Cannot transfer a table to itself.",
|
||||
"add_decoration":"Add Decoration",
|
||||
"choose_decoration":"Choose a Decoration",
|
||||
"delete_decoration":"Delete Decoration",
|
||||
@@ -68,9 +69,11 @@
|
||||
"reserved_for":"Reserved for [1]",
|
||||
"reserved":"Reserved",
|
||||
"confirm_delete_reservation":"Are you sure you want to delete the reservation on table [1]?",
|
||||
"confirm_reservation_name":"Who is this reservation for?",
|
||||
"error_table_exists":"Table already exists in room \"[1]\"",
|
||||
"error_table_exists_merged":"Table already exists in room \"[1]\", it is merged with table [2].",
|
||||
"error_delete_existing_table":"Can't delete a table that's currently active.",
|
||||
"error_self_merge" : "You can't merge a table with itself",
|
||||
"confirm_delete_table":"Are you sure you want to delete table [1]?",
|
||||
"orig_qty_header":"Original Qty",
|
||||
"selected_qty_header":"Selected Qty",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
let Application = {
|
||||
keyboard: null,
|
||||
mode: "default",
|
||||
mode: [],
|
||||
languageVars: {}
|
||||
};
|
||||
/** Parses a language variable. */
|
||||
let lang = (key, replacements) => {
|
||||
let finalValue = Application.languageVars[key];
|
||||
let finalValue = Application.languageVars[key] || '';
|
||||
if (!replacements)
|
||||
return finalValue;
|
||||
if (typeof replacements === 'string')
|
||||
@@ -28,16 +28,19 @@ let ajax = (endpoint, data, method = 'POST', successFunction, errorFunction, bef
|
||||
method: method,
|
||||
data: data,
|
||||
success: (response) => {
|
||||
if (successFunction)
|
||||
if (successFunction && response.status == 'success')
|
||||
successFunction(JSON.parse(response.data));
|
||||
else if (errorFunction && response.status != 'success') {
|
||||
errorFunction(JSON.parse(response.data));
|
||||
}
|
||||
},
|
||||
error: errorFunction,
|
||||
error: (error) => console.log(error.statusCode),
|
||||
beforeSend: beforeFunction
|
||||
});
|
||||
};
|
||||
/*
|
||||
For the flow of the app, synchronous is commonly preferred
|
||||
though trying to keep it's usage as low as possible.
|
||||
though trying to keep its usage as low as possible.
|
||||
*/
|
||||
let ajaxSync = (endpoint, data, method = 'POST') => {
|
||||
let response = JSON.parse($.ajax({
|
||||
@@ -56,11 +59,14 @@ let ajaxSync = (endpoint, data, method = 'POST') => {
|
||||
let redirect = (url) => {
|
||||
window.location.href = url;
|
||||
};
|
||||
let setLanguageVariables = () => {
|
||||
Application.languageVars = ajaxSync('/ajax/languageVars', null, 'GET');
|
||||
let setupCore = (languageVars) => {
|
||||
Application.languageVars = languageVars;
|
||||
const doc = $(document);
|
||||
doc.on('click', '#alertNo, #alertOk', hideAlerts);
|
||||
setElementVisibilityByMode();
|
||||
};
|
||||
// @ts-ignore
|
||||
let alert = (message, title = 'Message') => {
|
||||
let posAlert = (message, title = 'Message') => {
|
||||
let alertBox = $('#alert');
|
||||
alertBox.css('display', 'flex');
|
||||
alertBox.data('value', '');
|
||||
@@ -70,12 +76,11 @@ let alert = (message, title = 'Message') => {
|
||||
$('#alertYes').css('display', 'none');
|
||||
$('#alertNo').css('display', 'none');
|
||||
};
|
||||
// @ts-ignore
|
||||
let confirm = (message, data, title = 'Confirm', submitFunction = (data) => { hideAlerts(); }) => {
|
||||
let confirmation = (message, data, title = 'Confirm', submitFunction = (data) => { hideAlerts(); }) => {
|
||||
let alert = $('#alert');
|
||||
$(document).on('click', '#alert #alertYes', () => {
|
||||
submitFunction(data);
|
||||
hideAlerts();
|
||||
submitFunction(data);
|
||||
$(document).off('click', '#alert #alertYes');
|
||||
});
|
||||
alert.css('display', 'flex');
|
||||
@@ -85,12 +90,58 @@ let confirm = (message, data, title = 'Confirm', submitFunction = (data) => { hi
|
||||
$('#alertYes').css('display', 'flex');
|
||||
$('#alertNo').css('display', 'flex');
|
||||
};
|
||||
let hideAlerts = () => {
|
||||
$('#alert').hide();
|
||||
let hideAlerts = () => $('#alert').hide();
|
||||
let turnOnMode = (mode) => {
|
||||
Application.mode.push(mode);
|
||||
setElementVisibilityByMode();
|
||||
};
|
||||
$(() => {
|
||||
let doc = $(document);
|
||||
setLanguageVariables();
|
||||
doc.on('click', '#alertNo, #alertOk', () => $('#alert').hide());
|
||||
let turnOffMode = (mode) => {
|
||||
Application.mode = Application.mode.filter((value) => value != mode);
|
||||
setElementVisibilityByMode();
|
||||
};
|
||||
let toggleMode = (mode) => {
|
||||
if (!isInMode(mode))
|
||||
turnOnMode(mode);
|
||||
else
|
||||
turnOffMode(mode);
|
||||
};
|
||||
let clearModes = () => { Application.mode = []; };
|
||||
let isInMode = (mode) => Application.mode.includes(mode);
|
||||
let setElementVisibilityByMode = () => {
|
||||
const mode = Application.mode;
|
||||
const elements = $('[data-visible-in-mode]');
|
||||
elements.each((index, elem) => {
|
||||
let element = $(elem);
|
||||
let visibleInModes = element.data('visible-in-mode');
|
||||
let showElement = visibleInModes.every(visibleMode => {
|
||||
return mode.includes(visibleMode);
|
||||
});
|
||||
if (element.hasClass('useVisibility')) {
|
||||
if (showElement) {
|
||||
element.css('visibility', 'visible');
|
||||
}
|
||||
else
|
||||
element.css('visibility', 'hidden');
|
||||
}
|
||||
else
|
||||
element.toggle(showElement);
|
||||
});
|
||||
const invisibleElements = $('[data-invisible-in-mode]');
|
||||
invisibleElements.each((index, elem) => {
|
||||
let element = $(elem);
|
||||
let inVisibleInModes = element.data('invisible-in-mode');
|
||||
let hideElement = inVisibleInModes.every(invisibleMode => {
|
||||
return mode.includes(invisibleMode);
|
||||
});
|
||||
element.toggle(!hideElement);
|
||||
});
|
||||
$('[data-active-in-mode]').each((index, elem) => {
|
||||
const button = $(elem);
|
||||
const activeInMode = button.data('active-in-mode');
|
||||
mode.includes(activeInMode)
|
||||
? button.addClass('active')
|
||||
: button.removeClass('active');
|
||||
});
|
||||
};
|
||||
$(() => ajax('/ajax/languageVars', null, 'GET', setupCore, null, null));
|
||||
//# sourceMappingURL=dredgepos.core.js.map
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -17,8 +17,8 @@ let showVirtualNumpad = (heading, maxlength = 4, isPassword, allowDecimals = tru
|
||||
numpad.data('submitfunction', submitFunction);
|
||||
numpad.data('password', isPassword);
|
||||
numpad.data('allowdecimals', allowDecimals);
|
||||
$(document).unbind('keyup');
|
||||
$(document).keyup(e => {
|
||||
$(document).off('keyup');
|
||||
$(document).on('keyup', e => {
|
||||
let key = e.key;
|
||||
switch (key) {
|
||||
case 'Backspace':
|
||||
@@ -52,7 +52,6 @@ let virtualNumpadInput = (input) => {
|
||||
let submitFunction = numpad.data('submitfunction');
|
||||
let allowedValues = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'submit', 'clear'];
|
||||
let currentValue = numpad.data('value').toString();
|
||||
//Test
|
||||
if (allowDecimals)
|
||||
allowedValues.push('.', ',');
|
||||
let validInput = allowedValues.includes(input);
|
||||
@@ -91,11 +90,12 @@ let setupVirtualNumpad = () => {
|
||||
hideVirtualNumpad();
|
||||
});
|
||||
};
|
||||
let setupVirtualKeyboard = () => {
|
||||
let setupVirtualKeyboard = (keyboardLayouts) => {
|
||||
Application.keyboard = {
|
||||
capsLock: false,
|
||||
shift: false,
|
||||
layout: 'default'
|
||||
layouts: keyboardLayouts,
|
||||
currentLayout: 'default',
|
||||
};
|
||||
$(document).on('click', '.virtualKeyboardButton', e => {
|
||||
virtualKeyboardInput($(e.target).data('value'));
|
||||
@@ -138,7 +138,7 @@ let virtualKeyboardInput = (input) => {
|
||||
case 'submit':
|
||||
hideVirtualKeyboard();
|
||||
let submitFunction = keyboard.data('submitfunction');
|
||||
submitFunction();
|
||||
submitFunction(inputBox.text());
|
||||
break;
|
||||
case 'shift':
|
||||
if (Application.keyboard.capsLock)
|
||||
@@ -174,16 +174,17 @@ let virtualKeyboardInput = (input) => {
|
||||
}
|
||||
};
|
||||
let setKeyboardLayout = (layout, modifier = '') => {
|
||||
let keyboardLayout = ajaxSync('/languages/english/keyboardLayout.json', null, 'get');
|
||||
if (modifier != '')
|
||||
modifier = `_${modifier}`;
|
||||
Application.keyboard.currentLayout = layout;
|
||||
let layoutToLoad = Application.keyboard.layouts[layout];
|
||||
$('.virtualKeyboardRow').each((index, row) => {
|
||||
/*
|
||||
We start at 1 instead of 0. Makes it easier for non-programmers
|
||||
and translators making their own language packs
|
||||
*/
|
||||
index = index + 1;
|
||||
let currentRow = keyboardLayout[layout]["row" + index + modifier];
|
||||
let currentRow = layoutToLoad[`row${index}${modifier}`];
|
||||
$(row).children('a').each((keyIndex, button) => {
|
||||
let key = $(button);
|
||||
let keyValue = currentRow[keyIndex];
|
||||
@@ -211,6 +212,6 @@ let setKeyboardLayout = (layout, modifier = '') => {
|
||||
};
|
||||
$(() => {
|
||||
setupVirtualNumpad();
|
||||
setupVirtualKeyboard();
|
||||
ajax('/ajax/getKeyboardLayout/english', null, 'get', setupVirtualKeyboard, null, null);
|
||||
});
|
||||
//# sourceMappingURL=keyboards.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1,13 +1,13 @@
|
||||
let Application : ApplicationState = {
|
||||
keyboard : null,
|
||||
mode: "default",
|
||||
mode: [],
|
||||
languageVars: {}
|
||||
}
|
||||
|
||||
|
||||
/** Parses a language variable. */
|
||||
let lang = (key: string, replacements?: string[] | string) => {
|
||||
let finalValue = Application.languageVars[key]
|
||||
let finalValue = Application.languageVars[key] || ''
|
||||
|
||||
if(!replacements) return finalValue
|
||||
if(typeof replacements === 'string') replacements = [replacements]
|
||||
@@ -26,17 +26,20 @@
|
||||
}
|
||||
|
||||
/** Call an Ajax function asynchronously */
|
||||
let ajax = (endpoint : string, data: any, method = 'POST', successFunction : Function , errorFunction : JQuery.Ajax.ErrorCallback<any>, beforeFunction: any) => {
|
||||
let ajax = (endpoint : string, data: any, method = 'POST', successFunction : Function , errorFunction : Function, beforeFunction: any) => {
|
||||
data = (data == null) ? data : JSON.stringify(data)
|
||||
return $.ajax({
|
||||
url: endpoint,
|
||||
method: method,
|
||||
data: data,
|
||||
success: (response) => {
|
||||
if(successFunction)
|
||||
success: (response: ajaxResult) => {
|
||||
if(successFunction && response.status == 'success')
|
||||
successFunction(JSON.parse(response.data))
|
||||
else if (errorFunction && response.status != 'success'){
|
||||
errorFunction(JSON.parse(response.data))
|
||||
}
|
||||
},
|
||||
error: errorFunction,
|
||||
error: (error) => console.log(error.statusCode),
|
||||
beforeSend: beforeFunction
|
||||
})
|
||||
}
|
||||
@@ -44,7 +47,7 @@
|
||||
|
||||
/*
|
||||
For the flow of the app, synchronous is commonly preferred
|
||||
though trying to keep it's usage as low as possible.
|
||||
though trying to keep its usage as low as possible.
|
||||
*/
|
||||
let ajaxSync = (endpoint : string, data?: any, method = 'POST') => {
|
||||
let response = JSON.parse(
|
||||
@@ -69,12 +72,17 @@
|
||||
}
|
||||
|
||||
|
||||
let setLanguageVariables = () => {
|
||||
Application.languageVars = ajaxSync('/ajax/languageVars', null, 'GET')
|
||||
let setupCore = (languageVars: Record<string, string>) => {
|
||||
Application.languageVars = languageVars
|
||||
const doc = $(document)
|
||||
doc.on('click', '#alertNo, #alertOk', hideAlerts)
|
||||
|
||||
setElementVisibilityByMode()
|
||||
}
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
let alert = (message: string, title='Message') => {
|
||||
let posAlert = (message: string, title='Message') => {
|
||||
let alertBox = $('#alert')
|
||||
alertBox.css('display', 'flex');
|
||||
alertBox.data('value', '');
|
||||
@@ -86,13 +94,12 @@
|
||||
$('#alertNo').css('display', 'none');
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
let confirm = (message: string, data: any, title='Confirm', submitFunction = (data: any) => {hideAlerts()}) => {
|
||||
let confirmation = (message: string, data: any, title='Confirm', submitFunction = (data: any) => {hideAlerts()}) => {
|
||||
let alert = $('#alert')
|
||||
|
||||
$(document).on('click', '#alert #alertYes', () => {
|
||||
submitFunction(data)
|
||||
hideAlerts()
|
||||
submitFunction(data)
|
||||
$(document).off('click', '#alert #alertYes')
|
||||
})
|
||||
|
||||
@@ -106,13 +113,69 @@
|
||||
}
|
||||
|
||||
|
||||
let hideAlerts = () => {
|
||||
$('#alert').hide()
|
||||
let hideAlerts = () => $('#alert').hide()
|
||||
|
||||
let turnOnMode = (mode : PosMode) => {
|
||||
Application.mode.push(mode)
|
||||
setElementVisibilityByMode()
|
||||
}
|
||||
|
||||
$( () => {
|
||||
let doc = $(document)
|
||||
setLanguageVariables()
|
||||
let turnOffMode = (mode : PosMode) => {
|
||||
Application.mode = Application.mode.filter((value) => value != mode)
|
||||
setElementVisibilityByMode()
|
||||
|
||||
doc.on('click', '#alertNo, #alertOk', () => $('#alert').hide())
|
||||
}
|
||||
|
||||
let toggleMode = (mode: PosMode) => {
|
||||
if(!isInMode(mode))
|
||||
turnOnMode(mode)
|
||||
else
|
||||
turnOffMode(mode)
|
||||
}
|
||||
|
||||
let clearModes = () => {Application.mode = []}
|
||||
let isInMode = (mode: PosMode) => Application.mode.includes(mode)
|
||||
|
||||
let setElementVisibilityByMode = () => {
|
||||
const mode = Application.mode
|
||||
const elements = $('[data-visible-in-mode]')
|
||||
|
||||
elements.each((index, elem) => {
|
||||
let element = $(elem)
|
||||
let visibleInModes : PosModes = element.data('visible-in-mode')
|
||||
|
||||
let showElement = visibleInModes.every( visibleMode => {
|
||||
return mode.includes(visibleMode)
|
||||
});
|
||||
|
||||
if(element.hasClass('useVisibility')){
|
||||
if(showElement) {
|
||||
element.css('visibility', 'visible')
|
||||
} else element.css('visibility', 'hidden')
|
||||
} else element.toggle(showElement)
|
||||
})
|
||||
|
||||
const invisibleElements = $('[data-invisible-in-mode]')
|
||||
invisibleElements.each((index, elem) => {
|
||||
let element = $(elem)
|
||||
let inVisibleInModes: PosModes = element.data('invisible-in-mode')
|
||||
let hideElement = inVisibleInModes.every(invisibleMode => {
|
||||
return mode.includes(invisibleMode)
|
||||
})
|
||||
element.toggle(!hideElement)
|
||||
})
|
||||
|
||||
|
||||
$('[data-active-in-mode]').each((index, elem) =>{
|
||||
const button = $(elem)
|
||||
const activeInMode : PosMode = button.data('active-in-mode')
|
||||
|
||||
mode.includes(activeInMode)
|
||||
? button.addClass('active')
|
||||
: button.removeClass('active')
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
$( () => ajax('/ajax/languageVars', null, 'GET', setupCore, null, null))
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,9 @@
|
||||
let showVirtualNumpad = (heading: string, maxlength = 4, isPassword: boolean, allowDecimals = true, allowClose = true, submitFunction: Function) => {
|
||||
type KeyboardRowName = `row${number}${"" | "_"}${string}`;
|
||||
interface VirtualKeyboard {
|
||||
[layoutName: string]: Partial<Record<KeyboardRowName, string[]>>;
|
||||
}
|
||||
|
||||
let showVirtualNumpad = (heading: string, maxlength = 4, isPassword: boolean, allowDecimals = true, allowClose = true, submitFunction: Function) => {
|
||||
let numpad = $('#virtualNumpad');
|
||||
let inputBox = $('#virtualNumpadInput')
|
||||
let closeKeyboardButton = $('.closeKeyboards')
|
||||
@@ -23,10 +28,9 @@
|
||||
numpad.data('password', isPassword);
|
||||
numpad.data('allowdecimals', allowDecimals);
|
||||
|
||||
$(document).unbind('keyup');
|
||||
$(document).keyup(e => {
|
||||
$(document).off('keyup');
|
||||
$(document).on('keyup', e => {
|
||||
let key = e.key;
|
||||
|
||||
switch (key) {
|
||||
case 'Backspace':
|
||||
case 'Delete':
|
||||
@@ -64,7 +68,7 @@
|
||||
let submitFunction = numpad.data('submitfunction')
|
||||
let allowedValues = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'submit', 'clear']
|
||||
let currentValue = numpad.data('value').toString()
|
||||
//Test
|
||||
|
||||
if (allowDecimals)
|
||||
allowedValues.push('.', ',')
|
||||
|
||||
@@ -109,11 +113,12 @@
|
||||
});
|
||||
}
|
||||
|
||||
let setupVirtualKeyboard = () => {
|
||||
let setupVirtualKeyboard = (keyboardLayouts: VirtualKeyboard) => {
|
||||
Application.keyboard = {
|
||||
capsLock: false,
|
||||
shift: false,
|
||||
layout: 'default'
|
||||
layouts: keyboardLayouts,
|
||||
currentLayout: 'default',
|
||||
}
|
||||
|
||||
$(document).on('click', '.virtualKeyboardButton', e => {
|
||||
@@ -123,7 +128,7 @@
|
||||
setKeyboardLayout('default')
|
||||
}
|
||||
|
||||
let showVirtualKeyboard = (heading: string, maxlength = 32, isPassword = false, submitFunction = () => {
|
||||
let showVirtualKeyboard = (heading: string, maxlength = 32, isPassword = false, submitFunction :Function = () => {
|
||||
hideVirtualKeyboard()
|
||||
}) => {
|
||||
let keyboard = $('#virtualKeyboard')
|
||||
@@ -166,7 +171,7 @@
|
||||
case 'submit':
|
||||
hideVirtualKeyboard();
|
||||
let submitFunction = keyboard.data('submitfunction')
|
||||
submitFunction();
|
||||
submitFunction(inputBox.text());
|
||||
break;
|
||||
case 'shift':
|
||||
if (Application.keyboard.capsLock) break;
|
||||
@@ -206,8 +211,10 @@
|
||||
}
|
||||
|
||||
let setKeyboardLayout = (layout: string, modifier = '') => {
|
||||
let keyboardLayout = ajaxSync('/languages/english/keyboardLayout.json', null, 'get')
|
||||
|
||||
if (modifier != '') modifier = `_${modifier}`
|
||||
Application.keyboard.currentLayout = layout
|
||||
let layoutToLoad = Application.keyboard.layouts[layout]
|
||||
|
||||
$('.virtualKeyboardRow').each((index, row) => {
|
||||
/*
|
||||
@@ -215,7 +222,7 @@
|
||||
and translators making their own language packs
|
||||
*/
|
||||
index = index + 1;
|
||||
let currentRow: Record<string, string> = keyboardLayout[layout]["row" + index + modifier]
|
||||
let currentRow = layoutToLoad[`row${index}${modifier}`]
|
||||
|
||||
$(row).children('a').each((keyIndex, button) => {
|
||||
let key = $(button);
|
||||
@@ -252,5 +259,5 @@
|
||||
|
||||
$(() => {
|
||||
setupVirtualNumpad()
|
||||
setupVirtualKeyboard();
|
||||
ajax('/ajax/getKeyboardLayout/english', null, 'get',setupVirtualKeyboard, null, null)
|
||||
})
|
||||
|
||||
1
wwwroot/scripts/ts/test.ts
Normal file
1
wwwroot/scripts/ts/test.ts
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
type PosMode = "edit" | "void" | "transfer" | "default"
|
||||
type PosMode = "edit" | "void" | "transfer" | "default" | "tableSelected" | "decorationSelected" | "activeTableSelected" | "merge" | "reservedTableSelected"
|
||||
type PosModes = PosMode[]
|
||||
|
||||
interface ajaxResult {
|
||||
status: string
|
||||
@@ -7,11 +8,10 @@ interface ajaxResult {
|
||||
|
||||
interface ApplicationState {
|
||||
keyboard: keyboard
|
||||
mode: PosMode
|
||||
mode: PosModes
|
||||
languageVars: Record<any, string>
|
||||
}
|
||||
|
||||
|
||||
interface table {
|
||||
table_number: number,
|
||||
room_id: number
|
||||
@@ -25,20 +25,41 @@ interface table {
|
||||
rotation: number
|
||||
merged_children: string
|
||||
previous_state: string
|
||||
status: string
|
||||
table_id: number
|
||||
status: number
|
||||
id: number
|
||||
}
|
||||
|
||||
interface decoration {
|
||||
id: number
|
||||
decoration_room: number
|
||||
decoration_pos_x: number
|
||||
decoration_pos_y: number
|
||||
decoration_rotation: number
|
||||
decoration_width: number
|
||||
decoration_height: number
|
||||
decoration_image: string
|
||||
}
|
||||
|
||||
interface room {
|
||||
room_id: number
|
||||
id: number
|
||||
room_name: string
|
||||
background_image: string
|
||||
venue_id: number
|
||||
}
|
||||
|
||||
|
||||
interface reservation {
|
||||
id: number,
|
||||
reservation_name: string,
|
||||
reservation_time: number,
|
||||
reservation_covers: number,
|
||||
reservation_created_at: number,
|
||||
reservation_table_id: number,
|
||||
}
|
||||
|
||||
interface keyboard {
|
||||
capsLock: boolean
|
||||
shift: boolean
|
||||
layout: string
|
||||
layouts: VirtualKeyboard
|
||||
currentLayout: string
|
||||
}
|
||||
@@ -553,14 +553,14 @@ a.logOut{
|
||||
|
||||
.floorplanControls,
|
||||
.mergeControls{
|
||||
visibility:hidden;
|
||||
width:100%;
|
||||
flex-basis:33%;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
|
||||
.editControls a{
|
||||
.editControls > a,
|
||||
.editControls .posHeader{
|
||||
height:100%;
|
||||
display:flex;
|
||||
flex-wrap:wrap;
|
||||
@@ -568,12 +568,23 @@ a.logOut{
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
text-align:center;
|
||||
padding:0.5em;
|
||||
}
|
||||
|
||||
.editControls .posHeader{
|
||||
flex-direction:column;
|
||||
}
|
||||
|
||||
.posHeader.currentTable > * {
|
||||
width: 100%;
|
||||
flex:1;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.posHeader.currentTable b {align-items: flex-end}
|
||||
.posHeader.currentTable small {align-items: flex-start}
|
||||
|
||||
.floorplanControls a,
|
||||
.mergeControls a{
|
||||
display:flex;
|
||||
|
||||
@@ -27,13 +27,17 @@
|
||||
<div id="tableMap"></div>
|
||||
</div>
|
||||
<div id="centerBottomRow">
|
||||
<div class="editControls">
|
||||
<a class="posHeader currentTable"></a>
|
||||
<a onclick="loadScreen('orderScreen', 'table='+selectedTableNumber)" class="posButton"><!--[lang:order_table]--></a>
|
||||
<a class="posButton reserveTableButton"><!--[lang:reserve_table]--></a>
|
||||
<a onclick="loadScreen('paymentSplitter', 'table='+selectedTableNumber)" class="posButton payTableButton"><!--[lang:pay_table]--></a>
|
||||
<div class="editControls" data-visible-in-mode='["tableSelected"]'>
|
||||
<div class="posHeader currentTable">
|
||||
<b class="selectedTableNumber"></b>
|
||||
<a class="reservationStatus" data-visible-in-mode='["reservedTableSelected"]'></a>
|
||||
<small class="selectedTableCovers"></small>
|
||||
</div>
|
||||
<a class="posButton"><!--[lang:order_table]--></a>
|
||||
<a class="posButton reserveTableButton" data-invisible-in-mode='["reservedTableSelected"]'><!--[lang:reserve_table]--></a>
|
||||
<a class="posButton unreserveTableButton" data-visible-in-mode='["reservedTableSelected"]'><!--[lang:unreserve_table]--></a>
|
||||
<a class="posButton payTableButton"><!--[lang:pay_table]--></a>
|
||||
<a class="posButton viewTableButton"><!--[lang:view_table]--></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,17 +47,17 @@
|
||||
</div>
|
||||
<div class="middleCell">
|
||||
<a class="posButton editModeButton"><!--[lang:edit_floorplan]--></a>
|
||||
<div class="floorplanControls">
|
||||
<div class="floorplanControls useVisibility" data-visible-in-mode='["edit"]'>
|
||||
<a class="posButton addTableButton" ><!--[lang:add_table]--></a>
|
||||
<a class="posButton addDecoration"><!--[lang:add_decoration]--></a>
|
||||
<a class="posButton deleteDecoration"><!--[lang:delete_decoration]--></a>
|
||||
<a class="posButton deleteTableButton"><!--[lang:delete_table]--></a>
|
||||
<a class="posButton changeShapeButton"><!--[lang:change_shape]--></a>
|
||||
<a class="posButton deleteDecoration useVisibility" data-visible-in-mode='["decorationSelected", "edit"]'><!--[lang:delete_decoration]--></a>
|
||||
<a class="posButton deleteTableButton useVisibility" data-visible-in-mode='["tableSelected", "edit"]'><!--[lang:delete_table]--></a>
|
||||
<a class="posButton changeShapeButton useVisibility" data-visible-in-mode='["tableSelected", "edit"]'><!--[lang:change_shape]--></a>
|
||||
</div>
|
||||
<div class="mergeControls">
|
||||
<a onclick="mergeModeOn()" class="posButton mergeButton"><!--[lang:merge_table]--></a>
|
||||
<a onclick="unmergeTable()" class="posButton unmergeButton"><!--[lang:unmerge_table]--></a>
|
||||
<a class="transferTableButton posButton"><!--[lang:transfer_table]--></a>
|
||||
<div class="mergeControls useVisibility" data-visible-in-mode='["tableSelected"]'>
|
||||
<a class="posButton mergeButton" data-active-in-mode="merge"><!--[lang:merge_table]--></a>
|
||||
<a class="posButton unmergeButton" data-visible-in-mode='["tableSelected"]'><!--[lang:unmerge_table]--></a>
|
||||
<a class="transferTableButton posButton" data-active-in-mode="transfer" data-visible-in-mode='["activeTableSelected"]'><!--[lang:transfer_table]--></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottomCell">
|
||||
@@ -70,14 +74,5 @@
|
||||
</div>
|
||||
<div id="decoratorContent"><!--[var:decorator]--></div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var roomToLoad = 1;
|
||||
var width = 1152
|
||||
var height = 850
|
||||
$(document).ready( function () {
|
||||
setupTableMap();
|
||||
} );
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user