Actions

Module

JourneySystem: Difference between revisions

From Dune Awakening DB

mNo edit summary
mNo edit summary
 
Line 1: Line 1:
-- Module:JourneySystem (Fixed)
-- 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"


--------------------------------------------------
--------------------------------------------------
-- Function: getGroupIcon
-- Function: renderObjectives
-- Get icon for journey group - returns wiki markup
-- Called via AJAX to render objectives for a specific journey
-- Data should be passed from JavaScript
--------------------------------------------------
--------------------------------------------------
function p.getGroupIcon(frame)
function p.renderObjectives(frame)
     local groupName = frame.args[1] or ""
     local journeyId = frame.args.id or frame.args[1] or ""
    local size = frame.args[2] or "24"
   
    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'
    }
      
      
     local iconFile = groupIcons[groupName]
     if journeyId == "" then
    if iconFile 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>'
         -- Check if file exists
        local fileTitle = mw.title.new("File:" .. iconFile)
        if fileTitle and fileTitle.exists then
            return string.format('[[File:%s|%spx|link=]]', iconFile, size)
        end
     end
     end
      
      
     -- Return emoji fallback for now
     -- This would be called via AJAX with the journey ID
     local emojiIcons = {
     -- The actual data fetching happens in JavaScript
        ['A New Beginning'] = '🏜️',
    return string.format([[<div class="loading-objectives" data-journey-id="%s">Loading objectives...</div>]], journeyId)
        ['Vermillius Gap'] = '⛰️',
        ['Jabal Eifrit & Hagga Rift'] = '🗿',
        ['Find The Fremen'] = '👁️',
        ['Miscellaneous'] = '📜',
        ['Factions'] = '🏛️'
    }
   
    return emojiIcons[groupName] or '📍'
end
end


--------------------------------------------------
--------------------------------------------------
-- Function: getJourneyBackground
-- Function: renderMaterials
-- Get background image URL for journey card
-- Called via AJAX to render materials for a specific journey
-- Data should be passed from JavaScript
--------------------------------------------------
--------------------------------------------------
function p.getJourneyBackground(frame)
function p.renderMaterials(frame)
     local iconPath = frame.args[1] or ""
     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="materials-list">No journey selected</div>'
         return DEFAULT_JOURNEY_ICON
     end
     end
      
      
     -- Check if it's already a full URL
     -- This would be called via AJAX with the journey ID
    if iconPath:match("^https?://") then
     -- The actual data fetching happens in JavaScript
        return iconPath
     return string.format([[<div class="loading-materials" data-journey-id="%s">Loading materials...</div>]], journeyId)
    end
   
     -- Check if it's a File: reference - need to get the actual URL
     if iconPath:match("^File:") then
        iconPath = iconPath:gsub("^File:", "")
    end
   
    -- For file names, we need to construct the full URL
    -- This assumes your wiki files are at a standard path
    return string.format("https://dunedb.com/images/%s", iconPath)
end
end


--------------------------------------------------
--------------------------------------------------
-- Function: escapeHtml
-- Function: formatObjectiveItem
-- Escape text for HTML attributes
-- Formats a single objective with its tasks
-- Called from JavaScript with data
--------------------------------------------------
--------------------------------------------------
function p.escapeHtml(frame)
function p.formatObjectiveItem(frame)
     local text = frame.args[1] or ""
     local objectiveId = frame.args.id or ""
     -- Escape quotes and HTML entities
     local title = frame.args.title or ""
    text = text:gsub('&', '&amp;')  -- Must be first
     local seq = frame.args.seq or "1"
    text = text:gsub('"', '&quot;')
     local tasks = frame.args.tasks or ""
     text = text:gsub("'", '&#39;')
     local totalTasks = frame.args.totalTasks or "0"
     text = text:gsub('<', '&lt;')
   
    text = text:gsub('>', '&gt;')
     local collapsedClass = tonumber(seq) > 1 and " collapsed" or ""
    return text
end
 
--------------------------------------------------
-- Function: formatObjectives
-- Format objectives with proper HTML structure
--------------------------------------------------
function p.formatObjectives(frame)
     local journeyId = frame.args[1] or ""
     local output = ""
      
      
    -- The data comes from template, we just format it
     local output = string.format([[
     local index = 1
    while frame.args["obj_id_" .. index] do
        local objId = frame.args["obj_id_" .. index]
        local objTitle = frame.args["obj_title_" .. index] or ""
        local objSeq = frame.args["obj_seq_" .. index] or index
       
        local collapsedClass = index > 1 and " collapsed" or ""
       
        output = 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>
     <div class="objective-tasks">]], collapsedClass, objId, objSeq, objTitle)
     <div class="objective-tasks">%s</div>
       
</div>]], collapsedClass, objectiveId, seq, title, totalTasks, tasks)
        -- Format 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>]]
       
        index = index + 1
    end
      
      
     return output
     return output
Line 145: Line 68:


--------------------------------------------------
--------------------------------------------------
-- Function: formatMaterials
-- Function: formatTaskItem
-- Format material list with icons
-- Formats a single task item
--------------------------------------------------
--------------------------------------------------
function p.formatMaterials(frame)
function p.formatTaskItem(frame)
     local output = ""
     local taskId = frame.args.id or ""
     local totalCount = 0
     local description = frame.args.description or ""
     local index = 0
     local qty = frame.args.qty or ""
      
      
     -- Count materials first
     -- Apply iconization to the description
     while frame.args["mat_name_" .. (index + 1)] do
     local iconizedDesc = frame:preprocess('{{#invoke:DataTableParserV2|iconize|' .. description .. '}}')
        totalCount = totalCount + 1
   
         index = index + 1
    local qtyHtml = ""
    if qty ~= "" and qty ~= "0" then
         qtyHtml = string.format('<div class="task-qty">%s pcs</div>', qty)
     end
     end
      
      
     output = string.format([[
     return string.format([[
<div class="materials-progress">
<div class="task-item" data-task-id="%s">
     <span class="materials-progress-text">Materials Collected</span>
     <div class="task-checkbox"></div>
     <span class="materials-progress-count">0/%d</span>
     <div class="task-description">%s</div>
</div>
    %s
<div class="materials-list">
</div>]], taskId, iconizedDesc, qtyHtml)
     <div class="material-category">
end
        <div class="material-category-title">Required Materials</div>]], totalCount)
 
--------------------------------------------------
-- 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)
      
      
    -- Render materials
  return string.format([=[
    for i = 1, totalCount do
<div class="material-item" data-material-index="%s">
        local matName = frame.args["mat_name_" .. i] or ""
    <div class="material-checkbox"></div>
        local matQty = frame.args["mat_qty_" .. i] or "1"
    <div class="material-icon">%s</div>
       
    <div class="material-name">[[%s]]</div>
        -- Get icon
    <div class="material-qty">%s</div>
        local iconFile = matName:gsub("%s+", "_") .. "_-_Icon.png"
</div>]=], index, iconHtml, name, qty)
        local fileTitle = mw.title.new("File:" .. iconFile)
        local iconHtml = ""
       
        if fileTitle and fileTitle.exists then
            iconHtml = string.format('[[File:%s|20px|link=]]', iconFile)
        else
            iconHtml = '⚙️'
        end
 
        -- *** 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