diff --git a/lua/wikis/commons/ResultsTable.lua b/lua/wikis/commons/ResultsTable.lua index c02be12758e..fb026fdd09a 100644 --- a/lua/wikis/commons/ResultsTable.lua +++ b/lua/wikis/commons/ResultsTable.lua @@ -7,122 +7,154 @@ local Lua = require('Module:Lua') -local Abbreviation = Lua.import('Module:Abbreviation') +local BaseResultsTable = Lua.import('Module:ResultsTable/Base') local Class = Lua.import('Module:Class') -local Currency = Lua.import('Module:Currency') -local DateExt = Lua.import('Module:Date/Ext') +local FnUtil = Lua.import('Module:FnUtil') local Game = Lua.import('Module:Game') -local LeagueIcon = Lua.import('Module:LeagueIcon') -local Page = Lua.import('Module:Page') +local Opponent = Lua.import('Module:Opponent/Custom') local Placement = Lua.import('Module:Placement') local Table = Lua.import('Module:Table') -local BaseResultsTable = Lua.import('Module:ResultsTable/Base') - -local Opponent = Lua.import('Module:Opponent/Custom') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') +local TableWidgets = Lua.import('Module:Widget/Table2/All') +local WidgetUtil = Lua.import('Module:Widget/Util') ---@class ResultsTable: BaseResultsTable ---@operator call(table): ResultsTable local ResultsTable = Class.new(BaseResultsTable) +---@protected +---@return table[] +function ResultsTable:buildColumnDefinitions() + return WidgetUtil.collect( + { + align = 'left', + sortType = 'isoDate', + }, + {align = 'center'}, + {align = 'left'}, + self.config.showType and {align = 'center'} or nil, + self.config.displayGameIcons and {align = 'center'} or nil, + {align = 'left'}, + {align = 'left'}, + (self.config.queryType ~= Opponent.team or Table.isNotEmpty(self.config.aliases)) and { + align = 'center', + } or self.config.playerResultsOfTeam and { + align = 'center', + } or nil, + not self.config.hideResult and { + { + align = 'center', + unsortable = true, + }, + { + align = 'center', + unsortable = true, + }, + } or nil, + { + align = 'right', + sortType = 'currency', + } + ) +end + ---Builds the Header of the results/achievements table ----@return Html +---@return Widget function ResultsTable:buildHeader() - local header = mw.html.create('tr') - :tag('th'):css('width', '100px'):wikitext('Date'):done() - :tag('th'):css('min-width', '80px'):wikitext('Place'):done() - :tag('th'):css('min-width', '75px'):wikitext('Tier'):done() - - if self.config.showType then - header:tag('th'):css('min-width', '50px'):wikitext('Type') - end - - if self.config.displayGameIcons then - header:tag('th'):node(Abbreviation.make{text = 'G.', title = 'Game'}) - end - - header:tag('th'):css('width', '420px'):attr('colspan', 2):wikitext('Tournament') - - if self.config.queryType ~= Opponent.team or Table.isNotEmpty(self.config.aliases) then - header:tag('th'):css('min-width', '70px'):wikitext('Team') - elseif self.config.playerResultsOfTeam then - header:tag('th'):css('min-width', '105px'):wikitext('Player') - end - - if not self.config.hideResult then - header:tag('th'):css('min-width', '105px'):attr('colspan', 2):addClass('unsortable'):wikitext('Result') - end - - header:tag('th'):attr('data-sort-type', 'currency'):wikitext('Prize') - - return header + return TableWidgets.Row{children = WidgetUtil.collect( + TableWidgets.CellHeader{children = 'Date'}, + TableWidgets.CellHeader{children = 'Place'}, + TableWidgets.CellHeader{children = 'Tier'}, + self.config.showType and TableWidgets.CellHeader{children = 'Type'} or nil, + self.config.displayGameIcons and TableWidgets.CellHeader{ + children = HtmlWidgets.Abbreviation{children = 'G.', title = 'Game'} + } or nil, + TableWidgets.CellHeader{ + colspan = 2, + children = 'Tournament' + }, + (self.config.queryType ~= Opponent.team or Table.isNotEmpty(self.config.aliases)) and TableWidgets.CellHeader{ + children = 'Team' + } or self.config.playerResultsOfTeam and TableWidgets.CellHeader{ + children = 'Player' + } or nil, + not self.config.hideResult and TableWidgets.CellHeader{ + align = 'left', + colspan = 2, + children = 'Result' + } or nil, + TableWidgets.CellHeader{children = 'Prize'} + )} end ---Builds a placement row of the results/achievements table ----@param placement table +---@param placement placement ---@return Html function ResultsTable:buildRow(placement) - local placementCell = mw.html.create('td') - Placement._placement{parent = placementCell, placement = placement.placement} - - local row = mw.html.create('tr') - :addClass(self:rowHighlight(placement)) - :tag('td'):wikitext(DateExt.toYmdInUtc(placement.date)):done() - :node(placementCell) - - local tierDisplay, tierSortValue = self:tierDisplay(placement) - - row:tag('td'):attr('data-sort-value', tierSortValue):wikitext(tierDisplay) - - if self.config.showType then - row:tag('td'):wikitext(placement.type) - end - - if self.config.displayGameIcons then - row:tag('td'):node(Game.icon{game = placement.game}) - end - - local tournamentDisplayName = BaseResultsTable.tournamentDisplayName(placement) - - row - :tag('td'):css('width', '30px'):attr('data-sort-value', tournamentDisplayName):wikitext(LeagueIcon.display{ - icon = placement.icon, - iconDark = placement.icondark, - link = placement.parent, - name = tournamentDisplayName, - options = {noTemplate = true}, - }):done() - :tag('td'):attr('data-sort-value', tournamentDisplayName):css('text-align', 'left'):wikitext(Page.makeInternalLink( - {}, - tournamentDisplayName, - placement.pagename - )) - - if self.config.playerResultsOfTeam or - self.config.queryType ~= Opponent.team or - Table.isNotEmpty(self.config.aliases) then - - row:tag('td'):css('text-align', self.config.hideResult and 'left' or 'right') - :attr('data-sort-value', placement.opponentname) - :node(self:opponentDisplay(placement, - {teamForSolo = not self.config.playerResultsOfTeam, flip = not self.config.hideResult} - )) - end + return TableWidgets.Row{ + highlighted = self:rowHighlight(placement), + children = WidgetUtil.collect( + self:createDateCell(placement), + ResultsTable._placementToTableCell(placement.placement), + self:createTierCell(placement), + self:createTypeCell(placement), + self.config.displayGameIcons and TableWidgets.Cell{ + children = Game.icon{game = placement.game} + } or nil, + self:createTournamentCells(placement), + ( + self.config.playerResultsOfTeam or + self.config.queryType ~= Opponent.team or + Table.isNotEmpty(self.config.aliases) + ) and TableWidgets.Cell{ + align = self.config.hideResult and 'left' or 'right', + attributes = { + ['data-sort-value'] = placement.opponentname + }, + children = self:opponentDisplay( + placement, + {teamForSolo = not self.config.playerResultsOfTeam, flip = not self.config.hideResult} + ) + } or nil, + self:_buildResultCells(placement), + self:createPrizeCell{ + useIndivPrize = self.config.useIndivPrize and self.config.queryType ~= Opponent.team, + placement = placement + } + ) + } +end - if not self.config.hideResult then - local score, vsDisplay, groupAbbr = self:processVsData(placement) - row - :tag('td'):wikitext(score):done() - :tag('td'):css('text-align', 'left'):cssText(groupAbbr and 'padding-left:14px' or nil):node(vsDisplay or groupAbbr) +---@private +---@param placement string +---@return Widget +ResultsTable._placementToTableCell = FnUtil.memoize(function (placement) + local rawPlacement = Placement.raw(placement or '') + return TableWidgets.Cell{ + attributes = { + ['data-sort-value'] = rawPlacement.sort + }, + children = Placement.renderInWidget{placement = placement} + } +end) + +---@private +---@param placement placement +---@return Widget[]? +function ResultsTable:_buildResultCells(placement) + if self.config.hideResult then + return end - - local useIndivPrize = self.config.useIndivPrize and self.config.queryType ~= Opponent.team - row:tag('td'):wikitext(Currency.display('USD', - useIndivPrize and placement.individualprizemoney or placement.prizemoney, - {dashIfZero = true, displayCurrencyCode = false, formatValue = true} - )) - - return row + local score, vsDisplay, groupAbbr = self:processVsData(placement) + return { + TableWidgets.Cell{children = score}, + TableWidgets.Cell{ + align = 'left', + css = {padding = groupAbbr and '14px' or nil}, + children = vsDisplay or groupAbbr + } + } end return ResultsTable diff --git a/lua/wikis/commons/ResultsTable/Award.lua b/lua/wikis/commons/ResultsTable/Award.lua index 7a04c82f162..0fef02e38f7 100644 --- a/lua/wikis/commons/ResultsTable/Award.lua +++ b/lua/wikis/commons/ResultsTable/Award.lua @@ -7,93 +7,89 @@ local Lua = require('Module:Lua') +local BaseResultsTable = Lua.import('Module:ResultsTable/Base') local Class = Lua.import('Module:Class') -local Currency = Lua.import('Module:Currency') -local DateExt = Lua.import('Module:Date/Ext') -local LeagueIcon = Lua.import('Module:LeagueIcon') -local Page = Lua.import('Module:Page') - local Opponent = Lua.import('Module:Opponent/Custom') -local BaseResultsTable = Lua.import('Module:ResultsTable/Base') +local TableWidgets = Lua.import('Module:Widget/Table2/All') +local WidgetUtil = Lua.import('Module:Widget/Util') ---@class AwardsTable: BaseResultsTable ---@operator call(table): AwardsTable local AwardsTable = Class.new(BaseResultsTable) +---@protected +---@return table[] +function AwardsTable:buildColumnDefinitions() + return WidgetUtil.collect( + { + align = 'left', + sortType = 'isoDate', + }, + {align = 'left'}, + self.config.showType and { + align = 'center', + } or nil, + {align = 'left'}, + {align = 'left'}, + {align = 'left'}, + self.config.queryType ~= Opponent.team and { + align = 'center', + } or self.config.playerResultsOfTeam and { + align = 'center', + } or nil, + { + align = 'right', + sortType = 'currency', + } + ) +end + ---Builds the Header of the award table ----@return Html +---@return Widget function AwardsTable:buildHeader() - local header = mw.html.create('tr') - :tag('th'):css('width', '100px'):wikitext('Date'):done() - :tag('th'):css('min-width', '75px'):wikitext('Tier'):done() - - if self.config.showType then - header:tag('th'):css('min-width', '50px'):wikitext('Type') - end - - header - :tag('th'):css('width', '275px'):attr('colspan', 2):wikitext('Tournament'):done() - :tag('th'):css('min-width', '225px'):wikitext('Award') - - if self.config.queryType ~= Opponent.team then - header:tag('th'):css('min-width', '70px'):wikitext('Team') - elseif self.config.playerResultsOfTeam then - header:tag('th'):css('min-width', '105px'):wikitext('Player') - end - - header:tag('th'):attr('data-sort-type', 'currency'):wikitext('Prize') - - return header + return TableWidgets.Row{children = WidgetUtil.collect( + TableWidgets.CellHeader{children = 'Date'}, + TableWidgets.CellHeader{children = 'Tier'}, + self.config.showType and TableWidgets.CellHeader{children = 'Type'} or nil, + TableWidgets.CellHeader{ + colspan = 2, + children = 'Tournament' + }, + TableWidgets.CellHeader{children = 'Award'}, + self.config.queryType ~= Opponent.team and TableWidgets.CellHeader{ + children = 'Team' + } or self.config.playerResultsOfTeam and TableWidgets.CellHeader{ + children = 'Player' + } or nil, + TableWidgets.CellHeader{children = 'Prize'} + )} end ---Builds a row of the award table ----@param placement table ----@return Html +---@param placement placement +---@return Widget function AwardsTable:buildRow(placement) - local row = mw.html.create('tr') - :addClass(self:rowHighlight(placement)) - :tag('td'):wikitext(DateExt.toYmdInUtc(placement.date)):done() - - local tierDisplay, tierSortValue = self:tierDisplay(placement) - - row:tag('td'):attr('data-sort-value', tierSortValue):wikitext(tierDisplay) - - if self.config.showType then - row:tag('td'):wikitext(placement.type) - end - - local tournamentDisplayName = BaseResultsTable.tournamentDisplayName(placement) - - row - :tag('td'):css('width', '30px'):attr('data-sort-value', tournamentDisplayName):wikitext(LeagueIcon.display{ - icon = placement.icon, - iconDark = placement.icondark, - link = placement.parent, - name = tournamentDisplayName, - options = {noTemplate = true}, - }):done() - :tag('td'):attr('data-sort-value', tournamentDisplayName):css('text-align', 'left'):wikitext(Page.makeInternalLink( - {}, - tournamentDisplayName, - placement.pagename - )) - - row:tag('td'):wikitext(placement.extradata.award) - - if self.config.playerResultsOfTeam or self.config.queryType ~= Opponent.team then - row:tag('td'):css('text-align', 'left'):attr('data-sort-value', placement.opponentname):node(self:opponentDisplay( - placement, - {teamForSolo = not self.config.playerResultsOfTeam} - )) - end - - row:tag('td'):wikitext(Currency.display('USD', - self.config.queryType ~= Opponent.team and placement.individualprizemoney or placement.prizemoney, - {dashIfZero = true, displayCurrencyCode = false, formatValue = true} - )) - - return row + return TableWidgets.Row{ + highlighted = self:rowHighlight(placement), + children = WidgetUtil.collect( + self:createDateCell(placement), + self:createTierCell(placement), + self:createTypeCell(placement), + self:createTournamentCells(placement), + TableWidgets.Cell{children = placement.extradata.award}, + (self.config.playerResultsOfTeam or self.config.queryType ~= Opponent.team) and TableWidgets.Cell{ + attributes = { + ['data-sort-value'] = placement.opponentname + }, + children = self:opponentDisplay( + placement, + {teamForSolo = not self.config.playerResultsOfTeam} + ) + } or nil, + self:createPrizeCell{placement = placement} + ) + } end return AwardsTable diff --git a/lua/wikis/commons/ResultsTable/Base.lua b/lua/wikis/commons/ResultsTable/Base.lua index 2ed49915e25..9a52f3d8c63 100644 --- a/lua/wikis/commons/ResultsTable/Base.lua +++ b/lua/wikis/commons/ResultsTable/Base.lua @@ -10,19 +10,21 @@ local Lua = require('Module:Lua') local Abbreviation = Lua.import('Module:Abbreviation') local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') +local Currency = Lua.import('Module:Currency') +local DateExt = Lua.import('Module:Date/Ext') local Game = Lua.import('Module:Game') local HighlightConditions = Lua.import('Module:HighlightConditions') local Info = Lua.import('Module:Info', {loadData = true}) +local LeagueIcon = Lua.import('Module:LeagueIcon') local Logic = Lua.import('Module:Logic') local Namespace = Lua.import('Module:Namespace') +local Opponent = Lua.import('Module:Opponent/Custom') +local OpponentDisplay = Lua.import('Module:OpponentDisplay/Custom') local String = Lua.import('Module:StringUtils') local Table = Lua.import('Module:Table') local TeamTemplate = Lua.import('Module:TeamTemplate') local Tier = Lua.import('Module:Tier/Custom') -local Opponent = Lua.import('Module:Opponent/Custom') -local OpponentDisplay = Lua.import('Module:OpponentDisplay/Custom') - local Condition = Lua.import('Module:Condition') local ConditionTree = Condition.Tree local ConditionNode = Condition.Node @@ -31,6 +33,11 @@ local BooleanOperator = Condition.BooleanOperator local ColumnName = Condition.ColumnName local ConditionUtil = Condition.Util +local HtmlWidgets = Lua.import('Module:Widget/Html/All') +local LinkWidget = Lua.import('Module:Widget/Basic/Link') +local TableWidgets = Lua.import('Module:Widget/Table2/All') +local WidgetUtil = Lua.import('Module:Widget/Util') + local DEFAULT_VALUES = { order = 'desc', resolveOpponent = true, @@ -47,7 +54,7 @@ local QUERY_TYPES = { team = 'team', coach = 'coach', } -local SCORE_CONCAT = ' : ' +local SCORE_CONCAT = ' : ' local DEFAULT_RESULTS_SUB_PAGE = 'Results' local INVALID_TIER_DISPLAY = 'Undefined' local INVALID_TIER_SORT = 'ZZ' @@ -212,30 +219,32 @@ function BaseResultsTable:buildBaseConditions() :add{self:buildOpponentConditions()} if args.game then - conditions:add{ConditionNode(ColumnName('game'), Comparator.eq, args.game)} + conditions:add(ConditionNode(ColumnName('game'), Comparator.eq, args.game)) end local startDate = args.startdate or args.sdate if startDate then -- intentional > here to keep it as is in current modules -- possibly change to >= later - conditions:add{ConditionNode(ColumnName('date'), Comparator.gt, startDate)} + conditions:add(ConditionNode(ColumnName('date'), Comparator.gt, startDate)) end local endDate = args.enddate or args.edate if endDate then -- intentional < here to keep it as is in current modules -- possibly change to <= later - conditions:add{ConditionNode(ColumnName('date'), Comparator.lt, endDate)} + conditions:add(ConditionNode(ColumnName('date'), Comparator.lt, endDate)) end if args.placement then - conditions:add{ConditionNode(ColumnName('placement'), Comparator.eq, args.placement)} + conditions:add(ConditionNode(ColumnName('placement'), Comparator.eq, args.placement)) elseif Logic.readBool(args.awards) then - conditions:add{ConditionNode(ColumnName('mode'), Comparator.eq, 'award_individual')} + conditions:add(ConditionNode(ColumnName('mode'), Comparator.eq, 'award_individual')) else - conditions:add{ConditionNode(ColumnName('mode'), Comparator.neq, 'award_individual')} - conditions:add{ConditionNode(ColumnName('placement'), Comparator.neq, '')} + conditions:add{ + ConditionNode(ColumnName('mode'), Comparator.neq, 'award_individual'), + ConditionNode(ColumnName('placement'), Comparator.neq, '') + } end if args.tier then @@ -248,7 +257,7 @@ function BaseResultsTable:buildBaseConditions() end ---Builds Lpdb conditions for the given opponent ----@return table? +---@return ConditionTree? function BaseResultsTable:buildOpponentConditions() local config = self.config @@ -261,14 +270,14 @@ end -- todo: adjust once #1802 is done ---Builds Lpdb conditions for the non team opponent case ----@return table +---@return ConditionTree function BaseResultsTable:buildNonTeamOpponentConditions() local config = self.config local opponentConditions = ConditionTree(BooleanOperator.any) local opponents = Array.append(config.aliases, config.opponent) - for _, opponent in pairs(opponents) do + Array.forEach(opponents, function (opponent) opponent = config.resolveOpponent and mw.ext.TeamLiquidIntegration.resolve_redirect(opponent) or opponent @@ -278,33 +287,28 @@ function BaseResultsTable:buildNonTeamOpponentConditions() local prefix if config.queryType == QUERY_TYPES.solo then prefix = PLAYER_PREFIX - opponentConditions:add{ - ConditionTree(BooleanOperator.all):add{ - ConditionNode(ColumnName('opponenttype'), Comparator.eq, Opponent.solo), - ConditionNode(ColumnName('opponentname'), Comparator.eq, opponent), - }, - ConditionTree(BooleanOperator.all):add{ - ConditionNode(ColumnName('opponenttype'), Comparator.eq, Opponent.solo), - ConditionNode(ColumnName('opponentname'), Comparator.eq, opponentWithUnderscore), - }, - } + opponentConditions:add(ConditionTree(BooleanOperator.all):add{ + ConditionNode(ColumnName('opponenttype'), Comparator.eq, Opponent.solo), + ConditionUtil.anyOf(ColumnName('opponentname'), {opponent, opponentWithUnderscore}) + }) else prefix = COACH_PREFIX end - for playerIndex = 1, config.playerLimit do + Array.forEach(Array.range(1, config.playerLimit), function (playerIndex) + local playerColumnName = ColumnName('opponentplayers_' .. prefix .. playerIndex) opponentConditions:add{ - ConditionNode(ColumnName('opponentplayers_' .. prefix .. playerIndex), Comparator.eq, opponent), - ConditionNode(ColumnName('opponentplayers_' .. prefix .. playerIndex), Comparator.eq, opponentWithUnderscore), + ConditionNode(playerColumnName, Comparator.eq, opponent), + ConditionNode(playerColumnName, Comparator.eq, opponentWithUnderscore), } - end - end + end) + end) return opponentConditions end ---Builds Lpdb conditions for a team ----@return table +---@return ConditionTree function BaseResultsTable:buildTeamOpponentConditions() local config = self.config @@ -345,13 +349,13 @@ function BaseResultsTable:buildPlayersOnTeamOpponentConditions(opponentTeamTempl local opponentConditions = ConditionTree(BooleanOperator.any) local prefix = PLAYER_PREFIX - for _, teamTemplate in pairs(opponentTeamTemplates) do + Array.forEach(opponentTeamTemplates, function (teamTemplate) for playerIndex = 1, config.playerLimit do opponentConditions:add{ ConditionNode(ColumnName('opponentplayers_' .. prefix .. playerIndex .. 'template'), Comparator.eq, teamTemplate), } end - end + end) return ConditionTree(BooleanOperator.all):add{ opponentConditions, @@ -359,53 +363,65 @@ function BaseResultsTable:buildPlayersOnTeamOpponentConditions(opponentTeamTempl } end +---@private +---@return boolean +function BaseResultsTable:_isDataEmpty() + return Table.isEmpty(self.data) or Table.isEmpty(self.data[1]) +end + ---Builds the results/achievements/awards table ----@return Html +---@return Widget function BaseResultsTable:build() - local displayTable = mw.html.create('table') - :addClass('wikitable wikitable-striped sortable') - :css('text-align', 'center') - :node(self:buildHeader()) - - if Table.isEmpty(self.data) or Table.isEmpty(self.data[1]) then - return displayTable:node(mw.html.create('tr') - :tag('td'):attr('colspan', 42):wikitext('No recorded results found.')) - end - - -- Hidden tr that contains a td to prevent the first yearHeader from being inside thead - displayTable:node(mw.html.create('tr'):css('display', 'none'):tag('td'):allDone()) - - for _, dataSet in ipairs(self.data) do - for _, row in ipairs(self:_buildRows(dataSet)) do - displayTable:node(row) - end - end - - if self.config.onlyAchievements then - displayTable:tag('tr') - :tag('th') - :attr('colspan', 42) - :css('font-style', 'italic') - :wikitext('[[' .. self.config.opponent .. '/' .. self.config.resultsSubPage .. '|Extended list of results]]') - end - - displayTable:node(self.args.manualContent) + return TableWidgets.Table{ + sortable = true, + columns = self:buildColumnDefinitions(), + children = WidgetUtil.collect( + TableWidgets.TableHeader{children = {self:buildHeader()}}, + -- Hidden tr that contains a td to prevent the first yearHeader from being inside thead + not self:_isDataEmpty() and HtmlWidgets.Tr{ + css = {display = 'none'}, + children = HtmlWidgets.Td{} + } or nil, + TableWidgets.TableBody{children = WidgetUtil.collect(self:_buildTableBody(), self.args.manualContent)} + ), + footer = self.config.onlyAchievements and LinkWidget{ + link = self.config.opponent .. '/' .. self.config.resultsSubPage, + children = 'Extended list of results', + } or nil + } +end - return mw.html.create('div') - :addClass('table-responsive') - :node(displayTable) +---@private +---@return Widget[] +function BaseResultsTable:_buildTableBody() + if self:_isDataEmpty() then + return {TableWidgets.Row{children = TableWidgets.Cell{ + colspan = 42, + children = 'No recorded results found.' + }}} + end + return Array.flatMap(self.data, function (dataSet) + return self:_buildRows(dataSet) + end) end ----comment +---@private ---@param placementData table ---@return Html[] function BaseResultsTable:_buildRows(placementData) local rows = {} if placementData.header then - table.insert(rows, mw.html.create('tr'):addClass('sortbottom') - :tag('th'):attr('colspan', 42):wikitext(placementData.header):done() - :done()) + table.insert(rows, TableWidgets.Row{ + section = 'subhead', + classes = {'sortbottom'}, + css = {['font-weight'] = 'bold'}, + children = TableWidgets.CellHeader{ + align = 'center', + colspan = 42, + children = placementData.header + } + }) end for _, placement in ipairs(placementData) do @@ -415,19 +431,17 @@ function BaseResultsTable:_buildRows(placementData) return rows end --- overwritable ---Applies the row highlight ----@param placement table ----@return string? +---@protected +---@param placement placement +---@return boolean function BaseResultsTable:rowHighlight(placement) - if HighlightConditions.tournament(placement, self.config) then - return 'tournament-highlighted-bg' - end + return HighlightConditions.tournament(placement, self.config) end --- overwritable ---Builds the tier display ----@param placement table +---@protected +---@param placement placement ---@return string?, string? function BaseResultsTable:tierDisplay(placement) local tier, tierType, options = Tier.parseFromQueryData(placement) @@ -441,16 +455,16 @@ function BaseResultsTable:tierDisplay(placement) return Tier.display(tier, tierType, options), Tier.toSortValue(tier, tierType) end --- overwritable ---Builds the opponent display ----@param data table +---@protected +---@param data placement ---@param options table? ----@return Widget|Html? +---@return string|Widget? function BaseResultsTable:opponentDisplay(data, options) options = options or {} - if not data.opponenttype then - return mw.html.create():wikitext('-') + if not Opponent.isType(data.opponenttype) then + return '-' elseif data.opponenttype ~= Opponent.team and (data.opponenttype ~= Opponent.solo or not options.teamForSolo) then return OpponentDisplay.BlockOpponent{ opponent = Opponent.fromLpdbStruct(data) --[[@as standardOpponent]], @@ -506,27 +520,35 @@ end ---Builds team icon display with text below it ---@param teamDisplay Widget ----@param rawTeamTemplate table +---@param rawTeamTemplate teamTemplateData ---@param flip boolean? ----@return Html +---@return Widget function BaseResultsTable.teamIconDisplayWithText(teamDisplay, rawTeamTemplate, flip) - return mw.html.create() - :node(teamDisplay) - :node(mw.html.create('div') - :css('width', '60px') - :css('float', flip and 'right' or 'left') - :node( - mw.html.create('div') - :css('line-height', '1') - :css('font-size', '80%') - :css('text-align', 'center') - :wikitext('([[' .. rawTeamTemplate.page .. '|' .. rawTeamTemplate.shortname .. ']])') - ) - ) + return HtmlWidgets.Fragment{children = { + teamDisplay, + HtmlWidgets.Div{ + css = { + width = '60px', + float = flip and 'right' or 'left', + }, + children = HtmlWidgets.Div{ + css = { + ['line-height'] = 1, + ['font-size'] = '80%', + ['text-align'] = 'center', + }, + children = { + '(', + LinkWidget{link = rawTeamTemplate.page, children = rawTeamTemplate.shortname}, + ')' + } + } + } + }} end ---Builds the tournament display name ----@param placement table +---@param placement placement ---@return string function BaseResultsTable.tournamentDisplayName(placement) if String.isNotEmpty(placement.tournament) then @@ -537,8 +559,8 @@ function BaseResultsTable.tournamentDisplayName(placement) end ---Converts the lastvsdata to display components ----@param placement table ----@return string, Widget|Html?, string? +---@param placement placement +---@return string, string|Widget?, string? function BaseResultsTable:processVsData(placement) local lastVs = placement.lastvsdata or {} @@ -556,13 +578,98 @@ function BaseResultsTable:processVsData(placement) return score, vsDisplay end +---@protected +---@return table[] +function BaseResultsTable:buildColumnDefinitions() + error('BaseResultsTable:buildColumnDefinitions() cannot be called directly and must be overridden.') +end + +---@protected +---@return Widget function BaseResultsTable:buildHeader() - error('Function "buildHeader" needs to be set via the module that requires "Module:BaseResultsTable/Base"') + error('BaseResultsTable:buildHeader() cannot be called directly and must be overridden.') end ----@param placement table +---@protected +---@param placement placement +---@return Widget function BaseResultsTable:buildRow(placement) - error('Function "buildRow" needs to be set via the module that requires "Module:BaseResultsTable/Base"') + error('BaseResultsTable:buildRow() cannot be called directly and must be overridden.') +end + +---@protected +---@param placement placement +---@return Widget +function BaseResultsTable:createDateCell(placement) + return TableWidgets.Cell{children = DateExt.toYmdInUtc(placement.date)} +end + +---@protected +---@param placement placement +---@return Widget +function BaseResultsTable:createTierCell(placement) + local tierDisplay, tierSortValue = self:tierDisplay(placement) + return TableWidgets.Cell{ + attributes = { + ['data-sort-value'] = tierSortValue + }, + children = tierDisplay + } +end + +---@protected +---@param placement placement +---@return Widget? +function BaseResultsTable:createTypeCell(placement) + if not self.config.showType then + return + end + return TableWidgets.Cell{ + children = placement.type + } +end + +---@protected +---@param placement placement +---@return Widget[] +function BaseResultsTable:createTournamentCells(placement) + local tournamentDisplayName = BaseResultsTable.tournamentDisplayName(placement) + return { + TableWidgets.Cell{ + attributes = { + ['data-sort-value'] = tournamentDisplayName + }, + children = LeagueIcon.display{ + icon = placement.icon, + iconDark = placement.icondark, + link = placement.parent, + name = tournamentDisplayName, + options = {noTemplate = true}, + } + }, + TableWidgets.Cell{ + attributes = { + ['data-sort-value'] = tournamentDisplayName + }, + children = LinkWidget{ + children = tournamentDisplayName, + link = placement.pagename, + } + }, + } +end + +---@protected +---@param props {useIndivPrize: boolean?, placement: placement} +---@return Widget +function BaseResultsTable:createPrizeCell(props) + local useIndivPrize = Logic.nilOr(props.useIndivPrize, self.config.queryType ~= Opponent.team) + local placement = props.placement + return TableWidgets.Cell{children = Currency.display( + 'USD', + useIndivPrize and placement.individualprizemoney or placement.prizemoney, + {dashIfZero = true, displayCurrencyCode = false, formatValue = true} + )} end return BaseResultsTable diff --git a/lua/wikis/commons/ResultsTable/Custom.lua b/lua/wikis/commons/ResultsTable/Custom.lua index 37dab73bdb3..88980d94508 100644 --- a/lua/wikis/commons/ResultsTable/Custom.lua +++ b/lua/wikis/commons/ResultsTable/Custom.lua @@ -16,14 +16,14 @@ local CustomResultsTable = {} -- Template entry point for results and achievements tables ---@param args table ----@return Html +---@return Widget function CustomResultsTable.results(args) return ResultsTable(args):create():build() end -- Template entry point for awards tables ---@param args table ----@return Html +---@return Widget function CustomResultsTable.awards(args) return AwardsTable(args):create():build() end diff --git a/lua/wikis/counterstrike/ResultsTable/Custom.lua b/lua/wikis/counterstrike/ResultsTable/Custom.lua index 18f2ffaca8e..07fce7fc3f6 100644 --- a/lua/wikis/counterstrike/ResultsTable/Custom.lua +++ b/lua/wikis/counterstrike/ResultsTable/Custom.lua @@ -21,7 +21,7 @@ local CustomResultsTable = {} -- Template entry point for results and achievements tables ---@param args table ----@return Html +---@return Widget function CustomResultsTable.results(args) args.gameIcons = true args.showType = true @@ -34,7 +34,7 @@ end -- Template entry point for awards tables ---@param args table ----@return Html +---@return Widget function CustomResultsTable.awards(args) args.gameIcons = true args.showType = true diff --git a/lua/wikis/fortnite/ResultsTable/Custom.lua b/lua/wikis/fortnite/ResultsTable/Custom.lua index 3ab2bff2aca..b0c055a7c0a 100644 --- a/lua/wikis/fortnite/ResultsTable/Custom.lua +++ b/lua/wikis/fortnite/ResultsTable/Custom.lua @@ -21,7 +21,7 @@ local CustomResultsTable = {} -- Template entry point ---@param args table ----@return Html +---@return Widget function CustomResultsTable.results(args) local resultsTable = ResultsTable(args) @@ -33,7 +33,7 @@ function CustomResultsTable.results(args) end ---@param args table ----@return Html +---@return Widget function CustomResultsTable.awards(args) return AwardsTable(args):create():build() end diff --git a/lua/wikis/starcraft2/ResultsTable/Custom.lua b/lua/wikis/starcraft2/ResultsTable/Custom.lua index 10930b82a51..b8e5d4710de 100644 --- a/lua/wikis/starcraft2/ResultsTable/Custom.lua +++ b/lua/wikis/starcraft2/ResultsTable/Custom.lua @@ -31,7 +31,7 @@ local CustomResultsTable = {} -- Template entry point ---@param frame Frame ----@return Html? +---@return Widget? function CustomResultsTable.results(frame) local args = Arguments.getArgs(frame) args.useIndivPrize = true @@ -54,7 +54,7 @@ end -- Template entry point for awards ---@param frame Frame ----@return Html? +---@return Widget? function CustomResultsTable.awards(frame) local args = Arguments.getArgs(frame) args.useIndivPrize = true diff --git a/lua/wikis/trackmania/ResultsTable/Custom.lua b/lua/wikis/trackmania/ResultsTable/Custom.lua index 309ae06ce54..ccd192d3514 100644 --- a/lua/wikis/trackmania/ResultsTable/Custom.lua +++ b/lua/wikis/trackmania/ResultsTable/Custom.lua @@ -15,12 +15,16 @@ local AwardsTable = Lua.import('Module:ResultsTable/Award') local CustomResultsTable = {} -- Template entry point for results and achievements tables +---@param args table +---@return Widget function CustomResultsTable.results(args) args.hideresult = true return ResultsTable(args):create():build() end -- Template entry point for awards tables +---@param args table +---@return Widget function CustomResultsTable.awards(args) return AwardsTable(args):create():build() end