Compare commits

..

10 Commits

Author SHA1 Message Date
ostertun
b87f557a62 Merge branch 'hotfix/rank_quali' 2022-04-27 14:14:03 +02:00
ostertun
ae8aed446b gitflow-hotfix-stash: rank_quali 2022-04-27 14:13:53 +02:00
ostertun
343d898afd Merge branch 'release/v_1.11.7' 2022-04-27 13:35:19 +02:00
ostertun
1fc7b8fe6d gitflow-release-stash: v_1.11.7 2022-04-27 13:35:06 +02:00
ostertun
2014303fae added special rank links 2022-04-27 13:34:26 +02:00
ostertun
7b6ad832a9 new ranking calculation (via ranking DB table) 2022-04-27 13:13:41 +02:00
ostertun
eaf0fd5a95 Merge branch 'hotfix/rank_fault_info' 2022-04-25 11:31:24 +02:00
ostertun
6c547d43c5 Merge branch 'hotfix/rank_fault_info' into develop 2022-04-25 11:31:24 +02:00
ostertun
e9e56b66ab gitflow-hotfix-stash: rank_fault_info 2022-04-25 11:31:12 +02:00
ostertun
8ba463c8fe Merge branch 'release/v_1.11.6' into develop 2022-04-21 14:08:01 +02:00
4 changed files with 261 additions and 138 deletions

View File

@@ -1,4 +1,4 @@
const DB_VERSION = 7;
const DB_VERSION = 8;
const USER_ID = localStorage.getItem('auth_user');
const USER_NAME = localStorage.getItem('auth_username');
@@ -262,6 +262,9 @@ function dbGetRanking(minDate, maxDate, maxAge, ageStrict, altM = 9, ageCrew = f
return new Promise(async function(resolve) {
var rankNoResults = [];
// TODO: remove / Abwärtskompatibilität
//if (maxAge === true) maxAge = await dbGetClassProp('youth-age');
var sailors = await dbGetData('sailors');
var regattas = await dbGetRegattasRange(minDate, maxDate);
@@ -570,7 +573,7 @@ function sync() {
localTimes[entry['table']] = entry['time'];
});
syncInProgress = 12;
syncInProgress = 13;
var syncOkay = true;
log("[db] Sync Start");
$('#i-sync').addClass('fa-spin');
@@ -618,6 +621,33 @@ function sync() {
}
});
// RANKINGS
getJSON(QUERY_URL + 'get_rankings', function (code, data) {
if (code == 200) {
var os = db.transaction('rankings', 'readwrite').objectStore('rankings');
data.data.forEach(function (entry) {
os.put(entry);
});
os.openCursor().onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
if (!data.keys.includes(parseInt(cursor.key))) {
os.delete(cursor.key);
}
cursor.continue();
} else {
syncInProgress --;
log('[db] rankings synced, remaining:', syncInProgress);
}
};
} else {
log("[db] rankings: Something went wrong (HTTP " + code + ")");
syncOkay = false;
syncInProgress --;
log('[db] rankings failed, remaining:', syncInProgress);
}
});
// CLUBS
if (localTimes['clubs'] < serverTimes['clubs']) {
getJSON(QUERY_URL + 'get_clubs?changed-after=' + localTimes['clubs'], function (code, data) {
@@ -1155,6 +1185,11 @@ function initDatabase() {
var osClass = db.createObjectStore('class', { keyPath: 'key' });
}
if ((oldVersion < 8) && (newVersion >= 8)) {
log('[db] to version 8');
var osRankings = db.createObjectStore('rankings', { keyPath: 'id' });
}
// Force resync after db update
if (oldVersion >= 1) {
var osUpdateTimes = upgradeTransaction.objectStore('update_times');

View File

@@ -1,46 +1,45 @@
<?php
$sp['title'] = 'Ranglisten - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = 'index';
$sp['activenav'] = 3;
// Title, Inputs
$content = "<h1>Ranglisten</h1>";
$options = '<option value="year">Jahres-Rangliste</option>';
$options .= '<option value="youth">Jugend-Rangliste</option>';
$options .= '<option value="idjm">' . $_CLASS['youth-german-name'] . '-Rangliste</option>';
$options .= '<option value="user">Benutzerdefiniert</option>';
$content .= $tpl->load('select', ['html-id' => 'select-type', 'placeholder' => 'Rangliste', 'options' => $options, 'css-class' => 'mt-3 mb-0']);
$content .= $tpl->load('select', ['html-id' => 'select-year', 'placeholder' => 'Jahr', 'css-class' => 'mt-3 mb-0']);
$content .= $tpl->load('select', ['html-id' => 'select-type', 'placeholder' => 'Rangliste', 'css-class' => 'mt-3 mb-0']);
$content .= $tpl->load('input', ['html-id' => 'input-from', 'placeholder' => 'Von', 'type' => 'date', 'css-class' => 'mt-3']);
$content .= $tpl->load('input', ['html-id' => 'input-to', 'placeholder' => 'Bis', 'type' => 'date']);
$chbox = $tpl->load('checkbox', ['html-id' => 'input-jugend', 'placeholder' => 'Jugend']);
$content .= '<div class="mb-3" style="display:inline-block; width:50%;">' . $chbox . '</div>';
$chbox = $tpl->load('checkbox', ['html-id' => 'input-jugstrict', 'placeholder' => 'Streng']);
$content .= '<div class="mb-3" style="display:inline-block; width:50%;">' . $chbox . '</div>';
$content .= $tpl->load('input', ['html-id' => 'input-altm', 'placeholder' => 'alt. m', 'type' => 'number']);
$content .= $tpl->load('input', ['html-id' => 'input-maxage', 'placeholder' => 'max. Alter (leer = nicht prüfen)', 'type' => 'number']);
$content .= $tpl->load('checkbox', ['html-id' => 'input-agestrict', 'placeholder' => 'unb. Jahrgänge ausschließen']);
$content .= $tpl->load('checkbox', ['html-id' => 'input-agecrew', 'placeholder' => 'Crew auch prüfen']);
$content .= $tpl->load('button', ['Anzeigen', '#', 'html-id' => 'button-show']);
$sp['output'] .= $tpl->load('card', [$content]);
// Sepcial ranks
$sp['output'] .= $tpl->load('card', ['', 'html-id' => 'card-special-ranks']);
// No Results
$content = '<h2 class="color-white">ACHTUNG</h2>';
$content .= '<p class="color-white">Zu folgenden Regatten wurden noch keine Ergebnisse hinterlegt:</p>';
$content .= '<ul id="ul-noresults"></ul>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-noresults', 'css-class' => 'bg-red2-dark']);
// Ranking
$content = $tpl->load('input', ['html-id' => 'input-search', 'placeholder' => 'Suche', 'type' => 'text']);
$content .= '<div id="div-rank" class="ranking-list mb-0"></div>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-rank']);
// Menu
$items = '<p id="menu-item-text" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
$items .= '<div id="div-details" class="ranking-detail-list mb-3" style="line-height: 2em;"></div>';
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-rank', 'title' => 'Ranglisten-Details', 'height' => 500]);
$sp['scripts'] .= $scripts->load('rank');
?>
?>

View File

@@ -106,119 +106,213 @@ async function onRankingClicked(id) {
$('#menu-rank').scrollTop(0);
}
async function selectChange(callSiteScript = true) {
var type = $('#select-type').val();
var year = parseInt($('#select-year').val());
if (type == "user") {
$('#select-year').parent().hide();
$('#input-from').trigger('focusin').trigger('focusout').parent().show();
$('#input-to').trigger('focusin').trigger('focusout').parent().show();
$('#input-jugend').parent().parent().show();
$('#input-jugstrict').parent().parent().show();
$('#button-show').show();
} else {
$('#select-year').parent().show();
$('#input-from').parent().hide();
$('#input-to').parent().hide();
$('#input-jugend').parent().parent().hide();
$('#input-jugstrict').parent().parent().hide();
$('#button-show').hide();
var rankings;
var from, to, jugend, jugstrict;
switch (type) {
case 'year':
from = (year - 1) + '-12-01';
to = year + '-11-30';
jugend = jugstrict = false;
break;
case 'youth':
from = (year - 1) + '-12-01';
to = year + '-11-30';
jugend = jugstrict = true;
break;
case 'idjm':
var youthGermanName = await dbGetClassProp('youth-german-name');
var beginn = null;
var regattas = await dbGetData('regattas');
regattas.sort(function(a,b){ return b.date.localeCompare(a.date); });
for (var r in regattas) {
var regatta = regattas[r];
var date = parseDate(regatta.date);
if ((date < parseDate('01.01.' + year)) || (date > parseDate('31.12.' + year))) {
continue;
function selectChange(callSiteScript = true) {
return new Promise(async function (resolve) {
var year = $('#select-year').val();
if (year == "user") {
$('#select-type').parent().hide();
$('#input-from').trigger('focusin').trigger('focusout').parent().show();
$('#input-to').trigger('focusin').trigger('focusout').parent().show();
$('#input-altm').trigger('focusin').trigger('focusout').parent().show();
$('#input-maxage').trigger('focusin').trigger('focusout').parent().show();
$('#input-agestrict').parent().show();
$('#input-agecrew').parent().show();
$('#button-show').show();
$('#card-special-ranks').hide();
} else {
year = parseInt(year);
var type = $('#select-type').val();
console.log('[rank] selected', year, type);
$('#select-type').parent().show();
$('#input-from').parent().hide();
$('#input-to').parent().hide();
$('#input-altm').parent().hide();
$('#input-maxage').parent().hide();
$('#input-agestrict').parent().hide();
$('#input-agecrew').parent().hide();
$('#button-show').hide();
$('#card-special-ranks').hide(); // first hide, show only when there are special ranks
var rankingsShow = {};
var options = '';
for (var i in rankings) {
if (rankings[i].year_from !== null && rankings[i].year_from > year) continue;
if (rankings[i].year_to !== null && rankings[i].year_to < year) continue;
var alias = rankings[i].alias;
options += '<option value="' + alias + '">' + rankings[i].name + '</option>';
rankingsShow[alias] = rankings[i];
}
$('#select-type').html(options);
if (!(type in rankingsShow)) {
console.log('[rank] selected type', type, 'not found for year', year, '. Using `year`');
type = 'year';
}
$('#select-type').val(type).trigger('focusin').trigger('focusout');
// special ranks
getJSON(QUERY_URL + 'get_special_rankings', function (code, data) {
if (code == 200) {
var specialRanks = [];
for (var i in data.data) {
var sr = data.data[i];
if (sr.to < (year + '-01-01')) continue;
if (sr.to > (year + '-12-31')) continue;
specialRanks.push(sr);
}
if (regatta.name.indexOf(youthGermanName) >= 0) {
beginn = ((regatta.meldungSchluss != null) ? parseDate(regatta.meldungSchluss) : date);
break;
if (specialRanks.length > 0) {
var btns = '';
for (var i in specialRanks) {
var sr = specialRanks[i];
var link = 'https://regatten.net/frame.php?class=' + BOATCLASS + '&site=special_rank&rank_id=' + sr.id;
var name = sr.title;
var cssclass = i > 0 ? ' mt-3' : '';
btns += '<a class="btn btn-full rounded-s text-uppercase font-900 shadow-m bg-highlight' + cssclass + '" href="' + link + '">' + name + '</a>';
}
$('#card-special-ranks').find('.content').html(btns);
$('#card-special-ranks').show();
}
}
if (beginn != null) {
from = new Date(beginn);
from.setFullYear(from.getFullYear() - 1);
from.setDate(from.getDate() - 13);
from = formatDate('Y-m-d', from);
to = new Date(beginn);
to.setDate(to.getDate() - 14);
to = formatDate('Y-m-d', to);
jugend = true;
jugstrict = false;
} else {
$('#div-rank').html('Keine ' + youthGermanName + ' gefunden!');
$('#input-search').parent().hide();
return;
log("[rank] special_ranks: Something went wrong (HTTP " + code + ")");
}
break;
}
});
$('#input-from').val(from);
$('#input-to').val(to);
$('#input-jugend').prop('checked', jugend);
$('#input-jugstrict').prop('checked', jugstrict);
var from, to, altm, maxage, agestrict, agecrew;
altm = 9; maxage = false; agestrict = false; agecrew = false;
var r = rankingsShow[type];
console.log('[rank] type', type, '=>', r);
if (r.max_age !== null) {
maxage = r.max_age;
agestrict = r.age_strict == 1;
agecrew = r.age_crew == 1;
}
if (r.alt_m !== null) {
altm = r.alt_m;
}
switch (r.type) {
case 'year':
from = (year - 1) + '-12-01';
to = year + '-11-30';
break;
case 'quali':
// TODO: auslagern in function getRegattaBegin
var beginn = null;
var regattas = await dbGetData('regattas');
regattas.sort(function(a,b){ return b.date.localeCompare(a.date); });
for (var ri in regattas) {
var regatta = regattas[ri];
var date = parseDate(regatta.date);
if ((date < parseDate('01.01.' + year)) || (date > parseDate('31.12.' + year))) {
continue;
}
if (regatta.name.toLowerCase().indexOf(r.quali_search.toLowerCase()) >= 0) {
console.log('FOUND', regatta);
beginn = ((regatta.meldungSchluss != null) ? parseDate(regatta.meldungSchluss) : date);
break;
}
}
// END OF TODO
if (beginn !== null) {
from = new Date(beginn);
from.setFullYear(from.getFullYear() - 1);
from.setDate(from.getDate() - 13);
from = formatDate('Y-m-d', from);
to = new Date(beginn);
to.setDate(to.getDate() - 14);
to = formatDate('Y-m-d', to);
} else {
console.log('[rank] no regatta found');
from = year + '-12-31'; // reverse => no regattas will be found => no ranking
to = year + '-01-01';
break; // TODO: bessere Fehlermeldung - keine Regatta gefunden
}
break;
default: // TODO: bessere Fehlermeldung - tritt nur bei Fehlkonfiguration in DB auf
from = (year - 1) + '-12-01';
to = year + '-11-30';
break;
}
if (callSiteScript && (typeof siteScript === 'function')) {
history.replaceState(null, '', '?type=' + type + '&year=' + year);
showLoader();
siteScript();
console.log('[rank] setting', from, to, altm, maxage, agestrict, agecrew);
$('#input-from').val(from);
$('#input-to').val(to);
$('#input-altm').val(altm);
$('#input-maxage').val(maxage == false ? '' : maxage);
$('#input-agestrict').prop('checked', agestrict);
$('#input-agecrew').prop('checked', agecrew);
if (callSiteScript && (typeof siteScript === 'function')) {
history.replaceState(null, '', '?year=' + year + '&type=' + type);
showLoader();
siteScript();
}
}
}
resolve();
});
}
function buttonShowPressed() {
if (typeof siteScript === 'function') {
var chboxes = '';
if ($('#input-jugend').prop('checked')) chboxes += '&jugend=on'
if ($('#input-jugstrict').prop('checked')) chboxes += '&jugstrict=on'
history.replaceState(null, '', '?type=user&from=' + $('#input-from').val() + "&to=" + $('#input-to').val() + chboxes)
var additional = '';
if ($('#input-maxage').val() != '') additional += '&maxage=' + $('#input-maxage').val();
if ($('#input-agestrict').prop('checked')) additional += '&agestrict=on';
if ($('#input-agecrew').prop('checked')) additional += '&agecrew=on';
history.replaceState(null, '', '?year=user&from=' + $('#input-from').val() + "&to=" + $('#input-to').val() + "&altm=" + $('#input-altm').val() + additional)
showLoader();
siteScript();
}
}
function initSelects() {
var type = findGetParameter('type');
var year = findGetParameter('year');
if (type === null) type = 'year';
if (year === null) year = new Date().getFullYear();
return new Promise(async function(resolve) {
var year = findGetParameter('year');
var type = findGetParameter('type');
if (year === null) year = new Date().getFullYear();
if (type === null) type = 'year';
$('#select-type').val(type);
var years = await dbGetData('years');
years.sort(function (a, b) {
if (a['year'] > b['year']) return -1;
if (a['year'] < b['year']) return 1;
return 0;
});
var yearFound = year == 'user';
var options = '<option value="user">Benutzerdefiniert</option>';
for (id in years) {
var y = years[id]['year'];
options += '<option value="' + y + '">' + y + '</option>';
if (year == y) yearFound = true;
}
$('#select-year').html(options);
$('#select-year').val(yearFound ? year : years[0]);
$('#select-year').html('<option value="' + year + '">' + year + '</option>');
$('#select-year').val(year);
$('#select-type').html('<option value="' + type + '">' + type + '</option>');
$('#select-type').val(type);
if (type == "user") {
var from = findGetParameter('from');
var to = findGetParameter('to');
if (from === null) from = formatDate('Y-m-d')
if (to === null) to = formatDate('Y-m-d')
$('#input-from').val(from).trigger('focusin').trigger('focusout');
$('#input-to').val(to).trigger('focusin').trigger('focusout');
var jugend = findGetParameter('jugend');
var jugstrict = findGetParameter('jugstrict');
$('#input-jugend').prop('checked', jugend !== null);
$('#input-jugstrict').prop('checked', jugstrict !== null);
}
if (year == "user") {
var from = findGetParameter('from');
var to = findGetParameter('to');
if (from === null) from = formatDate('Y-m-d');
if (to === null) to = formatDate('Y-m-d');
$('#input-from').val(from).trigger('focusin').trigger('focusout');
$('#input-to').val(to).trigger('focusin').trigger('focusout');
var altm = findGetParameter('altm');
if (altm === null) altm = 9;
$('#input-altm').val(altm).trigger('focusin').trigger('focusout');
var maxage = findGetParameter('maxage');
if (maxage === null) maxage = '';
$('#input-maxage').val(maxage).trigger('focusin').trigger('focusout');
var agestrict = findGetParameter('agestrict');
var agecrew = findGetParameter('agecrew');
$('#input-agestrict').prop('checked', agestrict !== null);
$('#input-agecrew').prop('checked', agecrew !== null);
}
selectChange(false);
await selectChange(false);
resolve();
});
}
var firstCall = true;
@@ -231,7 +325,12 @@ async function drawList () {
var list = '';
rows.forEach(function (entry) {
if (entry == null) {
list += '<div><div align="center" class="color-highlight" style="white-space:normal;"><b>Ende der Rangliste gem&auml;&szlig; DSV-Ranglistenverordnung (min. m = 9 Wertungen)</b></div></div>';
var altm = $('#input-altm').val(); if (altm == '') altm = 9; else altm = parseInt(altm);
if (altm == 9) {
list += '<div><div align="center" class="color-highlight" style="white-space:normal;"><b>Ende der Rangliste gem&auml;&szlig; DSV-Ranglistenverordnung (min. m = 9 Wertungen)</b></div></div>';
} else {
list += '<div><div align="center" class="color-highlight" style="white-space:normal;"><b>Ende der Rangliste (min. m = ' + altm + ' Wertungen)</b></div></div>';
}
} else if (search($('#input-search').val(), entry.keywords)) {
list += entry.content;
}
@@ -243,27 +342,31 @@ async function drawList () {
var siteScript = async function() {
if (firstCall) {
firstCall = false;
initSelects();
$('#select-type').change(selectChange);
rankings = await dbGetData('rankings');
await initSelects();
$('#select-year').change(selectChange);
$('#select-type').change(selectChange);
$('#button-show').click(buttonShowPressed);
$('#input-search').on('input', drawList);
}
var minDate = parseDate($('#input-from').val());
var maxDate = parseDate($('#input-to').val());
var jugend = $('#input-jugend').prop('checked');
var jugstrict = $('#input-jugstrict').prop('checked');
var dbRanking = await dbGetRanking(minDate, maxDate, jugend, jugstrict);
var altm = $('#input-altm').val(); if (altm == '') altm = 9; else altm = parseInt(altm);
var maxage = $('#input-maxage').val(); if (maxage == '') maxage = false; else maxage = parseInt(maxage);
var agestrict = $('#input-agestrict').prop('checked');
var agecrew = $('#input-agecrew').prop('checked');
console.log('[rank] rank params:', minDate, maxDate, altm, maxage, agestrict, agecrew);
var dbRanking = await dbGetRanking(minDate, maxDate, maxage, agestrict, altm, agecrew);
ranking = dbRanking[0];
lastRanking = null;
lastRanking = null; // TODO: also for quali ranks
if (($('#select-type').val() == 'year') || ($('#select-type').val() == 'youth')) {
lastRanking = {};
var lYear = parseInt($('#select-year').val()) - 1;
var lMinDate = parseDate((lYear - 1) + '-12-01');
var lMaxDate = parseDate(lYear + '-11-30');
var lDbRanking = (await dbGetRanking(lMinDate, lMaxDate, jugend, jugstrict))[0];
var lDbRanking = (await dbGetRanking(lMinDate, lMaxDate, maxage, agestrict, altm, agecrew))[0];
for (var i in lDbRanking) {
lastRanking[lDbRanking[i].id] = lDbRanking[i].rank;
}
@@ -271,20 +374,6 @@ var siteScript = async function() {
var selectedYear = $('#select-year').val();
var years = await dbGetData('years');
years.sort(function (a, b) {
if (a['year'] > b['year']) return -1;
if (a['year'] < b['year']) return 1;
return 0;
});
var options = '';
for (id in years) {
var year = years[id]['year'];
options += '<option value="' + year + '">' + year + '</option>';
}
$('#select-year').html(options);
$('#select-year').val(selectedYear);
if (dbRanking[1].length > 0) {
$('#card-noresults').show();
list = '';
@@ -326,7 +415,7 @@ var siteScript = async function() {
if (entry['year'] != null) row.keywords.push(entry['year']);
if (club != null) row.keywords.push(club['kurz'], club['name']);
if (!dsvEnd && (entry.m < 9)) {
if (!dsvEnd && (entry.m < altm)) {
rows.push(null);
dsvEnd = true;
}

View File

@@ -1,5 +1,5 @@
<?php
define('PWA_VERSION', '1.11.6');
define('PWA_VERSION', '1.11.7h1');
?>