Commit 06003c06 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Implemented graphical column sorting for generating column_index values (in progress)

parent 146d00e7
......@@ -43,6 +43,7 @@ public class Column extends ChildEntity<Table> {
public final static String UTYPE_KEY = "utype";
public final static String UCD_KEY = "ucd";
public final static String UNIT_KEY = "unit";
public final static String COLUMN_INDEX = "column_index"; // TAP version >= 1.1
// Original datatype (computed from information_schema data), used for consistency checking
public final static String ORIGINAL_DATATYPE_KEY = "original_datatype";
......
/*
* _____________________________________________________________________________
*
* INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
* Trieste INAF - IA2 Italian Center for Astronomical Archives
* _____________________________________________________________________________
*
* Copyright (C) 2017 Istituto Nazionale di Astrofisica
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License Version 3 as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package it.inaf.ia2.tsm.webapp;
import it.inaf.ia2.tsm.Column;
import it.inaf.ia2.tsm.Status;
import it.inaf.ia2.tsm.Table;
import it.inaf.ia2.tsm.webapp.env.CustomPartialResponseWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.inject.Named;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import org.apache.deltaspike.core.api.scope.WindowScoped;
/**
*
* @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
*/
@Named
@WindowScoped
public class ColumnsSorter implements Serializable {
private static final long serialVersionUID = 1431422275331229274L;
private static class ColumnHolder {
String columnName;
int columnIndex;
ColumnHolder(String columnName, int columnIndex) {
this.columnName = columnName;
this.columnIndex = columnIndex;
}
}
private List<ColumnHolder> sortedColumns;
private List<String> unSortedColumns;
public void openModal(Table table) {
sortedColumns = new ArrayList<>();
unSortedColumns = new ArrayList<>();
for (Column column : table.getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED)) {
String columnName = column.getName();
Integer columnIndex = (Integer) column.getProperty(Column.COLUMN_INDEX).getValue();
if (columnIndex == null) {
unSortedColumns.add(columnName);
} else {
sortedColumns.add(new ColumnHolder(columnName, columnIndex));
}
}
Collections.sort(sortedColumns, new Comparator<ColumnHolder>() {
@Override
public int compare(ColumnHolder o1, ColumnHolder o2) {
return Integer.compare(o1.columnIndex, o2.columnIndex);
}
});
CustomPartialResponseWriter.getCurrentInstance().addCustomJSUpdate("main:columns_sorter", getJSONModel());
}
private JsonArrayBuilder getJABFromList(List<String> values) {
JsonArrayBuilder jab = Json.createArrayBuilder();
for (String value : values) {
jab.add(value);
}
return jab;
}
private String getJSONModel() {
JsonObjectBuilder job = Json.createObjectBuilder();
job.add("sortedColumns", getJABFromList(getSortedColumns()));
job.add("unSortedColumns", getJABFromList(unSortedColumns));
return job.build().toString();
}
public List<String> getSortedColumns() {
List<String> columns = new ArrayList<>();
for (ColumnHolder ch : sortedColumns) {
columns.add(ch.columnName);
}
return columns;
}
public List<String> getUnSortedColumns() {
return unSortedColumns;
}
}
......@@ -66,6 +66,7 @@ public class TapSchemaEditingBean implements Serializable {
private Schema selectedSchema;
private Table selectedTable;
private Column selectedColumn;
private boolean hasColumnsSorter;
private UpdateOperations updateOperations;
private EntitiesContainer currentAddingContainer;
......@@ -233,6 +234,7 @@ public class TapSchemaEditingBean implements Serializable {
}
}
selectedColumnChanged();
hasColumnsSorter = tapSchema.getTapSchemaModel().getTable(TapSchema.COLUMNS_TABLE).get(Column.COLUMN_INDEX) != null;
}
private void selectedColumnChanged() {
......@@ -416,6 +418,10 @@ public class TapSchemaEditingBean implements Serializable {
return true;
}
public boolean isHasColumnsSorter() {
return hasColumnsSorter;
}
public void reload() {
if (tapSchema.exists()) {
......
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:outputScript name="lib/jquery-ui.min.js" library="js" />
<h:outputScript name="columns-sorter.js" library="js" />
<div class="modal fade" tabindex="-1" role="dialog" id="columns-sorter">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&#215;</span></button>
<h4 class="modal-title">Sort columns</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-xs-6">
<p>
Unsorted columns
<a href="#" class="pull-right" id="shift-selection-unsorted">
<span class="glyphicon glyphicon-arrow-right"></span>
</a>
<a href="#" class="pull-right margin-right" id="toggle-selection-unsorted">
<span class="glyphicon glyphicon-check"></span>
</a>
</p>
</div>
<div class="col-xs-6">
<p>
Sorted columns
<a href="#" class="pull-right" id="shift-selection-sorted">
<span class="glyphicon glyphicon-arrow-left"></span>
</a>
<a href="#" class="pull-right margin-right" id="toggle-selection-sorted">
<span class="glyphicon glyphicon-check"></span>
</a>
</p>
</div>
</div>
<div class="columns-list-wrapper">
<div class="columns-list-row">
<ul class="sortable" id="unsorted-columns"></ul>
<ul class="sortable" id="sorted-columns"></ul>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</ui:composition>
\ No newline at end of file
......@@ -230,4 +230,47 @@ table input+label {
/* Margin fix for multicolumn layout */
#addablesModal .checkbox:first-child {
margin-top: 0;
}
\ No newline at end of file
}
/* Columns sorting */
ul.sortable {
list-style-type: none;
padding-left: 0;
}
ul.sortable li {
padding: 3px 10px;
border-radius: 4px;
border: 1px #bbb solid;
margin-bottom: 1px;
}
ul.sortable li input {
margin-right: 10px;
}
.columns-list-wrapper {
display: table;
width: 100%;
}
.columns-list-row {
display: table-row;
width: 100%;
}
.sortable {
display: table-cell;
width: 50%;
}
#unsorted-columns li {
margin-right: 5px;
}
#sorted-columns li {
margin-left: 10px;
}
.margin-right {
margin-right: 10px;
}
/*
* _____________________________________________________________________________
*
* INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
* Trieste INAF - IA2 Italian Center for Astronomical Archives
* _____________________________________________________________________________
*
* Copyright (C) 2017 Istituto Nazionale di Astrofisica
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License Version 3 as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
(function ($) {
function fillListContainer(container, values) {
var $container = $(container);
$container.empty();
for (var i = 0; i < values.length; i++) {
$container.append('<li class="bg-info"><input type="checkbox" />' + values[i] + '</li>');
}
}
function setupToggler(toggler, container) {
var $toggler = $(toggler);
$toggler.on('click', function (ev) {
var $container = $(container);
var check = $container.find('input[type="checkbox"]:checked').length
< $container.find('input[type="checkbox"]:not(:checked)').length;
$container.find('input[type="checkbox"]').prop('checked', check);
ev.preventDefault();
});
}
function setupShifter(shifter, source, target) {
var $shifter = $(shifter);
var $target = $(target);
$shifter.on('click', function (ev) {
$(source).find('input[type="checkbox"]:checked').each(function (index, element) {
$(element).prop('checked', false);
$(element).parent().appendTo($target);
});
ev.preventDefault();
});
}
TSM.openColumnsSorter = TSM.eventHandlerFactory(function (src, jsUpdate) {
// Reset event handlers
$('#columns-sorter a').off();
var model = JSON.parse(jsUpdate);
fillListContainer('#unsorted-columns', model.unSortedColumns);
fillListContainer('#sorted-columns', model.sortedColumns);
// Setting drag and sortable
$("#unsorted-columns, #sorted-columns").sortable({
connectWith: ".sortable"
}).disableSelection();
// Init toggle selection
setupToggler('#toggle-selection-unsorted', '#unsorted-columns');
setupToggler('#toggle-selection-sorted', '#sorted-columns');
// Init shift buttons
setupShifter('#shift-selection-unsorted', '#unsorted-columns', '#sorted-columns');
setupShifter('#shift-selection-sorted', '#sorted-columns', '#unsorted-columns');
// Showing modal
$('#columns-sorter').modal('show');
}, 'main:columns_sorter');
})(jQuery);
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -216,6 +216,10 @@
<span class="glyphicon glyphicon-plus-sign"></span>
<f:ajax execute="@form" render=":main:addables_modal_content" onevent="TSM.openAddablesModal" />
</h:commandLink>
<h:commandLink rendered="#{tapSchemaEditing.hasColumnsSorter}" id="columns_sorter" action="#{columnsSorter.openModal(tapSchemaEditing.selectedTable)}">
<span class="glyphicon glyphicon-sort-by-attributes"></span>
<f:ajax execute="@form" render="@this" onevent="TSM.openColumnsSorter" />
</h:commandLink>
</div>
<h:panelGroup rendered="#{tapSchemaEditing.selectedColumn ne null}" layout="block" class="columns-header-properties">
#{tapSchemaEditing.selectedColumn.name}
......@@ -526,6 +530,7 @@
</div>
<tsm_components:ucd_editor id="ucd-editor" />
<ui:include src="WEB-INF/include/colum_sorting_modal.xhtml" rendered="#{tapSchemaEditing.hasColumnsSorter}" />
</h:form>
<div class="modal fade" tabindex="-1" role="dialog" id="searchUCDModal">
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment