Editing Module:Feedback
From The Petit Planet Wiki
More actions
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
| Latest revision | Your text | ||
| Line 2: | Line 2: | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
-- | -- Helpers | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
local function isTruthy( | local function isTruthy(v) | ||
if | if v == nil then | ||
return false | return false | ||
end | end | ||
v = mw.text.trim(tostring(v)):lower() | |||
return | return v ~= '' | ||
and v ~= '0' | |||
and v ~= 'false' | |||
and v ~= 'no' | |||
and v ~= 'off' | |||
end | end | ||
local function formatUser(user) | local function formatUser(user) | ||
user = trim(user) | user = mw.text.trim(tostring(user or '')) | ||
if user == '' then | if user == '' or user:lower() == 'anonymous' then | ||
return 'Anonymous' | return 'Anonymous' | ||
end | end | ||
| Line 40: | Line 32: | ||
user | user | ||
) | ) | ||
end | end | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
-- | -- Feedback card | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
local function | local function renderCard(entry, showInstruction) | ||
local | |||
local resolved = | |||
(entry.status == 'resolved') | |||
local | local user = | ||
entry.user | |||
or 'Anonymous' | |||
local feedback = | |||
entry.feedback | |||
or 'No feedback provided' | |||
local | local page = | ||
entry.page | |||
local id = | |||
mw.text.trim( | |||
tostring(entry.id or '') | |||
) | ) | ||
local resolvedBy = | |||
mw.text.trim( | |||
tostring(entry.resolvedby or '') | |||
) | ) | ||
local resolvedDate = | |||
mw.text.trim( | |||
' | tostring(entry.resolveddate or '') | ||
) | ) | ||
local root = | local root = | ||
| Line 289: | Line 78: | ||
or 'feedback-box--unresolved' | or 'feedback-box--unresolved' | ||
) | ) | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- | -- Meta | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local | local meta = | ||
root:tag('div') | root:tag('div') | ||
:addClass('feedback- | :addClass('feedback-meta') | ||
if page and page ~= '' then | |||
meta:tag('span') | |||
:addClass('feedback-page') | |||
:wikitext( | |||
string.format( | |||
'[[%s]]', | |||
page | |||
) | |||
) | |||
meta:tag('span') | |||
:addClass('feedback-separator') | |||
:wikitext(' • ') | |||
end | |||
meta:tag('span') | |||
:addClass('feedback-user') | |||
:wikitext( | |||
formatUser(user) | |||
) | |||
meta:tag('span') | |||
:addClass('feedback-separator') | |||
:wikitext(' • ') | |||
meta:tag('span') | |||
:addClass('feedback-status') | :addClass('feedback-status') | ||
:addClass( | :addClass( | ||
| Line 331: | Line 128: | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- Feedback | -- Feedback body | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
root:tag('div') | |||
:addClass('feedback- | :addClass('feedback-body') | ||
:wikitext( | :wikitext(feedback) | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- | -- Resolution information | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local | if resolved and resolvedBy ~= '' then | ||
local resolution = | |||
root:tag('div') | |||
:addClass('feedback-resolution') | |||
resolution:wikitext( | |||
'Resolved by ' | |||
' | .. formatUser(resolvedBy) | ||
) | ) | ||
if resolvedDate ~= '' then | |||
resolution:wikitext( | |||
' on ' | |||
.. mw.text.nowiki(resolvedDate) | |||
) | |||
end | |||
end | end | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- | -- Resolve instruction | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
if showInstruction and not resolved then | |||
local instruction = | |||
root:tag('div') | |||
:addClass('feedback-instruction') | |||
if id ~= '' then | |||
instruction:wikitext( | |||
'If this feedback has been resolved, click the button below. ' | |||
:wikitext( | |||
' | |||
) | ) | ||
instruction:tag('span') | |||
:addClass('feedback-resolve-button') | |||
:attr('role', 'button') | |||
:attr('tabindex', '0') | |||
:attr('data-feedback-id', id) | |||
:wikitext('Resolve') | |||
else | |||
instruction:wikitext( | |||
'Add an ID to this feedback to enable the Resolve button.' | |||
) | |||
end | |||
end | end | ||
| Line 413: | Line 197: | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
-- | -- Save feedback | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
local function | local function saveFeedback(data) | ||
if not (mw.ext and mw.ext.bucket) then | |||
return false, 'Bucket extension is not available' | |||
end | |||
local bucket = | |||
mw.ext.bucket('feedback') | |||
local bucket = | |||
if not bucket then | if not bucket then | ||
return false, ' | return false, 'Feedback bucket could not be opened' | ||
end | end | ||
local success, err = pcall(function() | local success, err = | ||
pcall(function() | |||
bucket.put({ | |||
page = data.page, | |||
user = data.user, | |||
status = data.status, | |||
feedback = data.feedback, | |||
id = data.id, | |||
resolvedby = data.resolvedby, | |||
resolveddate = data.resolveddate | |||
}) | |||
end) | |||
if not success then | if not success then | ||
| Line 456: | Line 237: | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
-- | -- Main | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
function p.main(frame) | function p.main(frame) | ||
local parent = frame:getParent() | |||
local parent = | |||
frame:getParent() | |||
local args = | local args = | ||
| Line 471: | Line 252: | ||
if parent and parent.getTitle then | if parent and parent.getTitle then | ||
local title = parent:getTitle() | |||
local title = | |||
parent:getTitle() | |||
if title | if title | ||
| Line 477: | Line 260: | ||
and not title:find('^Template:') | and not title:find('^Template:') | ||
then | then | ||
pageTitle = title | pageTitle = title | ||
end | end | ||
end | end | ||
| Line 489: | Line 274: | ||
function p._main(args, pageTitle) | function p._main(args, pageTitle) | ||
local feedback = | local feedback = | ||
args.feedback | |||
or 'No feedback provided' | |||
local user = | |||
args.user | |||
or 'Anonymous' | |||
local id = | |||
args.id | |||
or '' | |||
local | local resolvedBy = | ||
args.resolvedby | |||
or '' | |||
local resolvedDate = | |||
args.resolveddate | |||
or '' | |||
local resolved = | local resolved = | ||
| Line 512: | Line 304: | ||
local currentPage = | local currentPage = | ||
pageTitle | |||
or mw.title.getCurrentTitle().fullText | |||
-------------------------------------------------------- | -------------------------------------------------------- | ||
| Line 548: | Line 318: | ||
feedback = feedback, | feedback = feedback, | ||
id = id, | id = id, | ||
resolvedby = resolvedBy, | |||
resolveddate = resolvedDate | |||
resolvedby = | |||
resolveddate = | |||
}) | }) | ||
if not saved then | if not saved then | ||
return | |||
return '<strong style="color:red;">Feedback bucket error: ' | |||
.. mw.text.nowiki( | .. mw.text.nowiki( | ||
saveError or 'Unknown error' | saveError or 'Unknown error' | ||
) | ) | ||
.. '</strong>' | .. '</strong>' | ||
end | end | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- Render | -- Render card | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local card = | local card = | ||
renderCard({ | |||
page = | page = nil, | ||
user = user, | user = user, | ||
status = status, | status = status, | ||
feedback = feedback, | feedback = feedback, | ||
id = id, | id = id, | ||
resolvedby = resolvedBy, | |||
resolveddate = resolvedDate | |||
}, true) | |||
resolvedby = | |||
resolveddate = | |||
}) | |||
-------------------------------------------------------- | -------------------------------------------------------- | ||
| Line 586: | Line 351: | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local | local categories = {} | ||
if resolved then | if resolved then | ||
table.insert( | |||
categories, | |||
'[[Category:Resolved Feedback]]' | '[[Category:Resolved Feedback]]' | ||
) | |||
else | else | ||
table.insert( | |||
categories, | |||
'[[Category:Unresolved Feedback]]' | '[[Category:Unresolved Feedback]]' | ||
) | |||
end | end | ||
if id == '' then | if mw.text.trim( | ||
tostring(id) | |||
) == '' then | |||
table.insert( | |||
categories, | |||
'[[Category:Feedbacks Missing ID]]' | '[[Category:Feedbacks Missing ID]]' | ||
) | |||
end | end | ||
return card .. | return card | ||
.. table.concat(categories) | |||
end | end | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
-- | -- Render feedback list | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
local function renderFeedbackList(results) | local function renderFeedbackList(results) | ||
if not results or #results == 0 then | if not results or #results == 0 then | ||
return '<em>No feedback entries found.</em>' | return '<em>No feedback entries found.</em>' | ||
| Line 618: | Line 398: | ||
for _, row in ipairs(results) do | for _, row in ipairs(results) do | ||
table.insert( | table.insert( | ||
list, | list, | ||
renderCard( | |||
row, | |||
false | |||
) | |||
) | ) | ||
end | end | ||
| Line 632: | Line 417: | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
-- | -- View feedback | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
function p. | function p.view(frame) | ||
local | |||
local parent = | |||
frame:getParent() | |||
local args | |||
if frame | |||
and frame.args | |||
and frame.args.status | |||
then | |||
args = | |||
frame.args | |||
elseif parent | |||
and parent.args | |||
and parent.args.status | |||
then | |||
args = | |||
parent.args | |||
elseif frame | |||
and frame.args | |||
then | |||
args = | |||
frame.args | |||
elseif parent | |||
and parent.args | |||
then | |||
args = | |||
parent.args | |||
else | |||
args = {} | |||
end | |||
return p._view( | |||
args, | |||
frame | |||
) | ) | ||
end | |||
function p._view(args, frame) | |||
if not (mw.ext and mw.ext.bucket) then | |||
return '<em>Bucket extension is not available.</em>' | |||
end | end | ||
frame = | |||
frame | |||
or mw.getCurrentFrame() | |||
local rawStatus = | |||
args.status | |||
or args[1] | |||
local filterStatus = | |||
rawStatus | |||
and mw.text.trim(rawStatus):lower() | |||
or nil | |||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- | -- Filtered views | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
if filterStatus == 'resolved' | |||
or filterStatus == 'unresolved' | |||
then | |||
local query = | |||
mw.ext.bucket('feedback') | |||
query.select( | |||
'page', | |||
'user', | |||
'status', | |||
'feedback', | |||
'id', | |||
'resolvedby', | |||
'resolveddate' | |||
) | |||
query.where( | |||
'status', | |||
filterStatus | |||
) | |||
return renderFeedbackList( | |||
query.run() | |||
) | |||
end | end | ||
| Line 787: | Line 524: | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
if filterStatus == 'all' then | |||
local query = | |||
mw.ext.bucket('feedback') | |||
query.select( | |||
'page', | |||
'user', | |||
'status', | |||
'feedback', | |||
'id', | |||
'resolvedby', | |||
'resolveddate' | |||
) | |||
return renderFeedbackList( | |||
query.run() | |||
) | ) | ||
end | |||
-------------------------------------------------------- | |||
-- Default tabbed view | |||
-------------------------------------------------------- | |||
local qAll = | |||
mw.ext.bucket('feedback') | |||
qAll.select( | |||
'page', | |||
'user', | |||
'status', | |||
'feedback', | |||
'id', | |||
'resolvedby', | |||
'resolveddate' | |||
) | ) | ||
local allEntries = | |||
qAll.run() | |||
local allList = {} | |||
local unresolvedList = {} | |||
local resolvedList = {} | |||
if allEntries and #allEntries > 0 then | |||
if | |||
for _, row in ipairs(allEntries) do | |||
local card = | |||
renderCard( | |||
row, | |||
false | |||
) | |||
table.insert( | |||
allList, | |||
card | |||
) | |||
if row.status == 'resolved' then | |||
table.insert( | |||
resolvedList, | |||
card | |||
) | |||
else | |||
table.insert( | |||
unresolvedList, | |||
card | |||
) | |||
end | |||
end | |||
end | |||
-------------------------------------------------------- | |||
-- All content | |||
-------------------------------------------------------- | |||
local allContent | |||
if #allList > 0 then | |||
allContent = | |||
table.concat( | |||
allList, | |||
'\n' | |||
) | ) | ||
else | |||
allContent = | |||
'<em>No feedback entries found.</em>' | |||
end | end | ||
-------------------------------------------------------- | |||
-- Unresolved content | |||
-------------------------------------------------------- | |||
local unresolvedContent | |||
if #unresolvedList > 0 then | |||
unresolvedContent = | |||
table.concat( | |||
unresolvedList, | |||
'\n' | |||
) | |||
else | else | ||
unresolvedContent = | |||
'<em>No unresolved feedback entries found.</em>' | |||
end | end | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- | -- Resolved content | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local | local resolvedContent | ||
if #resolvedList > 0 then | |||
resolvedContent = | |||
table.concat( | |||
resolvedList, | |||
'\n' | |||
) | |||
else | |||
resolvedContent = | |||
'<em>No resolved feedback entries found.</em>' | |||
end | end | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
-- | -- Tabber | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
local tabberBody = | |||
string.format( | |||
'All=\n%s\n|-|Unresolved=\n%s\n|-|Resolved=\n%s', | |||
allContent, | |||
unresolvedContent, | |||
resolvedContent | |||
) | ) | ||
return frame:callParserFunction( | |||
'#tag', | |||
{ | |||
'tabber', | |||
tabberBody | |||
} | |||
) | |||
end | end | ||
return p | return p | ||