Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Event datatable

From Sekaipedia
Revision as of 05:50, 24 April 2023 by ChaoticShadow (talk | contribs)

Documentation for this module may be created at Module:Event datatable/doc

local getArgs          = require('Module:Arguments').getArgs
local AskBuilder       = require('Module:AskBuilder')
local DatatableBuilder = require('Module:DatatableBuilder')
local QueryBuilder     = require('Module:QueryBuilder')

local DisplayFns    = require('Module:DisplayFunctions')
local ProcessingFns = require('Module:ProcessingFunctions')

local aicon = require('Module:Attribute icon')._main
local cicon = require('Module:Character icon')._main
local uicon = require('Module:Unit icon')._main

local VariablesLua = mw.ext.VariablesLua

local p = {}


local function formatLogo(logo)
	if logo then
		return string.format('[[File:%s|150px]]', logo)
	end
	
	return nil
end

local function formatName(pageName, eventName)
	return string.format('[[%s|%s]]', pageName, eventName)
end

local function formatUnit(unit)
	if unit and unit ~= 'Mixed' then
		return string.format(
			'%s %s',
			uicon({ unit, size = '25px' }),
			unit
		)
	end
	
	return unit
end

local function formatCharacters(characters)
	local characters = ProcessingFns.stringToArray(';')(characters)
	local icon_tbl = {}

	for _,x in ipairs(characters) do
		local _icon = cicon({ mw.text.trim(x), size = '40px' })
		if _icon then
			table.insert(icon_tbl, _icon)
		end
	end
	
	local wrapper = mw.html.create('div')
	wrapper
		:css({
			['display'] = 'flex',
			['flex-wrap'] = 'wrap',
			['gap'] = '5px'
		})
		:wikitext(table.concat(icon_tbl, ''))
	
	return tostring(wrapper)
end

local function formatAttribute(attribute)
	if attribute then
		return string.format(
			'%s %s',
			aicon({ attribute, size = '25px' }),
			attribute
		)
	end
end

local function columnToProperty(column)
	local map = {
		['id'] = 'Event ID',
		['unit'] = 'Unit focus',
		['start'] = 'Start date',
		['end'] = 'End date',
		['attribute'] = 'Bonus attribute',
		['characters'] = 'Bonus character',
		['type'] = 'Event type'
	}
	
	return map[column]
end

local function isColumn(arg)
	local columns = {
		'__page',
		'id',
		'unit',
		'start',
		'end',
		'attribute',
		'characters',
		'type'
	}
	
	for _,column in ipairs(columns) do
		if column == arg then
			return true
		end	
	end
	
	return false
end


function p.main(frame)
	local args = getArgs(frame)
	
	local qb = QueryBuilder.new()
	qb
		:setTables('events')
		:setFields([[
			event_id,
			_pageName,
			image,
			event_name,
			DATE_FORMAT(DATE_ADD(start, INTERVAL 9 HOUR), "%Y/%m/%d, %H:%i JST") = start,
			DATE_FORMAT(DATE_ADD(end, INTERVAL 9 HOUR), "%Y/%m/%d, %H:%i JST") =  end,
			unit_focus,
			type,
			characters,
			attribute
		]])
		:addWhere('event_id', '>', 0)
		:setOrderBy('event_id ASC')
		:setGroupBy('_pageID')
        :setLimit(200)
	qb
		:addWhere('type', '=', args['type'])
		:addWhereList(
			'unit_focus',
			'=',
			args['units'],
			';',
			'OR'
		)
		:addWhere('start', '<', args['start before'])
		:addWhere('start', '>', args['start after'])
		:addWhere('end', '<', args['end before'])
		:addWhere('end', '>', args['end after'])
	
	local datatable = DatatableBuilder.new()
	datatable
		:setColumns{
			{
				name = 'id',
				header = 'ID',
				dataFields = { 'event_id' }
			},
			{
				name = 'logo',
				header = 'Logo',
				dataFields = { 'image' },
				func = formatLogo,
				sortable = false
			},
			{
				name = 'name',
				header = 'Event',
				dataFields = { '_pageName', 'event_name' },
				func = formatName,
				css = { ['min-width'] = '150px' },
			},
			{
				name = 'unit',
				header = 'Unit focus',
				dataFields = { 'unit_focus' },
				func = formatUnit,
				css = { ['min-width'] = '200px' },
			},
			{
				name = 'start',
				header = 'Start date',
				dataFields = { 'start' }
			},
			{
				name = 'end',
				header = 'End date',
				dataFields = { 'end' }
			},
			{
				name = 'characters',
				header = 'Bonus characters',
				dataFields = { 'characters' },
				func = formatCharacters,
				css = { ['min-width'] = '150px' },
			},
			{
				name = 'attribute',
				header = 'Bonus attribute',
				dataFields = { 'attribute' },
				func = formatAttribute,
				css = { ['min-width'] = '150px' },
			},
			{
				name = 'type',
				header = 'Type',
				dataFields = { 'type' }
			},
		}
		:setData({})
	
	return datatable:tostring() .. 
	'<p>Data table has been disabled, see our [https://blog.sekaipedia.org/2023/04/unexpected-disruption-due-to-extension.html first] and [https://blog.sekaipedia.org/2023/04/acknowledgements-on-continued-wiki.html second] blog posts for more details.</p>'
	..
	'<p>Consider using [[:Category:Events]] instead.</p>'
end


local function defineDatatable(columns)
	local datatable = DatatableBuilder.new()
	datatable
		:setColumns{
			{
				name = 'id',
				header = 'ID',
				dataFields = { 'id' }
			},
			{
				name = 'logo',
				header = 'Logo',
				dataFields = { 'logo' },
				func = formatLogo,
				sortable = false
			},
			{
				name = '__page',
				header = 'Event',
				dataFields = { '__page', 'event name' },
				func = formatName,
				css = { ['min-width'] = '150px' },
			},
			{
				name = 'unit',
				header = 'Unit focus',
				dataFields = { 'unit' },
				func = formatUnit,
				css = { ['min-width'] = '200px' },
			},
			{
				name = 'start',
				header = 'Start date',
				dataFields = { 'start' }
			},
			{
				name = 'end',
				header = 'End date',
				dataFields = { 'end' }
			},
			{
				name = 'characters',
				header = 'Bonus characters',
				dataFields = { 'characters' },
				func = formatCharacters,
				css = { ['min-width'] = '150px' },
			},
			{
				name = 'attribute',
				header = 'Bonus attribute',
				dataFields = { 'attribute' },
				func = formatAttribute,
				css = { ['min-width'] = '150px' },
			},
			{
				name = 'type',
				header = 'Type',
				dataFields = { 'type' }
			},
		}
		
	if columns and #columns > 0 then
		for _, column in ipairs(columns) do
			datatable:setColumnVisibility(column, true)
		end
	end
	
	return datatable
end

function p.header(frame)
	local args = getArgs(frame)
	
	local columns = args['columns']
	
	columns = ProcessingFns.stringToArray(',')(columns)
	
	local actualColumns = {}
	for _,column in ipairs(columns) do
		if isColumn(column) then
			table.insert(actualColumns, column)
		end
	end
	
	local datatable = defineDatatable(actualColumns, true)
	
	VariablesLua.vardefine('event datatable columns', table.concat(actualColumns, ','))
	
	return tostring(datatable:renderHeader())
end

function p.row(frame)
	local args = getArgs(frame)
	
	local actualColumns = {}
	local columns = VariablesLua.var('event datatable columns')
	
	if columns then
		columns = ProcessingFns.stringToArray(',')(columns)
		for _,column in ipairs(columns) do
			if isColumn(column) then
				table.insert(actualColumns, column)
			end
		end
	end
	
	if #actualColumns == 0 then
		for column,_ in pairs(args) do
			if isColumn(column) then
				table.insert(actualColumns, column)
			end
		end
	end
	
	local datatable = defineDatatable(actualColumns, true)
	return tostring(datatable:renderRow(args))
end

function p.smw(frame)
	local args = getArgs(frame)
	local columns = args['columns']
	
	local ab = AskBuilder.new()
	ab
		:setCategory('Events')
		:setProperties(columns)
		:addWhere('Event ID', '>', 0)
		:setOrderBy('Event ID ASC')
		:setLimit(args['limit'] or 700)
		:setOffset(args['offset'])
	ab
		:addWhere('Event type', '=', args['type'])
		:addWhereList(
			'Unit focus',
			'=',
			args['units'],
			';',
			'OR'
		)
		:addWhere('Start date', '<', args['start before'])
		:addWhere('Start date', '>', args['start after'])
		:addWhere('End date', '<', args['end before'])
		:addWhere('End date', '>', args['end after'])
	
	return ab:ask(frame)
end

return p
Cookies help us deliver our services. By using our services, you agree to our use of cookies.