Actions

Module

JourneySystem: Difference between revisions

From Dune Awakening DB

Created page with "-- Module:JourneySystem (Optimized for Template Data Fetching) -- Handles formatting and utility functions only -- Data fetching is done in templates for better caching local p = {} -- Default placeholder image local DEFAULT_JOURNEY_ICON = "https://dunedb.com/images/3/39/WikiPlaceholder.jpg" -------------------------------------------------- -- Helper: Get journey icon with fallback -------------------------------------------------- local function getJourneyIcon(iconP..."
 
mNo edit summary
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
-- Module:JourneySystem (Optimized for Template Data Fetching)
-- Module:JourneySystem
-- Handles formatting and utility functions only
-- Minimal module for Journey display - focuses only on formatting, not data retrieval
-- Data fetching is done in templates for better caching
-- All external data queries are handled by the wiki template for better caching


local p = {}
local p = {}
 
local parser = require('Module:DataTableParserV2')
-- Default placeholder image
local DEFAULT_JOURNEY_ICON = "https://dunedb.com/images/3/39/WikiPlaceholder.jpg"


--------------------------------------------------
--------------------------------------------------
-- Helper: Get journey icon with fallback
-- Function: renderObjectives
-- Called via AJAX to render objectives for a specific journey
-- Data should be passed from JavaScript
--------------------------------------------------
--------------------------------------------------
local function getJourneyIcon(iconPath, size)
function p.renderObjectives(frame)
     size = size or "48px"
     local journeyId = frame.args.id or frame.args[1] or ""
 
      
     -- Check for null, empty string, or "NULL" string
     if journeyId == "" then
     if not iconPath or iconPath == "" or iconPath == "NULL" or iconPath == "null" then
         return '<div class="objectives-list"><div class="objective-item"><div class="objective-header"><div class="objective-title" style="color: var(--color-secondary);">No journey selected</div></div></div></div>'
         return string.format('<img src="%s" width="%s" height="%s" alt="Journey Icon">',
            DEFAULT_JOURNEY_ICON, size:match("(%d+)") or "48", size:match("(%d+)") or "48")
    end
 
    -- Check if it's already a full URL
    if iconPath:match("^https?://") then
        return string.format('<img src="%s" width="%s" height="%s" alt="Journey Icon">',
            iconPath, size:match("(%d+)") or "48", size:match("(%d+)") or "48")
    end
 
    -- Check if it's already a full File: reference
    if iconPath:match("^File:") then
        return string.format('[[%s|%s|link=]]', iconPath, size)
    end
 
    -- Check if it's a filename
    local fileTitle = mw.title.new("File:" .. iconPath)
    if fileTitle and fileTitle.exists then
        return string.format('[[File:%s|%s|link=]]', iconPath, size)
    else
        -- Fallback to placeholder
        return string.format('<img src="%s" width="%s" height="%s" alt="Journey Icon">',
            DEFAULT_JOURNEY_ICON, size:match("(%d+)") or "48", size:match("(%d+)") or "48")
     end
     end
   
    -- This would be called via AJAX with the journey ID
    -- The actual data fetching happens in JavaScript
    return string.format([[<div class="loading-objectives" data-journey-id="%s">Loading objectives...</div>]], journeyId)
end
end


--------------------------------------------------
--------------------------------------------------
-- Function: getIcon
-- Function: renderMaterials
-- Public function to get journey icon
-- Called via AJAX to render materials for a specific journey
-- Data should be passed from JavaScript
--------------------------------------------------
--------------------------------------------------
function p.getIcon(frame)
function p.renderMaterials(frame)
     local iconPath = frame.args[1] or ""
     local journeyId = frame.args.id or frame.args[1] or ""
    local groupName = frame.args[2] or ""
      
     local size = frame.args[3] or "48px"
     if journeyId == "" then
 
         return '<div class="materials-list">No journey selected</div>'
     if iconPath ~= "" then
         return getJourneyIcon(iconPath, size)
    else
        -- Use group-based fallback
        local groupIcons = {
            ['A New Beginning']          = 'Icon_Zone_NewBeginning.png',
            ['Vermillius Gap']          = 'Icon_Zone_Vermillius.png',
            ['Jabal Eifrit & Hagga Rift'] = 'Icon_Zone_Jabal.png',
            ['Find The Fremen']          = 'Icon_Trial_Fremen.png',
            ['Miscellaneous']            = 'Icon_Category_Standard.png',
            ['Factions']                = 'Icon_Category_Faction.png'
        }
        return getJourneyIcon(groupIcons[groupName], size)
     end
     end
   
    -- This would be called via AJAX with the journey ID
    -- The actual data fetching happens in JavaScript
    return string.format([[<div class="loading-materials" data-journey-id="%s">Loading materials...</div>]], journeyId)
end
end


--------------------------------------------------
--------------------------------------------------
-- Function: getGroupIcon
-- Function: formatObjectiveItem
-- Get icon for journey group
-- Formats a single objective with its tasks
--------------------------------------------------
-- Called from JavaScript with data
function p.getGroupIcon(frame)
    local groupName = frame.args[1] or ""
    local size      = frame.args[2] or "24px"
 
    local groupIcons = {
        ['A New Beginning']          = 'Icon_Zone_NewBeginning.png',
        ['Vermillius Gap']          = 'Icon_Zone_Vermillius.png',
        ['Jabal Eifrit & Hagga Rift'] = 'Icon_Zone_Jabal.png',
        ['Find The Fremen']          = 'Icon_Trial_Fremen.png',
        ['Miscellaneous']            = 'Icon_Category_Standard.png',
        ['Factions']                = 'Icon_Category_Faction.png'
    }
 
    return getJourneyIcon(groupIcons[groupName], size)
end
 
--------------------------------------------------
-- Function: buildJourneyJSON
-- Builds JSON from template data
--------------------------------------------------
function p.buildJourneyJSON(frame)
    -- Data is supplied by template; just return placeholder for now
    return '{}'
end
 
--------------------------------------------------
-- Function: escapeJson
--------------------------------------------------
function p.escapeJson(frame)
    local text = frame.args[1] or ""
    text = text:gsub('"',  '\\"')
              :gsub('\n', '\\n')
              :gsub('\r', '')
    return '"' .. text .. '"'
end
 
--------------------------------------------------
-- Function: escapeHtml
--------------------------------------------------
function p.escapeHtml(frame)
    local text = frame.args[1] or ""
    text = text:gsub('&', '&amp;')  -- Must be first
              :gsub('"', '&quot;')
              :gsub("'", '&#39;')
              :gsub('<', '&lt;')
              :gsub('>', '&gt;')
    return text
end
 
--------------------------------------------------
-- Function: formatObjectives
--------------------------------------------------
--------------------------------------------------
function p.formatObjectives(frame)
function p.formatObjectiveItem(frame)
     local output, index = "", 1
     local objectiveId = frame.args.id or ""
 
     local title = frame.args.title or ""
     while frame.args["obj_id_" .. index] do
    local seq = frame.args.seq or "1"
        local objId    = frame.args["obj_id_" .. index]
    local tasks = frame.args.tasks or ""
        local objTitle = frame.args["obj_title_" .. index] or ""
    local totalTasks = frame.args.totalTasks or "0"
        local objSeq  = frame.args["obj_seq_" .. index]  or index
   
        local collapsedClass = index > 1 and " collapsed" or ""
    local collapsedClass = tonumber(seq) > 1 and " collapsed" or ""
 
   
        output = output .. string.format([[
    local output = string.format([[
<div class="objective-item%s">
<div class="objective-item%s">
     <div class="objective-header" data-objective-id="%s">
     <div class="objective-header" data-objective-id="%s">
         <div class="objective-icon">%s</div>
         <div class="objective-icon">%s</div>
         <div class="objective-title">%s</div>
         <div class="objective-title">%s</div>
         <div class="objective-progress">0/0</div>
         <div class="objective-progress">0/%s</div>
    </div>
    <div class="objective-tasks">]], collapsedClass, objId, objSeq, objTitle)
 
        -- Tasks
        local taskIndex = 1
        while frame.args["task_" .. index .. "_" .. taskIndex] do
            local taskDesc = frame.args["task_" .. index .. "_" .. taskIndex]
            local taskQty  = frame.args["task_qty_" .. index .. "_" .. taskIndex]
 
            output = output .. string.format([[
        <div class="task-item">
            <div class="task-checkbox"></div>
            <div class="task-description">%s</div>]], taskDesc)
 
            if taskQty and taskQty ~= "" then
                output = output .. string.format('<div class="task-qty">%s pcs</div>', taskQty)
            end
 
            output = output .. '</div>\n'
            taskIndex = taskIndex + 1
        end
 
        output = output .. [[
     </div>
     </div>
</div>]]
    <div class="objective-tasks">%s</div>
        index = index + 1
</div>]], collapsedClass, objectiveId, seq, title, totalTasks, tasks)
     end
      
 
     return output
     return output
end
end


--------------------------------------------------
--------------------------------------------------
-- Function: formatMaterials
-- Function: formatTaskItem
-- Formats a single task item
--------------------------------------------------
--------------------------------------------------
function p.formatMaterials(frame)
function p.formatTaskItem(frame)
     local output, totalCount, idx = "", 0, 0
     local taskId = frame.args.id or ""
 
    local description = frame.args.description or ""
     -- Count materials
    local qty = frame.args.qty or ""
     while frame.args["mat_name_" .. (idx + 1)] do
   
        totalCount = totalCount + 1
     -- Apply iconization to the description
         idx        = idx + 1
     local iconizedDesc = frame:preprocess('{{#invoke:DataTableParserV2|iconize|' .. description .. '}}')
   
    local qtyHtml = ""
    if qty ~= "" and qty ~= "0" then
         qtyHtml = string.format('<div class="task-qty">%s pcs</div>', qty)
     end
     end
   
    return string.format([[
<div class="task-item" data-task-id="%s">
    <div class="task-checkbox"></div>
    <div class="task-description">%s</div>
    %s
</div>]], taskId, iconizedDesc, qtyHtml)
end


    output = string.format([[
--------------------------------------------------
<div class="materials-progress">
-- Function: formatMaterialItem
    <span class="materials-progress-text">Materials Collected</span>
-- Formats a single material item
    <span class="materials-progress-count">0/%d</span>
--------------------------------------------------
</div>
function p.formatMaterialItem(frame)
<div class="materials-list">
     local name = frame.args.name or ""
    <div class="material-category">
    local qty = frame.args.qty or "1"
        <div class="material-category-title">Required Materials</div>]], totalCount)
    local index = frame.args.index or "0"
 
   
    -- Render each material
    -- Try to get icon
     for i = 1, totalCount do
    local iconFile = name:gsub("%s+", "_") .. "_-_Icon.png"
        local matName = frame.args["mat_name_" .. i] or ""
    local iconHtml = string.format('[[File:%s|20px|link=]]', iconFile)
        local matQty  = frame.args["mat_qty_" .. i] or "1"
   
 
  return string.format([=[
        -- Icon lookup
<div class="material-item" data-material-index="%s">
        local iconFile = matName:gsub("%s+", "_") .. "_-_Icon.png"
    <div class="material-checkbox"></div>
        local fileTitle = mw.title.new("File:" .. iconFile)
    <div class="material-icon">%s</div>
        local iconHtml = fileTitle and fileTitle.exists
    <div class="material-name">[[%s]]</div>
                          and string.format('[[File:%s|20px|link=]]', iconFile)
    <div class="material-qty">%s</div>
                          or '⚙️'
</div>]=], index, iconHtml, name, qty)
 
        -- *** fixed delimiter here ***
        output = output .. string.format([=[
        <div class="material-item" data-material-index="%d">
            <div class="material-checkbox"></div>
            <div class="material-icon">%s</div>
            <div class="material-name">[[%s]]</div>
            <div class="material-qty">%s</div>
        </div>]=], i - 1, iconHtml, matName, matQty)
    end
 
    output = output .. [[
    </div>
</div>]]


    return output
end
end


return p
return p

Latest revision as of 01:41, 26 May 2025

Documentation for this module may be created at Module:JourneySystem/doc

-- Module:JourneySystem
-- Minimal module for Journey display - focuses only on formatting, not data retrieval
-- All external data queries are handled by the wiki template for better caching

local p = {}
local parser = require('Module:DataTableParserV2')

--------------------------------------------------
-- Function: renderObjectives
-- Called via AJAX to render objectives for a specific journey
-- Data should be passed from JavaScript
--------------------------------------------------
function p.renderObjectives(frame)
    local journeyId = frame.args.id or frame.args[1] or ""
    
    if journeyId == "" then
        return '<div class="objectives-list"><div class="objective-item"><div class="objective-header"><div class="objective-title" style="color: var(--color-secondary);">No journey selected</div></div></div></div>'
    end
    
    -- This would be called via AJAX with the journey ID
    -- The actual data fetching happens in JavaScript
    return string.format([[<div class="loading-objectives" data-journey-id="%s">Loading objectives...</div>]], journeyId)
end

--------------------------------------------------
-- Function: renderMaterials
-- Called via AJAX to render materials for a specific journey
-- Data should be passed from JavaScript
--------------------------------------------------
function p.renderMaterials(frame)
    local journeyId = frame.args.id or frame.args[1] or ""
    
    if journeyId == "" then
        return '<div class="materials-list">No journey selected</div>'
    end
    
    -- This would be called via AJAX with the journey ID
    -- The actual data fetching happens in JavaScript
    return string.format([[<div class="loading-materials" data-journey-id="%s">Loading materials...</div>]], journeyId)
end

--------------------------------------------------
-- Function: formatObjectiveItem
-- Formats a single objective with its tasks
-- Called from JavaScript with data
--------------------------------------------------
function p.formatObjectiveItem(frame)
    local objectiveId = frame.args.id or ""
    local title = frame.args.title or ""
    local seq = frame.args.seq or "1"
    local tasks = frame.args.tasks or ""
    local totalTasks = frame.args.totalTasks or "0"
    
    local collapsedClass = tonumber(seq) > 1 and " collapsed" or ""
    
    local output = string.format([[
<div class="objective-item%s">
    <div class="objective-header" data-objective-id="%s">
        <div class="objective-icon">%s</div>
        <div class="objective-title">%s</div>
        <div class="objective-progress">0/%s</div>
    </div>
    <div class="objective-tasks">%s</div>
</div>]], collapsedClass, objectiveId, seq, title, totalTasks, tasks)
    
    return output
end

--------------------------------------------------
-- Function: formatTaskItem
-- Formats a single task item
--------------------------------------------------
function p.formatTaskItem(frame)
    local taskId = frame.args.id or ""
    local description = frame.args.description or ""
    local qty = frame.args.qty or ""
    
    -- Apply iconization to the description
    local iconizedDesc = frame:preprocess('{{#invoke:DataTableParserV2|iconize|' .. description .. '}}')
    
    local qtyHtml = ""
    if qty ~= "" and qty ~= "0" then
        qtyHtml = string.format('<div class="task-qty">%s pcs</div>', qty)
    end
    
    return string.format([[
<div class="task-item" data-task-id="%s">
    <div class="task-checkbox"></div>
    <div class="task-description">%s</div>
    %s
</div>]], taskId, iconizedDesc, qtyHtml)
end

--------------------------------------------------
-- Function: formatMaterialItem
-- Formats a single material item
--------------------------------------------------
function p.formatMaterialItem(frame)
    local name = frame.args.name or ""
    local qty = frame.args.qty or "1"
    local index = frame.args.index or "0"
    
    -- Try to get icon
    local iconFile = name:gsub("%s+", "_") .. "_-_Icon.png"
    local iconHtml = string.format('[[File:%s|20px|link=]]', iconFile)
    
   return string.format([=[
<div class="material-item" data-material-index="%s">
    <div class="material-checkbox"></div>
    <div class="material-icon">%s</div>
    <div class="material-name">[[%s]]</div>
    <div class="material-qty">%s</div>
</div>]=], index, iconHtml, name, qty)

end

return p