идентификатор удаления выделенного
This commit is contained in:
@@ -104,7 +104,7 @@ DEFAULT_CONTEXT_VARIABLES: tuple[dict[str, Any], ...] = (
|
||||
{"key": "active_away_penalty_team_penalty", "label": "Активное удаление правой команды — командное (1/0)", "category": "Активные удаления — правая команда", "entity_type": "penalty", "scope": "match_shared", "source_type": "selection", "value_type": "text"},
|
||||
{"key": "active_away_penalty_time_type", "label": "Активное удаление правой команды — тип времени (2 / 2+2 / 4 / 5 / 5+20 / 10)", "category": "Активные удаления — правая команда", "entity_type": "penalty", "scope": "match_shared", "source_type": "selection", "value_type": "text", "description": "Пресет штрафного времени текущего удаления; доступен сразу после назначения времени, до запуска countdown."},
|
||||
{"key": "selected_penalty_infraction_id", "label": "Нарушение выбранного удаления", "category": "Выделенные", "entity_type": "penalty", "scope": "match", "source_type": "selection"},
|
||||
{"key": "selected_penalty_preset_id", "label": "Длительность выбранного удаления", "category": "Выделенные", "entity_type": "penalty", "scope": "match", "source_type": "selection"},
|
||||
{"key": "selected_penalty_preset_id", "label": "ID типа выбранного удаления (hockey_penalty_types.id)", "category": "Выделенные", "entity_type": "penalty", "scope": "match", "source_type": "selection", "value_type": "text", "description": "Реальный ID типа нарушения из hockey_penalty_types для выделенной карточки удаления во вкладке Игра. Обновляется при выборе другого удаления."},
|
||||
{"key": "selected_penalty_time_type", "label": "Тип времени выбранного удаления (2 / 2+2 / 4 / 5 / 5+20 / 10)", "category": "Выделенные", "entity_type": "penalty", "scope": "match", "source_type": "selection", "value_type": "text", "description": "Точное название выбранного пресета штрафного времени. Например: 2, 2+2, 4, 5, 5+20, 10."},
|
||||
{"key": "selected_penalty_side", "label": "Сторона выбранного удаления", "category": "Выделенные", "entity_type": "penalty", "scope": "match", "source_type": "selection"},
|
||||
{"key": "selected_penalty_event_time", "label": "Время события выбранного удаления", "category": "Выделенные", "entity_type": "penalty", "scope": "match", "source_type": "selection"},
|
||||
|
||||
16692
hockey_data/ui_builder/static/app.js
Normal file
16692
hockey_data/ui_builder/static/app.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5337,6 +5337,7 @@ function startCustomTooltips() {
|
||||
const boardComponent = hockeyPenaltyBoardComponent();
|
||||
const selectedEvent = boardComponent ? selectedHockeyEvent(boardComponent) : null;
|
||||
const selectedTimeType = String(selectedEvent?.preset || "");
|
||||
const selectedPenaltyTypeId = hockeyPenaltyInfractionDbId(selectedEvent);
|
||||
const values = {
|
||||
active_home_penalty_id: home?.penalty_id || "",
|
||||
active_home_penalty_player_id: home?.player_id || "",
|
||||
@@ -5348,9 +5349,9 @@ function startCustomTooltips() {
|
||||
active_away_penalty_player_db_id: away?.player_db_id || "",
|
||||
active_away_penalty_team_penalty: away ? (away.team_penalty ? "1" : "0") : "",
|
||||
active_away_penalty_time_type: away?.time_type || "",
|
||||
// Keep the currently highlighted Game-tab penalty type ready before
|
||||
// penalty_ready/penalty_assigned invokes any vMix trigger.
|
||||
selected_penalty_preset_id: selectedTimeType,
|
||||
// Real hockey_penalty_types.id of the highlighted Game-tab penalty.
|
||||
// Keep the textual duration (2 / 2+2 / 5+20 / ...) in a separate key.
|
||||
selected_penalty_preset_id: selectedPenaltyTypeId,
|
||||
selected_penalty_time_type: selectedTimeType,
|
||||
};
|
||||
const signature = JSON.stringify([gameId, values]);
|
||||
@@ -7034,7 +7035,11 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
return directory
|
||||
.filter((item) => item && item.active !== false)
|
||||
.map((item, index) => ({
|
||||
// `id` remains the stable penalty code for compatibility with old
|
||||
// saved boards/triggers. `dbId` is the real hockey_penalty_types.id.
|
||||
id: String(item.code || item.id || `INF_${index + 1}`),
|
||||
code: String(item.code || ""),
|
||||
dbId: String(item.id ?? ""),
|
||||
label: String(item.name || item.name_ru || item.name_en || item.code || `Нарушение ${index + 1}`),
|
||||
labelRu: String(item.name_ru || ""),
|
||||
labelEn: String(item.name_en || ""),
|
||||
@@ -8758,6 +8763,38 @@ function hockeyPenaltyPlayerIdentifiers(component, event) {
|
||||
return { externalId, dbId };
|
||||
}
|
||||
|
||||
function hockeyPenaltyInfractionDbId(event) {
|
||||
const infraction = event?.infraction;
|
||||
if (!infraction || typeof infraction !== "object") return "";
|
||||
|
||||
const direct = String(
|
||||
infraction.dbId
|
||||
|| infraction.db_id
|
||||
|| infraction.database_id
|
||||
|| infraction.raw?.id
|
||||
|| ""
|
||||
).trim();
|
||||
if (direct) return direct;
|
||||
|
||||
// Old saved penalty boards only contain the penalty code in infraction.id.
|
||||
// Recover the real DB PK from the current penalty directory so selecting an
|
||||
// old penalty still updates :selected_penalty_preset_id correctly.
|
||||
const lookupValues = new Set([
|
||||
String(infraction.code || "").trim(),
|
||||
String(infraction.id || "").trim(),
|
||||
].filter(Boolean));
|
||||
if (!lookupValues.size) return "";
|
||||
|
||||
const directory = getByPath(state.data, "hockey.penalty_directory");
|
||||
if (!Array.isArray(directory)) return "";
|
||||
const row = directory.find((item) => {
|
||||
const code = String(item?.code || "").trim();
|
||||
const id = String(item?.id ?? "").trim();
|
||||
return lookupValues.has(code) || lookupValues.has(id);
|
||||
});
|
||||
return row ? String(row.id ?? "").trim() : "";
|
||||
}
|
||||
|
||||
async function hockeyClearSelectedPenaltyMappingContext(side, { clearCommon = false } = {}) {
|
||||
if (!hockeyCanControl()) return false;
|
||||
const gameId = hockeyTimerSelectedGameId();
|
||||
@@ -8846,6 +8883,9 @@ async function hockeySelectPenaltyForPreview(component, event) {
|
||||
team_id: teamId,
|
||||
team_penalty: Boolean(event.teamPenalty),
|
||||
infraction_id: String(event.infraction?.id || ""),
|
||||
penalty_type_id: hockeyPenaltyInfractionDbId(event),
|
||||
// `preset_id` remains the legacy duration value in interaction payloads;
|
||||
// Mapping uses penalty_type_id for selected_penalty_preset_id below.
|
||||
preset_id: String(event.preset || ""),
|
||||
time_type: String(event.preset || ""),
|
||||
side,
|
||||
@@ -8878,7 +8918,7 @@ async function hockeySelectPenaltyForPreview(component, event) {
|
||||
selected_penalty_team_penalty: detail.team_penalty ? "1" : "0",
|
||||
selected_penalty_team_id: detail.team_id,
|
||||
selected_penalty_infraction_id: detail.infraction_id,
|
||||
selected_penalty_preset_id: detail.preset_id,
|
||||
selected_penalty_preset_id: detail.penalty_type_id,
|
||||
selected_penalty_time_type: detail.time_type,
|
||||
selected_penalty_side: detail.side,
|
||||
selected_penalty_event_time: detail.event_time,
|
||||
@@ -13400,6 +13440,8 @@ function renderHockeyPenaltyDashboard(node, component, runtime) {
|
||||
if (!infraction || typeof infraction !== "object") return null;
|
||||
return {
|
||||
id: String(infraction.id || ""),
|
||||
code: String(infraction.code || ""),
|
||||
dbId: String(infraction.dbId || infraction.db_id || infraction.database_id || ""),
|
||||
label: String(infraction.label || ""),
|
||||
labelRu: String(infraction.labelRu || infraction.name_ru || ""),
|
||||
labelEn: String(infraction.labelEn || infraction.name_en || ""),
|
||||
|
||||
Reference in New Issue
Block a user