Basculer le menu
Changer de menu des préférences
Basculer le menu personnel
Non connecté(e)
Votre adresse IP sera visible au public si vous faites des modifications.

« Module:Roadmap » : différence entre les versions

De Nefald
Hiob (discussion | contributions)
citizen
Hiob (discussion | contributions)
Aucun résumé des modifications
 
(5 versions intermédiaires par le même utilisateur non affichées)
Ligne 68 : Ligne 68 :
end
end
return nil
return nil
end
local function sanitizeClass(s)
if not s then return "" end
s = s:lower()
s = s:gsub("[^%w%-]", "")
return s
end
end


-- ------------------------------------------------------------
-- ------------------------------------------------------------
-- PARSEUR
-- PARSEUR (séparateur ;; au lieu de |)
-- ------------------------------------------------------------
-- ------------------------------------------------------------


Ligne 79 : Ligne 86 :
line = trim(line)
line = trim(line)
if line == "" or line:match("^%-%-") then
if line == "" or line:match("^%-%-") then
-- skip vide ou commentaire
-- skip
elseif line:match("^@section%s+") then
elseif line:match("^@section%s+") then
local titre = line:match("^@section%s+(.+)$")
local titre = line:match("^@section%s+(.+)$")
Ligne 86 : Ligne 93 :
titre = trim(titre or "Section"),
titre = trim(titre or "Section"),
})
})
elseif line:match("^item%s*|") then
elseif line:match("^item%s*;;") then
local parts = {}
local parts = {}
for part in line:gmatch("([^|]+)") do
for part in (line .. ";;"):gmatch("(.-);;") do
table.insert(parts, trim(part))
table.insert(parts, trim(part))
end
end
-- parts[1] = "item", parts[2] = statut, parts[3] = titre, etc.
local statut = trim(parts[2] or "planned"):lower()
local statut = trim(parts[2] or "planned"):lower()
local titre  = trim(parts[3] or "")
local titre  = trim(parts[3] or "")
Ligne 153 : Ligne 161 :
local s = CONFIG.statuts[statut] or CONFIG.statuts.planned
local s = CONFIG.statuts[statut] or CONFIG.statuts.planned
return string.format(
return string.format(
'<span class="roadmap-badge" title="%s">%s</span>',
'<span class="roadmap-badge roadmap-badge-%s" title="%s">%s</span>',
escapeHtml(s.label), s.icon
statut, escapeHtml(s.label), s.icon
)
)
end
end
Ligne 163 : Ligne 171 :
for _, tag in ipairs(tags) do
for _, tag in ipairs(tags) do
table.insert(parts, string.format(
table.insert(parts, string.format(
'<span class="roadmap-tag" data-tag="%s">%s</span>',
'<span class="roadmap-tag roadmap-tag-%s">%s</span>',
escapeHtml(tag), escapeHtml(tag)
sanitizeClass(tag), escapeHtml(tag)
))
))
end
end
Ligne 217 : Ligne 225 :
'<div class="roadmap-progress-wrap">'
'<div class="roadmap-progress-wrap">'
.. '<div class="roadmap-progress-label">'
.. '<div class="roadmap-progress-label">'
.. 'Progression : <strong>%d%%</strong> — %d / %d fonctionnalités'
.. 'Progression\194\160: <strong>%d%%</strong> — %d / %d fonctionnalités'
.. '</div>'
.. '</div>'
.. '<div class="roadmap-progress-bar">'
.. '<div class="roadmap-progress-bar">'
Ligne 234 : Ligne 242 :
if s then
if s then
table.insert(parts, string.format(
table.insert(parts, string.format(
'<span class="roadmap-legend-item">'
'<span class="roadmap-legend-item roadmap-%s">'
.. '<span class="roadmap-badge" '
.. '%s %s</span>',
.. 'style="width:16px;height:16px;min-width:16px;font-size:0.7em">'
key, htmlBadge(key), escapeHtml(s.label)
.. '%s</span> %s</span>',
s.icon, escapeHtml(s.label)
))
))
end
end
Ligne 246 : Ligne 252 :


local function htmlStats(elements)
local function htmlStats(elements)
local counts = {}
local counts = { done = 0, inprogress = 0, planned = 0, idea = 0, cancelled = 0 }
for key in pairs(CONFIG.statuts) do counts[key] = 0 end
for _, el in ipairs(elements) do
for _, el in ipairs(elements) do
if el.type == "item" and counts[el.statut] then
if el.type == "item" and counts[el.statut] then
Ligne 253 : Ligne 258 :
end
end
end
end
local parts = {}
local order = {
local ordre = { "done", "inprogress", "planned", "idea", "cancelled" }
{ key = "done",       label = "Terminé" },
for _, key in ipairs(ordre) do
{ key = "inprogress", label = "En cours" },
if counts[key] and counts[key] > 0 then
{ key = "planned",   label = "Planifié" },
local s = CONFIG.statuts[key]
{ key = "idea",       label = "Idée" },
{ key = "cancelled",  label = "Annulé" },
}
local parts = { '<div class="roadmap-stats">' }
for _, s in ipairs(order) do
if counts[s.key] > 0 then
table.insert(parts, string.format(
table.insert(parts, string.format(
'<span class="roadmap-stat">'
'<div class="roadmap-stat roadmap-stat-%s">'
.. '<span class="roadmap-stat-count">%d</span>'
.. '<span class="roadmap-stat-count">%d</span>'
.. '<span class="roadmap-stat-label">%s</span>'
.. '<span class="roadmap-stat-label">%s</span>'
.. '</span>',
.. '</div>',
counts[key], escapeHtml(s.label)
s.key, counts[s.key], s.label
))
))
end
end
end
end
return '<div class="roadmap-stats">' .. table.concat(parts, "") .. '</div>'
table.insert(parts, '</div>')
return table.concat(parts, "\n")
end
end


Ligne 276 : Ligne 287 :
function p.render(frame)
function p.render(frame)
local args = frame:getParent().args
local args = frame:getParent().args
local titre    = getParam(args, "titre") or "Roadmap"
local rawContenu = trim(args["contenu"] or args[1] or "")
--
local titre    = getParam(args, "titre", "title") or "Roadmap"
local subtitle = getParam(args, "subtitle")
local subtitle = getParam(args, "subtitle")
local rawContenu = trim(args["contenu"] or args[1] or "")
--
local showStats  = getParam(args, "stats") ~= "non"
local showLegende = getParam(args, "legende") ~= "non"
local elements = parseContenu(rawContenu)
local elements = parseContenu(rawContenu)
local pct, done, total = calcProgression(elements)
local pct, done, total = calcProgression(elements)
local html = {}
--
table.insert(html, '<div class="roadmap-container">')
local out = {}
-- Header
table.insert(out, '<div class="roadmap-container">')
table.insert(html, '<div class="roadmap-header">')
-- En-tête
table.insert(html, string.format(
table.insert(out, '<div class="roadmap-header">')
'<div><div class="roadmap-header-title">%s</div>',
table.insert(out, string.format('<div class="roadmap-title">%s</div>', escapeHtml(titre)))
escapeHtml(titre)
))
if subtitle then
if subtitle then
table.insert(html, string.format(
table.insert(out, string.format('<div class="roadmap-subtitle">%s</div>', escapeHtml(subtitle)))
'<div class="roadmap-subtitle">%s</div>',
escapeHtml(subtitle)
))
end
end
table.insert(html, '</div></div>')
table.insert(out, htmlProgressBar(pct, done, total))
-- Stats
table.insert(out, htmlStats(elements))
if showStats and #elements > 0 then
table.insert(out, htmlLegende())
table.insert(html, htmlStats(elements))
table.insert(out, '</div>')
end
-- Corps
-- Progression
local sectionOpen = false
if total > 0 then
table.insert(html, htmlProgressBar(pct, done, total))
end
-- Contenu
local inSection = false
for _, el in ipairs(elements) do
for _, el in ipairs(elements) do
if el.type == "section" then
if el.type == "section" then
if inSection then
if sectionOpen then
table.insert(html, '</div>')
table.insert(out, '</div>')
end
end
table.insert(html, htmlSection(el))
table.insert(out, htmlSection(el))
inSection = true
sectionOpen = true
elseif el.type == "item" then
elseif el.type == "item" then
table.insert(html, htmlItem(el))
table.insert(out, htmlItem(el))
end
end
end
if inSection then
table.insert(html, '</div>')
end
end
-- Légende
if sectionOpen then
if showLegende then
table.insert(out, '</div>')
table.insert(html, htmlLegende())
end
end
table.insert(html, '</div>')
table.insert(out, '</div>')
return table.concat(html, "\n")
return table.concat(out, "\n")
end
end


-- ------------------------------------------------------------
-- ------------------------------------------------------------
-- ITEM INLINE (usage standalone)
-- ITEM INLINE
-- ------------------------------------------------------------
-- ------------------------------------------------------------


Les témoins (''cookies'') nous aident à fournir nos services. En utilisant nos services, vous acceptez notre utilisation de témoins.