Jump to content
Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
If you make an edit, a temporary account will be created for you.

Module:Feedback: Difference between revisions

From The Petit Planet Wiki
ReisuDesign (talk | contribs)
No edit summary
ReisuDesign (talk | contribs)
No edit summary
Line 32: Line 32:
user
user
)
)
end
local function escapeAttribute(value)
value = tostring(value or '')
return mw.text.nowiki(value)
end
end


Line 50: Line 43:
local resolved = (entry.status == 'resolved')
local resolved = (entry.status == 'resolved')


local user = entry.user or 'Anonymous'
local user =
local feedback = entry.feedback or 'No feedback provided'
entry.user
local page = entry.page
or 'Anonymous'
local id = entry.id
 
local resolvedBy = entry.resolvedby
local feedback =
local resolvedDate = entry.resolveddate
entry.feedback
or 'No feedback provided'
 
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 = mw.html.create('div')
local root = mw.html.create('div')
Line 65: Line 76:
or 'feedback-box--unresolved'
or 'feedback-box--unresolved'
)
)


--------------------------------------------------------
--------------------------------------------------------
-- Metadata
-- Meta
--------------------------------------------------------
--------------------------------------------------------


local meta = root:tag('div')
local meta = root:tag('div')
:addClass('feedback-meta')
:addClass('feedback-meta')


if page and page ~= '' then
if page and page ~= '' then
meta:tag('span')
meta:tag('span')
:addClass('feedback-page')
:addClass('feedback-page')
:wikitext(
:wikitext(
string.format('[[%s]]', page)
string.format(
'[[%s]]',
page
)
)
)


Line 86: Line 97:
:addClass('feedback-separator')
:addClass('feedback-separator')
:wikitext(' • ')
:wikitext(' • ')
end
end


meta:tag('span')
meta:tag('span')
:addClass('feedback-user')
:addClass('feedback-user')
:wikitext(formatUser(user))
:wikitext(
 
formatUser(user)
)


meta:tag('span')
meta:tag('span')
:addClass('feedback-separator')
:addClass('feedback-separator')
:wikitext(' • ')
:wikitext(' • ')


meta:tag('span')
meta:tag('span')
Line 112: Line 121:
or 'Unresolved'
or 'Unresolved'
)
)


--------------------------------------------------------
--------------------------------------------------------
-- Feedback text
-- Feedback
--------------------------------------------------------
--------------------------------------------------------


Line 121: Line 129:
:addClass('feedback-body')
:addClass('feedback-body')
:wikitext(feedback)
:wikitext(feedback)


--------------------------------------------------------
--------------------------------------------------------
Line 127: Line 134:
--------------------------------------------------------
--------------------------------------------------------


if resolved and resolvedBy and resolvedBy ~= '' then
if resolved and resolvedBy ~= '' then


local resolutionMeta =
local resolution = root:tag('div')
'Resolved by ' .. formatUser(resolvedBy)
:addClass('feedback-resolution')


if resolvedDate and resolvedDate ~= '' then
resolution:wikitext(
resolutionMeta =
'Resolved by '
resolutionMeta
.. formatUser(resolvedBy)
.. ' on '
)
.. resolvedDate
 
if resolvedDate ~= '' then
resolution:wikitext(
' on '
.. mw.text.nowiki(resolvedDate)
)
end
end
root:tag('div')
:addClass('feedback-resolution')
:wikitext(resolutionMeta)
end
end


--------------------------------------------------------
--------------------------------------------------------
-- Resolution controls
-- Resolve instruction
--------------------------------------------------------
--------------------------------------------------------


Line 155: Line 161:
:addClass('feedback-instruction')
:addClass('feedback-instruction')


if id ~= '' then


instruction:tag('span')
instruction:wikitext(
:wikitext(
'If this feedback has been resolved, click the button below. '
'If this feedback has been resolved, '
.. 'click the button below.'
)
)
if id and id ~= '' then


instruction:tag('button')
instruction:tag('button')
:addClass('feedback-resolve-button')
:addClass('feedback-resolve-button')
:attr('type', 'button')
:attr('type', 'button')
:attr('data-feedback-id', escapeAttribute(id))
:attr('data-feedback-id', id)
:wikitext('Resolve')
:wikitext('Resolve')
else
instruction:wikitext(
'Add an ID to this feedback to enable the Resolve button.'
)


end
end
end
end


return tostring(root)
return tostring(root)
Line 190: Line 196:
end
end


 
local bucket =
local bucket = mw.ext.bucket('feedback')
mw.ext.bucket('feedback')


if not bucket then
if not bucket then
return false, 'Feedback bucket could not be opened'
return false, 'Feedback bucket could not be opened'
end
end


local success, err = pcall(function()
local success, err = pcall(function()
Line 211: Line 216:


end)
end)


if not success then
if not success then
return false, tostring(err)
return false, tostring(err)
end
end


return true
return true
Line 224: Line 227:
------------------------------------------------------------
------------------------------------------------------------
-- Main
-- Main
--
-- Used by Template:Feedback
--
-- Example:
--
-- {{Feedback
--  |feedback=Something could be improved here.
--  |user=Rei
--  |resolved=false
--  |id=1758012345678
--  |resolvedby=
--  |resolveddate=
-- }}
------------------------------------------------------------
------------------------------------------------------------


function p.main(frame)
function p.main(frame)


local parent = frame:getParent()
local parent =
frame:getParent()


local args =
local args =
parent and parent.args
parent and parent.args
or frame.args
or frame.args
--------------------------------------------------------
-- Get page title
--------------------------------------------------------


local pageTitle = nil
local pageTitle = nil
Line 256: Line 242:
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 264: Line 251:
pageTitle = title
pageTitle = title
end
end
end
end


 
return p._main(
return p._main(args, pageTitle)
args,
 
pageTitle
)
end
end


Line 278: Line 265:
args.feedback
args.feedback
or 'No feedback provided'
or 'No feedback provided'


local user =
local user =
Line 284: Line 270:
or 'Anonymous'
or 'Anonymous'


local id =
args.id
or ''
local resolvedBy =
args.resolvedby
or ''
local resolvedDate =
args.resolveddate
or ''


local resolved =
local resolved =
isTruthy(args.resolved)
isTruthy(args.resolved)


local status =
local status =
Line 293: Line 289:
and 'resolved'
and 'resolved'
or 'unresolved'
or 'unresolved'
local id =
mw.text.trim(
tostring(args.id or '')
)
local resolvedBy =
mw.text.trim(
tostring(args.resolvedby or '')
)
local resolvedDate =
mw.text.trim(
tostring(args.resolveddate or '')
)


local currentPage =
local currentPage =
pageTitle
pageTitle
or mw.title.getCurrentTitle().fullText
or mw.title.getCurrentTitle().fullText


--------------------------------------------------------
--------------------------------------------------------
Line 322: Line 298:
--------------------------------------------------------
--------------------------------------------------------


local saved, saveError = saveFeedback({
local saved, saveError =
page = currentPage,
saveFeedback({
user = user,
page = currentPage,
status = status,
user = user,
feedback = feedback
status = status,
})
feedback = feedback,
 
id = id,
resolvedby = resolvedBy,
resolveddate = resolvedDate
})


if not saved then
if not saved then
return '<strong style="color:red;">Feedback bucket error: '
return '<strong style="color:red;">Feedback bucket error: '
.. mw.text.nowiki(saveError or 'Unknown error')
.. mw.text.nowiki(
saveError or 'Unknown error'
)
.. '</strong>'
.. '</strong>'
end
end


--------------------------------------------------------
--------------------------------------------------------
-- Render feedback card
-- Render card
--------------------------------------------------------
--------------------------------------------------------


local card = renderCard({
local card =
 
renderCard({
page = nil,
page = nil,
 
user = user,
user = user,
status = status,
 
feedback = feedback,
status = status,
id = id,
 
resolvedby = resolvedBy,
feedback = feedback,
resolveddate = resolvedDate
 
}, true)
id = id,
 
resolvedby = resolvedBy,
 
resolveddate = resolvedDate
 
}, true)
 


--------------------------------------------------------
--------------------------------------------------------
-- Categorize feedback
-- Categories
--------------------------------------------------------
--------------------------------------------------------


local category
local categories = {}


if resolved then
if resolved then
 
table.insert(
category =
categories,
'[[Category:Resolved Feedback]]'
'[[Category:Resolved Feedback]]'
 
)
else
else
 
table.insert(
category =
categories,
'[[Category:Unresolved Feedback]]'
'[[Category:Unresolved Feedback]]'
 
)
end
end


if mw.text.trim(
tostring(id)
) == '' then


return card .. category
table.insert(
categories,
'[[Category:Feedbacks Missing ID]]'
)
end


return card
.. table.concat(categories)
end
end


Line 395: Line 374:
return '<em>No feedback entries found.</em>'
return '<em>No feedback entries found.</em>'
end
end


local list = {}
local list = {}


for _, row in ipairs(results) do
for _, row in ipairs(results) do
Line 404: Line 381:
table.insert(
table.insert(
list,
list,
renderCard(row, false)
renderCard(
row,
false
)
)
)


end
end


 
return table.concat(
return table.concat(list, '\n')
list,
 
'\n'
)
end
end


Line 421: Line 402:
function p.view(frame)
function p.view(frame)


local parent = frame:getParent()
local parent =
 
frame:getParent()


local args
local args
Line 431: Line 412:
then
then


args = frame.args
args =
frame.args


elseif parent
elseif parent
Line 438: Line 420:
then
then


args = parent.args
args =
parent.args


elseif frame
elseif frame
Line 444: Line 427:
then
then


args = frame.args
args =
frame.args


elseif parent
elseif parent
Line 450: Line 434:
then
then


args = parent.args
args =
parent.args


else
else
Line 458: Line 443:
end
end


 
return p._view(
return p._view(args, frame)
args,
 
frame
)
end
end




function p._view(args, frame)
function p._view(args, frame)
--------------------------------------------------------
-- Check Bucket
--------------------------------------------------------


if not (mw.ext and mw.ext.bucket) then
if not (mw.ext and mw.ext.bucket) then
 
return '<em>Bucket extension is not available.</em>'
return
'<em>Bucket extension is not available.</em>'
 
end
end


 
frame =
frame = frame or mw.getCurrentFrame()
frame
 
or mw.getCurrentFrame()
 
--------------------------------------------------------
-- Determine requested status
--------------------------------------------------------


local rawStatus =
local rawStatus =
args.status
args.status
or args[1]
or args[1]


local filterStatus =
local filterStatus =
Line 494: Line 468:
and mw.text.trim(rawStatus):lower()
and mw.text.trim(rawStatus):lower()
or nil
or nil


--------------------------------------------------------
--------------------------------------------------------
-- Specific status
-- Filtered views
--------------------------------------------------------
--------------------------------------------------------


Line 506: Line 479:
local query =
local query =
mw.ext.bucket('feedback')
mw.ext.bucket('feedback')


query.select(
query.select(
Line 512: Line 484:
'user',
'user',
'status',
'status',
'feedback'
'feedback',
'id',
'resolvedby',
'resolveddate'
)
)


query.where(
query.where(
Line 520: Line 494:
filterStatus
filterStatus
)
)


return renderFeedbackList(
return renderFeedbackList(
query.run()
query.run()
)
)
end
end


--------------------------------------------------------
--------------------------------------------------------
-- All feedback
-- All
--------------------------------------------------------
--------------------------------------------------------


Line 537: Line 508:
local query =
local query =
mw.ext.bucket('feedback')
mw.ext.bucket('feedback')


query.select(
query.select(
Line 543: Line 513:
'user',
'user',
'status',
'status',
'feedback'
'feedback',
'id',
'resolvedby',
'resolveddate'
)
)


return renderFeedbackList(
return renderFeedbackList(
query.run()
query.run()
)
)
end
end


--------------------------------------------------------
--------------------------------------------------------
-- Tabber mode
-- Default tabbed view
--------------------------------------------------------
--------------------------------------------------------


local qAll =
local qAll =
mw.ext.bucket('feedback')
mw.ext.bucket('feedback')


qAll.select(
qAll.select(
Line 566: Line 535:
'user',
'user',
'status',
'status',
'feedback'
'feedback',
'id',
'resolvedby',
'resolveddate'
)
)


local allEntries =
local allEntries =
qAll.run()
qAll.run()


local allList = {}
local allList = {}
local unresolvedList = {}
local unresolvedList = {}
local resolvedList = {}
local resolvedList = {}
--------------------------------------------------------
-- Split entries by status
--------------------------------------------------------


if allEntries and #allEntries > 0 then
if allEntries and #allEntries > 0 then
Line 588: Line 553:


local card =
local card =
renderCard(row, false)
renderCard(
 
row,
false
)


table.insert(
table.insert(
Line 595: Line 562:
card
card
)
)


if row.status == 'resolved' then
if row.status == 'resolved' then
Line 612: Line 578:


end
end
end
end
end
end


--------------------------------------------------------
--------------------------------------------------------
-- Build tab contents
-- All content
--------------------------------------------------------
--------------------------------------------------------


Line 627: Line 590:


allContent =
allContent =
table.concat(allList, '\n')
table.concat(
allList,
'\n'
)


else
else
Line 636: Line 602:
end
end


--------------------------------------------------------
-- Unresolved content
--------------------------------------------------------


local unresolvedContent
local unresolvedContent
Line 642: Line 611:


unresolvedContent =
unresolvedContent =
table.concat(unresolvedList, '\n')
table.concat(
unresolvedList,
'\n'
)


else
else
Line 651: Line 623:
end
end


--------------------------------------------------------
-- Resolved content
--------------------------------------------------------


local resolvedContent
local resolvedContent
Line 657: Line 632:


resolvedContent =
resolvedContent =
table.concat(resolvedList, '\n')
table.concat(
resolvedList,
'\n'
)


else
else
Line 665: Line 643:


end
end


--------------------------------------------------------
--------------------------------------------------------
Line 671: Line 648:
--------------------------------------------------------
--------------------------------------------------------


local tabberBody = string.format(
local tabberBody =
'All=\n%s\n|-|Unresolved=\n%s\n|-|Resolved=\n%s',
string.format(
allContent,
'All=\n%s\n|-|Unresolved=\n%s\n|-|Resolved=\n%s',
unresolvedContent,
allContent,
resolvedContent
unresolvedContent,
)
resolvedContent
 
)


return frame:callParserFunction(
return frame:callParserFunction(
Line 686: Line 663:
}
}
)
)
end
end


return p
return p