diff --git a/fxmanifest.lua b/fxmanifest.lua index a4b8419..1bdf554 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -51,7 +51,7 @@ client_scripts { 'modules/dispatch/**/client.lua', 'modules/progressbar/**/client.lua', 'modules/clothing/**/client.lua', - 'modules/input/*.lua', + 'modules/input/**/client.lua', 'modules/menu/*.lua', 'modules/helptext/**/client.lua', 'modules/notify/**/client.lua', @@ -61,6 +61,7 @@ client_scripts { 'modules/accessibility/client.lua', 'modules/skills/**/client.lua', 'init.lua', + -- 'unit_tests/input_test.lua', } ui_page 'web/dist/index.html' diff --git a/modules/clothing/fivem-appearance/server.lua b/modules/clothing/fivem-appearance/server.lua index 6a45f2a..8076d2d 100644 --- a/modules/clothing/fivem-appearance/server.lua +++ b/modules/clothing/fivem-appearance/server.lua @@ -4,7 +4,6 @@ Clothing.Players = {} Callback = Callback or Require("lib/utility/shared/callbacks.lua") Table = Table or Require('lib/utility/shared/tables.lua') -QBCore = QBCore or exports['qb-core']:GetCoreObject() --- Internal function to get the full appearance data including skin, model, and converted format --- @param src number The server ID of the player diff --git a/modules/input/_qb-input.lua b/modules/input/_default/client.lua similarity index 65% rename from modules/input/_qb-input.lua rename to modules/input/_default/client.lua index 375c052..d3e6a8f 100644 --- a/modules/input/_qb-input.lua +++ b/modules/input/_default/client.lua @@ -1,6 +1,44 @@ -local resourceName = "qb-input" -local configValue = BridgeClientConfig.InputSystem -if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end +function QBTypeToOxType(_type) + if _type == "text" then + return "input" + elseif _type == "password" then + return "input" + elseif _type == "number" then + return "number" + elseif _type == "radio" then + return "checkbox" + elseif _type == "checkbox" then + return "checkbox" + elseif _type == "select" then + return "select" + end +end + +function QBToOxInput(data) + local returnData = {} + for i, v in pairs(data) do + local input = { + label = v.text, + name = i, + type = QBTypeToOxType(v.type), + required = v.isRequired, + default = v.placeholder, + } + if v.type == "select" then + input.options = {} + for i, v in pairs(v.options) do + table.insert(input.options, {value = v.value, label = v.text}) + end + elseif v.type == "checkbox" then + for i, v in pairs(v.options) do + table.insert(returnData, {value = v.value, label = v.text}) + end + end + table.insert(returnData, input) + end + return returnData +end + function OxTypeToQBType(_type) if _type == "input" then @@ -58,35 +96,4 @@ function OxToQBInput(data) table.insert(returnData, input) end return returnData -end - -function OpenInput(title, data, isQBFormat, submitText) - local input = data.inputs - if not isQBFormat then - input = OxToQBInput(data) - end - local returnData = exports['qb-input']:ShowInput({ - header = title, - submitText = submitText or "Submit", - inputs = input - }) - if not returnData then return end - if returnData[1] then return returnData end - --converting to standard format (ox) - local convertedData = {} - if isQBFormat then - for i, v in pairs(input) do - for k, j in pairs(returnData) do - if k == v.text then - convertedData[tonumber(i)] = j - end - end - end - return convertedData - end - - for i, v in pairs(returnData) do - convertedData[tonumber(i)] = v - end - return convertedData -end +end \ No newline at end of file diff --git a/modules/input/client.lua b/modules/input/_default/olddata.lua similarity index 90% rename from modules/input/client.lua rename to modules/input/_default/olddata.lua index 1650cce..e61152b 100644 --- a/modules/input/client.lua +++ b/modules/input/_default/olddata.lua @@ -1,6 +1,6 @@ -if GetResourceState('ox_lib') ~= 'started' and GetResourceState('qb-menu') ~= 'started' then return end --- { +-- if GetResourceState('ox_lib') ~= 'started' and GetResourceState('qb-menu') ~= 'started' then return end +-- -- { -- header = "Test", -- submitText = "Bill", -- inputs = { @@ -76,38 +76,38 @@ if GetResourceState('ox_lib') ~= 'started' and GetResourceState('qb-menu') ~= 's --QB types: text, password, number, radio, checkbox, select, -- -- "input", "number", "checkbox", "select", "multi-select", "slider", "color", "date", "date-range", "time", "textarea", -Input = {} +-- Input = {} --- qb to ox ---Open menu +-- -- qb to ox +-- --Open menu -function Input.Open(title, data, isQBFormat, submitText) - if isQBFormat then - local inputs = data.inputs - if BridgeClientConfig.InputSystem == "ox" then - return lib.inputDialog(title, QBToOxInput(inputs)) - elseif BridgeClientConfig.InputSystem == "qb" then - return exports['qb-input']:ShowInput({ - header = title, - submitText = submitText or "Submit", - inputs = inputs - }) - end - else - if BridgeClientConfig.InputSystem == "ox" then - return lib.inputDialog(title, data) - elseif BridgeClientConfig.InputSystem == "qb" then - return exports['qb-input']:ShowInput({ - header = title, - submitText = submitText or "Submit", - inputs = OxToQBInput(data) - }) - end - end - return OpenInput(title, data, isQBFormat, submitText) -end +-- function Input.Open(title, data, isQBFormat, submitText) +-- if isQBFormat then +-- local inputs = data.inputs +-- if BridgeClientConfig.InputSystem == "ox" then +-- return lib.inputDialog(title, QBToOxInput(inputs)) +-- elseif BridgeClientConfig.InputSystem == "qb" then +-- return exports['qb-input']:ShowInput({ +-- header = title, +-- submitText = submitText or "Submit", +-- inputs = inputs +-- }) +-- end +-- else +-- if BridgeClientConfig.InputSystem == "ox" then +-- return lib.inputDialog(title, data) +-- elseif BridgeClientConfig.InputSystem == "qb" then +-- return exports['qb-input']:ShowInput({ +-- header = title, +-- submitText = submitText or "Submit", +-- inputs = OxToQBInput(data) +-- }) +-- end +-- end +-- return OpenInput(title, data, isQBFormat, submitText) +-- end -return Input +-- return Input --[[ diff --git a/modules/input/_oxlib.lua b/modules/input/_oxlib.lua deleted file mode 100644 index 6baa54c..0000000 --- a/modules/input/_oxlib.lua +++ /dev/null @@ -1,53 +0,0 @@ -local resourceName = "ox_lib" -local configValue = BridgeClientConfig.InputSystem -if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end - -function QBTypeToOxType(_type) - if _type == "text" then - return "input" - elseif _type == "password" then - return "input" - elseif _type == "number" then - return "number" - elseif _type == "radio" then - return "checkbox" - elseif _type == "checkbox" then - return "checkbox" - elseif _type == "select" then - return "select" - end -end - -function QBToOxInput(data) - local returnData = {} - for i, v in pairs(data) do - local input = { - label = v.text, - name = i, - type = QBTypeToOxType(v.type), - required = v.isRequired, - default = v.placeholder, - } - if v.type == "select" then - input.options = {} - for i, v in pairs(v.options) do - table.insert(input.options, {value = v.value, label = v.text}) - end - elseif v.type == "checkbox" then - for i, v in pairs(v.options) do - table.insert(returnData, {value = v.value, label = v.text}) - end - end - table.insert(returnData, input) - end - return returnData -end - -function OpenInput(title, data, isQBFormat, submitText) - local inputs = data.inputs - if isQBFormat then - return lib.inputDialog(title, QBToOxInput(inputs)) - else - return lib.inputDialog(title, data) - end -end \ No newline at end of file diff --git a/modules/input/_qb-input/client.lua b/modules/input/_qb-input/client.lua new file mode 100644 index 0000000..4efefa9 --- /dev/null +++ b/modules/input/_qb-input/client.lua @@ -0,0 +1,47 @@ +local resourceName = "qb-input" +local configValue = BridgeClientConfig.InputSystem +if (configValue == "auto" and GetResourceState(resourceName) == "missing") or (configValue ~= "auto" and configValue ~= resourceName) then return end + +Input = {} + + +-- this probably needs improvement +function Input.Open(title, data, isQBFormat, submitText) + local input = data.inputs + if not isQBFormat then + input = OxToQBInput(data) + end + local returnData = exports['qb-input']:ShowInput({ + header = title, + submitText = submitText or "Submit", + inputs = input + }) + if not returnData then return end + print(json.encode(returnData)) + if returnData[1] then return returnData end + --converting to standard format (ox) + local convertedData = {} + if isQBFormat then + for i, v in pairs(input) do + print("Converting input: " .. v.name) + for k, j in pairs(returnData) do + if k == v.name then + convertedData[tonumber(i)] = j + end + end + end + return convertedData + end + + for i, v in pairs(returnData) do + local index = i and tonumber(i) + if not index then + table.insert(convertedData, v) + else + convertedData[index] = v + end + end + return convertedData +end + +return Input diff --git a/modules/input/ox_lib/client.lua b/modules/input/ox_lib/client.lua new file mode 100644 index 0000000..bc6e05d --- /dev/null +++ b/modules/input/ox_lib/client.lua @@ -0,0 +1,16 @@ +local resourceName = "ox_lib" +local configValue = BridgeClientConfig.InputSystem +if (configValue == "auto" and GetResourceState(resourceName) == "missing") or (configValue ~= "auto" and configValue ~= resourceName) then return end + +Input = {} +function Input.Open(title, data, isQBFormat, submitText) + local inputs = data.inputs + if isQBFormat then + return lib.inputDialog(title, QBToOxInput(inputs)) + else + return lib.inputDialog(title, data) + end +end + +return Input + diff --git a/unit_tests/input_test.lua b/unit_tests/input_test.lua new file mode 100644 index 0000000..9e2635c --- /dev/null +++ b/unit_tests/input_test.lua @@ -0,0 +1,234 @@ +-- Test QB Format Input +RegisterCommand('input_test_qb', function() + local qbFormatData = { + inputs = { + { + text = "Player Name", + name = "playername", + type = "text", + isRequired = true, + default = "John Doe" + }, + { + text = "Player ID", + name = "playerid", + type = "number", + isRequired = true + }, + { + text = "Password", + name = "password", + type = "password", + isRequired = false + }, + { + text = "Vehicle Type", + name = "vehicle", + type = "select", + isRequired = true, + options = { + {value = "car", text = "Car"}, + {value = "bike", text = "Motorcycle"}, + {value = "truck", text = "Truck"} + } + }, + { + text = "Enable Notifications", + name = "notifications", + type = "checkbox", + isRequired = false, + options = { + {value = "email", text = "Email", checked = true}, + {value = "sms", text = "SMS", checked = false} + } + } + } + } + + local result = Input.Open("QB Format Test", qbFormatData, true, "Submit") + if result then + print("QB Format Result:") + for k, v in pairs(result) do + print(k .. ": " .. tostring(v)) + end + else + print("QB Format: User cancelled or no input") + end +end, false) + +-- Test Ox Format Input +RegisterCommand('input_test_ox', function() + local oxFormatData = { + { + type = "input", + label = "Character Name", + name = "charname", + required = true, + default = "Jane Smith" + }, + { + type = "number", + label = "Age", + name = "age", + required = true, + min = 18, + max = 100 + }, + { + type = "select", + label = "Job Category", + name = "jobcat", + required = true, + options = { + {value = "civ", label = "Civilian"}, + {value = "leo", label = "Law Enforcement"}, + {value = "ems", label = "Emergency Medical"} + } + }, + { + type = "checkbox", + label = "Has License", + name = "license", + required = false + }, + { + type = "color", + label = "Favorite Color", + name = "color", + default = "#ff0000" + }, + { + type = "date", + label = "Birth Date", + name = "birthdate", + format = "DD/MM/YYYY" + } + } + + local result = Input.Open("Ox Format Test", oxFormatData, false) + if result then + print("Ox Format Result:") + for k, v in pairs(result) do + print(k .. ": " .. tostring(v)) + end + else + print("Ox Format: User cancelled or no input") + end +end, false) + +-- Test Simple Text Input +RegisterCommand('input_test_simple', function() + local simpleData = { + inputs = { + { + text = "Enter your message", + name = "message", + type = "text", + isRequired = true + } + } + } + + local result = Input.Open("Simple Input", simpleData, true, "Send") + if result then + print("Simple Input Result: " .. (result.message or "No message")) + else + print("Simple Input: Cancelled") + end +end, false) + +-- Test All Input Types (QB Format) +RegisterCommand('input_test_all_types', function() + local allTypesData = { + inputs = { + { + text = "Text Input", + name = "text_field", + type = "text", + isRequired = false, + default = "Sample text" + }, + { + text = "Number Input", + name = "number_field", + type = "number", + isRequired = false, + default = 42 + }, + { + text = "Password Input", + name = "password_field", + type = "password", + isRequired = false + }, + { + text = "Radio Selection", + name = "radio_field", + type = "radio", + isRequired = false, + options = { + {value = "option1", text = "Option 1"}, + {value = "option2", text = "Option 2"}, + {value = "option3", text = "Option 3"} + } + }, + { + text = "Checkbox Options", + name = "checkbox_field", + type = "checkbox", + isRequired = false, + options = { + {value = "check1", text = "Check 1", checked = true}, + {value = "check2", text = "Check 2", checked = false}, + {value = "check3", text = "Check 3", checked = false} + } + }, + { + text = "Select Dropdown", + name = "select_field", + type = "select", + isRequired = false, + options = { + {value = "val1", text = "Value 1"}, + {value = "val2", text = "Value 2"}, + {value = "val3", text = "Value 3"} + } + } + } + } + + local result = Input.Open("All Input Types Test", allTypesData, true, "Test Submit") + if result then + print("All Types Result:", json.encode(result)) + + else + print("All Types: User cancelled") + end +end, false) + +-- Test Error Handling +RegisterCommand('input_test_error', function() + -- Test with invalid data + local result = Input.Open("Error Test", nil, true) + if result then + print("Error test unexpectedly succeeded") + else + print("Error test correctly handled nil data") + end + + -- Test with empty inputs + local emptyData = {inputs = {}} + local result2 = Input.Open("Empty Test", emptyData, true) + if result2 then + print("Empty test result: " .. json.encode(result2)) + else + print("Empty test: No result") + end +end, false) + +-- print("Input unit tests loaded. Available commands:") +-- print(" /input_test_qb - Test QB format input") +-- print(" /input_test_ox - Test Ox format input") +-- print(" /input_test_simple - Test simple text input") +-- print(" /input_test_all_types - Test all input types") +-- print(" /input_test_error - Test error handling") \ No newline at end of file