Skip to content
Permalink
Browse files

Added server side columns sorting on the Process Scheduler table

For easier usage of large tables in the Table_API_p.html page.
  • Loading branch information...
luccioman committed Jul 4, 2018
1 parent bb51555 commit 2bdd71de60a8115117422ee46b259d3f63c450a4
@@ -63,33 +63,53 @@ <h2>Process Scheduler</h2>
<span id="resCounter" style="display: inline;">
#(navigation)#
::
#(left)#<img src="env/grafics/navdl.gif" alt="no previous page" />::<a href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#" target="_self"><img src="env/grafics/navsl.gif" alt="previous page" /></a>#(/left)#
#(left)#<img src="env/grafics/navdl.gif" alt="no previous page" />::<a href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#&amp;sort=#[sort]#" target="_self"><img src="env/grafics/navsl.gif" alt="previous page" /></a>#(/left)#
#[startRecord]#-#[to]# of #[of]#
#(right)#<img src="env/grafics/navdr.gif" alt="no next page" />::<a href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#" target="_self"><img src="env/grafics/navsr.gif" alt="next page" /></a>#(/right)#
#(right)#<img src="env/grafics/navdr.gif" alt="no next page" />::<a href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#&amp;sort=#[sort]#" target="_self"><img src="env/grafics/navsr.gif" alt="next page" /></a>#(/right)#
<img src="env/grafics/nave.gif" alt="" />
#(/navigation)#

<input type="hidden" name="startRecord" value="#[startRecord]#" id="startRecordField"/>
<input type="hidden" name="maximumRecords" value="#[maximumRecords]#" />
<input type="hidden" name="inline" value="#(inline)#false::true#(/inline)#" />
<input type="hidden" name="filter" value="#[filter]#" />
<input type="hidden" name="sort" value="#[sort]#" />
<input type="text" name="query" value="#[query]#" onchange="resetStartRecord()" style="font-size:16px;float:left;border:0px;height:20px;background-image:url('env/grafics/find.gif');background-repeat:no-repeat;background-position:right top;"/>

</span>
<br/>
<div style="clear:both;">
<table class="sortable" style="border:0px; padding:2px; border-spacing:1px">
<table style="border:0px; padding:2px; border-spacing:1px" role="grid">
<tr class="TableHeader" valign="bottom">
<th class="sorttable_nosort"><input type="checkbox" id="allswitch" onclick="checkAll(this.form.id, this.checked);" /></th>
<th>Type</th>
<th style="width: 100%;">Comment</th>
<th>Call<br/>Count</th>
<th>Recording<br/>Date</th>
<th>Last&nbsp;Exec<br/>Date</th>
<th>Next&nbsp;Exec<br/>Date#(hasEditableNextExecDate)#:: <button type="submit" name="submitNextExecDates" class="btn btn-default btn-xs" title="Apply edited next execution dates">
<th #(sortedByType)#::aria-sort="#(asc)#descending::ascending#(/asc)#"#(/sortedByType)#>
<a class="sortTableLink" href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;sort=#(nextSortTypeDesc)#::-#(/nextSortTypeDesc)#type&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#" target="_self" title="Sort by #(nextSortTypeDesc)#ascending::descending#(/nextSortTypeDesc)# types">Type</a>
#(sortedByType)#::<span class="glyphicon glyphicon-chevron-#(asc)#down::up#(/asc)#"></span>#(/sortedByType)#
</th>
<th style="width: 100%;" #(sortedByComment)#::aria-sort="#(asc)#descending::ascending#(/asc)#"#(/sortedByComment)#>
<a class="sortTableLink" href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;sort=#(nextSortCommentDesc)#::-#(/nextSortCommentDesc)#comment&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#" target="_self" title="Sort by #(nextSortCommentDesc)#ascending::descending#(/nextSortCommentDesc)# comments">Comment</a>
#(sortedByComment)#::<span class="glyphicon glyphicon-chevron-#(asc)#down::up#(/asc)#"></span>#(/sortedByComment)#
</th>
<th #(sortedByApiCallCount)#::aria-sort="#(asc)#descending::ascending#(/asc)#"#(/sortedByApiCallCount)#>
<a class="sortTableLink" href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;sort=#(nextSortApiCallCountDesc)#::-#(/nextSortApiCallCountDesc)#apicall_count&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#" target="_self" title="Sort by #(nextSortApiCallCountDesc)#ascending::descending#(/nextSortApiCallCountDesc)# call counts">Call Count</a>
#(sortedByApiCallCount)#::<span class="glyphicon glyphicon-chevron-#(asc)#down::up#(/asc)#"></span>#(/sortedByApiCallCount)#
</th>
<th #(sortedByDateRecording)#::aria-sort="#(asc)#descending::ascending#(/asc)#"#(/sortedByDateRecording)#>
<a class="sortTableLink" href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;sort=#(nextSortDateRecordingDesc)#::-#(/nextSortDateRecordingDesc)#date_recording&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#" target="_self" title="Sort by #(nextSortDateRecordingDesc)#ascending::descending#(/nextSortDateRecordingDesc)# recording dates">Recording&nbsp;Date</a>
#(sortedByDateRecording)#::<span class="glyphicon glyphicon-chevron-#(asc)#down::up#(/asc)#"></span>#(/sortedByDateRecording)#
</th>
<th #(sortedByDateLastExec)#::aria-sort="#(asc)#descending::ascending#(/asc)#"#(/sortedByDateLastExec)#>
<a class="sortTableLink" href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;sort=#(nextSortDateLastExecDesc)#::-#(/nextSortDateLastExecDesc)#date_last_exec&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#" target="_self" title="Sort by #(nextSortDateLastExecDesc)#ascending::descending#(/nextSortDateLastExecDesc)# last execution dates">Last&nbsp;Exec&nbsp;Date</a>
#(sortedByDateLastExec)#::<span class="glyphicon glyphicon-chevron-#(asc)#down::up#(/asc)#"></span>#(/sortedByDateLastExec)#
</th>
<th #(sortedByDateNextExec)#::aria-sort="#(asc)#descending::ascending#(/asc)#"#(/sortedByDateNextExec)#>
<a class="sortTableLink" href="Table_API_p.html?startRecord=#[startRecord]#&amp;maximumRecords=#[maximumRecords]#&amp;sort=#(nextSortDateNextExecDesc)#::-#(/nextSortDateNextExecDesc)#date_next_exec&amp;inline=#(inline)#false::true#(/inline)#&amp;filter=#[filter]#&amp;query=#[query]#" target="_self" title="Sort by #(nextSortDateNextExecDesc)#ascending::descending#(/nextSortDateNextExecDesc)# last execution dates">Next&nbsp;Exec&nbsp;Date</a>
#(sortedByDateNextExec)#::<span class="glyphicon glyphicon-chevron-#(asc)#down::up#(/asc)#"></span>#(/sortedByDateNextExec)#
#(hasEditableNextExecDate)#:: <button type="submit" name="submitNextExecDates" class="btn btn-default btn-xs" title="Apply edited next execution dates">
<span class="glyphicon glyphicon-ok"></span>
<span> Apply</span>
</button>#(/hasEditableNextExecDate)#
</button>
#(/hasEditableNextExecDate)#
</th>
<th class="sorttable_nosort">Event Trigger</th>
<th class="sorttable_nosort">Scheduler</th>
@@ -44,6 +44,7 @@
import net.yacy.data.WorkTables;
import net.yacy.kelondro.blob.Tables;
import net.yacy.kelondro.blob.Tables.Row;
import net.yacy.kelondro.blob.Tables.SortDirection;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.search.query.QueryParams;
@@ -86,6 +87,21 @@ public static serverObjects respond(final RequestHeader header, final serverObje
if (post != null && post.containsKey("filter") && post.get("filter", "").length() > 0) {
typefilter = Pattern.compile(post.get("filter", ".*"));
}

/* Applying JSON API convention for the sort parameter format (http://jsonapi.org/format/#fetching-sorting) */
String sortParam = WorkTables.TABLE_API_COL_DATE_RECORDING;
if(post != null) {
sortParam = post.get("sort", WorkTables.TABLE_API_COL_DATE_RECORDING).trim();
}
final SortDirection sortDir;
final String sortColumn;
if(sortParam.startsWith("-")) {
sortColumn = sortParam.substring(1);
sortDir = SortDirection.DESC;
} else {
sortColumn = sortParam;
sortDir = SortDirection.ASC;
}

// process scheduler and event input actions
boolean scheduleeventaction = false; // flag if schedule info of row changes
@@ -310,6 +326,8 @@ public static serverObjects respond(final RequestHeader header, final serverObje
final String nextTransactionToken = TransactionManager.getTransactionToken(header);
prop.put(TransactionManager.TRANSACTION_TOKEN_PARAM, nextTransactionToken);
prop.put("showtable_" + TransactionManager.TRANSACTION_TOKEN_PARAM, nextTransactionToken);

final Date now = new Date();

// insert rows
final List<Tables.Row> table = new ArrayList<Tables.Row>(maximumRecords);
@@ -319,7 +337,22 @@ public static serverObjects respond(final RequestHeader header, final serverObje
try {
tablesize = sb.tables.size(WorkTables.TABLE_API_NAME);
final Iterator<Tables.Row> plainIterator = sb.tables.iterator(WorkTables.TABLE_API_NAME);
final Iterator<Tables.Row> mapIterator = Tables.orderBy(plainIterator, -1, WorkTables.TABLE_API_COL_DATE_RECORDING).iterator();
final Iterator<Tables.Row> mapIterator;
if(sortColumn.isEmpty()) {
mapIterator = plainIterator;
} else {
if (WorkTables.TABLE_API_COL_APICALL_COUNT.equals(sortColumn)
|| WorkTables.TABLE_API_COL_APICALL_SCHEDULE_TIME.equals(sortColumn)) {
mapIterator = Tables.orderByInt(plainIterator, sortColumn, 0, sortDir).iterator();
} else if (WorkTables.TABLE_API_COL_DATE.equals(sortColumn)
|| WorkTables.TABLE_API_COL_DATE_RECORDING.equals(sortColumn)
|| WorkTables.TABLE_API_COL_DATE_LAST_EXEC.equals(sortColumn)
|| WorkTables.TABLE_API_COL_DATE_NEXT_EXEC.equals(sortColumn)) {
mapIterator = Tables.orderByDate(plainIterator, sortColumn, now, sortDir).iterator();
} else {
mapIterator = Tables.orderByString(plainIterator, sortColumn, "", sortDir).iterator();
}
}
Tables.Row r;
boolean dark = true;
boolean scheduledactions = false;
@@ -380,7 +413,6 @@ public static serverObjects respond(final RequestHeader header, final serverObje
// then work on the list
for (final Tables.Row row : table) {
final String rowPKStr = UTF8.String(row.getPK());
final Date now = new Date();
final Date date = row.containsKey(WorkTables.TABLE_API_COL_DATE) ? row.get(WorkTables.TABLE_API_COL_DATE, now) : null;
final Date date_recording = row.get(WorkTables.TABLE_API_COL_DATE_RECORDING, date);
final Date date_last_exec = row.get(WorkTables.TABLE_API_COL_DATE_LAST_EXEC, date);
@@ -536,6 +568,10 @@ public static serverObjects respond(final RequestHeader header, final serverObje
prop.put("showtable_inline", (inline) ? 1 : 0);
prop.put("showtable_filter", typefilter.pattern());
prop.put("showtable_query", queryParam);
prop.put("showtable_sort", sortParam);

putTableSortProperties(prop, sortDir, sortColumn);

if (filteredSize > maximumRecords) {
prop.put("showtable_navigation", 1);
prop.put("showtable_navigation_startRecord", startRecord);
@@ -547,6 +583,7 @@ public static serverObjects respond(final RequestHeader header, final serverObje
prop.put("showtable_navigation_left_inline", (inline) ? 1 : 0);
prop.put("showtable_navigation_left_filter", typefilter.pattern());
prop.put("showtable_navigation_left_query", queryParam);
prop.put("showtable_navigation_left_sort", sortParam);
prop.put("showtable_navigation_left", startRecord == 0 ? 0 : 1);
prop.put("showtable_navigation_filter", typefilter.pattern());
prop.put("showtable_navigation_right", startRecord + maximumRecords >= filteredSize ? 0 : 1);
@@ -555,11 +592,55 @@ public static serverObjects respond(final RequestHeader header, final serverObje
prop.put("showtable_navigation_right_inline", (inline) ? 1 : 0);
prop.put("showtable_navigation_right_filter", typefilter.pattern());
prop.put("showtable_navigation_right_query", queryParam);
prop.put("showtable_navigation_right_sort", sortParam);
} else {
prop.put("showtable_navigation", 0);
}

// return rewrite properties
return prop;
}

/**
* Fill the serverObjects instance with table columns sort properties.
*
* @param prop
* the serverObjects instance to fill. Must not be null.
* @param sortDir
* the current sort direction
* @param sortColumn
* the current sort column
*/
private static void putTableSortProperties(final serverObjects prop, final SortDirection sortDir,
final String sortColumn) {
boolean sortedByAsc = WorkTables.TABLE_API_COL_TYPE.equals(sortColumn) && sortDir == SortDirection.ASC;
prop.put("showtable_sortedByType", WorkTables.TABLE_API_COL_TYPE.equals(sortColumn));
prop.put("showtable_sortedByType_asc", sortedByAsc);
prop.put("showtable_nextSortTypeDesc", sortedByAsc);

sortedByAsc = WorkTables.TABLE_API_COL_COMMENT.equals(sortColumn) && sortDir == SortDirection.ASC;
prop.put("showtable_sortedByComment", WorkTables.TABLE_API_COL_COMMENT.equals(sortColumn));
prop.put("showtable_sortedByComment_asc", sortedByAsc);
prop.put("showtable_nextSortCommentDesc", sortedByAsc);

sortedByAsc = WorkTables.TABLE_API_COL_APICALL_COUNT.equals(sortColumn) && sortDir == SortDirection.ASC;
prop.put("showtable_sortedByApiCallCount", WorkTables.TABLE_API_COL_APICALL_COUNT.equals(sortColumn));
prop.put("showtable_sortedByApiCallCount_asc", sortedByAsc);
prop.put("showtable_nextSortApiCallCountDesc", sortedByAsc);

sortedByAsc = WorkTables.TABLE_API_COL_DATE_RECORDING.equals(sortColumn) && sortDir == SortDirection.ASC;
prop.put("showtable_sortedByDateRecording", WorkTables.TABLE_API_COL_DATE_RECORDING.equals(sortColumn));
prop.put("showtable_sortedByDateRecording_asc", sortedByAsc);
prop.put("showtable_nextSortDateRecordingDesc", sortedByAsc);

sortedByAsc = WorkTables.TABLE_API_COL_DATE_LAST_EXEC.equals(sortColumn) && sortDir == SortDirection.ASC;
prop.put("showtable_sortedByDateLastExec", WorkTables.TABLE_API_COL_DATE_LAST_EXEC.equals(sortColumn));
prop.put("showtable_sortedByDateLastExec_asc", sortedByAsc);
prop.put("showtable_nextSortDateLastExecDesc", sortedByAsc);

sortedByAsc = WorkTables.TABLE_API_COL_DATE_NEXT_EXEC.equals(sortColumn) && sortDir == SortDirection.ASC;
prop.put("showtable_sortedByDateNextExec", WorkTables.TABLE_API_COL_DATE_NEXT_EXEC.equals(sortColumn));
prop.put("showtable_sortedByDateNextExec_asc", sortedByAsc);
prop.put("showtable_nextSortDateNextExecDesc", sortedByAsc);
}
}
@@ -15,7 +15,7 @@
## "global classes" ##
# i.e. ".strong"; ".left"; ".error";
###############################################
## "privat classes" ##
## "private classes" ##
# all HTML-elements with a specific class
# i.e. "div.content"; "span.left";
# and
@@ -607,6 +607,12 @@ a.thumblink {
overflow: hidden;
}

/* Link in a table header that triggers server-side table sorting */
a.sortTableLink, a.sortTableLink:link, a.sortTableLink:visited, a.sortTableLink:hover {
text-decoration: none;
color: white;
}

/*----------
<em>
*/
@@ -3294,13 +3294,12 @@ to a scheduler for a periodic execution.==einem Scheduler für periodische Ausf
"next page"=="Keine nächste Seite"
"previous page"=="Keine vorherige Seite"
of #[of]#== von #[of]#
>Date==>Datum
>Type==>Typ
>Comment==>Kommentar
Call<br/>Count<==Aufruf<br/>Zähler<
Recording<==Aufzeichnungs<
Last&nbsp;Exec==Letzte&nbsp;Ausführung
Next&nbsp;Exec==Nächste&nbsp;Ausführung
Call Count<==Aufruf Zähler<
Recording&nbsp;Date==Aufzeichnungs&nbsp;Datum
Last&nbsp;Exec&nbsp;Date==Letzte&nbsp;Ausführung&nbsp;Datum
Next&nbsp;Exec&nbsp;Date==Nächste&nbsp;Ausführung&nbsp;Datum
#>URL<==>URL<
>Event Trigger<==>Ereignis Auslöser<
"clone"=="Ereignis klonen"
@@ -1215,7 +1215,7 @@ YaCy Supporters<==Sostenitori di YaCy<
"next page"=="pagina successiva"
"previous page"=="pagina precedente"
# of #[of]#== su #[of]#
>Date==>Data
&nbsp;Date==&nbsp;Data
>URL<==>URL<
"clone"=="clona"
>Scheduler<==>Schedulatore<
@@ -8765,26 +8765,23 @@
<trans-unit id="1449865e" xml:space="preserve" approved="no" translate="yes">
<source> of #[of]#</source>
</trans-unit>
<trans-unit id="38a150c" xml:space="preserve" approved="no" translate="yes">
<source>&gt;Date</source>
</trans-unit>
<trans-unit id="391b498" xml:space="preserve" approved="no" translate="yes">
<source>&gt;Type</source>
</trans-unit>
<trans-unit id="c4676441" xml:space="preserve" approved="no" translate="yes">
<source>&gt;Comment</source>
</trans-unit>
<trans-unit id="c2a0ac2a" xml:space="preserve" approved="no" translate="yes">
<source>Call&lt;br/&gt;Count&lt;</source>
<source>Call Count&lt;</source>
</trans-unit>
<trans-unit id="a2a91c8b" xml:space="preserve" approved="no" translate="yes">
<source>Recording&lt;</source>
<source>Recording&amp;nbsp;Date</source>
</trans-unit>
<trans-unit id="9c5940cb" xml:space="preserve" approved="no" translate="yes">
<source>Last&amp;nbsp;Exec</source>
<source>Last&amp;nbsp;Exec&amp;nbsp;Date</source>
</trans-unit>
<trans-unit id="409928e8" xml:space="preserve" approved="no" translate="yes">
<source>Next&amp;nbsp;Exec</source>
<source>Next&amp;nbsp;Exec&amp;nbsp;Date</source>
</trans-unit>
<trans-unit id="2ef20848" xml:space="preserve" approved="no" translate="yes">
<source>&gt;Event Trigger&lt;</source>
@@ -3444,13 +3444,12 @@ to a scheduler for a periodic execution.==в планировщик для пе
"next page"=="следующая страница"
"previous page"=="предыдущая страница"
of #[of]#== по #[of]#
>Date==>Дата
>Type==>Тип
>Comment==>Комментарий
Call<br/>Count<==Количество<br/>вызовов<
Recording<==Запись<
Last&nbsp;Exec==Дата&nbsp;последнего запуска
Next&nbsp;Exec==Дата&nbsp;следующего запуска
Call Count<==Количество вызовов<
Recording&nbsp;Date==Запись&nbsp;Дата
Last&nbsp;Exec&nbsp;Date==Дата&nbsp;последнего запуска&nbsp;Дата
Next&nbsp;Exec&nbsp;Date==Дата&nbsp;следующего запуска&nbsp;Дата
#>URL<==>URL-адрес<
>Event Trigger<==>Триггер событий<
"clone"=="клонировать"

0 comments on commit 2bdd71d

Please sign in to comment.
You can’t perform that action at this time.