From 7c6611059a03eddde3ce436e836660e34983e880 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 29 Dec 2025 11:24:19 +0900 Subject: [PATCH 01/22] type annotation --- lua/wikis/commons/AutomaticPointsTable.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index d7408596aae..35204843d4a 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -30,6 +30,10 @@ local POINTS_TYPE = { SECURED = 'SECURED' } +---@class AutomaticPointsTable +---@operator call(Frame): AutomaticPointsTable +---@field args table +---@field parsedInput table local AutomaticPointsTable = Class.new( function(self, frame) self.frame = frame @@ -38,6 +42,8 @@ local AutomaticPointsTable = Class.new( end ) +---@param frame Frame +---@return Html function AutomaticPointsTable.run(frame) local pointsTable = AutomaticPointsTable(frame) From 5e9ae57e194eb43ab377f776266473d4ff0d4497 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 29 Dec 2025 14:43:10 +0900 Subject: [PATCH 02/22] respect page variable --- lua/wikis/commons/AutomaticPointsTable.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 35204843d4a..23f72f895ec 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -15,6 +15,7 @@ local TableDisplay = Lua.import('Module:AutomaticPointsTable/Display') local MinifiedDisplay = Lua.import('Module:AutomaticPointsTable/MinifiedDisplay') local Json = Lua.import('Module:Json') local Logic = Lua.import('Module:Logic') +local Lpdb = Lua.import('Module:Lpdb') local String = Lua.import('Module:StringUtils') local Table = Lua.import('Module:Table') @@ -78,6 +79,9 @@ function AutomaticPointsTable.run(frame) end function AutomaticPointsTable:storeLPDB(pointsData) + if Lpdb.isStorageDisabled() then + return + end local date = os.date() Array.forEach(pointsData, function(teamPointsData) local team = teamPointsData.team From 9affd4a13a9e89af34e14e93d83793586b8c6705 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 29 Dec 2025 14:56:15 +0900 Subject: [PATCH 03/22] type annotate config --- lua/wikis/commons/AutomaticPointsTable.lua | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 23f72f895ec..35c87799dca 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -31,10 +31,19 @@ local POINTS_TYPE = { SECURED = 'SECURED' } +---@class AutomaticPointsTableConfig +---@field positionBackgrounds string[] +---@field tournaments table[] +---@field teams table[] +---@field shouldTableBeMinified boolean +---@field limit number +---@field lpdbName string +---@field shouldResolveRedirect boolean + ---@class AutomaticPointsTable ---@operator call(Frame): AutomaticPointsTable ---@field args table ----@field parsedInput table +---@field parsedInput AutomaticPointsTableConfig local AutomaticPointsTable = Class.new( function(self, frame) self.frame = frame @@ -105,6 +114,8 @@ function AutomaticPointsTable:storeLPDB(pointsData) end) end +---@param args table +---@return AutomaticPointsTableConfig function AutomaticPointsTable:parseInput(args) local positionBackgrounds = self:parsePositionBackgroundData(args) local tournaments = self:parseTournaments(args) From ce2fa27e41929e081e8878c3ca2b5afc04eb1616 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 29 Dec 2025 15:00:46 +0900 Subject: [PATCH 04/22] type annotate parsed args --- lua/wikis/commons/AutomaticPointsTable.lua | 27 +++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 35c87799dca..eb060654fb2 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -34,12 +34,19 @@ local POINTS_TYPE = { ---@class AutomaticPointsTableConfig ---@field positionBackgrounds string[] ---@field tournaments table[] ----@field teams table[] +---@field teams AutomaticPointsTableParsedTeam[] ---@field shouldTableBeMinified boolean ---@field limit number ---@field lpdbName string ---@field shouldResolveRedirect boolean +---@class AutomaticPointsTableParsedTeam +---@field name string +---@field aliases string[] +---@field deductions table +---@field manualPoints table +---@field tiebreakerPoints number + ---@class AutomaticPointsTable ---@operator call(Frame): AutomaticPointsTable ---@field args table @@ -138,6 +145,8 @@ end --- parses the positionbg arguments, these are the background colors of specific --- positions, usually used to indicate if a team in a specific position will end up qualifying +---@param args table +---@return string[] function AutomaticPointsTable:parsePositionBackgroundData(args) local positionBackgrounds = {} for _, background in Table.iter.pairsByPrefix(args, 'positionbg') do @@ -146,6 +155,8 @@ function AutomaticPointsTable:parsePositionBackgroundData(args) return positionBackgrounds end +---@param args table +---@return table[] function AutomaticPointsTable:parseTournaments(args) local tournaments = {} for _, tournament in Table.iter.pairsByPrefix(args, 'tournament') do @@ -154,6 +165,10 @@ function AutomaticPointsTable:parseTournaments(args) return tournaments end +---@param args table +---@param tournamentCount integer +---@param shouldResolveRedirect boolean +---@return AutomaticPointsTableParsedTeam[] function AutomaticPointsTable:parseTeams(args, tournamentCount, shouldResolveRedirect) local teams = {} for _, team in Table.iter.pairsByPrefix(args, 'team') do @@ -171,6 +186,10 @@ end --- Parses the team aliases, used in cases where a team is picked up by an org or changed --- name in some of the tournaments, in which case aliases are required to correctly query --- the team's results & points +---@param team table +---@param tournamentCount integer +---@param shouldResolveRedirect boolean +---@return string[] function AutomaticPointsTable:parseAliases(team, tournamentCount, shouldResolveRedirect) local aliases = {} local parseAlias = function(x) @@ -192,6 +211,9 @@ end --- Parses the teams' deductions, used in cases where a team has disbanded or made a roster --- change that causes them to lose a portion or all of their points that they've accumulated --- up until that change +---@param team table +---@param tournamentCount integer +---@return table function AutomaticPointsTable:parseDeductions(team, tournamentCount) local deductions = {} for index = 1, tournamentCount do @@ -210,6 +232,9 @@ function AutomaticPointsTable:parseDeductions(team, tournamentCount) return deductions end +---@param team table +---@param tournamentCount integer +---@return table function AutomaticPointsTable:parseManualPoints(team, tournamentCount) local manualPoints = {} for index = 1, tournamentCount do From b4d94a73c1b76b9890bd09bbd00eab01c35eadc8 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 29 Dec 2025 16:10:00 +0900 Subject: [PATCH 05/22] make stylesheet dark theme compliant --- stylesheets/commons/AutomaticPointsTable.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stylesheets/commons/AutomaticPointsTable.scss b/stylesheets/commons/AutomaticPointsTable.scss index 87f7f9adb18..f4c811e2372 100644 --- a/stylesheets/commons/AutomaticPointsTable.scss +++ b/stylesheets/commons/AutomaticPointsTable.scss @@ -40,7 +40,7 @@ Author(s): XtratoS white-space: nowrap; margin-left: -5px; padding-top: 6px; - background-color: #f5f5f5; + background-color: var( --table-header-variant-background-color ); } .automatic-points-table .divCell.border-top-right { From dcd688895b79542e800876edd7189879ed85ce3f Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 29 Dec 2025 16:15:29 +0900 Subject: [PATCH 06/22] more typing --- lua/wikis/commons/AutomaticPointsTable.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index eb060654fb2..c820341efd7 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -46,6 +46,7 @@ local POINTS_TYPE = { ---@field deductions table ---@field manualPoints table ---@field tiebreakerPoints number +---@field results placement[] ---@class AutomaticPointsTable ---@operator call(Frame): AutomaticPointsTable @@ -245,6 +246,9 @@ function AutomaticPointsTable:parseManualPoints(team, tournamentCount) return manualPoints end +---@param teams AutomaticPointsTableParsedTeam[] +---@param tournaments table[] +---@return table[] function AutomaticPointsTable:generateReverseAliases(teams, tournaments) local reverseAliases = {} local shouldResolveRedirect = self.parsedInput.shouldResolveRedirect @@ -265,7 +269,10 @@ function AutomaticPointsTable:generateReverseAliases(teams, tournaments) return reverseAliases end - +---@param teams AutomaticPointsTableParsedTeam[] +---@param tournaments table[] +---@return AutomaticPointsTableParsedTeam[] +---@return {name: string, placements: placement[]}[] function AutomaticPointsTable:queryPlacements(teams, tournaments) -- to get a team index, use reverseAliases[tournamentIndex][alias] local reverseAliases = self:generateReverseAliases(teams, tournaments) @@ -300,7 +307,7 @@ function AutomaticPointsTable:queryPlacements(teams, tournaments) result.extradata = nil table.insert(tournament.placements, result) - local participant = result.participant + local participant = result.opponentname local teamIndex = reverseAliases[tournamentIndex][participant] if teamIndex ~= nil then teams[teamIndex].results[tournamentIndex] = result From 4981debb0385e05220eb048df6071b843bfc032b Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 29 Dec 2025 16:24:40 +0900 Subject: [PATCH 07/22] more typing --- lua/wikis/commons/AutomaticPointsTable.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index c820341efd7..35e910af140 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -25,6 +25,7 @@ local Comparator = Condition.Comparator local BooleanOperator = Condition.BooleanOperator local ColumnName = Condition.ColumnName +---@enum PointsType local POINTS_TYPE = { MANUAL = 'MANUAL', PRIZE = 'PRIZE', @@ -318,6 +319,9 @@ function AutomaticPointsTable:queryPlacements(teams, tournaments) return teams, tournaments end +---@param teams AutomaticPointsTableParsedTeam[] +---@param tournaments {name: string, placements: placement[], shouldDeductionsBeVisible: boolean}[] +---@return {team: AutomaticPointsTableParsedTeam, totalPoints: number, tiebreakerPoints: number}[] function AutomaticPointsTable:getPointsData(teams, tournaments) return Table.mapValues(teams, function(team) @@ -327,13 +331,14 @@ function AutomaticPointsTable:getPointsData(teams, tournaments) local manualPoints = team.manualPoints[tournamentIndex] local placement = team.results[tournamentIndex] - local pointsForTournament = self:calculatePointsForTournament(placement, manualPoints) + local pointsForTournament = self:calculatePointsForTournament(placement, manualPoints) --[[@as table]] if Table.isNotEmpty(pointsForTournament) then totalPoints = totalPoints + pointsForTournament.amount end local deduction = team.deductions[tournamentIndex] if Table.isNotEmpty(deduction) then + ---@cast deduction -nil pointsForTournament.deduction = deduction -- will only show the deductions column if there's atleast one team with -- some deduction for a tournament @@ -352,6 +357,9 @@ function AutomaticPointsTable:getPointsData(teams, tournaments) ) end +---@param placement {prizePoints: number?, securedPoints: number?} +---@param manualPoints number? +---@return {amount: number?, type: PointsType?} function AutomaticPointsTable:calculatePointsForTournament(placement, manualPoints) -- manual points get highest priority if manualPoints ~= nil then From 30d253f1293250042ee1fbf35fc26fcc8bd62c0f Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:51:02 +0900 Subject: [PATCH 08/22] full overhaul --- lua/wikis/commons/AutomaticPointsTable.lua | 427 +++++++----------- .../commons/AutomaticPointsTable/Display.lua | 248 ---------- .../AutomaticPointsTable/MinifiedDisplay.lua | 182 -------- .../commons/Widget/AutomaticPointsTable.lua | 139 ++++++ 4 files changed, 310 insertions(+), 686 deletions(-) delete mode 100644 lua/wikis/commons/AutomaticPointsTable/Display.lua delete mode 100644 lua/wikis/commons/AutomaticPointsTable/MinifiedDisplay.lua create mode 100644 lua/wikis/commons/Widget/AutomaticPointsTable.lua diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 35e910af140..7cdb1860402 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -11,13 +11,16 @@ local Arguments = Lua.import('Module:Arguments') local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') local Condition = Lua.import('Module:Condition') -local TableDisplay = Lua.import('Module:AutomaticPointsTable/Display') -local MinifiedDisplay = Lua.import('Module:AutomaticPointsTable/MinifiedDisplay') +local DateExt = Lua.import('Module:Date/Ext') +local FnUtil = Lua.import('Module:FnUtil') local Json = Lua.import('Module:Json') local Logic = Lua.import('Module:Logic') local Lpdb = Lua.import('Module:Lpdb') +local Opponent = Lua.import('Module:Opponent/Custom') local String = Lua.import('Module:StringUtils') local Table = Lua.import('Module:Table') +local TeamTemplate = Lua.import('Module:TeamTemplate') +local Tournament = Lua.import('Module:Tournament') local ConditionTree = Condition.Tree local ConditionNode = Condition.Node @@ -25,6 +28,8 @@ local Comparator = Condition.Comparator local BooleanOperator = Condition.BooleanOperator local ColumnName = Condition.ColumnName +local AutomaticPointsTableWidget = Lua.import('Module:Widget/AutomaticPointsTable') + ---@enum PointsType local POINTS_TYPE = { MANUAL = 'MANUAL', @@ -34,20 +39,21 @@ local POINTS_TYPE = { ---@class AutomaticPointsTableConfig ---@field positionBackgrounds string[] ----@field tournaments table[] ----@field teams AutomaticPointsTableParsedTeam[] +---@field tournaments StandardTournament[] +---@field opponents AutomaticPointsTableOpponent[] ---@field shouldTableBeMinified boolean ---@field limit number ---@field lpdbName string ---@field shouldResolveRedirect boolean ----@class AutomaticPointsTableParsedTeam ----@field name string ----@field aliases string[] ----@field deductions table ----@field manualPoints table +---@class AutomaticPointsTableOpponent +---@field opponent standardOpponent +---@field aliases string[][] ---@field tiebreakerPoints number ----@field results placement[] +---@field results {type: PointsType?, amount: number?, deduction: number?, note: string?}[] +---@field totalPoints number +---@field placement integer +---@field background string? ---@class AutomaticPointsTable ---@operator call(Frame): AutomaticPointsTable @@ -62,64 +68,34 @@ local AutomaticPointsTable = Class.new( ) ---@param frame Frame ----@return Html +---@return Widget function AutomaticPointsTable.run(frame) - local pointsTable = AutomaticPointsTable(frame) - - local teams = pointsTable.parsedInput.teams - local tournaments = pointsTable.parsedInput.tournaments - local teamsWithResults, tournamentsWithResults = pointsTable:queryPlacements(teams, tournaments) - local pointsData = pointsTable:getPointsData(teamsWithResults, tournamentsWithResults) - local sortedData = pointsTable:sortData(pointsData) - local sortedDataWithPositions = pointsTable:addPositionData(sortedData) - local positionBackgrounds = pointsTable.parsedInput.positionBackgrounds - local limit = pointsTable.parsedInput.limit - - -- A display module is a module that takes in 3 arguments and returns some html, - -- which will be displayed when this module is invoked - local usedDisplayModule - if pointsTable.parsedInput.shouldTableBeMinified then - usedDisplayModule = MinifiedDisplay - else - usedDisplayModule = TableDisplay - end - - pointsTable:storeLPDB(sortedDataWithPositions) - - local divTable = usedDisplayModule( - sortedDataWithPositions, - tournamentsWithResults, - positionBackgrounds, - limit - ) - - return divTable:create() + local pointsTable = AutomaticPointsTable(frame):process() + mw.logObject(pointsTable.opponents, 'opponents') + return pointsTable:display() end -function AutomaticPointsTable:storeLPDB(pointsData) - if Lpdb.isStorageDisabled() then - return - end - local date = os.date() - Array.forEach(pointsData, function(teamPointsData) - local team = teamPointsData.team - local teamName = string.lower(team.aliases[#team.aliases]) +---@param opponents AutomaticPointsTableOpponent[] +function AutomaticPointsTable:storeLPDB(opponents) + local date = DateExt.getContextualDateOrNow() + Array.forEach(opponents, function(opponent) + local teamName = Opponent.toName(opponent.opponent) local lpdbName = self.parsedInput.lpdbName local uniqueId = teamName .. '_' .. lpdbName - local position = teamPointsData.position - local totalPoints = teamPointsData.totalPoints + local position = opponent.placement + local totalPoints = opponent.totalPoints local objectData = { type = 'automatic_points', name = teamName, information = position, date = date, - extradata = Json.stringify({ + extradata = { position = position, totalPoints = totalPoints - }) + } } - mw.ext.LiquipediaDB.lpdb_datapoint(uniqueId, objectData) + mw.ext.LiquipediaDB.lpdb_datapoint(uniqueId, Json.stringifySubTables(objectData)) end) end @@ -128,20 +104,18 @@ end function AutomaticPointsTable:parseInput(args) local positionBackgrounds = self:parsePositionBackgroundData(args) local tournaments = self:parseTournaments(args) - local shouldResolveRedirect = Logic.readBool(args.resolveRedirect) - local teams = self:parseTeams(args, #tournaments, shouldResolveRedirect) + local opponents = self:parseOpponents(args, tournaments) local minified = Logic.readBool(args.minified) - local limit = tonumber(args.limit) or #teams + local limit = tonumber(args.limit) or #opponents local lpdbName = args.lpdbName or mw.title.getCurrentTitle().text return { positionBackgrounds = positionBackgrounds, tournaments = tournaments, - teams = teams, + opponents = opponents, shouldTableBeMinified = minified, limit = limit, - lpdbName = lpdbName, - shouldResolveRedirect = shouldResolveRedirect, + lpdbName = lpdbName } end @@ -158,54 +132,74 @@ function AutomaticPointsTable:parsePositionBackgroundData(args) end ---@param args table ----@return table[] +---@return StandardTournament[] function AutomaticPointsTable:parseTournaments(args) local tournaments = {} for _, tournament in Table.iter.pairsByPrefix(args, 'tournament') do - table.insert(tournaments, (Json.parse(tournament))) + Array.appendWith(tournaments, Tournament.getTournament(tournament)) end return tournaments end ---@param args table ----@param tournamentCount integer ----@param shouldResolveRedirect boolean ----@return AutomaticPointsTableParsedTeam[] -function AutomaticPointsTable:parseTeams(args, tournamentCount, shouldResolveRedirect) - local teams = {} - for _, team in Table.iter.pairsByPrefix(args, 'team') do - local parsedTeam = Json.parse(team) - parsedTeam.aliases = self:parseAliases(parsedTeam, tournamentCount, shouldResolveRedirect) - parsedTeam.deductions = self:parseDeductions(parsedTeam, tournamentCount) - parsedTeam.manualPoints = self:parseManualPoints(parsedTeam, tournamentCount) - parsedTeam.tiebreakerPoints = tonumber(parsedTeam.tiebreaker_points) or 0 - parsedTeam.results = {} - table.insert(teams, parsedTeam) +---@param tournaments StandardTournament[] +---@return AutomaticPointsTableOpponent[] +function AutomaticPointsTable:parseOpponents(args, tournaments) + local opponents = {} + for _, opponentArgs in Table.iter.pairsByPrefix(args, 'opponent') do + local parsedArgs = Json.parseIfString(opponentArgs) + local parsedOpponent = { + opponent = Opponent.readOpponentArgs(parsedArgs), + tiebreakerPoints = tonumber(parsedArgs.tiebreaker) or 0, + background = parsedArgs.bg, + } + assert(parsedOpponent.opponent.type == Opponent.team) + assert(not Opponent.isTbd(parsedOpponent.opponent)) + local aliases = self:parseAliases(parsedArgs, parsedOpponent.opponent, #tournaments) + + parsedOpponent.results = Array.map(tournaments, function (tournament, tournamentIndex) + local manualPoints = parsedArgs['points' .. tournamentIndex] + if String.isNotEmpty(manualPoints) then + return Table.mergeInto({ + type = POINTS_TYPE.MANUAL, + amount = tonumber(manualPoints) + }, self:parseDeduction(parsedArgs, tournamentIndex)) + end + + local queriedPoints = self:queryPlacement(aliases[tournamentIndex], tournament) + + if not queriedPoints then + return {} + end + + return Table.merge(queriedPoints, self:parseDeduction(parsedArgs, tournamentIndex)) + end) + + parsedOpponent.totalPoints = Array.reduce(parsedOpponent.results, function (aggregate, result) + return aggregate + (result.amount or 0) - (result.deduction or 0) + end, 0) + + Array.appendWith(opponents, parsedOpponent) end - return teams + return opponents end --- Parses the team aliases, used in cases where a team is picked up by an org or changed --- name in some of the tournaments, in which case aliases are required to correctly query --- the team's results & points ----@param team table +---@param args table +---@param opponent standardOpponent ---@param tournamentCount integer ----@param shouldResolveRedirect boolean ----@return string[] -function AutomaticPointsTable:parseAliases(team, tournamentCount, shouldResolveRedirect) +---@return string[][] +function AutomaticPointsTable:parseAliases(args, opponent, tournamentCount) local aliases = {} - local parseAlias = function(x) - if (shouldResolveRedirect) then - return mw.ext.TeamLiquidIntegration.resolve_redirect(x) - end - return mw.language.getContentLanguage():ucfirst(x) - end - local lastAlias = team.name + local lastAliases = TeamTemplate.queryHistoricalNames(Opponent.toName(opponent)) + for index = 1, tournamentCount do - if String.isNotEmpty(team['alias' .. index]) then - lastAlias = team['alias' .. index] + if String.isNotEmpty(args['alias' .. index]) then + lastAliases = TeamTemplate.queryHistoricalNames(args['alias' .. index]) end - aliases[index] = parseAlias(lastAlias) + aliases[index] = lastAliases end return aliases end @@ -213,148 +207,54 @@ end --- Parses the teams' deductions, used in cases where a team has disbanded or made a roster --- change that causes them to lose a portion or all of their points that they've accumulated --- up until that change ----@param team table ----@param tournamentCount integer ----@return table -function AutomaticPointsTable:parseDeductions(team, tournamentCount) - local deductions = {} - for index = 1, tournamentCount do - if String.isNotEmpty(team['deduction' .. index]) then - if not deductions[index] then - deductions[index] = {} - end - deductions[index].amount = tonumber(team['deduction' .. index]) - - if String.isNotEmpty(team['deduction' .. index .. 'note']) then - deductions[index].note = team['deduction' .. index .. 'note'] - end - end - end - - return deductions -end - ----@param team table ----@param tournamentCount integer ----@return table -function AutomaticPointsTable:parseManualPoints(team, tournamentCount) - local manualPoints = {} - for index = 1, tournamentCount do - if String.isNotEmpty(team['points' .. index]) then - manualPoints[index] = tonumber(team['points' .. index]) - end - end - return manualPoints -end - ----@param teams AutomaticPointsTableParsedTeam[] ----@param tournaments table[] ----@return table[] -function AutomaticPointsTable:generateReverseAliases(teams, tournaments) - local reverseAliases = {} - local shouldResolveRedirect = self.parsedInput.shouldResolveRedirect - for tournamentIndex = 1, #tournaments do - reverseAliases[tournamentIndex] = {} - Array.forEach(teams, - function(team, index) - local alias - if shouldResolveRedirect then - alias = mw.ext.TeamLiquidIntegration.resolve_redirect(team.aliases[tournamentIndex]) - else - alias = team.aliases[tournamentIndex] - end - reverseAliases[tournamentIndex][alias] = index - end - ) +---@param args table +---@param index integer +---@return {deduction: number?, note: string?}[] +function AutomaticPointsTable:parseDeduction(args, index) + local deduction = args['deduction' .. index] + if String.isEmpty(deduction) then + return {} + elseif not Logic.isNumeric(deduction) then + return {} end - return reverseAliases + return { + deduction = tonumber(deduction), + note = args['deduction' .. index .. 'note'] + } end ----@param teams AutomaticPointsTableParsedTeam[] ----@param tournaments table[] ----@return AutomaticPointsTableParsedTeam[] ----@return {name: string, placements: placement[]}[] -function AutomaticPointsTable:queryPlacements(teams, tournaments) - -- to get a team index, use reverseAliases[tournamentIndex][alias] - local reverseAliases = self:generateReverseAliases(teams, tournaments) - - local queryParams = { - limit = 5000, - query = 'tournament, participant, placement, extradata' +---@param aliases string[] +---@param tournament StandardTournament +function AutomaticPointsTable:queryPlacement(aliases, tournament) + local conditions = ConditionTree(BooleanOperator.all):add{ + ConditionNode(ColumnName('parent'), Comparator.eq, tournament.pageName), + ConditionNode(ColumnName('opponenttype'), Comparator.eq, Opponent.team), + Condition.Util.anyOf(ColumnName('opponenttemplate'), aliases), } + local result = mw.ext.LiquipediaDB.lpdb('placement', { + conditions = tostring(conditions), + limit = 1, + query = 'extradata' + })[1] - local tree = ConditionTree(BooleanOperator.any) - local columnName = ColumnName('tournament') - local tournamentIndices = {} - Array.forEach(tournaments, - function(t, index) - tree:add(ConditionNode(columnName, Comparator.eq, t.name)) - tournamentIndices[t.name] = index - t.placements = {} - end - ) - local conditions = tree:toString() - - queryParams.conditions = conditions - local allQueryResult = mw.ext.LiquipediaDB.lpdb('placement', queryParams) - - Array.forEach(allQueryResult, - function(result) - local tournamentIndex = tournamentIndices[result.tournament] - local tournament = tournaments[tournamentIndex] - - result.prizePoints = tonumber(result.extradata.prizepoints) - result.securedPoints = tonumber(result.extradata.securedpoints) - result.extradata = nil - table.insert(tournament.placements, result) - - local participant = result.opponentname - local teamIndex = reverseAliases[tournamentIndex][participant] - if teamIndex ~= nil then - teams[teamIndex].results[tournamentIndex] = result - end - end - ) + if not result then + return + end - return teams, tournaments -end + local prizePoints = tonumber(result.extradata.prizepoints) + local securedPoints = tonumber(result.extradata.securedpoints) ----@param teams AutomaticPointsTableParsedTeam[] ----@param tournaments {name: string, placements: placement[], shouldDeductionsBeVisible: boolean}[] ----@return {team: AutomaticPointsTableParsedTeam, totalPoints: number, tiebreakerPoints: number}[] -function AutomaticPointsTable:getPointsData(teams, tournaments) - return Table.mapValues(teams, - function(team) - local teamPointsData = {} - local totalPoints = 0 - for tournamentIndex = 1, #tournaments do - local manualPoints = team.manualPoints[tournamentIndex] - local placement = team.results[tournamentIndex] - - local pointsForTournament = self:calculatePointsForTournament(placement, manualPoints) --[[@as table]] - if Table.isNotEmpty(pointsForTournament) then - totalPoints = totalPoints + pointsForTournament.amount - end - - local deduction = team.deductions[tournamentIndex] - if Table.isNotEmpty(deduction) then - ---@cast deduction -nil - pointsForTournament.deduction = deduction - -- will only show the deductions column if there's atleast one team with - -- some deduction for a tournament - tournaments[tournamentIndex].shouldDeductionsBeVisible = true - totalPoints = totalPoints - (deduction.amount or 0) - end - - teamPointsData[tournamentIndex] = pointsForTournament - end - - teamPointsData.team = team - teamPointsData.totalPoints = totalPoints - teamPointsData.tiebreakerPoints = team.tiebreakerPoints - return teamPointsData - end - ) + if prizePoints then + return { + amount = prizePoints, + type = POINTS_TYPE.PRIZE, + } + elseif securedPoints then + return { + amount = securedPoints, + type = POINTS_TYPE.SECURED, + } + end end ---@param placement {prizePoints: number?, securedPoints: number?} @@ -390,44 +290,59 @@ function AutomaticPointsTable:calculatePointsForTournament(placement, manualPoin end --- sort by total points (desc) then by name (asc) -function AutomaticPointsTable:sortData(pointsData, teams) - table.sort(pointsData, - function(a, b) - if a.totalPoints ~= b.totalPoints then - return a.totalPoints > b.totalPoints - end - if a.tiebreakerPoints ~= b.tiebreakerPoints then - return a.tiebreakerPoints > b.tiebreakerPoints +---@param opponents AutomaticPointsTableOpponent[] +---@return AutomaticPointsTableOpponent[] +function AutomaticPointsTable:sortData(opponents) + return Array.sortBy(opponents, FnUtil.identity, + ---@param opp1 AutomaticPointsTableOpponent + ---@param opp2 AutomaticPointsTableOpponent + function (opp1, opp2) + local totalPoints1 = opp1.totalPoints + local totalPoints2 = opp2.totalPoints + if totalPoints1 ~= totalPoints2 then + return totalPoints1 > totalPoints2 + elseif opp1.tiebreakerPoints ~= opp2.tiebreakerPoints then + return opp1.tiebreakerPoints > opp2.tiebreakerPoints end - local aName = a.team.aliases[#a.team.aliases] - local bName = b.team.aliases[#b.team.aliases] - return aName < bName + return Opponent.toName(opp1.opponent) < Opponent.toName(opp2.opponent) end ) +end - return pointsData +---@param opponents AutomaticPointsTableOpponent[] +---@return AutomaticPointsTableOpponent[] +function AutomaticPointsTable:addPlacements(opponents) + Array.forEach(opponents, function (opponent, index) + if index == 1 then + opponent.placement = index + elseif opponent.totalPoints ~= opponents[index - 1].totalPoints then + opponent.placement = index + elseif opponent.tiebreakerPoints ~= opponents[index - 1].totalPoints then + opponent.placement = index + else + opponent.placement = opponents[index - 1].placement + end + end) + return opponents end -function AutomaticPointsTable:addPositionData(pointsData) - local teamPosition = 0 - local previousTotalPoints = pointsData[1].totalPoints + 1 - local previousTiebreakerPoints = pointsData[1].tiebreakerPoints + 1 - - return Table.map(pointsData, - function(index, dataPoint) - local lessTotalPoints = dataPoint.totalPoints < previousTotalPoints - local equalTotalPoints = dataPoint.totalPoints == previousTotalPoints - local lessTiebreakerPoints = dataPoint.tiebreakerPoints < previousTiebreakerPoints - if lessTotalPoints or (equalTotalPoints and lessTiebreakerPoints) then - teamPosition = index - end - dataPoint.position = teamPosition - previousTotalPoints = dataPoint.totalPoints - previousTiebreakerPoints = dataPoint.tiebreakerPoints +---@return self +function AutomaticPointsTable:process() + self.opponents = self:addPlacements(self:sortData(self.parsedInput.opponents)) + if Lpdb.isStorageEnabled() then + self:storeLPDB(self.opponents) + end + return self +end - return index, dataPoint - end - ) +---@return Widget +function AutomaticPointsTable:display() + return AutomaticPointsTableWidget{ + opponents = self.opponents, + tournaments = self.parsedInput.tournaments, + limit = self.parsedInput.limit, + positionBackgrounds = self.parsedInput.positionBackgrounds, + } end return AutomaticPointsTable diff --git a/lua/wikis/commons/AutomaticPointsTable/Display.lua b/lua/wikis/commons/AutomaticPointsTable/Display.lua deleted file mode 100644 index 59e1600ffd1..00000000000 --- a/lua/wikis/commons/AutomaticPointsTable/Display.lua +++ /dev/null @@ -1,248 +0,0 @@ ---- --- @Liquipedia --- page=Module:AutomaticPointsTable/Display --- --- Please see https://github.com/Liquipedia/Lua-Modules to contribute --- - -local Lua = require('Module:Lua') - -local Array = Lua.import('Module:Array') -local Class = Lua.import('Module:Class') -local Logic = Lua.import('Module:Logic') -local String = Lua.import('Module:StringUtils') -local Table = Lua.import('Module:Table') - -local POINTS_TYPE = { - MANUAL = 'MANUAL', - PRIZE = 'PRIZE', - SECURED = 'SECURED' -} - -local PointsDivTable = Class.new( - function(self, pointsData, tournaments, positionBackgrounds, limit) - self.root = mw.html.create('div') :addClass('divTable') - :addClass('border-color-grey') :addClass('border-bottom') - - local columnCount = Array.reduce(tournaments, function(count, t) - return count + (t.shouldDeductionsBeVisible and 2 or 1) - end, 0) - - local innerWrapper = mw.html.create('div') :addClass('fixed-size-table-container') - :addClass('border-color-grey') - :css('width', tostring(450 + (columnCount * 50)) .. 'px') - :node(self.root) - - self.wrapper = mw.html.create('div') :addClass('table-responsive') - :addClass('automatic-points-table') - :node(innerWrapper) - - self.rows = {} - self.pointsData = pointsData - self.tournaments = tournaments - self.positionBackgrounds = positionBackgrounds - self.limit = limit - end -) - -local TableRow = Class.new( - function(self, pointsData, tournaments, positionBackground) - self.root = mw.html.create('div'):addClass('divRow') - self.cells = {} - - local team = pointsData.team - if team.bg then - self.root:addClass('bg-' .. team.bg) - end - - self.pointsData = pointsData - self.tournaments = tournaments - self.team = team - self.positionBackground = positionBackground - end -) - -local TableHeaderRow = Class.new( - function(self, tournaments) - self.tournaments = tournaments - self.root = mw.html.create('div') :addClass('divHeaderRow') :addClass('diagonal') - self.cells = {} - end -) - -function PointsDivTable:row(row) - table.insert(self.rows, row) - return self -end - -function PointsDivTable:create() - local headerRow = TableHeaderRow(self.tournaments) - self:row(headerRow) - - local limit = self.limit - Array.forEach(self.pointsData, function(teamPointsData, index) - if index > limit then return end - local positionBackground = self.positionBackgrounds[index] - self:row(TableRow(teamPointsData, self.tournaments, positionBackground)) - end) - - for _, row in pairs(self.rows) do - self.root:node(row:create()) - end - - return self.wrapper -end - -function TableRow:create() - -- fixed cells - self:positionCell(self.pointsData.position, self.positionBackground) - self:nameCell(self.team) - self:totalCell(self.pointsData.totalPoints) - -- variable cells - Array.forEach(self.pointsData, function(points, index) - local tournament = self.tournaments[index] - self:pointsCell(points, tournament) - if tournament.shouldDeductionsBeVisible then - self:deductionCell(points.deduction) - end - end) - - for _, cell in pairs(self.cells) do - self.root:node(cell) - end - return self.root -end - -local function wrapInDiv(text) - return mw.html.create('div'):wikitext(tostring(text)) -end - -function TableRow:baseCell(text, bg, bold) - local div = wrapInDiv(text) :addClass('divCell') :addClass('va-middle') - :addClass('centered-cell') :addClass('border-color-grey') :addClass('border-top-right') - - if bg then - div:addClass('bg-' .. bg) - end - if bold then - div:css('font-weight', 'bold') - end - return div -end - -function TableRow:totalCell(points) - local totalCell = self:baseCell(points, nil, true) - table.insert(self.cells, totalCell) - return self -end - -function TableRow:positionCell(position, bg) - local positionCell = self:baseCell(position .. '.', bg, true) - table.insert(self.cells, positionCell) - return self -end - -function TableRow:nameCell(team) - local lastAlias = team.aliases[#team.aliases] - local teamDisplay = team.display and team.display or mw.ext.TeamTemplate.team(lastAlias) - local nameCell = self:baseCell(teamDisplay, team.bg):addClass('name-cell') - table.insert(self.cells, nameCell) - return self -end - -function TableRow:pointsCell(points, tournament) - local finished = Logic.readBool(tournament.finished) - local pointString = points.amount ~= nil and points.amount or (finished and '-' or '') - local pointsCell = self:baseCell(pointString) - if points.type == POINTS_TYPE.SECURED then - pointsCell:css('font-weight', 'lighter'):css('font-style', 'italic') - end - table.insert(self.cells, pointsCell) - return self -end - -function TableRow:deductionCell(deduction) - if Table.isEmpty(deduction) then - table.insert(self.cells, self:baseCell('')) - return self - end - local abbr = mw.html.create('abbr'):addClass('bg-down'):addClass('deduction-box') - :wikitext(deduction.amount) - if String.isNotEmpty(deduction.note) then - abbr:attr('title', deduction.note) - end - local deductionCell = self:baseCell(abbr) - table.insert(self.cells, deductionCell) - return self -end - -function TableHeaderRow:cell(header) - local additionalClass = header.additionalClass - - local innerDiv = wrapInDiv(header.text) :addClass('border-color-grey') - :addClass('content') - - local outerDiv = mw.html.create('div') :addClass('divCell') - :addClass('diagonal-header-div-cell') - if additionalClass then - outerDiv:addClass(additionalClass) - end - outerDiv:node(innerDiv) - table.insert(self.cells, outerDiv) - return self -end - -function TableHeaderRow:create() - -- fixed headers - local headers = {{ - text = 'Ranking', - additionalClass = 'ranking' - }, { - text = 'Team', - additionalClass = 'team' - }, { - text = 'Total Points' - }} - Array.forEach(headers, function(h) self:headerCell(h) end) - -- variable headers (according to tournaments in given in module arguments) - Array.forEach(self.tournaments, - function(tournament) - self:headerCell({ - text = tournament.display and tournament.display or tournament.name - }) - - if tournament.shouldDeductionsBeVisible then - local deductionsHeader = tournament['deductionsheader'] - self:headerCell({ - text = deductionsHeader and deductionsHeader or 'Deductions' - }) - end - end - ) - - for _, cell in pairs(self.cells) do - self.root:node(cell) - end - return self.root -end - -function TableHeaderRow:headerCell(header) - local innerDiv = wrapInDiv(header.text) - :addClass('border-color-grey') - :addClass('content') - - local outerDiv = mw.html.create('div') :addClass('divCell') - :addClass('diagonal-header-div-cell') - - local additionalClass = header.additionalClass - if additionalClass then - - outerDiv:addClass(additionalClass) - end - outerDiv:node(innerDiv) - - table.insert(self.cells, outerDiv) - return self -end - -return PointsDivTable diff --git a/lua/wikis/commons/AutomaticPointsTable/MinifiedDisplay.lua b/lua/wikis/commons/AutomaticPointsTable/MinifiedDisplay.lua deleted file mode 100644 index 37168822776..00000000000 --- a/lua/wikis/commons/AutomaticPointsTable/MinifiedDisplay.lua +++ /dev/null @@ -1,182 +0,0 @@ ---- --- @Liquipedia --- page=Module:AutomaticPointsTable/MinifiedDisplay --- --- Please see https://github.com/Liquipedia/Lua-Modules to contribute --- - -local Lua = require('Module:Lua') - -local Array = Lua.import('Module:Array') -local Class = Lua.import('Module:Class') - -local PointsDivTable = Class.new( - function(self, pointsData, tournaments, positionBackgrounds, limit) - self.root = mw.html.create('div') :addClass('divTable') - :addClass('border-color-grey') :addClass('border-bottom') - - local innerWrapper = mw.html.create('div') :addClass('fixed-size-table-container') - :addClass('border-color-grey') - :css('width', '316px') - :node(self.root) - - self.wrapper = mw.html.create('div') :addClass('table-responsive') - :addClass('automatic-points-table') :addClass('minified') - :node(innerWrapper) - - self.rows = {} - self.pointsData = pointsData - self.tournaments = tournaments - self.positionBackgrounds = positionBackgrounds - self.limit = limit - end -) - -local TableRow = Class.new( - function(self, pointsData, tournaments, positionBackground) - self.root = mw.html.create('div'):addClass('divRow') - self.cells = {} - - local team = pointsData.team - if team.bg then - self.root:addClass('bg-' .. team.bg) - end - - self.pointsData = pointsData - self.tournaments = tournaments - self.team = team - self.positionBackground = positionBackground - end -) - -local TableHeaderRow = Class.new( - function(self, tournaments) - self.tournaments = tournaments - self.root = mw.html.create('div') :addClass('divHeaderRow') - self.cells = {} - end -) - -function PointsDivTable:row(row) - table.insert(self.rows, row) - return self -end - -function PointsDivTable:create() - local headerRow = TableHeaderRow(self.tournaments) - self:row(headerRow) - - local limit = self.limit - Array.forEach(self.pointsData, function(teamPointsData, index) - if index > limit then return end - local positionBackground = self.positionBackgrounds[index] - self:row(TableRow(teamPointsData, self.tournaments, positionBackground)) - end) - - for _, row in pairs(self.rows) do - self.root:node(row:create()) - end - - return self.wrapper -end - -function TableRow:create() - -- fixed cells - self:positionCell(self.pointsData.position, self.positionBackground) - self:nameCell(self.team) - self:totalCell(self.pointsData.totalPoints) - - for _, cell in pairs(self.cells) do - self.root:node(cell) - end - return self.root -end - -local function wrapInDiv(text) - return mw.html.create('div'):wikitext(tostring(text)) -end - -function TableRow:baseCell(text, bg, bold) - local div = wrapInDiv(text) :addClass('divCell') :addClass('va-middle') - :addClass('centered-cell') :addClass('border-color-grey') :addClass('border-top-right') - - if bg then - div:addClass('bg-' .. bg) - end - if bold then - div:css('font-weight', 'bold') - end - return div -end - -function TableRow:totalCell(points) - local totalCell = self:baseCell(points, nil, true) - table.insert(self.cells, totalCell) - return self -end - -function TableRow:positionCell(position, bg) - local positionCell = self:baseCell(position .. '.', bg, true) - table.insert(self.cells, positionCell) - return self -end - -function TableRow:nameCell(team) - local lastAlias = team.aliases[#team.aliases] - local teamDisplay = team.display and team.display or mw.ext.TeamTemplate.team(lastAlias) - local nameCell = self:baseCell(teamDisplay, team.bg):addClass('name-cell') - table.insert(self.cells, nameCell) - return self -end - -function TableHeaderRow:cell(header) - local additionalClass = header.additionalClass - - local innerDiv = wrapInDiv(header.text) :addClass('border-color-grey') - :addClass('content') - - local outerDiv = mw.html.create('div') :addClass('divCell') - if additionalClass then - outerDiv:addClass(additionalClass) - end - outerDiv:node(innerDiv) - table.insert(self.cells, outerDiv) - return self -end - -function TableHeaderRow:create() - -- fixed headers - local headers = {{ - text = '#', - width = '35px' - }, { - text = 'Team', - width = '225px' - }, { - text = 'Points', - width = '50px' - }} - Array.forEach(headers, function(h) self:headerCell(h) end) - - for _, cell in pairs(self.cells) do - self.root:node(cell) - end - return self.root -end - -function TableHeaderRow:headerCell(header) - local innerDiv = wrapInDiv(header.text) - :addClass('border-color-grey') - :addClass('content') - - local outerDiv = mw.html.create('div') :addClass('divCell') - :addClass('border-right') :css('text-align', 'center') - - outerDiv:css('width', header.width) - outerDiv:node(innerDiv) - - table.insert(self.cells, outerDiv) - return self -end - -return PointsDivTable diff --git a/lua/wikis/commons/Widget/AutomaticPointsTable.lua b/lua/wikis/commons/Widget/AutomaticPointsTable.lua new file mode 100644 index 00000000000..9dfeb265338 --- /dev/null +++ b/lua/wikis/commons/Widget/AutomaticPointsTable.lua @@ -0,0 +1,139 @@ +--- +-- @Liquipedia +-- page=Module:Widget/AutomaticPointsTable +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- + +local Lua = require('Module:Lua') + +local Array = Lua.import('Module:Array') +local Class = Lua.import('Module:Class') +local OpponentDisplay = Lua.import('Module:OpponentDisplay/Custom') + +local Widget = Lua.import('Module:Widget') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') +local Div = HtmlWidgets.Div +local TournamentTitle = Lua.import('Module:Widget/Tournament/Title') +local WidgetUtil = Lua.import('Module:Widget/Util') + +---@class AutomaticPointsTableWidgetProps +---@field opponents AutomaticPointsTableOpponent +---@field tournaments StandardTournament[] +---@field limit integer +---@field positionBackgrounds string[] + +---@class AutomaticPointsTableWidget: Widget +---@operator call(AutomaticPointsTableWidgetProps): AutomaticPointsTableWidget +---@field props AutomaticPointsTableWidgetProps +local AutomaticPointsTableWidget = Class.new(Widget) + +function AutomaticPointsTableWidget:render() + return Div{ + classes = {'table-responsive', 'automatic-points-table'}, + children = Div{ + classes = {'fixed-size-table-container', 'border-color-grey'}, + css = {width = (450 + #self.props.tournaments * 50) .. 'px'}, + children = self:createTable() + } + } +end + +function AutomaticPointsTableWidget:createTable() + return Div{ + classes = {'divTable', 'border-color-grey', 'border-bottom'}, + children = WidgetUtil.collect( + self:createHeader(), + Array.map(self.props.opponents, function (opponent, opponentIndex) + return self:createRow(opponent, opponentIndex) + end) + ) + } +end + +---@param child string|Widget +---@param additionalClass string? +---@return Widget +function AutomaticPointsTableWidget._createHeaderCell(child, additionalClass) + return Div{ + classes = {'divCell', 'diagonal-header-div-cell', additionalClass}, + children = Div{ + classes = {'border-color-grey', 'content'}, + children = child + } + } +end + +function AutomaticPointsTableWidget:createHeader() + local tournaments = self.props.tournaments + + return Div{ + classes = {'divHeaderRow', 'diagonal'}, + children = WidgetUtil.collect( + AutomaticPointsTableWidget._createHeaderCell('Ranking','ranking'), + AutomaticPointsTableWidget._createHeaderCell('Team', 'team'), + AutomaticPointsTableWidget._createHeaderCell('Total Points'), + Array.map(tournaments, function (tournament) + return AutomaticPointsTableWidget._createHeaderCell(TournamentTitle{tournament = tournament}) + end) + ) + } +end + +---@param props {children: string|number|Widget|Html|(string|number|Widget|Html)[]?, +---additionalClasses: string[]?, background: string?, bold: boolean?, css: table?} +---@return Widget +function AutomaticPointsTableWidget._createRowCell(props) + return Div{ + classes = Array.extend( + 'divCell', + 'va-middle', + 'centered-cell', + 'border-color-grey', + 'border-top-right', + props.background and ('bg-' .. props.background) or nil, + props.additionalClasses + ), + css = props.css, + children = Div{ + classes = {'border-color-grey', 'content'}, + children = props.children + } + } +end + +---@param opponent AutomaticPointsTableOpponent +---@param opponentIndex integer +---@return Widget +function AutomaticPointsTableWidget:createRow(opponent, opponentIndex) + return Div{ + classes = {'divRow', opponent.background and ('bg-' .. opponent.background) or nil}, + children = WidgetUtil.collect( + AutomaticPointsTableWidget._createRowCell{ + background = self.props.positionBackgrounds[opponentIndex], + children = opponent.placement, + bold = true, + }, + AutomaticPointsTableWidget._createRowCell{ + additionalClasses = {'name-cell'}, + background = opponent.background, + children = OpponentDisplay.InlineOpponent{opponent = opponent.opponent}, + }, + AutomaticPointsTableWidget._createRowCell{ + bold = true, + children = opponent.totalPoints, + }, + Array.map(opponent.results, function (result, resultIndex) + return AutomaticPointsTableWidget._createRowCell{ + css = result.type == "SECURED" and { + ['font-weight'] = 'lighter', + ['font-style'] = 'italic' + } or nil, + children = result.amount or (self.props.tournaments[resultIndex].phase == "FINISHED" and '-' or nil), + } + end) + ) + } +end + +return AutomaticPointsTableWidget From 7ed0e95d33afcda7cfa837b5905044cb654503dc Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Tue, 30 Dec 2025 09:20:03 +0900 Subject: [PATCH 09/22] type annotation --- lua/wikis/commons/Widget/AutomaticPointsTable.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lua/wikis/commons/Widget/AutomaticPointsTable.lua b/lua/wikis/commons/Widget/AutomaticPointsTable.lua index 9dfeb265338..b4314c432ee 100644 --- a/lua/wikis/commons/Widget/AutomaticPointsTable.lua +++ b/lua/wikis/commons/Widget/AutomaticPointsTable.lua @@ -28,6 +28,7 @@ local WidgetUtil = Lua.import('Module:Widget/Util') ---@field props AutomaticPointsTableWidgetProps local AutomaticPointsTableWidget = Class.new(Widget) +---@return Widget function AutomaticPointsTableWidget:render() return Div{ classes = {'table-responsive', 'automatic-points-table'}, @@ -39,6 +40,8 @@ function AutomaticPointsTableWidget:render() } end +---@protected +---@return Widget function AutomaticPointsTableWidget:createTable() return Div{ classes = {'divTable', 'border-color-grey', 'border-bottom'}, @@ -51,6 +54,7 @@ function AutomaticPointsTableWidget:createTable() } end +---@private ---@param child string|Widget ---@param additionalClass string? ---@return Widget @@ -64,6 +68,8 @@ function AutomaticPointsTableWidget._createHeaderCell(child, additionalClass) } end +---@protected +---@return Widget function AutomaticPointsTableWidget:createHeader() local tournaments = self.props.tournaments @@ -80,6 +86,7 @@ function AutomaticPointsTableWidget:createHeader() } end +---@private ---@param props {children: string|number|Widget|Html|(string|number|Widget|Html)[]?, ---additionalClasses: string[]?, background: string?, bold: boolean?, css: table?} ---@return Widget @@ -102,6 +109,7 @@ function AutomaticPointsTableWidget._createRowCell(props) } end +---@protected ---@param opponent AutomaticPointsTableOpponent ---@param opponentIndex integer ---@return Widget From 8db21b10a8703be6ec79d8bc8e2eb24b2e0786a5 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Tue, 30 Dec 2025 09:20:53 +0900 Subject: [PATCH 10/22] add note support --- lua/wikis/commons/AutomaticPointsTable.lua | 2 ++ lua/wikis/commons/Widget/AutomaticPointsTable.lua | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 7cdb1860402..5905681f543 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -54,6 +54,7 @@ local POINTS_TYPE = { ---@field totalPoints number ---@field placement integer ---@field background string? +---@field note string? ---@class AutomaticPointsTable ---@operator call(Frame): AutomaticPointsTable @@ -152,6 +153,7 @@ function AutomaticPointsTable:parseOpponents(args, tournaments) opponent = Opponent.readOpponentArgs(parsedArgs), tiebreakerPoints = tonumber(parsedArgs.tiebreaker) or 0, background = parsedArgs.bg, + note = parsedArgs.note, } assert(parsedOpponent.opponent.type == Opponent.team) assert(not Opponent.isTbd(parsedOpponent.opponent)) diff --git a/lua/wikis/commons/Widget/AutomaticPointsTable.lua b/lua/wikis/commons/Widget/AutomaticPointsTable.lua index b4314c432ee..562685c8285 100644 --- a/lua/wikis/commons/Widget/AutomaticPointsTable.lua +++ b/lua/wikis/commons/Widget/AutomaticPointsTable.lua @@ -125,7 +125,7 @@ function AutomaticPointsTableWidget:createRow(opponent, opponentIndex) AutomaticPointsTableWidget._createRowCell{ additionalClasses = {'name-cell'}, background = opponent.background, - children = OpponentDisplay.InlineOpponent{opponent = opponent.opponent}, + children = OpponentDisplay.InlineOpponent{opponent = opponent.opponent, note = opponent.note}, }, AutomaticPointsTableWidget._createRowCell{ bold = true, From 874f3f8f29f087e99dbd3686256abcd746c36411 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Tue, 30 Dec 2025 09:25:56 +0900 Subject: [PATCH 11/22] fix placement logic --- lua/wikis/commons/AutomaticPointsTable.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 5905681f543..d7d327f03b8 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -319,7 +319,7 @@ function AutomaticPointsTable:addPlacements(opponents) opponent.placement = index elseif opponent.totalPoints ~= opponents[index - 1].totalPoints then opponent.placement = index - elseif opponent.tiebreakerPoints ~= opponents[index - 1].totalPoints then + elseif opponent.tiebreakerPoints ~= opponents[index - 1].tiebreakerPoints then opponent.placement = index else opponent.placement = opponents[index - 1].placement From 822e097aab7b3631b50f21a5627eca4ec784a13a Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Tue, 30 Dec 2025 09:55:36 +0900 Subject: [PATCH 12/22] add qualified input handling --- lua/wikis/commons/AutomaticPointsTable.lua | 19 ++++++++++-- .../commons/Widget/AutomaticPointsTable.lua | 30 +++++++++++++++---- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index d7d327f03b8..afbe5545ee3 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -16,6 +16,7 @@ local FnUtil = Lua.import('Module:FnUtil') local Json = Lua.import('Module:Json') local Logic = Lua.import('Module:Logic') local Lpdb = Lua.import('Module:Lpdb') +local Operator = Lua.import('Module:Operator') local Opponent = Lua.import('Module:Opponent/Custom') local String = Lua.import('Module:StringUtils') local Table = Lua.import('Module:Table') @@ -50,7 +51,8 @@ local POINTS_TYPE = { ---@field opponent standardOpponent ---@field aliases string[][] ---@field tiebreakerPoints number ----@field results {type: PointsType?, amount: number?, deduction: number?, note: string?}[] +---@field results {type: PointsType?, amount: number?, qualified: boolean?, deduction: number?, note: string?}[] +---@field qualified boolean ---@field totalPoints number ---@field placement integer ---@field background string? @@ -161,10 +163,13 @@ function AutomaticPointsTable:parseOpponents(args, tournaments) parsedOpponent.results = Array.map(tournaments, function (tournament, tournamentIndex) local manualPoints = parsedArgs['points' .. tournamentIndex] + local qualified = Logic.readBoolOrNil(parsedArgs['qualified' .. tournamentIndex]) if String.isNotEmpty(manualPoints) then return Table.mergeInto({ + qualified = qualified, type = POINTS_TYPE.MANUAL, amount = tonumber(manualPoints) + }, self:parseDeduction(parsedArgs, tournamentIndex)) end @@ -174,12 +179,13 @@ function AutomaticPointsTable:parseOpponents(args, tournaments) return {} end - return Table.merge(queriedPoints, self:parseDeduction(parsedArgs, tournamentIndex)) + return Table.merge(queriedPoints, {qualified = qualified}, self:parseDeduction(parsedArgs, tournamentIndex)) end) parsedOpponent.totalPoints = Array.reduce(parsedOpponent.results, function (aggregate, result) return aggregate + (result.amount or 0) - (result.deduction or 0) end, 0) + parsedOpponent.qualified = Array.any(parsedOpponent.results, Operator.property('qualified')) Array.appendWith(opponents, parsedOpponent) end @@ -299,6 +305,13 @@ function AutomaticPointsTable:sortData(opponents) ---@param opp1 AutomaticPointsTableOpponent ---@param opp2 AutomaticPointsTableOpponent function (opp1, opp2) + if opp1.qualified then + if not opp2.qualified then + return true + end + elseif opp2.qualified then + return false + end local totalPoints1 = opp1.totalPoints local totalPoints2 = opp2.totalPoints if totalPoints1 ~= totalPoints2 then @@ -317,6 +330,8 @@ function AutomaticPointsTable:addPlacements(opponents) Array.forEach(opponents, function (opponent, index) if index == 1 then opponent.placement = index + elseif opponent.qualified ~= opponents[index - 1].qualified then + opponent.placement = index elseif opponent.totalPoints ~= opponents[index - 1].totalPoints then opponent.placement = index elseif opponent.tiebreakerPoints ~= opponents[index - 1].tiebreakerPoints then diff --git a/lua/wikis/commons/Widget/AutomaticPointsTable.lua b/lua/wikis/commons/Widget/AutomaticPointsTable.lua index 562685c8285..719e0fc3128 100644 --- a/lua/wikis/commons/Widget/AutomaticPointsTable.lua +++ b/lua/wikis/commons/Widget/AutomaticPointsTable.lua @@ -14,9 +14,12 @@ local OpponentDisplay = Lua.import('Module:OpponentDisplay/Custom') local Widget = Lua.import('Module:Widget') local HtmlWidgets = Lua.import('Module:Widget/Html/All') local Div = HtmlWidgets.Div +local IconFa = Lua.import('Module:Widget/Image/Icon/Fontawesome') local TournamentTitle = Lua.import('Module:Widget/Tournament/Title') local WidgetUtil = Lua.import('Module:Widget/Util') +local QUALIFIED_ICON = IconFa{iconName = 'qualified', color = 'forest-green-text', hover = 'Qualified'} + ---@class AutomaticPointsTableWidgetProps ---@field opponents AutomaticPointsTableOpponent ---@field tournaments StandardTournament[] @@ -120,28 +123,43 @@ function AutomaticPointsTableWidget:createRow(opponent, opponentIndex) AutomaticPointsTableWidget._createRowCell{ background = self.props.positionBackgrounds[opponentIndex], children = opponent.placement, - bold = true, + css = {['font-weight'] = 'bold'}, }, AutomaticPointsTableWidget._createRowCell{ additionalClasses = {'name-cell'}, background = opponent.background, children = OpponentDisplay.InlineOpponent{opponent = opponent.opponent, note = opponent.note}, }, - AutomaticPointsTableWidget._createRowCell{ - bold = true, - children = opponent.totalPoints, - }, + self:_createTotalPointsCell(opponent), Array.map(opponent.results, function (result, resultIndex) + local resultDisplay + if result.qualified then + resultDisplay = QUALIFIED_ICON + elseif result.amount then + resultDisplay = result.amount + elseif self.props.tournaments[resultIndex].phase == 'FINISHED' then + resultDisplay = '-' + end return AutomaticPointsTableWidget._createRowCell{ css = result.type == "SECURED" and { ['font-weight'] = 'lighter', ['font-style'] = 'italic' } or nil, - children = result.amount or (self.props.tournaments[resultIndex].phase == "FINISHED" and '-' or nil), + children = resultDisplay, } end) ) } end +---@private +---@param opponent AutomaticPointsTableOpponent +---@return Widget +function AutomaticPointsTableWidget:_createTotalPointsCell(opponent) + return AutomaticPointsTableWidget._createRowCell{ + css = {['font-weight'] = 'bold'}, + children = opponent.qualified and QUALIFIED_ICON or opponent.totalPoints, + } +end + return AutomaticPointsTableWidget From 3fbf2f9382c4abcd6142426beaf2e5b17d042486 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Tue, 30 Dec 2025 10:32:44 +0900 Subject: [PATCH 13/22] add deduction display --- lua/wikis/commons/AutomaticPointsTable.lua | 14 ++++--- .../commons/Widget/AutomaticPointsTable.lua | 40 ++++++++++++++----- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index afbe5545ee3..54f3b8fffbd 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -170,7 +170,7 @@ function AutomaticPointsTable:parseOpponents(args, tournaments) type = POINTS_TYPE.MANUAL, amount = tonumber(manualPoints) - }, self:parseDeduction(parsedArgs, tournamentIndex)) + }, self:parseDeduction(parsedArgs, tournament, tournamentIndex)) end local queriedPoints = self:queryPlacement(aliases[tournamentIndex], tournament) @@ -179,7 +179,7 @@ function AutomaticPointsTable:parseOpponents(args, tournaments) return {} end - return Table.merge(queriedPoints, {qualified = qualified}, self:parseDeduction(parsedArgs, tournamentIndex)) + return Table.merge(queriedPoints, {qualified = qualified}, self:parseDeduction(parsedArgs, tournament, tournamentIndex)) end) parsedOpponent.totalPoints = Array.reduce(parsedOpponent.results, function (aggregate, result) @@ -216,18 +216,20 @@ end --- change that causes them to lose a portion or all of their points that they've accumulated --- up until that change ---@param args table ----@param index integer +---@param tournament StandardTournament +---@param tournamentIndex integer ---@return {deduction: number?, note: string?}[] -function AutomaticPointsTable:parseDeduction(args, index) - local deduction = args['deduction' .. index] +function AutomaticPointsTable:parseDeduction(args, tournament, tournamentIndex) + local deduction = args['deduction' .. tournamentIndex] if String.isEmpty(deduction) then return {} elseif not Logic.isNumeric(deduction) then return {} end + tournament.extradata.includesDeduction = true return { deduction = tonumber(deduction), - note = args['deduction' .. index .. 'note'] + note = args['deduction' .. tournamentIndex .. 'note'] } end diff --git a/lua/wikis/commons/Widget/AutomaticPointsTable.lua b/lua/wikis/commons/Widget/AutomaticPointsTable.lua index 719e0fc3128..350912ec0eb 100644 --- a/lua/wikis/commons/Widget/AutomaticPointsTable.lua +++ b/lua/wikis/commons/Widget/AutomaticPointsTable.lua @@ -33,11 +33,17 @@ local AutomaticPointsTableWidget = Class.new(Widget) ---@return Widget function AutomaticPointsTableWidget:render() + local numCols = Array.reduce(self.props.tournaments, function (aggregate, tournament) + if tournament.extradata.includesDeduction then + return aggregate + 2 + end + return aggregate + 1 + end, 0) return Div{ classes = {'table-responsive', 'automatic-points-table'}, children = Div{ classes = {'fixed-size-table-container', 'border-color-grey'}, - css = {width = (450 + #self.props.tournaments * 50) .. 'px'}, + css = {width = (450 + numCols * 50) .. 'px'}, children = self:createTable() } } @@ -82,8 +88,11 @@ function AutomaticPointsTableWidget:createHeader() AutomaticPointsTableWidget._createHeaderCell('Ranking','ranking'), AutomaticPointsTableWidget._createHeaderCell('Team', 'team'), AutomaticPointsTableWidget._createHeaderCell('Total Points'), - Array.map(tournaments, function (tournament) - return AutomaticPointsTableWidget._createHeaderCell(TournamentTitle{tournament = tournament}) + Array.flatMap(tournaments, function (tournament) + return { + AutomaticPointsTableWidget._createHeaderCell(TournamentTitle{tournament = tournament}), + tournament.extradata.includesDeduction and AutomaticPointsTableWidget._createHeaderCell('Deductions') or nil + } end) ) } @@ -131,7 +140,7 @@ function AutomaticPointsTableWidget:createRow(opponent, opponentIndex) children = OpponentDisplay.InlineOpponent{opponent = opponent.opponent, note = opponent.note}, }, self:_createTotalPointsCell(opponent), - Array.map(opponent.results, function (result, resultIndex) + Array.flatMap(opponent.results, function (result, resultIndex) local resultDisplay if result.qualified then resultDisplay = QUALIFIED_ICON @@ -140,12 +149,23 @@ function AutomaticPointsTableWidget:createRow(opponent, opponentIndex) elseif self.props.tournaments[resultIndex].phase == 'FINISHED' then resultDisplay = '-' end - return AutomaticPointsTableWidget._createRowCell{ - css = result.type == "SECURED" and { - ['font-weight'] = 'lighter', - ['font-style'] = 'italic' - } or nil, - children = resultDisplay, + return { + AutomaticPointsTableWidget._createRowCell{ + css = result.type == "SECURED" and { + ['font-weight'] = 'lighter', + ['font-style'] = 'italic' + } or nil, + children = resultDisplay, + }, + self.props.tournaments[resultIndex].extradata.includesDeduction and AutomaticPointsTableWidget._createRowCell{ + children = result.deduction and { + HtmlWidgets.Abbr{ + classes = {'deduction-box'}, + title = result.note, + children = result.deduction + } + } or nil + } or nil } end) ) From 5247dbc843993f6f6b31d310bac35907f3fe1fc9 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Tue, 30 Dec 2025 10:45:55 +0900 Subject: [PATCH 14/22] use BlockOpponent looks slightly better --- lua/wikis/commons/Widget/AutomaticPointsTable.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/wikis/commons/Widget/AutomaticPointsTable.lua b/lua/wikis/commons/Widget/AutomaticPointsTable.lua index 350912ec0eb..ae0fc6c2a26 100644 --- a/lua/wikis/commons/Widget/AutomaticPointsTable.lua +++ b/lua/wikis/commons/Widget/AutomaticPointsTable.lua @@ -137,7 +137,7 @@ function AutomaticPointsTableWidget:createRow(opponent, opponentIndex) AutomaticPointsTableWidget._createRowCell{ additionalClasses = {'name-cell'}, background = opponent.background, - children = OpponentDisplay.InlineOpponent{opponent = opponent.opponent, note = opponent.note}, + children = OpponentDisplay.BlockOpponent{opponent = opponent.opponent, note = opponent.note}, }, self:_createTotalPointsCell(opponent), Array.flatMap(opponent.results, function (result, resultIndex) From e235ad1b148dea7fa4568847195208c5d14a192b Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Tue, 30 Dec 2025 10:46:05 +0900 Subject: [PATCH 15/22] lint --- lua/wikis/commons/AutomaticPointsTable.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 54f3b8fffbd..bff32d9b786 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -179,7 +179,9 @@ function AutomaticPointsTable:parseOpponents(args, tournaments) return {} end - return Table.merge(queriedPoints, {qualified = qualified}, self:parseDeduction(parsedArgs, tournament, tournamentIndex)) + return Table.merge( + queriedPoints, {qualified = qualified}, self:parseDeduction(parsedArgs, tournament, tournamentIndex) + ) end) parsedOpponent.totalPoints = Array.reduce(parsedOpponent.results, function (aggregate, result) From a897aea9bff31970b4d6b0a975ac08f275683b07 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 31 Dec 2025 11:37:22 +0900 Subject: [PATCH 16/22] add todo note --- lua/wikis/commons/AutomaticPointsTable.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index bff32d9b786..0117f87c8a1 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -187,6 +187,8 @@ function AutomaticPointsTable:parseOpponents(args, tournaments) parsedOpponent.totalPoints = Array.reduce(parsedOpponent.results, function (aggregate, result) return aggregate + (result.amount or 0) - (result.deduction or 0) end, 0) + + -- TODO: Automate qualified once #6762 is merged parsedOpponent.qualified = Array.any(parsedOpponent.results, Operator.property('qualified')) Array.appendWith(opponents, parsedOpponent) From 21e0e5d05a8ed85532f27bd685b08e379f58e605 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 31 Dec 2025 11:38:21 +0900 Subject: [PATCH 17/22] move note --- lua/wikis/commons/AutomaticPointsTable.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 0117f87c8a1..04d10b1a10d 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -163,6 +163,7 @@ function AutomaticPointsTable:parseOpponents(args, tournaments) parsedOpponent.results = Array.map(tournaments, function (tournament, tournamentIndex) local manualPoints = parsedArgs['points' .. tournamentIndex] + -- TODO: Automate qualified once #6762 is merged local qualified = Logic.readBoolOrNil(parsedArgs['qualified' .. tournamentIndex]) if String.isNotEmpty(manualPoints) then return Table.mergeInto({ @@ -188,7 +189,6 @@ function AutomaticPointsTable:parseOpponents(args, tournaments) return aggregate + (result.amount or 0) - (result.deduction or 0) end, 0) - -- TODO: Automate qualified once #6762 is merged parsedOpponent.qualified = Array.any(parsedOpponent.results, Operator.property('qualified')) Array.appendWith(opponents, parsedOpponent) From 6bd138692a2715ac5d62946d1042e458869dde2d Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 2 Jan 2026 09:07:44 +0900 Subject: [PATCH 18/22] kick logging --- lua/wikis/commons/AutomaticPointsTable.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 04d10b1a10d..b4b8ee1f87a 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -74,7 +74,6 @@ local AutomaticPointsTable = Class.new( ---@return Widget function AutomaticPointsTable.run(frame) local pointsTable = AutomaticPointsTable(frame):process() - mw.logObject(pointsTable.opponents, 'opponents') return pointsTable:display() end From 1777091ab7e80477726bac5d3177deaed19b40ff Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 2 Jan 2026 09:08:35 +0900 Subject: [PATCH 19/22] rename to opponentName instead of teamName --- lua/wikis/commons/AutomaticPointsTable.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index b4b8ee1f87a..95ec01729f4 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -81,14 +81,14 @@ end function AutomaticPointsTable:storeLPDB(opponents) local date = DateExt.getContextualDateOrNow() Array.forEach(opponents, function(opponent) - local teamName = Opponent.toName(opponent.opponent) + local opponentName = Opponent.toName(opponent.opponent) local lpdbName = self.parsedInput.lpdbName - local uniqueId = teamName .. '_' .. lpdbName + local uniqueId = opponentName .. '_' .. lpdbName local position = opponent.placement local totalPoints = opponent.totalPoints local objectData = { type = 'automatic_points', - name = teamName, + name = opponentName, information = position, date = date, extradata = { From 51435fed1523267d0f4890e4fb405fe17283330e Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 2 Jan 2026 09:15:35 +0900 Subject: [PATCH 20/22] style --- lua/wikis/commons/AutomaticPointsTable.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index 95ec01729f4..a089956c4de 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -117,7 +117,7 @@ function AutomaticPointsTable:parseInput(args) opponents = opponents, shouldTableBeMinified = minified, limit = limit, - lpdbName = lpdbName + lpdbName = lpdbName, } end From aa95adad6585521313c6863e62b9d1f5e7482e78 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 2 Jan 2026 09:15:47 +0900 Subject: [PATCH 21/22] remove unused param --- lua/wikis/commons/AutomaticPointsTable.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/wikis/commons/AutomaticPointsTable.lua b/lua/wikis/commons/AutomaticPointsTable.lua index a089956c4de..e299f795023 100644 --- a/lua/wikis/commons/AutomaticPointsTable.lua +++ b/lua/wikis/commons/AutomaticPointsTable.lua @@ -45,7 +45,6 @@ local POINTS_TYPE = { ---@field shouldTableBeMinified boolean ---@field limit number ---@field lpdbName string ----@field shouldResolveRedirect boolean ---@class AutomaticPointsTableOpponent ---@field opponent standardOpponent From fc0335dee9636e7a7adee81b5c48225d2987d6d9 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 2 Jan 2026 09:16:17 +0900 Subject: [PATCH 22/22] single quote for string --- lua/wikis/commons/Widget/AutomaticPointsTable.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/wikis/commons/Widget/AutomaticPointsTable.lua b/lua/wikis/commons/Widget/AutomaticPointsTable.lua index ae0fc6c2a26..75c8b591868 100644 --- a/lua/wikis/commons/Widget/AutomaticPointsTable.lua +++ b/lua/wikis/commons/Widget/AutomaticPointsTable.lua @@ -151,7 +151,7 @@ function AutomaticPointsTableWidget:createRow(opponent, opponentIndex) end return { AutomaticPointsTableWidget._createRowCell{ - css = result.type == "SECURED" and { + css = result.type == 'SECURED' and { ['font-weight'] = 'lighter', ['font-style'] = 'italic' } or nil,