| Latest revision |
Your text |
| Line 1: |
Line 1: |
| local p = {}
| |
|
| |
| ------------------------------------------------------------ | | ------------------------------------------------------------ |
| -- HELPERS | | -- Resolve control |
| ------------------------------------------------------------
| |
| | |
| local function isTruthy(value)
| |
| if value == nil then
| |
| return false
| |
| end
| |
| | |
| value = mw.text.trim(tostring(value)):lower()
| |
| | |
| return value == 'true'
| |
| or value == 'yes'
| |
| or value == '1'
| |
| or value == 'resolved'
| |
| end
| |
| | |
| | |
| local function trim(value)
| |
| if value == nil then
| |
| return ''
| |
| end
| |
| | |
| return mw.text.trim(tostring(value))
| |
| end
| |
| | |
| | |
| local function formatUser(user)
| |
| user = trim(user)
| |
| | |
| if user == '' then
| |
| return 'Anonymous'
| |
| end
| |
| | |
| return string.format(
| |
| '[[User:%s|%s]]',
| |
| user,
| |
| user
| |
| )
| |
| end
| |
| | |
| | |
| local function currentSubjectPage()
| |
| local title = mw.title.getCurrentTitle()
| |
| | |
| if title.subjectPageTitle then
| |
| return title.subjectPageTitle.fullText
| |
| end
| |
| | |
| return title.fullText
| |
| end
| |
| | |
| | |
| local function getBucket()
| |
| if not (mw.ext and mw.ext.bucket) then
| |
| return nil
| |
| end
| |
| | |
| return mw.ext.bucket('feedback')
| |
| end
| |
| | |
| | |
| local function sortNewestFirst(entries)
| |
| table.sort(
| |
| entries,
| |
| function(a, b)
| |
| local aDate = trim(a.createddate)
| |
| local bDate = trim(b.createddate)
| |
| | |
| return aDate > bDate
| |
| end
| |
| )
| |
| | |
| return entries
| |
| end
| |
| | |
| | |
| local function queryFeedback(page)
| |
| local bucket = getBucket()
| |
| | |
| if not bucket then
| |
| return {}
| |
| end
| |
| | |
| local query = bucket
| |
| | |
| query.select(
| |
| 'page',
| |
| 'user',
| |
| 'status',
| |
| 'feedback',
| |
| 'id',
| |
| 'createddate',
| |
| 'link',
| |
| 'image',
| |
| 'resolvedby',
| |
| 'resolveddate'
| |
| )
| |
| | |
| query.where(
| |
| 'page',
| |
| page
| |
| )
| |
| | |
| local success, results = pcall(function()
| |
| return query.run()
| |
| end)
| |
| | |
| if not success or not results then
| |
| return {}
| |
| end
| |
| | |
| return sortNewestFirst(results)
| |
| end
| |
| | |
| | |
| ------------------------------------------------------------
| |
| -- ATTACHMENTS
| |
| ------------------------------------------------------------
| |
| | |
| local function renderAttachments(entry)
| |
| local wrapper =
| |
| mw.html.create('div')
| |
| :addClass('feedback-attachments')
| |
| | |
| local link = trim(entry.link)
| |
| | |
| if link ~= '' then
| |
| local linkWrapper =
| |
| wrapper:tag('span')
| |
| :addClass('feedback-attachment-link')
| |
|
| |
| linkWrapper:tag('span')
| |
| :addClass('feedback-attachment-icon')
| |
|
| |
| linkWrapper:wikitext(
| |
| '[' .. link .. ' ' .. mw.text.nowiki(link) .. ']'
| |
| )
| |
| end
| |
| | |
| local image = trim(entry.image)
| |
| | |
| if image ~= '' then
| |
| image = mw.ustring.gsub(
| |
| image,
| |
| '^File:',
| |
| ''
| |
| )
| |
| | |
| local title =
| |
| mw.title.new('File:' .. image)
| |
| | |
| if title then
| |
| local imageWrapper =
| |
| wrapper:tag('span')
| |
| :addClass('feedback-attachment-image')
| |
|
| |
| imageWrapper:tag('span')
| |
| :addClass('feedback-attachment-icon')
| |
|
| |
| imageWrapper:wikitext(
| |
| '[' ..
| |
| title:fullUrl() ..
| |
| ' ' ..
| |
| mw.text.nowiki(image) ..
| |
| ']'
| |
| )
| |
| end
| |
| end
| |
| | |
| return wrapper
| |
| end
| |
| | |
| | |
| ------------------------------------------------------------
| |
| -- RESOLUTION
| |
| ------------------------------------------------------------
| |
| | |
| local function renderResolution(parent, entry)
| |
| local resolvedBy = trim(entry.resolvedby)
| |
| local resolvedDate = trim(entry.resolveddate)
| |
| | |
| if resolvedBy == '' and resolvedDate == '' then
| |
| return
| |
| end
| |
| | |
| local resolution =
| |
| parent:tag('div')
| |
| :addClass('feedback-resolution')
| |
| | |
| resolution:wikitext('Resolved by ')
| |
| | |
| if resolvedBy ~= '' then
| |
| resolution:wikitext(
| |
| formatUser(resolvedBy)
| |
| )
| |
| else
| |
| resolution:wikitext('Unknown')
| |
| end
| |
| | |
| if resolvedDate ~= '' then
| |
| resolution:wikitext(
| |
| ' on ' .. mw.text.nowiki(resolvedDate)
| |
| )
| |
| end
| |
| end
| |
| | |
| | |
| ------------------------------------------------------------
| |
| -- RESOLVE CONTROL
| |
| ------------------------------------------------------------ | | ------------------------------------------------------------ |
|
| |
|
| Line 216: |
Line 6: |
| parent, | | parent, |
| id, | | id, |
| page, | | compact, |
| compact | | page |
| ) | | ) |
| if trim(id) == '' then | | |
| | if not id or id == '' then |
| return | | return |
| end | | end |
|
| |
| local wrapper =
| |
| parent:tag('div')
| |
| :addClass('feedback-resolve')
| |
|
| |
|
| local control = | | local control = |
| wrapper:tag('span') | | parent:tag('span') |
| :addClass('feedback-resolve-button') | | :addClass('feedback-resolve-button') |
| :attr( | | :attr( |
| 'data-feedback-id', | | 'data-feedback-id', |
| id | | id |
| )
| |
| :attr(
| |
| 'data-feedback-page',
| |
| page or ''
| |
| )
| |
| :attr(
| |
| 'role',
| |
| 'button'
| |
| )
| |
| :attr(
| |
| 'tabindex',
| |
| '0'
| |
| )
| |
| :attr(
| |
| 'aria-label',
| |
| 'Resolve feedback'
| |
| ) | | ) |
|
| |
|
| if compact then | | if page and page ~= '' then |
| control
| | control:attr( |
| :addClass(
| | 'data-feedback-page', |
| 'feedback-resolve-button--compact'
| | page |
| )
| |
| :attr(
| |
| 'title',
| |
| 'Resolve feedback'
| |
| )
| |
| :wikitext('✓')
| |
| else
| |
| control:wikitext('Resolve')
| |
| end
| |
| end
| |
| | |
| | |
| ------------------------------------------------------------
| |
| -- FULL FEEDBACK CARD
| |
| ------------------------------------------------------------
| |
| | |
| local function renderFullCard(entry)
| |
| local resolved =
| |
| trim(entry.status):lower() == 'resolved'
| |
| | |
| local id = trim(entry.id)
| |
| local page = trim(entry.page)
| |
| local feedback = trim(entry.feedback)
| |
| local user = trim(entry.user)
| |
| local createddate = trim(entry.createddate)
| |
| | |
| local root =
| |
| mw.html.create('div')
| |
| :addClass('feedback-box')
| |
| :addClass(
| |
| resolved
| |
| and 'feedback-box--resolved'
| |
| or 'feedback-box--unresolved'
| |
| )
| |
| | |
| if id ~= '' then
| |
| root:attr( | |
| 'data-feedback-id', | |
| id | |
| ) | | ) |
| end | | end |
|
| |
|
| -------------------------------------------------------- | | if compact then |
| -- Main content column
| |
| --------------------------------------------------------
| |
|
| |
|
| local content =
| | control |
| root:tag('div') | | :addClass('feedback-resolve-button--compact') |
| :addClass('feedback-content') | | :attr('aria-label', 'Resolve feedback') |
| | | :attr('title', 'Resolve feedback') |
| --------------------------------------------------------
| | :wikitext('✓') |
| -- Main line
| |
| --------------------------------------------------------
| |
| | |
| local main =
| |
| content:tag('div')
| |
| :addClass('feedback-main-line') | |
| | |
| --------------------------------------------------------
| |
| -- Status
| |
| --------------------------------------------------------
| |
| | |
| main:tag('span')
| |
| :addClass('feedback-status')
| |
| :addClass(
| |
| resolved
| |
| and 'feedback-status--resolved'
| |
| or 'feedback-status--unresolved'
| |
| )
| |
| :wikitext(
| |
| resolved
| |
| and 'Resolved'
| |
| or 'Unresolved'
| |
| )
| |
| | |
| --------------------------------------------------------
| |
| -- Feedback text
| |
| --------------------------------------------------------
| |
| | |
| main:tag('span')
| |
| :addClass('feedback-text')
| |
| :wikitext(
| |
| feedback ~= ''
| |
| and feedback
| |
| or 'No feedback provided'
| |
| )
| |
| | |
| --------------------------------------------------------
| |
| -- Metadata
| |
| --------------------------------------------------------
| |
| | |
| local meta =
| |
| main:tag('span')
| |
| :addClass('feedback-inline-meta')
| |
| | |
| if user ~= '' then
| |
| meta:wikitext(
| |
| ' · ' .. formatUser(user) | |
| )
| |
| end
| |
| | |
| if createddate ~= '' then
| |
| meta:wikitext(
| |
| ' · ' .. mw.text.nowiki(createddate)
| |
| )
| |
| end
| |
| | |
| --------------------------------------------------------
| |
| -- Attachments
| |
| --------------------------------------------------------
| |
|
| |
| content:node(
| |
| renderAttachments(entry)
| |
| )
| |
| | |
| --------------------------------------------------------
| |
| -- Resolution information
| |
| --------------------------------------------------------
| |
| | |
| renderResolution(
| |
| content,
| |
| entry
| |
| )
| |
| | |
| --------------------------------------------------------
| |
| -- Missing ID warning
| |
| --------------------------------------------------------
| |
| | |
| if id == '' then
| |
| content:tag('div')
| |
| :addClass('feedback-missing-id')
| |
| :wikitext( | |
| 'This feedback entry is missing an ID.'
| |
| )
| |
| end
| |
| | |
| --------------------------------------------------------
| |
| -- Resolve button
| |
| --
| |
| -- IMPORTANT:
| |
| -- This is outside .feedback-content so it
| |
| -- remains on the right.
| |
| --------------------------------------------------------
| |
| | |
| if not resolved then
| |
| renderResolveControl(
| |
| root,
| |
| id,
| |
| page,
| |
| false
| |
| )
| |
| end
| |
| | |
| return tostring(root)
| |
| end
| |
|
| |
|
|
| |
| ------------------------------------------------------------
| |
| -- COMPACT CARD
| |
| ------------------------------------------------------------
| |
|
| |
| local function renderCompactCard(entry)
| |
| return renderFullCard(entry)
| |
| end
| |
|
| |
|
| |
| ------------------------------------------------------------
| |
| -- SAVE FEEDBACK
| |
| ------------------------------------------------------------
| |
|
| |
| local function saveFeedback(data)
| |
| local bucket = getBucket()
| |
|
| |
| if not bucket then
| |
| return false, 'Bucket extension is not available'
| |
| end
| |
|
| |
| local success, err = pcall(function()
| |
| bucket.put({
| |
| page = data.page,
| |
| user = data.user,
| |
| status = data.status,
| |
| feedback = data.feedback,
| |
| id = data.id,
| |
| createddate = data.createddate,
| |
| link = data.link,
| |
| image = data.image,
| |
| resolvedby = data.resolvedby,
| |
| resolveddate = data.resolveddate
| |
| })
| |
| end)
| |
|
| |
| if not success then
| |
| return false, tostring(err)
| |
| end
| |
|
| |
| return true
| |
| end
| |
|
| |
|
| |
| ------------------------------------------------------------
| |
| -- MAIN
| |
| --
| |
| -- Used by Template:Feedback
| |
| ------------------------------------------------------------
| |
|
| |
| function p.main(frame)
| |
| local parent = frame:getParent()
| |
|
| |
| local args =
| |
| parent and parent.args
| |
| or frame.args
| |
|
| |
| local pageTitle = nil
| |
|
| |
| if parent and parent.getTitle then
| |
| local title = parent:getTitle()
| |
|
| |
| if title
| |
| and title ~= ''
| |
| and not title:find('^Template:')
| |
| then
| |
| pageTitle = title
| |
| end
| |
| end
| |
|
| |
| return p._main(
| |
| args,
| |
| pageTitle
| |
| )
| |
| end
| |
|
| |
|
| |
| function p._main(args, pageTitle)
| |
| local feedback =
| |
| trim(args.feedback)
| |
|
| |
| if feedback == '' then
| |
| feedback = 'No feedback provided'
| |
| end
| |
|
| |
| local user =
| |
| trim(args.user)
| |
|
| |
| if user == '' then
| |
| user = 'Anonymous'
| |
| end
| |
|
| |
| local resolved =
| |
| isTruthy(args.resolved)
| |
|
| |
| local status =
| |
| resolved
| |
| and 'resolved'
| |
| or 'unresolved'
| |
|
| |
| local currentPage =
| |
| trim(pageTitle)
| |
|
| |
| if currentPage == '' then
| |
| currentPage =
| |
| mw.title.getCurrentTitle().fullText
| |
| end
| |
|
| |
| local id =
| |
| trim(args.id)
| |
|
| |
| local createddate =
| |
| trim(args.createddate)
| |
|
| |
| local link =
| |
| trim(args.link)
| |
|
| |
| local image =
| |
| trim(args.image)
| |
|
| |
| local resolvedby =
| |
| trim(args.resolvedby)
| |
|
| |
| local resolveddate =
| |
| trim(args.resolveddate)
| |
|
| |
| --------------------------------------------------------
| |
| -- Save to Bucket
| |
| --------------------------------------------------------
| |
|
| |
| local saved, saveError =
| |
| saveFeedback({
| |
| page = currentPage,
| |
| user = user,
| |
| status = status,
| |
| feedback = feedback,
| |
| id = id,
| |
| createddate = createddate,
| |
| link = link,
| |
| image = image,
| |
| resolvedby = resolvedby,
| |
| resolveddate = resolveddate
| |
| })
| |
|
| |
| if not saved then
| |
| return
| |
| '<strong style="color:red;">Feedback bucket error: '
| |
| .. mw.text.nowiki(
| |
| saveError or 'Unknown error'
| |
| )
| |
| .. '</strong>'
| |
| end
| |
|
| |
| --------------------------------------------------------
| |
| -- Render
| |
| --------------------------------------------------------
| |
|
| |
| local card =
| |
| renderFullCard({
| |
| page = currentPage,
| |
| user = user,
| |
| status = status,
| |
| feedback = feedback,
| |
| id = id,
| |
| createddate = createddate,
| |
| link = link,
| |
| image = image,
| |
| resolvedby = resolvedby,
| |
| resolveddate = resolveddate
| |
| })
| |
|
| |
| --------------------------------------------------------
| |
| -- Categories
| |
| --------------------------------------------------------
| |
|
| |
| local category
| |
|
| |
| if resolved then
| |
| category =
| |
| '[[Category:Resolved Feedback]]'
| |
| else | | else |
| category =
| |
| '[[Category:Unresolved Feedback]]'
| |
| end
| |
|
| |
|
| if id == '' then
| | control |
| category = | | :attr('role', 'button') |
| category ..
| | :attr('tabindex', '0') |
| '[[Category:Feedbacks Missing ID]]'
| | :attr('aria-label', 'Resolve feedback') |
| end
| | :wikitext('Resolve') |
| | |
| return card .. category
| |
| end
| |
| | |
| | |
| ------------------------------------------------------------
| |
| -- RENDER FEEDBACK LIST
| |
| ------------------------------------------------------------
| |
| | |
| local function renderFeedbackList(results)
| |
| if not results or #results == 0 then
| |
| return '<em>No feedback entries found.</em>'
| |
| end
| |
| | |
| local list = {}
| |
| | |
| for _, row in ipairs(results) do
| |
| table.insert(
| |
| list,
| |
| renderFullCard(row)
| |
| )
| |
| end
| |
| | |
| return table.concat(
| |
| list,
| |
| '\n'
| |
| )
| |
| end
| |
| | |
| | |
| ------------------------------------------------------------
| |
| -- PAGE FEEDBACK
| |
| ------------------------------------------------------------
| |
| | |
| function p.page(frame)
| |
| local page =
| |
| currentSubjectPage()
| |
| | |
| local entries =
| |
| queryFeedback(page)
| |
| | |
| local unresolved = {}
| |
| local resolved = {}
| |
| | |
| for _, entry in ipairs(entries) do
| |
| if trim(entry.status):lower()
| |
| == 'resolved'
| |
| then
| |
| table.insert(
| |
| resolved,
| |
| entry
| |
| )
| |
| else
| |
| table.insert(
| |
| unresolved,
| |
| entry
| |
| )
| |
| end
| |
| end
| |
| | |
| local root =
| |
| mw.html.create('section')
| |
| :attr( | |
| 'id',
| |
| 'feedback-section'
| |
| )
| |
| :addClass('feedback-page')
| |
| | |
| --------------------------------------------------------
| |
| -- Heading
| |
| --------------------------------------------------------
| |
| | |
| root:tag('h2')
| |
| :addClass('feedback-page-title')
| |
| :wikitext('Feedbacks')
| |
| | |
| --------------------------------------------------------
| |
| -- Filters
| |
| --------------------------------------------------------
| |
| | |
| local filters =
| |
| root:tag('div')
| |
| :addClass('feedback-filters')
| |
| | |
| local function addFilter(
| |
| label,
| |
| value,
| |
| active
| |
| )
| |
| return filters:tag('button')
| |
| :attr( | |
| 'type',
| |
| 'button'
| |
| )
| |
| :attr( | |
| 'data-feedback-filter',
| |
| value
| |
| )
| |
| :addClass('feedback-filter')
| |
| :addClass(
| |
| active
| |
| and 'feedback-filter--active'
| |
| or nil
| |
| )
| |
| :wikitext(label)
| |
| end
| |
| | |
| addFilter(
| |
| 'Unresolved',
| |
| 'unresolved',
| |
| true
| |
| )
| |
| | |
| addFilter(
| |
| 'Resolved',
| |
| 'resolved',
| |
| false
| |
| )
| |
| | |
| addFilter(
| |
| 'All',
| |
| 'all',
| |
| false
| |
| )
| |
| | |
| --------------------------------------------------------
| |
| -- Unresolved
| |
| --------------------------------------------------------
| |
| | |
| local unresolvedList =
| |
| root:tag('div')
| |
| :addClass(
| |
| 'feedback-page-list'
| |
| )
| |
| :addClass(
| |
| 'feedback-page-list--unresolved'
| |
| )
| |
| :addClass(
| |
| 'feedback-page-list--visible'
| |
| )
| |
| | |
| if #unresolved == 0 then
| |
| unresolvedList:tag('div')
| |
| :addClass('feedback-empty')
| |
| :wikitext(
| |
| 'No unresolved feedback.'
| |
| )
| |
| else
| |
| for _, entry in ipairs(unresolved) do
| |
| unresolvedList:wikitext(
| |
| renderCompactCard(entry)
| |
| )
| |
| end
| |
| end
| |
| | |
| --------------------------------------------------------
| |
| -- Resolved
| |
| --------------------------------------------------------
| |
| | |
| local resolvedList =
| |
| root:tag('div')
| |
| :addClass(
| |
| 'feedback-page-list'
| |
| )
| |
| :addClass(
| |
| 'feedback-page-list--resolved'
| |
| )
| |
| | |
| if #resolved == 0 then
| |
| resolvedList:tag('div')
| |
| :addClass('feedback-empty')
| |
| :wikitext(
| |
| 'No resolved feedback.'
| |
| )
| |
| else
| |
| for _, entry in ipairs(resolved) do
| |
| resolvedList:wikitext(
| |
| renderCompactCard(entry)
| |
| )
| |
| end
| |
| end
| |
| | |
| --------------------------------------------------------
| |
| -- All
| |
| --------------------------------------------------------
| |
| | |
| local allList =
| |
| root:tag('div')
| |
| :addClass(
| |
| 'feedback-page-list'
| |
| )
| |
| :addClass(
| |
| 'feedback-page-list--all'
| |
| )
| |
| | |
| if #entries == 0 then
| |
| allList:tag('div')
| |
| :addClass('feedback-empty')
| |
| :wikitext( | |
| 'No feedback.'
| |
| )
| |
| else
| |
| for _, entry in ipairs(entries) do
| |
| allList:wikitext(
| |
| renderCompactCard(entry)
| |
| )
| |
| end
| |
| end
| |
| | |
| return tostring(root)
| |
| end
| |
| | |
| | |
| ------------------------------------------------------------
| |
| -- COUNTS
| |
| ------------------------------------------------------------
| |
| | |
| function p.counts(frame)
| |
| local entries =
| |
| queryFeedback(
| |
| currentSubjectPage()
| |
| )
| |
| | |
| local unresolved = 0
| |
| local resolved = 0
| |
| | |
| for _, entry in ipairs(entries) do
| |
| if trim(entry.status):lower()
| |
| == 'resolved'
| |
| then
| |
| resolved = resolved + 1
| |
| else
| |
| unresolved = unresolved + 1
| |
| end
| |
| end
| |
| | |
| return tostring(
| |
| mw.html.create('span')
| |
| :addClass('feedback-count-data')
| |
| :attr(
| |
| 'data-unresolved',
| |
| unresolved
| |
| )
| |
| :attr(
| |
| 'data-resolved',
| |
| resolved
| |
| )
| |
| )
| |
| end
| |
| | |
| | |
| ------------------------------------------------------------
| |
| -- TABLE / DASHBOARD
| |
| ------------------------------------------------------------
| |
| | |
| local function renderTable(entries)
| |
| if not entries or #entries == 0 then
| |
| return '<em>No feedback entries found.</em>'
| |
| end
| |
| | |
| local table =
| |
| mw.html.create('table')
| |
| :addClass('feedback-table')
| |
| | |
| local head =
| |
| table:tag('thead')
| |
| :tag('tr')
| |
| | |
| head:tag('th')
| |
| :wikitext('Status')
| |
| | |
| head:tag('th')
| |
| :wikitext('Page')
| |
| | |
| head:tag('th')
| |
| :wikitext('Feedback')
| |
| | |
| head:tag('th')
| |
| :wikitext('User')
| |
| | |
| head:tag('th')
| |
| :wikitext('Date')
| |
| | |
| local body =
| |
| table:tag('tbody')
| |
| | |
| for _, entry in ipairs(entries) do
| |
| local row =
| |
| body:tag('tr')
| |
| | |
| local resolved =
| |
| trim(entry.status):lower()
| |
| == 'resolved'
| |
| | |
| row:tag('td')
| |
| :addClass(
| |
| resolved
| |
| and 'feedback-table-status--resolved'
| |
| or 'feedback-table-status--unresolved'
| |
| )
| |
| :wikitext(
| |
| resolved
| |
| and 'Resolved'
| |
| or 'Unresolved'
| |
| )
| |
| | |
| row:tag('td')
| |
| :addClass('feedback-table-page')
| |
| :wikitext(
| |
| entry.page or ''
| |
| )
| |
| | |
| row:tag('td')
| |
| :addClass('feedback-table-text')
| |
| :wikitext(
| |
| entry.feedback or ''
| |
| )
| |
| | |
| row:tag('td')
| |
| :wikitext(
| |
| formatUser(entry.user)
| |
| )
| |
|
| |
|
| row:tag('td')
| |
| :wikitext(
| |
| entry.createddate or ''
| |
| )
| |
| end | | end |
|
| |
| return tostring(table)
| |
| end | | end |
|
| |
|
| |
| function p.view(frame)
| |
| 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)
| |
| local bucket =
| |
| getBucket()
| |
|
| |
| if not bucket then
| |
| return
| |
| '<em>Bucket extension is not available.</em>'
| |
| end
| |
|
| |
| local rawStatus =
| |
| args.status
| |
| or args[1]
| |
|
| |
| local filterStatus =
| |
| rawStatus
| |
| and trim(rawStatus):lower()
| |
| or nil
| |
|
| |
| --------------------------------------------------------
| |
| -- Query
| |
| --------------------------------------------------------
| |
|
| |
| local query =
| |
| bucket
| |
|
| |
| query.select(
| |
| 'page',
| |
| 'user',
| |
| 'status',
| |
| 'feedback',
| |
| 'id',
| |
| 'createddate',
| |
| 'link',
| |
| 'image',
| |
| 'resolvedby',
| |
| 'resolveddate'
| |
| )
| |
|
| |
| if filterStatus == 'resolved'
| |
| or filterStatus == 'unresolved'
| |
| then
| |
| query.where(
| |
| 'status',
| |
| filterStatus
| |
| )
| |
| end
| |
|
| |
| local success, entries =
| |
| pcall(function()
| |
| return query.run()
| |
| end)
| |
|
| |
| if not success or not entries then
| |
| return
| |
| '<em>Could not load feedback.</em>'
| |
| end
| |
|
| |
| entries =
| |
| sortNewestFirst(entries)
| |
|
| |
| --------------------------------------------------------
| |
| -- Specific status
| |
| --------------------------------------------------------
| |
|
| |
| if filterStatus == 'resolved'
| |
| or filterStatus == 'unresolved'
| |
| then
| |
| return renderFeedbackList(
| |
| entries
| |
| )
| |
| end
| |
|
| |
| --------------------------------------------------------
| |
| -- All
| |
| --------------------------------------------------------
| |
|
| |
| return renderTable(entries)
| |
| end
| |
|
| |
|
| |
| p.table = p.view
| |
|
| |
| return p
| |