[WIP] Added Resource table loading to planning web

This commit is contained in:
Robert von Burg 2016-04-01 18:24:35 +02:00
parent 47d605dabb
commit a74508ba12
39 changed files with 18424 additions and 125 deletions

View File

@ -17,6 +17,7 @@ package li.strolch.persistence.api;
import java.util.List;
import ch.eitchnet.privilege.model.Certificate;
import li.strolch.agent.api.ActivityMap;
import li.strolch.agent.api.AuditTrail;
import li.strolch.agent.api.OrderMap;
@ -49,7 +50,6 @@ import li.strolch.model.query.OrderQuery;
import li.strolch.model.query.ResourceQuery;
import li.strolch.runtime.StrolchConstants;
import li.strolch.service.api.Command;
import ch.eitchnet.privilege.model.Certificate;
/**
* <p>

View File

@ -15,44 +15,26 @@
*/
package li.strolch.runtime.query.inmemory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import ch.eitchnet.utils.StringMatchMode;
import li.strolch.model.StrolchElement;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class IdSelector<T extends StrolchElement> implements Selector<T> {
private StringMatchMode matchMode;
private List<String> ids;
public IdSelector() {
this.ids = new ArrayList<>(1);
}
/**
* @param id
*/
public IdSelector(String id) {
this.ids = new ArrayList<>(1);
this.ids.add(id);
}
/**
* @param ids
* @param matchMode
*/
public IdSelector(String... ids) {
this.ids = Arrays.asList(ids);
}
/**
* @param ids
*/
public IdSelector(List<String> ids) {
public IdSelector(List<String> ids, StringMatchMode matchMode) {
this.ids = ids;
this.matchMode = matchMode;
}
/**
@ -62,6 +44,13 @@ public class IdSelector<T extends StrolchElement> implements Selector<T> {
return this.ids;
}
/**
* @return the matchMode
*/
public StringMatchMode getMatchMode() {
return this.matchMode;
}
/**
* @param id
* @return
@ -78,10 +67,10 @@ public class IdSelector<T extends StrolchElement> implements Selector<T> {
String elemId = element.getId();
if (this.ids.size() == 1)
return this.ids.get(0).equals(elemId);
return this.matchMode.matches(elemId, this.ids.get(0));
for (String id : this.ids) {
if (elemId.equals(id))
if (this.matchMode.matches(elemId, id))
return true;
}

View File

@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import ch.eitchnet.utils.dbc.DBC;
import li.strolch.model.GroupedParameterizedElement;
import li.strolch.model.query.AndSelection;
import li.strolch.model.query.BooleanSelection;
@ -29,6 +30,7 @@ import li.strolch.model.query.NotSelection;
import li.strolch.model.query.OrSelection;
import li.strolch.model.query.ParameterBagSelection;
import li.strolch.model.query.ParameterBagSelection.NullParameterBagSelection;
import li.strolch.model.query.ParameterSelection.AnyTypeParameterSelection;
import li.strolch.model.query.ParameterSelection.BooleanParameterSelection;
import li.strolch.model.query.ParameterSelection.DateParameterSelection;
import li.strolch.model.query.ParameterSelection.DateRangeParameterSelection;
@ -52,13 +54,12 @@ import li.strolch.model.query.ordering.StrolchQueryOrderingVisitor;
import li.strolch.persistence.api.StrolchDao;
import li.strolch.runtime.query.inmemory.ParameterBagSelector.NullParameterBagSelector;
import li.strolch.runtime.query.inmemory.ParameterSelector.StringParameterSelector;
import ch.eitchnet.utils.dbc.DBC;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public abstract class InMemoryQueryVisitor<T extends GroupedParameterizedElement, S extends StrolchDao<?>> implements
StrolchRootElementSelectionVisitor, ParameterSelectionVisitor, StrolchQueryOrderingVisitor {
public abstract class InMemoryQueryVisitor<T extends GroupedParameterizedElement, S extends StrolchDao<?>>
implements StrolchRootElementSelectionVisitor, ParameterSelectionVisitor, StrolchQueryOrderingVisitor {
private Comparator<T> comparator;
private Navigator<T> navigator;
@ -152,7 +153,7 @@ public abstract class InMemoryQueryVisitor<T extends GroupedParameterizedElement
@Override
public void visit(IdSelection selection) {
addSelector(new IdSelector<T>(selection.getIds()));
addSelector(new IdSelector<T>(selection.getIds(), selection.getMatchMode()));
}
@Override
@ -163,11 +164,11 @@ public abstract class InMemoryQueryVisitor<T extends GroupedParameterizedElement
@Override
public void visit(StringParameterSelection selection) {
StringParameterSelector<T> stringSelector = //
ParameterSelector.<T> stringSelector( //
selection.getBagKey(), //
selection.getParamKey(), //
selection.getValue(),//
selection.getMatchMode());
ParameterSelector.<T> stringSelector( //
selection.getBagKey(), //
selection.getParamKey(), //
selection.getValue(), //
selection.getMatchMode());
addSelector(stringSelector);
}
@ -253,6 +254,12 @@ public abstract class InMemoryQueryVisitor<T extends GroupedParameterizedElement
addSelector(new ParameterBagSelector<T>(selection.getBagKey()));
}
@Override
public void visit(AnyTypeParameterSelection selection) {
addSelector(ParameterSelector.<T> anyTypeSelection(selection.getBagKey(), selection.getParamKey(),
selection.getValue(), selection.getMatchMode()));
}
@Override
public InMemoryQueryVisitor<T, S> visit(OrderById ordering) {
this.comparator = new InMemoryStrolchQueryOrderingVisitor<T>().visit(ordering).getComparator();

View File

@ -15,12 +15,11 @@
*/
package li.strolch.runtime.query.inmemory;
import li.strolch.model.StrolchElement;
import ch.eitchnet.utils.StringMatchMode;
import li.strolch.model.StrolchElement;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class NameSelector<T extends StrolchElement> implements Selector<T> {

View File

@ -18,6 +18,8 @@ package li.strolch.runtime.query.inmemory;
import java.util.Date;
import java.util.List;
import ch.eitchnet.utils.StringMatchMode;
import ch.eitchnet.utils.collections.DateRange;
import li.strolch.model.GroupedParameterizedElement;
import li.strolch.model.ParameterBag;
import li.strolch.model.parameter.BooleanParameter;
@ -27,9 +29,8 @@ import li.strolch.model.parameter.FloatParameter;
import li.strolch.model.parameter.IntegerParameter;
import li.strolch.model.parameter.ListParameter;
import li.strolch.model.parameter.LongParameter;
import li.strolch.model.parameter.Parameter;
import li.strolch.model.parameter.StringParameter;
import ch.eitchnet.utils.StringMatchMode;
import ch.eitchnet.utils.collections.DateRange;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
@ -82,8 +83,8 @@ public abstract class ParameterSelector<T extends GroupedParameterizedElement> i
return new DurationParameterSelector<>(bagKey, paramKey, value);
}
public static <T extends GroupedParameterizedElement> DateRangeParameterSelector<T> dateRangeSelector(
String bagKey, String paramKey, DateRange dateRange) {
public static <T extends GroupedParameterizedElement> DateRangeParameterSelector<T> dateRangeSelector(String bagKey,
String paramKey, DateRange dateRange) {
return new DateRangeParameterSelector<>(bagKey, paramKey, dateRange);
}
@ -97,8 +98,8 @@ public abstract class ParameterSelector<T extends GroupedParameterizedElement> i
return new IntegerListParameterSelector<>(bagKey, paramKey, value);
}
public static <T extends GroupedParameterizedElement> FloatListParameterSelector<T> floatListSelector(
String bagKey, String paramKey, List<Double> value) {
public static <T extends GroupedParameterizedElement> FloatListParameterSelector<T> floatListSelector(String bagKey,
String paramKey, List<Double> value) {
return new FloatListParameterSelector<>(bagKey, paramKey, value);
}
@ -112,6 +113,39 @@ public abstract class ParameterSelector<T extends GroupedParameterizedElement> i
return new NullParameterSelector<>(bagKey, paramKey);
}
public static <T extends GroupedParameterizedElement> AnyTypeParameterSelector<T> anyTypeSelection(String bagKey,
String paramKey, String value, StringMatchMode matchMode) {
return new AnyTypeParameterSelector<>(bagKey, paramKey, value, matchMode);
}
public static class AnyTypeParameterSelector<T extends GroupedParameterizedElement> extends ParameterSelector<T> {
private StringMatchMode matchMode;
private String value;
public AnyTypeParameterSelector(String bagKey, String key, String value, StringMatchMode matchMode) {
super(bagKey, key);
this.value = value;
this.matchMode = matchMode;
}
@Override
public boolean select(GroupedParameterizedElement element) {
ParameterBag bag = element.getParameterBag(this.bagKey);
if (bag == null) {
return false;
}
Parameter<?> parameter = bag.getParameter(this.paramKey);
if (parameter == null)
return false;
String valueAsString = parameter.getValueAsString();
return this.matchMode.matches(valueAsString, this.value);
}
}
public static class NullParameterSelector<T extends GroupedParameterizedElement> extends ParameterSelector<T> {
public NullParameterSelector(String bagKey, String key) {
@ -325,8 +359,8 @@ public abstract class ParameterSelector<T extends GroupedParameterizedElement> i
}
}
public static abstract class AbstractListParameterSelector<U, T extends GroupedParameterizedElement> extends
ParameterSelector<T> {
public static abstract class AbstractListParameterSelector<U, T extends GroupedParameterizedElement>
extends ParameterSelector<T> {
private List<U> value;
@ -349,32 +383,32 @@ public abstract class ParameterSelector<T extends GroupedParameterizedElement> i
}
}
public static class StringListParameterSelector<T extends GroupedParameterizedElement> extends
AbstractListParameterSelector<String, T> {
public static class StringListParameterSelector<T extends GroupedParameterizedElement>
extends AbstractListParameterSelector<String, T> {
public StringListParameterSelector(String bagKey, String paramKey, List<String> value) {
super(bagKey, paramKey, value);
}
}
public static class IntegerListParameterSelector<T extends GroupedParameterizedElement> extends
AbstractListParameterSelector<Integer, T> {
public static class IntegerListParameterSelector<T extends GroupedParameterizedElement>
extends AbstractListParameterSelector<Integer, T> {
public IntegerListParameterSelector(String bagKey, String paramKey, List<Integer> value) {
super(bagKey, paramKey, value);
}
}
public static class FloatListParameterSelector<T extends GroupedParameterizedElement> extends
AbstractListParameterSelector<Double, T> {
public static class FloatListParameterSelector<T extends GroupedParameterizedElement>
extends AbstractListParameterSelector<Double, T> {
public FloatListParameterSelector(String bagKey, String paramKey, List<Double> value) {
super(bagKey, paramKey, value);
}
}
public static class LongListParameterSelector<T extends GroupedParameterizedElement> extends
AbstractListParameterSelector<Long, T> {
public static class LongListParameterSelector<T extends GroupedParameterizedElement>
extends AbstractListParameterSelector<Long, T> {
public LongListParameterSelector(String bagKey, String paramKey, List<Long> value) {
super(bagKey, paramKey, value);

View File

@ -19,36 +19,74 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import ch.eitchnet.utils.StringMatchMode;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class IdSelection extends StrolchElementSelection {
private List<String> ids;
public IdSelection() {
this.ids = new ArrayList<>(1);
}
private StringMatchMode matchMode;
/**
* Instantiate using {@link StringMatchMode#es()}
*
* @param id
*/
public IdSelection(String id) {
this.ids = new ArrayList<>(1);
this.ids.add(id);
this.matchMode = StringMatchMode.es();
}
/**
* @param id
* @param matchMode
*/
public IdSelection(String id, StringMatchMode matchMode) {
this.ids = new ArrayList<>(1);
this.ids.add(id);
this.matchMode = matchMode;
}
/**
* Instantiate using {@link StringMatchMode#es()}
*
* @param matchMode
* @param ids
*/
public IdSelection(String... ids) {
this.matchMode = StringMatchMode.es();
this.ids = Arrays.asList(ids);
}
/**
* @param matchMode
* @param ids
*/
public IdSelection(StringMatchMode matchMode, String... ids) {
this.matchMode = matchMode;
this.ids = Arrays.asList(ids);
}
/**
* @param ids
* @param matchMode
*/
public IdSelection(List<String> ids, StringMatchMode matchMode) {
this.matchMode = matchMode;
this.ids = ids;
}
/**
* Instantiate using {@link StringMatchMode#es()}
*
* @param ids
* @param matchMode
*/
public IdSelection(List<String> ids) {
this.matchMode = StringMatchMode.es();
this.ids = ids;
}
@ -59,8 +97,16 @@ public class IdSelection extends StrolchElementSelection {
return this.ids;
}
/**
* @return the matchMode
*/
public StringMatchMode getMatchMode() {
return this.matchMode;
}
/**
* @param id
*
* @return
*/
public IdSelection with(String id) {

View File

@ -116,7 +116,8 @@ public abstract class ParameterSelection implements Selection {
return new StringListParameterSelection(bagKey, paramKey, value);
}
public static IntegerListParameterSelection integerListSelection(String bagKey, String paramKey, List<Integer> value) {
public static IntegerListParameterSelection integerListSelection(String bagKey, String paramKey,
List<Integer> value) {
return new IntegerListParameterSelection(bagKey, paramKey, value);
}
@ -132,6 +133,36 @@ public abstract class ParameterSelection implements Selection {
return new NullParameterSelection(bagKey, paramKey);
}
public static AnyTypeParameterSelection anyTypeSelection(String bagKey, String paramKey, String value,
StringMatchMode matchMode) {
return new AnyTypeParameterSelection(bagKey, paramKey, value, matchMode);
}
public static class AnyTypeParameterSelection extends ParameterSelection {
private StringMatchMode matchMode;
private String value;
public AnyTypeParameterSelection(String bagKey, String paramKey, String value, StringMatchMode matchMode) {
super(bagKey, paramKey);
this.value = value;
this.matchMode = matchMode;
}
public String getValue() {
return this.value;
}
public StringMatchMode getMatchMode() {
return this.matchMode;
}
@Override
public void accept(ParameterSelectionVisitor visitor) {
visitor.visit(this);
}
}
public static class NullParameterSelection extends ParameterSelection {
public NullParameterSelection(String bagKey, String paramKey) {

View File

@ -15,6 +15,7 @@
*/
package li.strolch.model.query;
import li.strolch.model.query.ParameterSelection.AnyTypeParameterSelection;
import li.strolch.model.query.ParameterSelection.BooleanParameterSelection;
import li.strolch.model.query.ParameterSelection.DateParameterSelection;
import li.strolch.model.query.ParameterSelection.DateRangeParameterSelection;
@ -58,5 +59,7 @@ public interface ParameterSelectionVisitor extends QueryVisitor {
public void visit(LongListParameterSelection selection);
public void visit(NullParameterSelection nullParameterSelection);
public void visit(NullParameterSelection selection);
public void visit(AnyTypeParameterSelection selection);
}

View File

@ -58,6 +58,7 @@
<impl>li.strolch.rest.RestfulStrolchComponent</impl>
<depends>SessionHandler</depends>
<Properties>
<secureCookie>false</secureCookie>
<corsEnabled>true</corsEnabled>
<corsOrigin>http://localhost:8080</corsOrigin>
</Properties>

View File

@ -0,0 +1,196 @@
table.dataTable {
clear: both;
margin-top: 6px !important;
margin-bottom: 6px !important;
max-width: none !important;
}
table.dataTable td,
table.dataTable th {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
table.dataTable td.dataTables_empty,
table.dataTable th.dataTables_empty {
text-align: center;
}
table.dataTable.nowrap th,
table.dataTable.nowrap td {
white-space: nowrap;
}
div.dataTables_wrapper div.dataTables_length label {
font-weight: normal;
text-align: left;
white-space: nowrap;
}
div.dataTables_wrapper div.dataTables_length select {
width: 75px;
display: inline-block;
}
div.dataTables_wrapper div.dataTables_filter {
text-align: right;
}
div.dataTables_wrapper div.dataTables_filter label {
font-weight: normal;
white-space: nowrap;
text-align: left;
}
div.dataTables_wrapper div.dataTables_filter input {
margin-left: 0.5em;
display: inline-block;
width: auto;
}
div.dataTables_wrapper div.dataTables_info {
padding-top: 0.85em;
white-space: nowrap;
}
div.dataTables_wrapper div.dataTables_paginate {
margin: 0;
white-space: nowrap;
text-align: right;
}
div.dataTables_wrapper div.dataTables_paginate ul.pagination {
margin: 2px 0;
white-space: nowrap;
}
div.dataTables_wrapper div.dataTables_processing {
position: absolute;
top: 50%;
left: 50%;
width: 200px;
margin-left: -100px;
margin-top: -26px;
text-align: center;
padding: 1em 0;
}
table.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting,
table.dataTable thead > tr > td.sorting_asc,
table.dataTable thead > tr > td.sorting_desc,
table.dataTable thead > tr > td.sorting {
padding-right: 30px;
}
table.dataTable thead > tr > th:active,
table.dataTable thead > tr > td:active {
outline: none;
}
table.dataTable thead .sorting,
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc,
table.dataTable thead .sorting_asc_disabled,
table.dataTable thead .sorting_desc_disabled {
cursor: pointer;
position: relative;
}
table.dataTable thead .sorting:before, table.dataTable thead .sorting:after,
table.dataTable thead .sorting_asc:before,
table.dataTable thead .sorting_asc:after,
table.dataTable thead .sorting_desc:before,
table.dataTable thead .sorting_desc:after,
table.dataTable thead .sorting_asc_disabled:before,
table.dataTable thead .sorting_asc_disabled:after,
table.dataTable thead .sorting_desc_disabled:before,
table.dataTable thead .sorting_desc_disabled:after {
position: absolute;
bottom: 0.9em;
display: block;
opacity: 0.3;
}
table.dataTable thead .sorting:before,
table.dataTable thead .sorting_asc:before,
table.dataTable thead .sorting_desc:before,
table.dataTable thead .sorting_asc_disabled:before,
table.dataTable thead .sorting_desc_disabled:before {
right: 1em;
content: "\2191";
}
table.dataTable thead .sorting:after,
table.dataTable thead .sorting_asc:after,
table.dataTable thead .sorting_desc:after,
table.dataTable thead .sorting_asc_disabled:after,
table.dataTable thead .sorting_desc_disabled:after {
right: 0.5em;
content: "\2193";
}
table.dataTable thead .sorting_asc:before,
table.dataTable thead .sorting_desc:after {
opacity: 1;
}
table.dataTable thead .sorting_asc_disabled:before,
table.dataTable thead .sorting_desc_disabled:after {
opacity: 0;
}
div.dataTables_scrollHead table.dataTable {
margin-bottom: 0 !important;
}
div.dataTables_scrollBody table {
border-top: none;
margin-top: 0 !important;
margin-bottom: 0 !important;
}
div.dataTables_scrollBody table thead .sorting:after,
div.dataTables_scrollBody table thead .sorting_asc:after,
div.dataTables_scrollBody table thead .sorting_desc:after {
display: none;
}
div.dataTables_scrollBody table tbody tr:first-child th,
div.dataTables_scrollBody table tbody tr:first-child td {
border-top: none;
}
div.dataTables_scrollFoot table {
margin-top: 0 !important;
border-top: none;
}
@media screen and (max-width: 767px) {
div.dataTables_wrapper div.dataTables_length,
div.dataTables_wrapper div.dataTables_filter,
div.dataTables_wrapper div.dataTables_info,
div.dataTables_wrapper div.dataTables_paginate {
text-align: center;
}
}
table.dataTable.table-condensed > thead > tr > th {
padding-right: 20px;
}
table.dataTable.table-condensed .sorting:after,
table.dataTable.table-condensed .sorting_asc:after,
table.dataTable.table-condensed .sorting_desc:after {
top: 6px;
right: 6px;
}
table.table-bordered.dataTable {
border-collapse: separate !important;
}
table.table-bordered.dataTable th,
table.table-bordered.dataTable td {
border-left-width: 0;
}
table.table-bordered.dataTable th:last-child, table.table-bordered.dataTable th:last-child,
table.table-bordered.dataTable td:last-child,
table.table-bordered.dataTable td:last-child {
border-right-width: 0;
}
table.table-bordered.dataTable tbody th,
table.table-bordered.dataTable tbody td {
border-bottom-width: 0;
}
div.dataTables_scrollHead table.table-bordered {
border-bottom-width: 0;
}
div.table-responsive > div.dataTables_wrapper > div.row {
margin: 0;
}
div.table-responsive > div.dataTables_wrapper > div.row > div[class^="col-"]:first-child {
padding-left: 0;
}
div.table-responsive > div.dataTables_wrapper > div.row > div[class^="col-"]:last-child {
padding-right: 0;
}

View File

@ -0,0 +1 @@
table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:75px;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:0.85em;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:before,table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:before,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:before,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:0.9em;display:block;opacity:0.3}table.dataTable thead .sorting:before,table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_desc:before,table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_desc_disabled:before{right:1em;content:"\2191"}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{right:0.5em;content:"\2193"}table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_desc:after{opacity:1}table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_desc_disabled:after{opacity:0}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-condensed>thead>tr>th{padding-right:20px}table.dataTable.table-condensed .sorting:after,table.dataTable.table-condensed .sorting_asc:after,table.dataTable.table-condensed .sorting_desc:after{top:6px;right:6px}table.table-bordered.dataTable{border-collapse:separate !important}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0}

View File

@ -0,0 +1,453 @@
/*
* Table styles
*/
table.dataTable {
width: 100%;
margin: 0 auto;
clear: both;
border-collapse: separate;
border-spacing: 0;
/*
* Header and footer styles
*/
/*
* Body styles
*/
}
table.dataTable thead th,
table.dataTable tfoot th {
font-weight: bold;
}
table.dataTable thead th,
table.dataTable thead td {
padding: 10px 18px;
border-bottom: 1px solid #111;
}
table.dataTable thead th:active,
table.dataTable thead td:active {
outline: none;
}
table.dataTable tfoot th,
table.dataTable tfoot td {
padding: 10px 18px 6px 18px;
border-top: 1px solid #111;
}
table.dataTable thead .sorting,
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc {
cursor: pointer;
*cursor: hand;
}
table.dataTable thead .sorting,
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc,
table.dataTable thead .sorting_asc_disabled,
table.dataTable thead .sorting_desc_disabled {
background-repeat: no-repeat;
background-position: center right;
}
table.dataTable thead .sorting {
background-image: url("../images/sort_both.png");
}
table.dataTable thead .sorting_asc {
background-image: url("../images/sort_asc.png");
}
table.dataTable thead .sorting_desc {
background-image: url("../images/sort_desc.png");
}
table.dataTable thead .sorting_asc_disabled {
background-image: url("../images/sort_asc_disabled.png");
}
table.dataTable thead .sorting_desc_disabled {
background-image: url("../images/sort_desc_disabled.png");
}
table.dataTable tbody tr {
background-color: #ffffff;
}
table.dataTable tbody tr.selected {
background-color: #B0BED9;
}
table.dataTable tbody th,
table.dataTable tbody td {
padding: 8px 10px;
}
table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
border-top: 1px solid #ddd;
}
table.dataTable.row-border tbody tr:first-child th,
table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,
table.dataTable.display tbody tr:first-child td {
border-top: none;
}
table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
border-top: 1px solid #ddd;
border-right: 1px solid #ddd;
}
table.dataTable.cell-border tbody tr th:first-child,
table.dataTable.cell-border tbody tr td:first-child {
border-left: 1px solid #ddd;
}
table.dataTable.cell-border tbody tr:first-child th,
table.dataTable.cell-border tbody tr:first-child td {
border-top: none;
}
table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
background-color: #f9f9f9;
}
table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {
background-color: #acbad4;
}
table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {
background-color: #f6f6f6;
}
table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {
background-color: #aab7d1;
}
table.dataTable.order-column tbody tr > .sorting_1,
table.dataTable.order-column tbody tr > .sorting_2,
table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,
table.dataTable.display tbody tr > .sorting_2,
table.dataTable.display tbody tr > .sorting_3 {
background-color: #fafafa;
}
table.dataTable.order-column tbody tr.selected > .sorting_1,
table.dataTable.order-column tbody tr.selected > .sorting_2,
table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,
table.dataTable.display tbody tr.selected > .sorting_2,
table.dataTable.display tbody tr.selected > .sorting_3 {
background-color: #acbad5;
}
table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
background-color: #f1f1f1;
}
table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
background-color: #f3f3f3;
}
table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
background-color: whitesmoke;
}
table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
background-color: #a6b4cd;
}
table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
background-color: #a8b5cf;
}
table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
background-color: #a9b7d1;
}
table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
background-color: #fafafa;
}
table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
background-color: #fcfcfc;
}
table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
background-color: #fefefe;
}
table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
background-color: #acbad5;
}
table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
background-color: #aebcd6;
}
table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
background-color: #afbdd8;
}
table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {
background-color: #eaeaea;
}
table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {
background-color: #ececec;
}
table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {
background-color: #efefef;
}
table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {
background-color: #a2aec7;
}
table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {
background-color: #a3b0c9;
}
table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {
background-color: #a5b2cb;
}
table.dataTable.no-footer {
border-bottom: 1px solid #111;
}
table.dataTable.nowrap th, table.dataTable.nowrap td {
white-space: nowrap;
}
table.dataTable.compact thead th,
table.dataTable.compact thead td {
padding: 4px 17px 4px 4px;
}
table.dataTable.compact tfoot th,
table.dataTable.compact tfoot td {
padding: 4px;
}
table.dataTable.compact tbody th,
table.dataTable.compact tbody td {
padding: 4px;
}
table.dataTable th.dt-left,
table.dataTable td.dt-left {
text-align: left;
}
table.dataTable th.dt-center,
table.dataTable td.dt-center,
table.dataTable td.dataTables_empty {
text-align: center;
}
table.dataTable th.dt-right,
table.dataTable td.dt-right {
text-align: right;
}
table.dataTable th.dt-justify,
table.dataTable td.dt-justify {
text-align: justify;
}
table.dataTable th.dt-nowrap,
table.dataTable td.dt-nowrap {
white-space: nowrap;
}
table.dataTable thead th.dt-head-left,
table.dataTable thead td.dt-head-left,
table.dataTable tfoot th.dt-head-left,
table.dataTable tfoot td.dt-head-left {
text-align: left;
}
table.dataTable thead th.dt-head-center,
table.dataTable thead td.dt-head-center,
table.dataTable tfoot th.dt-head-center,
table.dataTable tfoot td.dt-head-center {
text-align: center;
}
table.dataTable thead th.dt-head-right,
table.dataTable thead td.dt-head-right,
table.dataTable tfoot th.dt-head-right,
table.dataTable tfoot td.dt-head-right {
text-align: right;
}
table.dataTable thead th.dt-head-justify,
table.dataTable thead td.dt-head-justify,
table.dataTable tfoot th.dt-head-justify,
table.dataTable tfoot td.dt-head-justify {
text-align: justify;
}
table.dataTable thead th.dt-head-nowrap,
table.dataTable thead td.dt-head-nowrap,
table.dataTable tfoot th.dt-head-nowrap,
table.dataTable tfoot td.dt-head-nowrap {
white-space: nowrap;
}
table.dataTable tbody th.dt-body-left,
table.dataTable tbody td.dt-body-left {
text-align: left;
}
table.dataTable tbody th.dt-body-center,
table.dataTable tbody td.dt-body-center {
text-align: center;
}
table.dataTable tbody th.dt-body-right,
table.dataTable tbody td.dt-body-right {
text-align: right;
}
table.dataTable tbody th.dt-body-justify,
table.dataTable tbody td.dt-body-justify {
text-align: justify;
}
table.dataTable tbody th.dt-body-nowrap,
table.dataTable tbody td.dt-body-nowrap {
white-space: nowrap;
}
table.dataTable,
table.dataTable th,
table.dataTable td {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/*
* Control feature layout
*/
.dataTables_wrapper {
position: relative;
clear: both;
*zoom: 1;
zoom: 1;
}
.dataTables_wrapper .dataTables_length {
float: left;
}
.dataTables_wrapper .dataTables_filter {
float: right;
text-align: right;
}
.dataTables_wrapper .dataTables_filter input {
margin-left: 0.5em;
}
.dataTables_wrapper .dataTables_info {
clear: both;
float: left;
padding-top: 0.755em;
}
.dataTables_wrapper .dataTables_paginate {
float: right;
text-align: right;
padding-top: 0.25em;
}
.dataTables_wrapper .dataTables_paginate .paginate_button {
box-sizing: border-box;
display: inline-block;
min-width: 1.5em;
padding: 0.5em 1em;
margin-left: 2px;
text-align: center;
text-decoration: none !important;
cursor: pointer;
*cursor: hand;
color: #333 !important;
border: 1px solid transparent;
border-radius: 2px;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
color: #333 !important;
border: 1px solid #979797;
background-color: white;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%);
/* Chrome10+,Safari5.1+ */
background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%);
/* FF3.6+ */
background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%);
/* IE10+ */
background: -o-linear-gradient(top, white 0%, #dcdcdc 100%);
/* Opera 11.10+ */
background: linear-gradient(to bottom, white 0%, #dcdcdc 100%);
/* W3C */
}
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
cursor: default;
color: #666 !important;
border: 1px solid transparent;
background: transparent;
box-shadow: none;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
color: white !important;
border: 1px solid #111;
background-color: #585858;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #585858 0%, #111 100%);
/* Chrome10+,Safari5.1+ */
background: -moz-linear-gradient(top, #585858 0%, #111 100%);
/* FF3.6+ */
background: -ms-linear-gradient(top, #585858 0%, #111 100%);
/* IE10+ */
background: -o-linear-gradient(top, #585858 0%, #111 100%);
/* Opera 11.10+ */
background: linear-gradient(to bottom, #585858 0%, #111 100%);
/* W3C */
}
.dataTables_wrapper .dataTables_paginate .paginate_button:active {
outline: none;
background-color: #2b2b2b;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
/* Chrome10+,Safari5.1+ */
background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
/* FF3.6+ */
background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
/* IE10+ */
background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
/* Opera 11.10+ */
background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);
/* W3C */
box-shadow: inset 0 0 3px #111;
}
.dataTables_wrapper .dataTables_paginate .ellipsis {
padding: 0 1em;
}
.dataTables_wrapper .dataTables_processing {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 40px;
margin-left: -50%;
margin-top: -25px;
padding-top: 20px;
text-align: center;
font-size: 1.2em;
background-color: white;
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
}
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_processing,
.dataTables_wrapper .dataTables_paginate {
color: #333;
}
.dataTables_wrapper .dataTables_scroll {
clear: both;
}
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {
*margin-top: -1px;
-webkit-overflow-scrolling: touch;
}
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td {
vertical-align: middle;
}
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {
height: 0;
overflow: hidden;
margin: 0 !important;
padding: 0 !important;
}
.dataTables_wrapper.no-footer .dataTables_scrollBody {
border-bottom: 1px solid #111;
}
.dataTables_wrapper.no-footer div.dataTables_scrollHead table,
.dataTables_wrapper.no-footer div.dataTables_scrollBody table {
border-bottom: none;
}
.dataTables_wrapper:after {
visibility: hidden;
display: block;
content: "";
clear: both;
height: 0;
}
@media screen and (max-width: 767px) {
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_paginate {
float: none;
text-align: center;
}
.dataTables_wrapper .dataTables_paginate {
margin-top: 0.5em;
}
}
@media screen and (max-width: 640px) {
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter {
float: none;
text-align: center;
}
.dataTables_wrapper .dataTables_filter {
margin-top: 0.5em;
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,180 @@
table.dataTable.dtr-inline.collapsed > tbody > tr > td.child,
table.dataTable.dtr-inline.collapsed > tbody > tr > th.child,
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dataTables_empty {
cursor: default !important;
}
table.dataTable.dtr-inline.collapsed > tbody > tr > td.child:before,
table.dataTable.dtr-inline.collapsed > tbody > tr > th.child:before,
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dataTables_empty:before {
display: none !important;
}
table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child,
table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child {
position: relative;
padding-left: 30px;
cursor: pointer;
}
table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child:before,
table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child:before {
top: 8px;
left: 4px;
height: 16px;
width: 16px;
display: block;
position: absolute;
color: white;
border: 2px solid white;
border-radius: 16px;
box-shadow: 0 0 3px #444;
box-sizing: content-box;
text-align: left;
font-family: 'Courier New', Courier, monospace;
text-indent: 4px;
line-height: 16px;
content: '+';
background-color: #337ab7;
}
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child:before,
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th:first-child:before {
content: '-';
background-color: #d33333;
}
table.dataTable.dtr-inline.collapsed > tbody > tr.child td:before {
display: none;
}
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child,
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child {
padding-left: 27px;
}
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child:before,
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child:before {
top: 5px;
left: 4px;
height: 14px;
width: 14px;
border-radius: 14px;
line-height: 14px;
text-indent: 3px;
}
table.dataTable.dtr-column > tbody > tr > td.control,
table.dataTable.dtr-column > tbody > tr > th.control {
position: relative;
cursor: pointer;
}
table.dataTable.dtr-column > tbody > tr > td.control:before,
table.dataTable.dtr-column > tbody > tr > th.control:before {
top: 50%;
left: 50%;
height: 16px;
width: 16px;
margin-top: -10px;
margin-left: -10px;
display: block;
position: absolute;
color: white;
border: 2px solid white;
border-radius: 16px;
box-shadow: 0 0 3px #444;
box-sizing: content-box;
text-align: left;
font-family: 'Courier New', Courier, monospace;
text-indent: 4px;
line-height: 16px;
content: '+';
background-color: #337ab7;
}
table.dataTable.dtr-column > tbody > tr.parent td.control:before,
table.dataTable.dtr-column > tbody > tr.parent th.control:before {
content: '-';
background-color: #d33333;
}
table.dataTable > tbody > tr.child {
padding: 0.5em 1em;
}
table.dataTable > tbody > tr.child:hover {
background: transparent !important;
}
table.dataTable > tbody > tr.child ul {
display: inline-block;
list-style-type: none;
margin: 0;
padding: 0;
}
table.dataTable > tbody > tr.child ul li {
border-bottom: 1px solid #efefef;
padding: 0.5em 0;
}
table.dataTable > tbody > tr.child ul li:first-child {
padding-top: 0;
}
table.dataTable > tbody > tr.child ul li:last-child {
border-bottom: none;
}
table.dataTable > tbody > tr.child span.dtr-title {
display: inline-block;
min-width: 75px;
font-weight: bold;
}
div.dtr-modal {
position: fixed;
box-sizing: border-box;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 100;
padding: 10em 1em;
}
div.dtr-modal div.dtr-modal-display {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 50%;
height: 50%;
overflow: auto;
margin: auto;
z-index: 102;
overflow: auto;
background-color: #f5f5f7;
border: 1px solid black;
border-radius: 0.5em;
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.6);
}
div.dtr-modal div.dtr-modal-content {
position: relative;
padding: 1em;
}
div.dtr-modal div.dtr-modal-close {
position: absolute;
top: 6px;
right: 6px;
width: 22px;
height: 22px;
border: 1px solid #eaeaea;
background-color: #f9f9f9;
text-align: center;
border-radius: 3px;
cursor: pointer;
z-index: 12;
}
div.dtr-modal div.dtr-modal-close:hover {
background-color: #eaeaea;
}
div.dtr-modal div.dtr-modal-background {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 101;
background: rgba(0, 0, 0, 0.6);
}
@media screen and (max-width: 767px) {
div.dtr-modal div.dtr-modal-display {
width: 95%;
}
}

View File

@ -0,0 +1 @@
table.dataTable.dtr-inline.collapsed>tbody>tr>td.child,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty{cursor:default !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty:before{display:none !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td:first-child,table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child{position:relative;padding-left:30px;cursor:pointer}table.dataTable.dtr-inline.collapsed>tbody>tr>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child:before{top:8px;left:4px;height:16px;width:16px;display:block;position:absolute;color:white;border:2px solid white;border-radius:16px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:left;font-family:'Courier New', Courier, monospace;text-indent:4px;line-height:16px;content:'+';background-color:#337ab7}table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before{content:'-';background-color:#d33333}table.dataTable.dtr-inline.collapsed>tbody>tr.child td:before{display:none}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td:first-child,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th:first-child{padding-left:27px}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td:first-child:before,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th:first-child:before{top:5px;left:4px;height:14px;width:14px;border-radius:14px;line-height:14px;text-indent:3px}table.dataTable.dtr-column>tbody>tr>td.control,table.dataTable.dtr-column>tbody>tr>th.control{position:relative;cursor:pointer}table.dataTable.dtr-column>tbody>tr>td.control:before,table.dataTable.dtr-column>tbody>tr>th.control:before{top:50%;left:50%;height:16px;width:16px;margin-top:-10px;margin-left:-10px;display:block;position:absolute;color:white;border:2px solid white;border-radius:16px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:left;font-family:'Courier New', Courier, monospace;text-indent:4px;line-height:16px;content:'+';background-color:#337ab7}table.dataTable.dtr-column>tbody>tr.parent td.control:before,table.dataTable.dtr-column>tbody>tr.parent th.control:before{content:'-';background-color:#d33333}table.dataTable>tbody>tr.child{padding:0.5em 1em}table.dataTable>tbody>tr.child:hover{background:transparent !important}table.dataTable>tbody>tr.child ul{display:inline-block;list-style-type:none;margin:0;padding:0}table.dataTable>tbody>tr.child ul li{border-bottom:1px solid #efefef;padding:0.5em 0}table.dataTable>tbody>tr.child ul li:first-child{padding-top:0}table.dataTable>tbody>tr.child ul li:last-child{border-bottom:none}table.dataTable>tbody>tr.child span.dtr-title{display:inline-block;min-width:75px;font-weight:bold}div.dtr-modal{position:fixed;box-sizing:border-box;top:0;left:0;height:100%;width:100%;z-index:100;padding:10em 1em}div.dtr-modal div.dtr-modal-display{position:absolute;top:0;left:0;bottom:0;right:0;width:50%;height:50%;overflow:auto;margin:auto;z-index:102;overflow:auto;background-color:#f5f5f7;border:1px solid black;border-radius:0.5em;box-shadow:0 12px 30px rgba(0,0,0,0.6)}div.dtr-modal div.dtr-modal-content{position:relative;padding:1em}div.dtr-modal div.dtr-modal-close{position:absolute;top:6px;right:6px;width:22px;height:22px;border:1px solid #eaeaea;background-color:#f9f9f9;text-align:center;border-radius:3px;cursor:pointer;z-index:12}div.dtr-modal div.dtr-modal-close:hover{background-color:#eaeaea}div.dtr-modal div.dtr-modal-background{position:fixed;top:0;left:0;right:0;bottom:0;z-index:101;background:rgba(0,0,0,0.6)}@media screen and (max-width: 767px){div.dtr-modal div.dtr-modal-display{width:95%}}

View File

@ -0,0 +1,180 @@
table.dataTable.dtr-inline.collapsed > tbody > tr > td.child,
table.dataTable.dtr-inline.collapsed > tbody > tr > th.child,
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dataTables_empty {
cursor: default !important;
}
table.dataTable.dtr-inline.collapsed > tbody > tr > td.child:before,
table.dataTable.dtr-inline.collapsed > tbody > tr > th.child:before,
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dataTables_empty:before {
display: none !important;
}
table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child,
table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child {
position: relative;
padding-left: 30px;
cursor: pointer;
}
table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child:before,
table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child:before {
top: 8px;
left: 4px;
height: 16px;
width: 16px;
display: block;
position: absolute;
color: white;
border: 2px solid white;
border-radius: 16px;
box-shadow: 0 0 3px #444;
box-sizing: content-box;
text-align: left;
font-family: 'Courier New', Courier, monospace;
text-indent: 4px;
line-height: 16px;
content: '+';
background-color: #31b131;
}
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child:before,
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th:first-child:before {
content: '-';
background-color: #d33333;
}
table.dataTable.dtr-inline.collapsed > tbody > tr.child td:before {
display: none;
}
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child,
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child {
padding-left: 27px;
}
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child:before,
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child:before {
top: 5px;
left: 4px;
height: 14px;
width: 14px;
border-radius: 14px;
line-height: 14px;
text-indent: 3px;
}
table.dataTable.dtr-column > tbody > tr > td.control,
table.dataTable.dtr-column > tbody > tr > th.control {
position: relative;
cursor: pointer;
}
table.dataTable.dtr-column > tbody > tr > td.control:before,
table.dataTable.dtr-column > tbody > tr > th.control:before {
top: 50%;
left: 50%;
height: 16px;
width: 16px;
margin-top: -10px;
margin-left: -10px;
display: block;
position: absolute;
color: white;
border: 2px solid white;
border-radius: 16px;
box-shadow: 0 0 3px #444;
box-sizing: content-box;
text-align: left;
font-family: 'Courier New', Courier, monospace;
text-indent: 4px;
line-height: 16px;
content: '+';
background-color: #31b131;
}
table.dataTable.dtr-column > tbody > tr.parent td.control:before,
table.dataTable.dtr-column > tbody > tr.parent th.control:before {
content: '-';
background-color: #d33333;
}
table.dataTable > tbody > tr.child {
padding: 0.5em 1em;
}
table.dataTable > tbody > tr.child:hover {
background: transparent !important;
}
table.dataTable > tbody > tr.child ul {
display: inline-block;
list-style-type: none;
margin: 0;
padding: 0;
}
table.dataTable > tbody > tr.child ul li {
border-bottom: 1px solid #efefef;
padding: 0.5em 0;
}
table.dataTable > tbody > tr.child ul li:first-child {
padding-top: 0;
}
table.dataTable > tbody > tr.child ul li:last-child {
border-bottom: none;
}
table.dataTable > tbody > tr.child span.dtr-title {
display: inline-block;
min-width: 75px;
font-weight: bold;
}
div.dtr-modal {
position: fixed;
box-sizing: border-box;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 100;
padding: 10em 1em;
}
div.dtr-modal div.dtr-modal-display {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 50%;
height: 50%;
overflow: auto;
margin: auto;
z-index: 102;
overflow: auto;
background-color: #f5f5f7;
border: 1px solid black;
border-radius: 0.5em;
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.6);
}
div.dtr-modal div.dtr-modal-content {
position: relative;
padding: 1em;
}
div.dtr-modal div.dtr-modal-close {
position: absolute;
top: 6px;
right: 6px;
width: 22px;
height: 22px;
border: 1px solid #eaeaea;
background-color: #f9f9f9;
text-align: center;
border-radius: 3px;
cursor: pointer;
z-index: 12;
}
div.dtr-modal div.dtr-modal-close:hover {
background-color: #eaeaea;
}
div.dtr-modal div.dtr-modal-background {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 101;
background: rgba(0, 0, 0, 0.6);
}
@media screen and (max-width: 767px) {
div.dtr-modal div.dtr-modal-display {
width: 95%;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

View File

@ -6,10 +6,15 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="stylesheet" href="css/external/bootstrap.css">
<link rel="stylesheet" href="css/external/font-awesome.css">
<link rel="stylesheet" href="css/external/alertify/alertify.css" />
<link rel="stylesheet" href="css/external/alertify/themes/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="css/external/bootstrap.css">
<link rel="stylesheet" type="text/css" href="css/external/font-awesome.css">
<link rel="stylesheet" type="text/css" href="css/external/alertify/alertify.css"/>
<link rel="stylesheet" type="text/css" href="css/external/alertify/themes/bootstrap.min.css"/>
<!--link rel="stylesheet" type="text/css" href="css/external/jquery.dataTables.css"/-->
<link rel="stylesheet" type="text/css" href="css/external/dataTables.bootstrap4.css"/>
<link rel="stylesheet" type="text/css" href="css/external/responsive.bootstrap.css"/>
<!-- Application -->
<link rel="stylesheet" href="css/application.css">
@ -24,7 +29,9 @@
<div class="col-sm-offset-3 col-sm-9">
<div class="row">
<div class="col-sm-2 nav-row">
<a href="#"> <span class="fa fa-database nav-icon"></span><br/> <span class="nav-text">Model</span>
<a href="#model" data-function="navigate" data-target="model"> <span
class="fa fa-database nav-icon"></span><br/> <span
class="nav-text">Model</span>
</a>
</div>
<div class="col-sm-2 nav-row">
@ -39,7 +46,7 @@
<div id="page-content" class="col-sm-12">
<!-- is loaded dynamically by each parts initializer -->
<!-- is loaded dynamically by each parts initializer -->
</div>
</div>
@ -109,10 +116,14 @@
<iframe name="form_catcher" class="hidden" src="about:blank"></iframe>
<!-- External JavaScript dependencies -->
<script src="js/external/jquery.js"></script>
<script src="js/external/tether.js"></script>
<script src="js/external/bootstrap.js"></script>
<script src="js/external/alertify.js"></script>
<script type="text/javascript" src="js/external/jquery.js"></script>
<script type="text/javascript" src="js/external/tether.js"></script>
<script type="text/javascript" src="js/external/bootstrap.js"></script>
<script type="text/javascript" src="js/external/alertify.js"></script>
<script type="text/javascript" src="js/external/jquery.dataTables.js"></script>
<script type="text/javascript" src="js/external/dataTables.bootstrap4.js"></script>
<script type="text/javascript" src="js/external/dataTables.responsive.js"></script>
<!-- Application -->
<script src="js/i18n.js"></script>

View File

@ -51,7 +51,7 @@ strolch.auth.init = function () {
strolch.fn.toggleSubmitBtn('#authForm');
}
});
}, 3000);
}, 300);
} else if (sessionData) {
usernameTxt.prop('disabled', false).val(strolch.fn.getSessionData().username);
@ -77,5 +77,5 @@ strolch.auth.submitAuthForm = function (e) {
strolch.fn.toggleSubmitBtn('#authForm');
setTimeout(function () {
strolch.fn.doAuth('#authForm', username, password);
}, 3000);
}, 300);
};

View File

@ -13,7 +13,8 @@ strolch.const = {
url_base: 'planningwebapp',
urls: {
auth: 'rest/strolch/authentication',
version: 'rest/strolch/version'
version: 'rest/strolch/version',
resources: 'rest/strolch/model/resources'
},
auth_token: 'auth_token',

View File

@ -0,0 +1,184 @@
/*! DataTables Bootstrap 3 integration
* ©2011-2015 SpryMedia Ltd - datatables.net/license
*/
/**
* DataTables integration for Bootstrap 3. This requires Bootstrap 3 and
* DataTables 1.10 or newer.
*
* This file sets the defaults and adds options to DataTables to style its
* controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
* for further information.
*/
(function( factory ){
if ( typeof define === 'function' && define.amd ) {
// AMD
define( ['jquery', 'datatables.net'], function ( $ ) {
return factory( $, window, document );
} );
}
else if ( typeof exports === 'object' ) {
// CommonJS
module.exports = function (root, $) {
if ( ! root ) {
root = window;
}
if ( ! $ || ! $.fn.dataTable ) {
// Require DataTables, which attaches to jQuery, including
// jQuery if needed and have a $ property so we can access the
// jQuery object that is used
$ = require('datatables.net')(root, $).$;
}
return factory( $, root, root.document );
};
}
else {
// Browser
factory( jQuery, window, document );
}
}(function( $, window, document, undefined ) {
'use strict';
var DataTable = $.fn.dataTable;
/* Set the defaults for DataTables initialisation */
$.extend( true, DataTable.defaults, {
dom:
"<'row'<'col-md-6'l><'col-md-6'f>>" +
"<'row'<'col-md-12'tr>>" +
"<'row'<'col-md-5'i><'col-md-7'p>>",
renderer: 'bootstrap'
} );
/* Default class modification */
$.extend( DataTable.ext.classes, {
sWrapper: "dataTables_wrapper form-inline dt-bootstrap4",
sFilterInput: "form-control input-sm",
sLengthSelect: "form-control input-sm",
sProcessing: "dataTables_processing panel panel-default",
sPageButton: "paginate_button page-item"
} );
/* Bootstrap paging button renderer */
DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {
var api = new DataTable.Api( settings );
var classes = settings.oClasses;
var lang = settings.oLanguage.oPaginate;
var aria = settings.oLanguage.oAria.paginate || {};
var btnDisplay, btnClass, counter=0;
var attach = function( container, buttons ) {
var i, ien, node, button;
var clickHandler = function ( e ) {
e.preventDefault();
if ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) {
api.page( e.data.action ).draw( 'page' );
}
};
for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
button = buttons[i];
if ( $.isArray( button ) ) {
attach( container, button );
}
else {
btnDisplay = '';
btnClass = '';
switch ( button ) {
case 'ellipsis':
btnDisplay = '&#x2026;';
btnClass = 'disabled';
break;
case 'first':
btnDisplay = lang.sFirst;
btnClass = button + (page > 0 ?
'' : ' disabled');
break;
case 'previous':
btnDisplay = lang.sPrevious;
btnClass = button + (page > 0 ?
'' : ' disabled');
break;
case 'next':
btnDisplay = lang.sNext;
btnClass = button + (page < pages-1 ?
'' : ' disabled');
break;
case 'last':
btnDisplay = lang.sLast;
btnClass = button + (page < pages-1 ?
'' : ' disabled');
break;
default:
btnDisplay = button + 1;
btnClass = page === button ?
'active' : '';
break;
}
if ( btnDisplay ) {
node = $('<li>', {
'class': classes.sPageButton+' '+btnClass,
'id': idx === 0 && typeof button === 'string' ?
settings.sTableId +'_'+ button :
null
} )
.append( $('<a>', {
'href': '#',
'aria-controls': settings.sTableId,
'aria-label': aria[ button ],
'data-dt-idx': counter,
'tabindex': settings.iTabIndex,
'class': 'page-link'
} )
.html( btnDisplay )
)
.appendTo( container );
settings.oApi._fnBindAction(
node, {action: button}, clickHandler
);
counter++;
}
}
}
};
// IE9 throws an 'unknown error' if document.activeElement is used
// inside an iframe or frame.
var activeEl;
try {
// Because this approach is destroying and recreating the paging
// elements, focus is lost on the select button which is bad for
// accessibility. So we want to restore focus once the draw has
// completed
activeEl = $(host).find(document.activeElement).data('dt-idx');
}
catch (e) {}
attach(
$(host).empty().html('<ul class="pagination"/>').children('ul'),
buttons
);
if ( activeEl ) {
$(host).find( '[data-dt-idx='+activeEl+']' ).focus();
}
};
return DataTable;
}));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
/*! Bootstrap integration for DataTables' Responsive
* ©2015 SpryMedia Ltd - datatables.net/license
*/
(function( factory ){
if ( typeof define === 'function' && define.amd ) {
// AMD
define( ['jquery', 'datatables.net-bs', 'datatables.net-responsive'], function ( $ ) {
return factory( $, window, document );
} );
}
else if ( typeof exports === 'object' ) {
// CommonJS
module.exports = function (root, $) {
if ( ! root ) {
root = window;
}
if ( ! $ || ! $.fn.dataTable ) {
$ = require('datatables.net-bs')(root, $).$;
}
if ( ! $.fn.dataTable.Responsive ) {
require('datatables.net-responsive')(root, $);
}
return factory( $, root, root.document );
};
}
else {
// Browser
factory( jQuery, window, document );
}
}(function( $, window, document, undefined ) {
'use strict';
var DataTable = $.fn.dataTable;
var _display = DataTable.Responsive.display;
var _original = _display.modal;
_display.modal = function ( options ) {
return function ( row, update, render ) {
if ( ! $.fn.modal ) {
_original( row, update, render );
}
else {
if ( ! update ) {
var modal = $(
'<div class="modal fade" role="dialog">'+
'<div class="modal-dialog" 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">&times;</span></button>'+
'</div>'+
'<div class="modal-body"/>'+
'</div>'+
'</div>'+
'</div>'
);
if ( options && options.header ) {
modal.find('div.modal-header')
.append( '<h4 class="modal-title">'+options.header( row )+'</h4>' );
}
modal.find( 'div.modal-body' ).append( render() );
modal
.appendTo( 'body' )
.modal();
}
}
};
};
return DataTable.Responsive;
}));

View File

@ -267,6 +267,46 @@ strolch.fn.toggleSubmitBtn = function (formId) {
spinner.show();
};
/*
* DataTable helpers
*/
strolch.fn.initDataTable = function (tableId, columns, url, queryData) {
var table = $('#' + tableId);
if ($.fn.dataTable.isDataTable(table)) {
table.DataTable().destroy();
table.empty();
}
// init table
table.dataTable({
columns: columns,
lengthMenu: [[5, 10, 20, -1], [5, 10, 20, 'All']],
processing: true,
serverSide: true,
ajax: function (data, callback, settings) {
queryData.draw = data.draw;
queryData.pageSize = data.length;
queryData.page = data.start / data.length + 1;
queryData.sortBy = data.columns[data.order[0].column].data;
queryData.ascending = data.order[0].dir == 'asc';
queryData.query = data.search.value;
$.ajax({
dataType: 'json',
url: url,
data: queryData,
success: function (data) {
data.recordsTotal = data.dataSetSize;
data.recordsFiltered = data.nrOfElements;
callback(data);
}
});
}
});
};
/*
* Part loading
*/
@ -393,6 +433,9 @@ strolch.fn.equalsArray = function (a, b) {
return $(a).not(b).length === 0 && $(b).not(a).length === 0;
};
strolch.fn.logException = function (e) {
(console.error || console.log).call(console, e, e.stack || e);
};
/*
* hack for multiple modals over each other - until bootstrap fixes this

View File

@ -10,6 +10,7 @@ if (typeof strolch == 'undefined') {
}
strolch.index = {};
strolch.const.partNames = ['model'];
jQuery(document).ready(function ($) {
strolch.index.init();
@ -26,8 +27,14 @@ strolch.index.init = function () {
return;
}
// multiple Modal hack
strolch.fn.multipleModalsHack();
strolch.index.registerHandlers();
// re-auth modal form handler
strolch.fn.onModalShow('#reauthFormModal', strolch.fn.logout);
strolch.fn.onModalFormSubmit('#reauthFormModal', '#reauthForm', function () {
setTimeout(strolch.fn.reAuth, 3000);
});
// validate session still alive
console.log('AuthToken exists, validating...');
@ -43,78 +50,98 @@ strolch.index.init = function () {
});
};
strolch.index.registerHandlers = function () {
strolch.fn.onModalShow('#reauthFormModal', strolch.fn.logout);
strolch.fn.onModalFormSubmit('#reauthFormModal', '#reauthForm', function () {
setTimeout(strolch.fn.reAuth, 3000);
});
};
strolch.index.start = function () {
var components = ['model'];
var componentsLoaded = [];
var componentsFailed = [];
strolch.index.loadParts();
strolch.index.registerHandlers();
};
var handleLoadDone = function () {
if (!strolch.fn.equalsArray(components, componentsLoaded)) {
strolch.index.registerHandlers = function () {
strolch.index.registerNavigationHandlers();
};
strolch.index.registerNavigationHandlers = function () {
$('*[data-function=navigate]').unbind('click').click(function (e) {
var target = $(this).data('target');
var part = strolch.parts[target];
if (part === 'undefined') {
alertify.alert(i18n.t('navigate.error'), i18n.t('navigate.error.missingpart', {part: part}));
return;
}
if (componentsFailed.length != 0) {
alertify.alert(i18n.t('component.load.error'), i18n.t('component.load.error.msg', {components: componentsFailed}));
$.each(strolch.const.partNames, function (index, value) {
strolch.parts[value].hide();
});
part.show();
});
};
strolch.index.loadParts = function () {
var partsLoaded = [];
var partsFailed = [];
var handleLoadDone = function () {
if (!strolch.fn.equalsArray(strolch.const.partNames, partsLoaded)) {
return;
}
if (partsFailed.length != 0) {
alertify.alert(i18n.t('part.load.error'), i18n.t('part.load.error.msg', {parts: partsFailed}));
return;
}
console.log("Finished loading parts.");
};
$.each(components, function (index, value) {
$.each(strolch.const.partNames, function (index, value) {
var component = value;
var partName = value;
$("#page-content").load("parts/" + component + ".html", function (responseText, textStatus, req) {
$("#page-content").load("parts/" + partName + ".html", function (responseText, textStatus, req) {
if (req.status != 200) {
console.error("Failed to load HTML for " + component + " due to status " + req.status);
componentsFailed.push(component);
componentsLoaded.push(component);
console.error("Failed to load HTML for " + partName + " due to status " + req.status);
partsFailed.push(partName);
partsLoaded.push(partName);
handleLoadDone();
} else {
console.log("Loaded HTML for " + component);
console.log("Loaded HTML for " + partName);
$.getScript("js/parts/" + component + ".js", function (responseText, textStatus, req) {
console.log("Loaded JS for " + component);
$.getScript("js/parts/" + partName + ".js", function (responseText, textStatus, req) {
console.log("Loaded JS for " + partName);
if (req.status != 200) {
console.error("Failed to load JS for " + component + " due to status " + req.status);
componentsFailed.push(component);
console.error("Failed to load JS for " + partName + " due to status " + req.status);
partsFailed.push(partName);
} else {
var componentNs = strolch.parts[component];
if (componentNs === 'undefined' || componentNs.init === 'undefined' || componentNs.show === 'undefined') {
componentsFailed.push(component + "(missing NS, init() or show())");
var part = strolch.parts[partName];
if (part === 'undefined' || part.init === 'undefined' || part.show === 'undefined') {
partsFailed.push(partName + "(missing part, init() or show())");
}
try {
componentNs.init();
part.init();
} catch (e) {
console.error(e);
componentsFailed.push(component + "(init failed!)");
strolch.fn.logException(e);
partsFailed.push(partName + "(init failed!)");
}
}
componentsLoaded.push(component);
partsLoaded.push(partName);
handleLoadDone();
});
}
});
});
};

View File

@ -1,4 +1,3 @@
// THIS IS A TEMPLATE - EXTEND FOR OWN PART
/*
@ -9,12 +8,14 @@ if (typeof strolch.parts == 'undefined') {
}
// define the namespace:
strolch.parts.TEMPLATE_NAME = {};
strolch.parts.TEMPLATE_NAME = {
name: TEMPLATE
};
// Required function init() - called to initialize when loaded
strolch.parts.TEMPLATE_NAME.init = function () {
strolch.parts.TEMPLATE_NAME.registerHandlers();
strolch.parts.TEMPLATE_NAME.registerHandlers();
};
// delegate function to register handlers (called from init)

View File

@ -8,25 +8,60 @@
if (typeof strolch.parts == 'undefined') {
strolch.parts = {};
}
strolch.parts.model = {};
strolch.parts.model = {
name: 'model',
loadedResources: false
};
strolch.parts.model.init = function (domParent) {
strolch.parts.model.prepareResourceTable();
strolch.parts.model.registerHandlers();
};
strolch.parts.model.registerHandlers = function () {
console.log("Registered handlers");
console.log('Registered handlers');
};
strolch.parts.model.show = function () {
$('#part-model').show();
};
strolch.parts.model.hide = function () {
$('#part-model').hide();
};
strolch.parts.model.prepareResourceTable = function () {
// query => the search criteria
// queryBy => the fields to use in searching, default is null/all
// sortBy => a single column to sort by
// ascending => true|false
// pageSize => integer, max number of elements to return per page,
// prepare query data
var data = {
query: '',
queryBy: '',
sortBy: '',
ascending: true,
pageSize: 1
};
var url = strolch.fn.url(strolch.const.urls.resources);
var columns = strolch.parts.model.prepareColumns();
strolch.fn.initDataTable('modelResourceTable', columns, url, data);
};
strolch.parts.model.prepareColumns = function () {
var columns = [];
columns.push({title: 'Id', width: 50, data: 'Id'});
columns.push({title: 'Name', data: 'Name'});
columns.push({title: 'Type', data: 'Type'});
return columns;
};

View File

@ -7,6 +7,6 @@
"auth-validating-token" : "Validating existing session...",
"auth-token-invalid" : "Existing session invalid, please login.",
"component.load.error" : "Component loading failed",
"component.load.error.msg" : "Failed to load the following components: ${components}"
"part.load.error" : "Part loading failed",
"part.load.error.msg" : "Failed to load the following part: ${parts}"
}

View File

@ -9,16 +9,20 @@
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="resources" role="tabpanel">
<h1>Resources</h1>
<table id="resourcesTable" class="table table-striped">
<table id="modelResourceTable" class="table table-striped">
<caption>The resources for the current user's realm</caption>
</table>
</div>
<div class="tab-pane" id="orders" role="tabpanel">Orders</div>
<div class="tab-pane" id="orders" role="tabpanel">
<table id="modelOrderTable" class="table table-striped">
<caption>The orders for the current user's realm</caption>
</table>
</div>
</div>
</div>

View File

@ -23,6 +23,7 @@ import li.strolch.rest.endpoint.AuditsService;
import li.strolch.rest.endpoint.AuthenticationService;
import li.strolch.rest.endpoint.EnumQuery;
import li.strolch.rest.endpoint.Inspector;
import li.strolch.rest.endpoint.ModelQuery;
import li.strolch.rest.endpoint.PrivilegePoliciesService;
import li.strolch.rest.endpoint.PrivilegeRolesService;
import li.strolch.rest.endpoint.PrivilegeUsersService;
@ -47,6 +48,7 @@ public class StrolchRestfulClasses {
restfulClasses.add(AuthenticationService.class);
restfulClasses.add(Inspector.class);
restfulClasses.add(VersionQuery.class);
restfulClasses.add(ModelQuery.class);
restfulClasses.add(EnumQuery.class);
// privilege

View File

@ -17,20 +17,20 @@ package li.strolch.rest;
import java.text.MessageFormat;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import li.strolch.exception.StrolchAccessDeniedException;
import li.strolch.rest.model.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.eitchnet.privilege.model.Restrictable;
import ch.eitchnet.utils.helper.StringHelper;
import li.strolch.exception.StrolchAccessDeniedException;
import li.strolch.rest.model.Result;
@Provider
public class StrolchRestfulExceptionMapper implements ExceptionMapper<Exception> {
@ -42,6 +42,9 @@ public class StrolchRestfulExceptionMapper implements ExceptionMapper<Exception>
logger.error(MessageFormat.format("Handling exception {0}", ex.getClass()), ex); //$NON-NLS-1$
if (ex instanceof NotFoundException)
return Response.status(Status.NOT_FOUND).entity(new Result(ex)).type(MediaType.APPLICATION_JSON).build();
if (ex instanceof StrolchAccessDeniedException) {
StrolchAccessDeniedException e = (StrolchAccessDeniedException) ex;
StringBuilder sb = new StringBuilder();

View File

@ -21,6 +21,7 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.HEAD;
@ -68,7 +69,7 @@ public class AuthenticationService {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response login(Login login, @Context HttpHeaders headers) {
public Response login(Login login, @Context HttpServletRequest request, @Context HttpHeaders headers) {
LoginResult loginResult = new LoginResult();
@ -115,9 +116,13 @@ public class AuthenticationService {
}
loginResult.setPrivileges(privileges);
boolean secureCookie = restfulStrolchComponent.isSecureCookie();
if (secureCookie && !request.getScheme().equals("https")) {
logger.warn(
"Authorization cookie is secure, but connection is not secure! Cookie won't be passed to client!");
}
NewCookie cookie = new NewCookie(StrolchRestfulConstants.STROLCH_AUTHORIZATION, certificate.getAuthToken(),
"/", null, "Authorization header", (int) TimeUnit.DAYS.toSeconds(1),
restfulStrolchComponent.isSecureCookie());
"/", null, "Authorization header", (int) TimeUnit.DAYS.toSeconds(1), secureCookie);
return Response.ok().entity(loginResult)//
.header(HttpHeaders.AUTHORIZATION, certificate.getAuthToken()).cookie(cookie).build();

View File

@ -0,0 +1,187 @@
package li.strolch.rest.endpoint;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import ch.eitchnet.privilege.model.Certificate;
import ch.eitchnet.utils.StringMatchMode;
import ch.eitchnet.utils.collections.Paging;
import ch.eitchnet.utils.helper.StringHelper;
import li.strolch.agent.api.ResourceMap;
import li.strolch.model.Resource;
import li.strolch.model.json.ResourceToJsonVisitor;
import li.strolch.model.parameter.Parameter;
import li.strolch.model.query.IdSelection;
import li.strolch.model.query.NameSelection;
import li.strolch.model.query.OrSelection;
import li.strolch.model.query.ParameterSelection;
import li.strolch.model.query.ResourceQuery;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.rest.RestfulStrolchComponent;
import li.strolch.rest.StrolchRestfulConstants;
import li.strolch.rest.model.StrolchElementOverview;
import li.strolch.rest.model.TypeDetail;
import li.strolch.runtime.StrolchConstants;
@Path("strolch/model")
public class ModelQuery {
/**
* <p>
* Query Resources
* </p>
*
* @param realm
* the realm for which the resource type overview is to be returned
* @param type
*
* @return an overview of the {@link Resource Resources} with the given type. This is a list of overviews of the
* resources
*
* @see TypeDetail
* @see StrolchElementOverview
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("resources")
public Response queryResources(@BeanParam QueryData queryData, @Context HttpServletRequest request) {
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
String realmName = queryData.getRealmName();
if (StringHelper.isEmpty(realmName))
realmName = StrolchConstants.DEFAULT_REALM;
List<Resource> resources = new ArrayList<>();
Set<String> queryBy = queryData.getQueryByNames();
Set<String> queryTypes = queryData.getTypes();
long dataSetSize = 0L;
try (StrolchTransaction tx = openTx(cert, realmName)) {
ResourceMap resourceMap = tx.getResourceMap();
if (queryTypes.isEmpty()) {
Set<String> types = resourceMap.getTypes(tx);
dataSetSize = resourceMap.querySize(tx);
for (String type : types) {
query(queryData, resources, queryBy, tx, type);
}
} else {
for (String type : queryTypes) {
dataSetSize = resourceMap.querySize(tx, type);
query(queryData, resources, queryBy, tx, type);
}
}
tx.doNothingOnClose();
}
String orderBy = queryData.getOrderBy();
boolean asc = queryData.isAscending();
if (StringHelper.isNotEmpty(orderBy)) {
if (orderBy.equals(QueryData.ID)) {
resources.sort((r1, r2) -> asc ? r1.getId().compareTo(r2.getId()) : r2.getId().compareTo(r1.getId()));
} else if (orderBy.equals(QueryData.NAME)) {
resources.sort(
(r1, r2) -> asc ? r1.getName().compareTo(r2.getName()) : r2.getName().compareTo(r1.getName()));
} else if (orderBy.equals(QueryData.TYPE)) {
resources.sort(
(r1, r2) -> asc ? r1.getType().compareTo(r2.getType()) : r2.getType().compareTo(r1.getType()));
} else {
String[] parts = orderBy.split(":");
String bagKey = parts[0];
String paramKey = parts[1];
resources.sort((r1, r2) -> {
Parameter<?> param1 = r1.getParameter(bagKey, paramKey);
Parameter<?> param2 = r2.getParameter(bagKey, paramKey);
if (asc)
return param1.getValueAsString().compareTo(param2.getValueAsString());
return param2.getValueAsString().compareTo(param1.getValueAsString());
});
}
}
// paging
Paging<Resource> paging = Paging.asPage(resources, queryData.getPageSize(), queryData.getPage());
// get page
List<Resource> page = paging.getPage();
// build JSON response
JsonObject root = new JsonObject();
root.addProperty("msg", "-");
root.addProperty("draw", queryData.getDraw());
root.addProperty("dataSetSize", dataSetSize);
root.addProperty("nrOfElements", paging.getNrOfElements());
if (StringHelper.isNotEmpty(orderBy))
root.addProperty("sortBy", orderBy);
root.addProperty("ascending", asc);
root.addProperty("nrOfPages", paging.getNrOfPages());
root.addProperty("pageSize", paging.getPageSize());
root.addProperty("page", paging.getPageToReturn());
// add items
JsonArray data = new JsonArray();
for (Resource resource : page) {
JsonObject element = new ResourceToJsonVisitor().visit(resource);
data.add(element);
}
root.add("data", data);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String entity = gson.toJson(root);
return Response.ok(entity).build();
}
private void query(QueryData queryData, List<Resource> resources, Set<String> queryBy, StrolchTransaction tx,
String type) {
ResourceQuery<Resource> query = ResourceQuery.query(type);
OrSelection or = new OrSelection();
for (String queryB : queryBy) {
if (queryB.equals(QueryData.TYPE))
continue;
if (queryB.equals(QueryData.ID)) {
or.with(new IdSelection(queryData.getQuery(), StringMatchMode.ci()));
} else if (queryB.equals(QueryData.NAME)) {
or.with(new NameSelection(queryData.getQuery(), StringMatchMode.ci()));
} else {
String[] parts = queryB.split(":");
String bagKey = parts[0];
String paramKey = parts[1];
or.with(ParameterSelection.anyTypeSelection(bagKey, paramKey, queryData.getQuery(),
StringMatchMode.ci()));
}
}
if (or.hasSelection())
query.with(or);
else
query.withAny();
resources.addAll(tx.doQuery(query));
}
private StrolchTransaction openTx(Certificate certificate, String realm) {
return RestfulStrolchComponent.getInstance().getContainer().getRealm(realm).openTx(certificate,
Inspector.class);
}
}

View File

@ -0,0 +1,134 @@
package li.strolch.rest.endpoint;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.QueryParam;
import ch.eitchnet.utils.helper.StringHelper;
public class QueryData {
public static final String ID = "Id";
public static final String NAME = "Name";
public static final String TYPE = "Type";
@QueryParam("realm")
private String realmName;
@QueryParam("draw")
private int draw;
@QueryParam("orderBy")
private String orderBy;
@QueryParam("ascending")
private boolean ascending;
@QueryParam("pageSize")
private int pageSize;
@QueryParam("page")
private int page;
@QueryParam("query")
private String query;
@QueryParam("queryBy")
private String queryBy;
@QueryParam("types")
private String type;
public String getRealmName() {
return this.realmName;
}
public void setRealmName(String realmName) {
this.realmName = realmName;
}
public int getDraw() {
return this.draw;
}
public void setDraw(int draw) {
this.draw = draw;
}
public String getOrderBy() {
return this.orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public boolean isAscending() {
return this.ascending;
}
public void setAscending(boolean ascending) {
this.ascending = ascending;
}
public int getPageSize() {
return this.pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPage() {
return this.page;
}
public void setPage(int page) {
this.page = page;
}
public String getQuery() {
return this.query;
}
public void setQuery(String query) {
this.query = query;
}
public String getQueryBy() {
return this.queryBy;
}
public void setQueryBy(String queryBy) {
this.queryBy = queryBy;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public Set<String> getQueryByNames() {
return toSet(this.queryBy);
}
public Set<String> getTypes() {
return toSet(this.type);
}
private Set<String> toSet(String value) {
if (StringHelper.isEmpty(value))
return Collections.emptySet();
if (!value.contains(","))
return Collections.singleton(value);
return new HashSet<>(Arrays.asList(value.split(",")));
}
}