You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2022/08/25 14:34:04 UTC
[myfaces-tobago] branch main updated: feat: Sheet multi column sorting (#3053) (#3054)
This is an automated email from the ASF dual-hosted git repository.
lofwyr pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git
The following commit(s) were added to refs/heads/main by this push:
new 3c4e463871 feat: Sheet multi column sorting (#3053) (#3054)
3c4e463871 is described below
commit 3c4e46387110ca517750be21d15eda54f1c339b5
Author: Udo Schnurpfeil <gi...@schnurpfeil.de>
AuthorDate: Thu Aug 25 16:33:58 2022 +0200
feat: Sheet multi column sorting (#3053) (#3054)
issue: TOBAGO-2155
Co-authored-by: Udo Schnurpfeil <ud...@irian.eu>
(cherry picked from commit 49433654e4d1ba27167271d389a4df77a6dd462b)
---
.../myfaces/tobago/component/Attributes.java | 3 +-
.../tobago/internal/component/AbstractUISheet.java | 10 +-
.../internal/renderkit/renderer/SheetRenderer.java | 66 +++++++++--
.../taglib/component/SheetTagDeclaration.java | 8 ++
.../myfaces/tobago/internal/util/SortingUtils.java | 42 +++----
.../apache/myfaces/tobago/model/SheetState.java | 114 ++++++++++++++----
.../apache/myfaces/tobago/model/SortedColumn.java | 52 ++++++++
.../myfaces/tobago/model/SortedColumnList.java | 120 +++++++++++++++++++
.../myfaces/tobago/renderkit/css/TobagoClass.java | 9 ++
.../tobago/internal/util/SortingUtilsUnitTest.java | 46 ++++++-
.../myfaces/tobago/model/SheetStateUnitTest.java | 132 +++++++++++++++++++++
.../tobago/renderkit/css/TobagoClassUnitTest.java | 4 +-
.../example/demo/SheetMultiSortingController.java | 125 +++++++++++++++++++
.../content/080-sheet/10-sort/Sheet_Sorting.xhtml | 43 ++++++-
tobago-theme/src/main/scss/_tobago.scss | 86 ++++++++++++--
.../src/main/css/tobago.css | 58 ++++++++-
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
.../src/main/css/tobago.css | 58 ++++++++-
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
.../src/main/css/tobago.css | 58 ++++++++-
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
.../tobago-theme-speyside/src/main/css/tobago.css | 58 ++++++++-
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
.../tobago-theme-standard/src/main/css/tobago.css | 58 ++++++++-
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
35 files changed, 1076 insertions(+), 104 deletions(-)
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
index b0f55f0960..5e80a5c8d3 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
@@ -408,6 +408,7 @@ public enum Attributes {
sortable,
sortActionListener,
sortActionListenerExpression,
+ maxSortColumns,
small,
spanX,
spanY,
@@ -451,7 +452,7 @@ public enum Attributes {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private final String explicit;
+ private final String explicit;
Attributes() {
this(null);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
index d551bf6587..82571dce88 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
@@ -142,13 +142,13 @@ public abstract class AbstractUISheet extends AbstractUIData
final ELContext elContext = facesContext.getELContext();
SheetState sheetState = (SheetState) expression.getValue(elContext);
if (sheetState == null) {
- sheetState = new SheetState();
+ sheetState = new SheetState(getMaxSortColumns());
expression.setValue(elContext, sheetState);
}
return sheetState;
}
- state = new SheetState();
+ state = new SheetState(getMaxSortColumns());
return state;
}
@@ -439,7 +439,7 @@ public abstract class AbstractUISheet extends AbstractUIData
protected void sort(final FacesContext facesContext, final SortActionEvent event) {
final SheetState sheetState = getSheetState(getFacesContext());
- if (sheetState.isToBeSorted()) {
+ if (sheetState.getToBeSortedLevel() > 0) {
final MethodExpression expression = getSortActionListenerExpression();
if (expression != null) {
try {
@@ -455,7 +455,7 @@ public abstract class AbstractUISheet extends AbstractUIData
} else {
SortingUtils.sort(this, null);
}
- sheetState.setToBeSorted(false);
+ sheetState.sorted();
}
}
@@ -577,4 +577,6 @@ public abstract class AbstractUISheet extends AbstractUIData
public abstract ShowPosition getShowDirectLinks();
public abstract boolean isLazy();
+
+ public abstract Integer getMaxSortColumns();
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
index 9a835b01e2..1d43f3d86a 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
@@ -51,6 +51,8 @@ import org.apache.myfaces.tobago.layout.TextAlign;
import org.apache.myfaces.tobago.model.ExpandedState;
import org.apache.myfaces.tobago.model.Selectable;
import org.apache.myfaces.tobago.model.SheetState;
+import org.apache.myfaces.tobago.model.SortedColumn;
+import org.apache.myfaces.tobago.model.SortedColumnList;
import org.apache.myfaces.tobago.model.TreePath;
import org.apache.myfaces.tobago.renderkit.RendererBase;
import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
@@ -89,6 +91,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
@@ -835,6 +838,7 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
boolean sortable = false;
boolean ascending = false;
boolean descending = false;
+ CssItem sortPosition = null;
String tip = ComponentUtils.getStringAttribute(column, Attributes.tip);
// sorter icons should only displayed when there is only 1 column and not input
CommandMap behaviorCommands = null;
@@ -864,16 +868,57 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
tip += ResourceUtils.getString(facesContext, "sheet.sorting");
final SheetState sheetState = sheet.getSheetState(facesContext);
- if (column.getId().equals(sheetState.getSortedColumnId())) {
- final String sortTitle;
- if (sheetState.isAscending()) {
- sortTitle = ResourceUtils.getString(facesContext, "sheet.ascending");
- ascending = true;
- } else {
- sortTitle = ResourceUtils.getString(facesContext, "sheet.descending");
- descending = true;
+ final SortedColumnList sortedColumnList = sheetState.getSortedColumnList();
+
+ final int index = sortedColumnList.indexOf(column.getId());
+ if (index >= 0) {
+ if (sortedColumnList.isShowNumbers()) { // ignore number circles otherwise
+ switch (index) {
+ case 0:
+ sortPosition = TobagoClass.CIRCLE__1;
+ break;
+ case 1:
+ sortPosition = TobagoClass.CIRCLE__2;
+ break;
+ case 2:
+ sortPosition = TobagoClass.CIRCLE__3;
+ break;
+ case 3:
+ sortPosition = TobagoClass.CIRCLE__4;
+ break;
+ case 4:
+ sortPosition = TobagoClass.CIRCLE__5;
+ break;
+ case 5:
+ sortPosition = TobagoClass.CIRCLE__6;
+ break;
+ case 6:
+ sortPosition = TobagoClass.CIRCLE__7;
+ break;
+ case 7:
+ sortPosition = TobagoClass.CIRCLE__8;
+ break;
+ case 8:
+ sortPosition = TobagoClass.CIRCLE__9;
+ break;
+ default:
+ // should not happen
+ LOG.warn("Index {} not supported!", index);
+ }
+ }
+
+ final SortedColumn sortedColumn = sortedColumnList.get(index);
+ if (Objects.equals(column.getId(), sortedColumn.getId())) {
+ final String sortTitle;
+ if (sortedColumn.isAscending()) {
+ sortTitle = ResourceUtils.getString(facesContext, "sheet.ascending");
+ ascending = true;
+ } else {
+ sortTitle = ResourceUtils.getString(facesContext, "sheet.descending");
+ descending = true;
+ }
+ tip += " - " + sortTitle;
}
- tip += " - " + sortTitle;
}
}
}
@@ -881,7 +926,8 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
writer.writeClassAttribute(
sortable ? TobagoClass.SORTABLE : null,
ascending ? TobagoClass.ASCENDING : null,
- descending ? TobagoClass.DESCENDING : null);
+ descending ? TobagoClass.DESCENDING : null,
+ sortPosition);
writer.writeAttribute(HtmlAttributes.TITLE, tip, true);
encodeBehavior(writer, behaviorCommands);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
index 042607f02a..8019e87b8f 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
@@ -286,4 +286,12 @@ public interface SheetTagDeclaration
@UIComponentTagAttribute(type = "boolean", defaultValue = "true")
void setShowPageRangeArrows(String showPageRangeArrows);
+ /**
+ * The maximum count of multi-sorted columns to indicate.
+ * @since 5.3.0
+ */
+ @TagAttribute
+ @UIComponentTagAttribute(type = "java.lang.Integer", defaultValue = "0")
+ void setMaxSortColumns(String maxSortColumns);
+
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/SortingUtils.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/SortingUtils.java
index 8a4d4ffba0..51da6163a5 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/SortingUtils.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/SortingUtils.java
@@ -24,6 +24,7 @@ import org.apache.myfaces.tobago.component.RendererTypes;
import org.apache.myfaces.tobago.internal.component.AbstractUICommand;
import org.apache.myfaces.tobago.internal.component.AbstractUISheet;
import org.apache.myfaces.tobago.model.SheetState;
+import org.apache.myfaces.tobago.model.SortedColumn;
import org.apache.myfaces.tobago.util.MessageUtils;
import org.apache.myfaces.tobago.util.ValueExpressionComparator;
import org.slf4j.Logger;
@@ -57,26 +58,30 @@ public class SortingUtils {
public static void sort(final AbstractUISheet sheet, final Comparator comparator) {
final FacesContext facesContext = FacesContext.getCurrentInstance();
- Object data = sheet.getValue();
- if (data instanceof DataModel) {
- data = ((DataModel) data).getWrappedData();
- }
+ final Object value = sheet.getValue();
+ final Object data = value instanceof DataModel ? ((DataModel) value).getWrappedData() : value;
final SheetState sheetState = sheet.getSheetState(facesContext);
- final String sortedColumnId = sheetState.getSortedColumnId();
- LOG.debug("sorterId = '{}'", sortedColumnId);
-
boolean success = false;
- if (sortedColumnId != null) {
- final UIColumn column = (UIColumn) sheet.findComponent(sortedColumnId);
- if (column != null) {
- success = sort(facesContext, sheet, data, column, sheetState, comparator);
- } else {
- LOG.error("No column to sort found, sorterId = '{}'!", sortedColumnId);
- addNotSortableMessage(facesContext, null);
+ if (sheetState.getToBeSortedLevel() > 0) {
+ UIColumn column = null;
+ try {
+ for (int i = sheetState.getToBeSortedLevel() - 1; i >= 0; i--) {
+ final SortedColumn sortedColumn = sheetState.getSortedColumnList().get(i);
+ column = (UIColumn) sheet.findComponent(sortedColumn.getId());
+ if (column != null) {
+ success = sort(facesContext, sheet, data, column, sortedColumn.isAscending(), sheetState, comparator);
+ } else {
+ LOG.error("No column to sort found, sorterId = '{}'!", sortedColumn.getId());
+ addNotSortableMessage(facesContext, null);
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Error while extracting sortMethod :" + e.getMessage(), e);
+ addNotSortableMessage(facesContext, column);
}
} else {
- LOG.debug("No sorterId!");
+ LOG.debug("Not to be sorted!");
}
if (!success) {
@@ -86,7 +91,7 @@ public class SortingUtils {
private static boolean sort(
final FacesContext facesContext, final AbstractUISheet sheet, final Object data, final UIColumn column,
- final SheetState sheetState, Comparator comparator) {
+ final boolean ascending, final SheetState sheetState, Comparator comparator) {
final Comparator actualComparator;
@@ -94,7 +99,6 @@ public class SortingUtils {
try {
final UIComponent child = getFirstSortableChild(column.getChildren());
if (child != null) {
- final boolean descending = !sheetState.isAscending();
final String attribute = (child instanceof AbstractUICommand ? Attributes.label : Attributes.value).getName();
final ValueExpression expression = child.getValueExpression(attribute);
if (expression != null) {
@@ -104,7 +108,7 @@ public class SortingUtils {
addNotSortableMessage(facesContext, column);
return false;
}
- actualComparator = new ValueExpressionComparator(facesContext, var, expression, descending, comparator);
+ actualComparator = new ValueExpressionComparator(facesContext, var, expression, !ascending, comparator);
} else {
LOG.error("No sorting performed, because no expression found for "
+ "attribute '{}' in component '{}' with id='{}'! You may check the type of the component!",
@@ -118,8 +122,6 @@ public class SortingUtils {
return false;
}
} catch (final Exception e) {
- LOG.error("Error while extracting sortMethod :" + e.getMessage(), e);
- addNotSortableMessage(facesContext, column);
return false;
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java
index 5f7df2e7d7..2a3cf0cfcf 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java
@@ -20,6 +20,7 @@
package org.apache.myfaces.tobago.model;
import org.apache.myfaces.tobago.event.SortActionEvent;
+import org.apache.myfaces.tobago.internal.util.Deprecation;
import org.apache.myfaces.tobago.internal.util.StringUtils;
import java.io.Serializable;
@@ -31,24 +32,36 @@ public class SheetState implements Serializable, ScrollPositionState {
private static final long serialVersionUID = 2L;
private int first;
- private String sortedColumnId;
- private boolean ascending;
- private boolean toBeSorted;
+ private SortedColumnList sortedColumnList;
private List<Integer> columnWidths;
private List<Integer> selectedRows;
private ScrollPosition scrollPosition;
private ExpandedState expandedState;
private SelectedState selectedState;
+ /**
+ * @deprecated since 5.3.0
+ */
+ @Deprecated
public SheetState() {
- reset();
+ this(1);
}
+ public SheetState(final int maxSortColumns) {
+ reset(maxSortColumns);
+ }
+
+ /**
+ * @deprecated since 5.3.0
+ */
+ @Deprecated
public void reset() {
+ reset(1);
+ }
+
+ public void reset(final int maxSortColumns) {
first = -1;
- sortedColumnId = null;
- ascending = true;
- toBeSorted = false;
+ sortedColumnList = new SortedColumnList(maxSortColumns);
columnWidths = new ArrayList<>();
resetSelected();
if (expandedState != null) {
@@ -77,28 +90,65 @@ public class SheetState implements Serializable, ScrollPositionState {
this.selectedRows = selectedRows;
}
+ /**
+ * @deprecated since 5.3.0
+ */
+ @Deprecated
public String getSortedColumnId() {
- return sortedColumnId;
+ if (sortedColumnList.isEmpty()) {
+ return null;
+ } else {
+ return sortedColumnList.getFirst().getId();
+ }
}
+ /**
+ * @deprecated since 5.3.0, please use {@link #updateSortState(String id)}
+ */
+ @Deprecated
public void setSortedColumnId(final String sortedColumnId) {
- if (StringUtils.notEquals(this.sortedColumnId, sortedColumnId)) {
- this.sortedColumnId = sortedColumnId;
- toBeSorted = true;
+ Deprecation.LOG.warn("Method SheetState.setSortedColumnId() should not be called!");
+ if (sortedColumnList.isEmpty()) {
+ sortedColumnList.add(sortedColumnId, true);
+ } else {
+ if (StringUtils.notEquals(sortedColumnList.getFirst().getId(), sortedColumnId)) {
+ sortedColumnList.getFirst().setId(sortedColumnId);
+ }
}
}
+ /**
+ * @deprecated since 5.3.0
+ */
+ @Deprecated
public boolean isAscending() {
- return ascending;
+ if (sortedColumnList.isEmpty()) {
+ return true;
+ } else {
+ return sortedColumnList.getFirst().isAscending();
+ }
}
+ /**
+ * @param ascending
+ * @deprecated since 5.3.0, please use {@link #updateSortState(String id)}
+ */
+ @Deprecated
public void setAscending(final boolean ascending) {
- if (this.ascending != ascending) {
- this.ascending = ascending;
- toBeSorted = true;
+ Deprecation.LOG.warn("Method SheetState.setAscending() should not be called!");
+ if (sortedColumnList.isEmpty()) {
+ sortedColumnList.add(null, ascending);
+ } else {
+ if (sortedColumnList.getFirst().isAscending() != ascending) {
+ sortedColumnList.getFirst().setAscending(ascending);
+ }
}
}
+ public SortedColumnList getSortedColumnList() {
+ return sortedColumnList;
+ }
+
public List<Integer> getColumnWidths() {
return columnWidths;
}
@@ -133,17 +183,11 @@ public class SheetState implements Serializable, ScrollPositionState {
}
public void updateSortState(final String columnId) {
- if (columnId.equals(sortedColumnId)) {
- setAscending(!isAscending());
- } else {
- setAscending(true);
- setSortedColumnId(columnId);
- }
+ sortedColumnList.updateSortState(columnId);
}
public void resetSortState() {
- setAscending(true);
- setSortedColumnId(null);
+ sortedColumnList.clear();
}
@Override
@@ -177,11 +221,31 @@ public class SheetState implements Serializable, ScrollPositionState {
this.selectedState = selectedState;
}
+ /**
+ * @deprecated since 5.3.0, please use {@link #getToBeSortedLevel()}
+ */
+ @Deprecated
public boolean isToBeSorted() {
- return toBeSorted;
+ return getToBeSortedLevel() > 0;
}
+ /**
+ * @deprecated since 5.3.0, please use {@link #sorted()}
+ */
+ @Deprecated
public void setToBeSorted(final boolean toBeSorted) {
- this.toBeSorted = toBeSorted;
+ if (toBeSorted) {
+ sortedColumnList.setToBeSortedLevel(Math.max(1, sortedColumnList.getToBeSortedLevel()));
+ } else {
+ sorted();
+ }
+ }
+
+ public int getToBeSortedLevel() {
+ return sortedColumnList.getToBeSortedLevel();
+ }
+
+ public void sorted() {
+ sortedColumnList.sorted();
}
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SortedColumn.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SortedColumn.java
new file mode 100644
index 0000000000..f66af7b4b6
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SortedColumn.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.tobago.model;
+
+import java.io.Serializable;
+
+public class SortedColumn implements Serializable {
+ private String id;
+ private boolean ascending;
+
+ public SortedColumn(String id, boolean ascending) {
+ this.id = id;
+ this.ascending = ascending;
+ }
+
+ public void toggle() {
+ ascending = !ascending;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public boolean isAscending() {
+ return ascending;
+ }
+
+ public void setAscending(boolean ascending) {
+ this.ascending = ascending;
+ }
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SortedColumnList.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SortedColumnList.java
new file mode 100644
index 0000000000..9853de7f0c
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SortedColumnList.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.tobago.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class SortedColumnList implements Serializable {
+ private final int max;
+ private final boolean showNumbers;
+ private final List<SortedColumn> list;
+ private int toBeSortedLevel;
+
+ public SortedColumnList(final int max) {
+ this.max = Math.max(max, 1);
+ this.showNumbers = max >= 1;
+ this.list = new ArrayList<>(max);
+ this.toBeSortedLevel = 0;
+ }
+
+ public boolean isEmpty() {
+ return list.size() == 0;
+ }
+
+ public SortedColumn getFirst() {
+ return list.size() > 0 ? list.get(0) : null;
+ }
+
+ public void updateSortState(final String columnId) {
+ if (getFirst() != null && Objects.equals(getFirst().getId(), columnId)) {
+ getFirst().toggle();
+ toBeSortedLevel = Math.max(1, toBeSortedLevel);
+ } else {
+ final int index = indexOf(columnId);
+ if (index >= 0) {
+ list.remove(index);
+ toBeSortedLevel--;
+ }
+ list.add(0, new SortedColumn(columnId, true));
+ toBeSortedLevel++;
+ checkSize();
+ }
+ }
+
+ /**
+ * @deprecated Only for backward compatibility of deprecated functions!
+ */
+ @Deprecated
+ public void add(final String columnId, final boolean ascending) {
+ list.add(new SortedColumn(columnId, ascending));
+ toBeSortedLevel++;
+ checkSize();
+ }
+
+ public SortedColumn get(int index) {
+ return list.get(index);
+ }
+
+ private void checkSize() {
+ while (size() > max) {
+ list.remove(size() - 1);
+ }
+ if (toBeSortedLevel > max) {
+ toBeSortedLevel = max;
+ }
+ }
+
+ public int size() {
+ return list.size();
+ }
+
+ public void clear() {
+ list.clear();
+ }
+
+ public void sorted() {
+ toBeSortedLevel = 0;
+ }
+
+ public int indexOf(String id) {
+ for (int i = 0; i < size(); i++) {
+ SortedColumn sortedColumn = list.get(i);
+ if (Objects.equals(sortedColumn.getId(), id)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public boolean isShowNumbers() {
+ return showNumbers;
+ }
+
+ public int getToBeSortedLevel() {
+ return toBeSortedLevel;
+ }
+
+ public void setToBeSortedLevel(int toBeSortedLevel) {
+ this.toBeSortedLevel = toBeSortedLevel;
+ }
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/TobagoClass.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/TobagoClass.java
index c22608e36a..2a7d5a6fa8 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/TobagoClass.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/TobagoClass.java
@@ -35,6 +35,15 @@ public enum TobagoClass implements CssItem {
// tbd: can this be removed, when using <tobago-button>?
BUTTON("tobago-button"),
// BUTTONS("tobago-buttons"),
+ CIRCLE__1("tobago-circle-1"),
+ CIRCLE__2("tobago-circle-2"),
+ CIRCLE__3("tobago-circle-3"),
+ CIRCLE__4("tobago-circle-4"),
+ CIRCLE__5("tobago-circle-5"),
+ CIRCLE__6("tobago-circle-6"),
+ CIRCLE__7("tobago-circle-7"),
+ CIRCLE__8("tobago-circle-8"),
+ CIRCLE__9("tobago-circle-9"),
COLLAPSED("tobago-collapsed"),
// DATE("tobago-date"),
// DATE__PICKER("tobago-date-picker"),
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/SortingUtilsUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/SortingUtilsUnitTest.java
index dd3acb3a3c..22cb51719c 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/SortingUtilsUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/SortingUtilsUnitTest.java
@@ -46,7 +46,7 @@ public class SortingUtilsUnitTest extends AbstractTobagoTestBase {
final List<Fruit> list = Fruit.getFreshFruits();
final UISheet sheet = new UISheet();
- sheet.getState().setSortedColumnId("id");
+ sheet.getState().updateSortState("id");
final UIColumn column = new UIColumn();
column.setId("id");
sheet.getChildren().add(column);
@@ -60,10 +60,15 @@ public class SortingUtilsUnitTest extends AbstractTobagoTestBase {
Assertions.assertEquals(Pear.KOESTLICHE_AUS_CHARNEUX, list.get(3));
}
- @Test
- public void testUIOut() {
+ /**
+ * @deprecated
+ */
+ @Test
+ @Deprecated
+ public void testUIOutDeprected() {
final List<Fruit> list = Fruit.getFreshFruits();
final UISheet sheet = new UISheet();
+ sheet.setMaxSortColumns(1);
sheet.getState().setSortedColumnId("id");
sheet.setVar("var");
final UIColumn column = new UIColumn();
@@ -92,11 +97,44 @@ public class SortingUtilsUnitTest extends AbstractTobagoTestBase {
Assertions.assertEquals(Apple.GOLDEN_DELICIOUS, list.get(3));
}
+ @Test
+ public void testUIOut() {
+ final List<Fruit> list = Fruit.getFreshFruits();
+ final UISheet sheet = new UISheet();
+ sheet.setMaxSortColumns(1);
+ sheet.getState().updateSortState("id");
+ sheet.setVar("var");
+ final UIColumn column = new UIColumn();
+ column.setId("id");
+ sheet.getChildren().add(column);
+ sheet.setValue(list);
+ final UIOut out = new UIOut();
+ column.getChildren().add(out);
+ out.setValueExpression(Attributes.value.getName(),
+ new MockValueExpression("#{var.name}", String.class));
+ Assertions.assertNotNull(out.getValueExpression(Attributes.value.getName()));
+
+ SortingUtils.sort(sheet, null);
+
+ Assertions.assertEquals(Apple.GOLDEN_DELICIOUS, list.get(0));
+ Assertions.assertEquals(Pear.KOESTLICHE_AUS_CHARNEUX, list.get(1));
+ Assertions.assertEquals(Apple.SCHOENER_AUS_BOSKOOP, list.get(2));
+ Assertions.assertEquals(Pear.WILLIAMS_CHRIST, list.get(3));
+
+ sheet.getState().updateSortState("id");
+ SortingUtils.sort(sheet, null);
+
+ Assertions.assertEquals(Pear.WILLIAMS_CHRIST, list.get(0));
+ Assertions.assertEquals(Apple.SCHOENER_AUS_BOSKOOP, list.get(1));
+ Assertions.assertEquals(Pear.KOESTLICHE_AUS_CHARNEUX, list.get(2));
+ Assertions.assertEquals(Apple.GOLDEN_DELICIOUS, list.get(3));
+ }
+
@Test
public void testUILink() {
final List<Fruit> list = Fruit.getFreshFruits();
final UISheet sheet = new UISheet();
- sheet.getState().setSortedColumnId("id");
+ sheet.getState().updateSortState("id");
final UIColumn column = new UIColumn();
column.setId("id");
sheet.getChildren().add(column);
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/model/SheetStateUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/model/SheetStateUnitTest.java
new file mode 100644
index 0000000000..e5304c2f91
--- /dev/null
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/model/SheetStateUnitTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.tobago.model;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class SheetStateUnitTest {
+
+ @Test
+ public void testState() {
+ final SheetState state = new SheetState(3);
+ final SortedColumnList list = state.getSortedColumnList();
+
+ Assertions.assertNull(list.getFirst());
+ Assertions.assertEquals(0, list.size());
+ Assertions.assertEquals(0, list.getToBeSortedLevel());
+
+ state.updateSortState("a");
+
+ Assertions.assertEquals("a", list.getFirst().getId());
+ Assertions.assertTrue(list.getFirst().isAscending());
+ Assertions.assertEquals(1, list.size());
+ Assertions.assertEquals(1, list.getToBeSortedLevel());
+
+ state.updateSortState("a");
+
+ Assertions.assertEquals("a", list.getFirst().getId());
+ Assertions.assertFalse(list.getFirst().isAscending());
+ Assertions.assertEquals(1, list.size());
+ Assertions.assertEquals(1, list.getToBeSortedLevel());
+
+ state.updateSortState("a");
+
+ Assertions.assertEquals("a", list.getFirst().getId());
+ Assertions.assertTrue(list.getFirst().isAscending());
+ Assertions.assertEquals(1, list.size());
+ Assertions.assertEquals(1, list.getToBeSortedLevel());
+
+ state.updateSortState("b");
+
+ Assertions.assertEquals("b", list.getFirst().getId());
+ Assertions.assertTrue(list.getFirst().isAscending());
+ Assertions.assertEquals(2, list.size());
+ Assertions.assertEquals(2, list.getToBeSortedLevel());
+
+ state.sorted();
+
+ Assertions.assertEquals("b", list.getFirst().getId());
+ Assertions.assertTrue(list.getFirst().isAscending());
+ Assertions.assertEquals(2, list.size());
+ Assertions.assertEquals(0, list.getToBeSortedLevel());
+
+ state.updateSortState("b");
+
+ Assertions.assertEquals("b", list.getFirst().getId());
+ Assertions.assertFalse(list.getFirst().isAscending());
+ Assertions.assertEquals(2, list.size());
+ Assertions.assertEquals(1, list.getToBeSortedLevel());
+
+ state.updateSortState("b");
+
+ Assertions.assertEquals("b", list.getFirst().getId());
+ Assertions.assertTrue(list.getFirst().isAscending());
+ Assertions.assertEquals(2, list.size());
+ Assertions.assertEquals(1, list.getToBeSortedLevel());
+
+ state.updateSortState("c");
+
+ Assertions.assertEquals("c", list.getFirst().getId());
+ Assertions.assertTrue(list.getFirst().isAscending());
+ Assertions.assertEquals(3, list.size());
+ Assertions.assertEquals(2, list.getToBeSortedLevel());
+
+ state.updateSortState("d");
+
+ Assertions.assertEquals("d", list.getFirst().getId());
+ Assertions.assertTrue(list.getFirst().isAscending());
+ Assertions.assertEquals(3, list.size());
+ Assertions.assertEquals(3, list.getToBeSortedLevel());
+
+ state.updateSortState("d");
+
+ Assertions.assertEquals("d", list.getFirst().getId());
+ Assertions.assertFalse(list.getFirst().isAscending());
+ Assertions.assertEquals(3, list.size());
+ Assertions.assertEquals(3, list.getToBeSortedLevel());
+
+ Assertions.assertEquals(-1, list.indexOf("a"));
+ Assertions.assertEquals(2, list.indexOf("b"));
+ Assertions.assertEquals(1, list.indexOf("c"));
+ Assertions.assertEquals(0, list.indexOf("d"));
+
+ }
+
+ @Test
+ public void testBug() {
+ final SheetState state = new SheetState(3);
+ final SortedColumnList list = state.getSortedColumnList();
+
+ state.updateSortState("a");
+
+ state.updateSortState("b");
+
+ state.updateSortState("c");
+
+ Assertions.assertEquals(3, list.size());
+ Assertions.assertEquals(3, list.getToBeSortedLevel());
+
+ state.updateSortState("b");
+
+ Assertions.assertEquals(3, list.size());
+ Assertions.assertEquals(3, list.getToBeSortedLevel());
+ }
+}
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/css/TobagoClassUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/css/TobagoClassUnitTest.java
index 71499bdccd..f98c9333e6 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/css/TobagoClassUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/css/TobagoClassUnitTest.java
@@ -31,8 +31,8 @@ public class TobagoClassUnitTest {
@Test
public void testNames() throws NoSuchFieldException {
- final String fieldRegex = "[A-Z_]*[A-Z]";
- final String nameRegex = "[a-z][a-zA-Z\\-]*[a-z]";
+ final String fieldRegex = "[A-Z][A-Z_0-9]*";
+ final String nameRegex = "[a-z][a-zA-Z\\-]*[a-z0-9]";
for (final TobagoClass value : TobagoClass.values()) {
final boolean ignoreByTest = TobagoClass.class.getField(value.name()).isAnnotationPresent(Deprecated.class);
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetMultiSortingController.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetMultiSortingController.java
new file mode 100644
index 0000000000..dcb04edf3e
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetMultiSortingController.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.tobago.example.demo;
+
+import org.apache.myfaces.tobago.model.SheetState;
+
+import jakarta.enterprise.context.SessionScoped;
+import jakarta.inject.Named;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@SessionScoped
+@Named
+public class SheetMultiSortingController implements Serializable {
+
+ private static final String[] NAMES = {"Avery", "James", "Riley"};
+ private static final String[] SPECIES = {"Cat", "Goat", "Pig"};
+ private static final String[] GENDER = {"male", "female"};
+ private final List<Animal> animalList;
+ private final SheetState sheetState;
+
+ public SheetMultiSortingController() {
+ animalList = new ArrayList<>();
+
+ int age = 10;
+
+ for (final String name : NAMES) {
+ for (final String species : SPECIES) {
+ for (String gender : GENDER) {
+ animalList.add(new Animal(name, species, gender, age));
+ age++;
+ }
+ }
+ }
+
+ sheetState = new SheetState(3);
+ shuffle();
+ }
+
+ public void shuffle() {
+ Collections.shuffle(animalList);
+ sheetState.resetSortState();
+ }
+
+ public void sortByApi() {
+ sheetState.resetSortState();
+ sheetState.updateSortState("age");
+ sheetState.updateSortState("species");
+ sheetState.updateSortState("species");
+ sheetState.updateSortState("gender");
+ }
+
+ public SheetState getSheetState() {
+ return sheetState;
+ }
+
+ public List<Animal> getAnimalList() {
+ return animalList;
+ }
+
+ public static class Animal {
+ private String name;
+ private String species;
+ private String gender;
+ private int age;
+
+ public Animal(String name, String species, String gender, int age) {
+ this.name = name;
+ this.species = species;
+ this.gender = gender;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSpecies() {
+ return species;
+ }
+
+ public void setSpecies(String species) {
+ this.species = species;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public void setGender(String gender) {
+ this.gender = gender;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+ }
+}
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/10-sort/Sheet_Sorting.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/10-sort/Sheet_Sorting.xhtml
index 75f0cb2c85..2f66692b01 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/10-sort/Sheet_Sorting.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/10-sort/Sheet_Sorting.xhtml
@@ -20,7 +20,8 @@
<ui:composition template="/main.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:tc="http://myfaces.apache.org/tobago/component"
- xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
+ xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
+ xmlns:f="http://xmlns.jcp.org/jsf/core">
<p>Sorting can be enable via the <code>sortable</code> attribute in the
<code class="language-markup"><tc:column/></code>.
@@ -28,7 +29,7 @@
<code class="language-markup"><tc:sheet/></code>.</p>
<p>It's important to have a component inside the <code class="language-markup"><tc:column/></code>,
e. g. <code class="language-markup"><tc:out value="\#{object.name}"/></code>.
- If there is only a fragment like <code class="language-markup">\#{object.name}</code>,
+ If there is only a fragment like <code class="language-markup">\#{object.name}</code>,
sorting will not be possible!</p>
<p>Tag Library Documentation:
<tc:link label="<tc:sheet/>" image="#{request.contextPath}/image/feather-leaf.png"
@@ -62,8 +63,8 @@
Now, the sign for period numbers is ignored by sorting.</p>
<demo-highlight language="markup"><tc:sheet value="\#{sheetController.solarList}"
- var="solarobject" rows="4"
- sortActionListener="\#{sheetController.sheetSorter}">
+ var="solarobject" rows="4"
+ sortActionListener="\#{sheetController.sheetSorter}">
<tc:column id="namecol" label="Name" sortable="true">
...
</demo-highlight>
@@ -84,4 +85,38 @@
</tc:column>
</tc:sheet>
</tc:section>
+
+ <tc:section label="Multi-Column Sorting">
+ <p>
+ With the attribute <code>maxSortColumns</code> it is possible to visualize
+ more than one sorting column. In this example you can sort by 3 columns.
+ It works by clicking the column header in the reverse order. It's also possible
+ to use ascending and descanding orders mixed.
+ </p>
+ <p>
+ It is also possible to use this via the API from the application like the button below shows.
+ </p>
+ <tc:button label="Shuffle" action="#{sheetMultiSortingController.shuffle}">
+ <f:ajax render="multi-column-sorting" execute="@this"/>
+ </tc:button>
+ <tc:button label="Sort by API" action="#{sheetMultiSortingController.sortByApi}">
+ <f:ajax render="multi-column-sorting" execute="@this"/>
+ </tc:button>
+ <tc:sheet id="multi-column-sorting" value="#{sheetMultiSortingController.animalList}" var="object"
+ state="#{sheetMultiSortingController.sheetState}"
+ markup="small" maxSortColumns="3">
+ <tc:column id="name" label="Name" sortable="true">
+ <tc:out value="#{object.name}" labelLayout="skip"/>
+ </tc:column>
+ <tc:column id="species" label="Species" sortable="true">
+ <tc:out value="#{object.species}" labelLayout="skip"/>
+ </tc:column>
+ <tc:column id="gender" label="Gender" sortable="true">
+ <tc:out value="#{object.gender}" labelLayout="skip"/>
+ </tc:column>
+ <tc:column id="age" label="Age" sortable="true">
+ <tc:out value="#{object.age}" labelLayout="skip"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
</ui:composition>
diff --git a/tobago-theme/src/main/scss/_tobago.scss b/tobago-theme/src/main/scss/_tobago.scss
index fb84597f33..55abf488a7 100644
--- a/tobago-theme/src/main/scss/_tobago.scss
+++ b/tobago-theme/src/main/scss/_tobago.scss
@@ -19,17 +19,27 @@
/* used bootstrap icons ---------------------------------------------------- */
+$icon-nbsp: " ";
$icon-alert-info: "\f646";
$icon-alert-warning: "\f33a";
$icon-alert-danger: "\f622";
$icon-star: "\f588";
$icon-star-fill: "\f586";
-$icon-star-sep: " ";
+$icon-star-sep: $icon-nbsp;
$icon-stars: $icon-star-fill + $icon-star-sep + $icon-star-fill + $icon-star-sep + $icon-star-fill + $icon-star-sep + $icon-star-fill + $icon-star-sep + $icon-star-fill;
$icon-trash: "\f5de";
$icon-sort: "\F127";
-$icon-sort-ascending: "\F57B";
-$icon-sort-descending: "\F575";
+$icon-sort-ascending: "\f57a";
+$icon-sort-descending: "\f574";
+$icon-sort-1: "\f797";
+$icon-sort-2: "\f79d";
+$icon-sort-3: "\f7a3";
+$icon-sort-4: "\f7a9";
+$icon-sort-5: "\f7af";
+$icon-sort-6: "\f7b5";
+$icon-sort-7: "\f7bb";
+$icon-sort-8: "\f7c1";
+$icon-sort-9: "\f7c7";
/* non-bootstrap variables --------------------------------------- */
@@ -1342,14 +1352,72 @@ tobago-sheet {
opacity: 0.5;
}
- &.tobago-ascending::after {
- content: $icon-sort-ascending;
- opacity: 1;
+ &.tobago-ascending {
+ &::after {
+ content: $icon-sort-ascending;
+ opacity: 1;
+ }
+ &.tobago-circle-1::after {
+ content: $icon-sort-ascending + $icon-nbsp + $icon-sort-1;
+ }
+ &.tobago-circle-2::after {
+ content: $icon-sort-ascending + $icon-nbsp + $icon-sort-2;
+ }
+ &.tobago-circle-3::after {
+ content: $icon-sort-ascending + $icon-nbsp + $icon-sort-3;
+ }
+ &.tobago-circle-4::after {
+ content: $icon-sort-ascending + $icon-nbsp + $icon-sort-4;
+ }
+ &.tobago-circle-5::after {
+ content: $icon-sort-ascending + $icon-nbsp + $icon-sort-5;
+ }
+ &.tobago-circle-6::after {
+ content: $icon-sort-ascending + $icon-nbsp + $icon-sort-6;
+ }
+ &.tobago-circle-7::after {
+ content: $icon-sort-ascending + $icon-nbsp + $icon-sort-7;
+ }
+ &.tobago-circle-8::after {
+ content: $icon-sort-ascending + $icon-nbsp + $icon-sort-8;
+ }
+ &.tobago-circle-9::after {
+ content: $icon-sort-ascending + $icon-nbsp + $icon-sort-9;
+ }
}
- &.tobago-descending::after {
- content: $icon-sort-descending;
- opacity: 1;
+ &.tobago-descending {
+ &::after {
+ content: $icon-sort-descending;
+ opacity: 1;
+ }
+ &.tobago-circle-1::after {
+ content: $icon-sort-descending + $icon-nbsp + $icon-sort-1;
+ }
+ &.tobago-circle-2::after {
+ content: $icon-sort-descending + $icon-nbsp + $icon-sort-2;
+ }
+ &.tobago-circle-3::after {
+ content: $icon-sort-descending + $icon-nbsp + $icon-sort-3;
+ }
+ &.tobago-circle-4::after {
+ content: $icon-sort-descending + $icon-nbsp + $icon-sort-4;
+ }
+ &.tobago-circle-5::after {
+ content: $icon-sort-descending + $icon-nbsp + $icon-sort-5;
+ }
+ &.tobago-circle-6::after {
+ content: $icon-sort-descending + $icon-nbsp + $icon-sort-6;
+ }
+ &.tobago-circle-7::after {
+ content: $icon-sort-descending + $icon-nbsp + $icon-sort-7;
+ }
+ &.tobago-circle-8::after {
+ content: $icon-sort-descending + $icon-nbsp + $icon-sort-8;
+ }
+ &.tobago-circle-9::after {
+ content: $icon-sort-descending + $icon-nbsp + $icon-sort-9;
+ }
}
}
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
index 08b8d78298..053eb0c76e 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
@@ -11463,13 +11463,67 @@ tobago-sheet .tobago-sortable:after {
opacity: 0.5;
}
tobago-sheet .tobago-sortable.tobago-ascending::after {
- content: "\f57b";
+ content: "\f57a";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-1::after {
+ content: "\f57a \f797";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-2::after {
+ content: "\f57a \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-3::after {
+ content: "\f57a \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-4::after {
+ content: "\f57a \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-5::after {
+ content: "\f57a \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-6::after {
+ content: "\f57a \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-7::after {
+ content: "\f57a \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-8::after {
+ content: "\f57a \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-9::after {
+ content: "\f57a \f7c7";
+}
tobago-sheet .tobago-sortable.tobago-descending::after {
- content: "\f575";
+ content: "\f574";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-1::after {
+ content: "\f574 \f797";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-2::after {
+ content: "\f574 \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-3::after {
+ content: "\f574 \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-4::after {
+ content: "\f574 \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-5::after {
+ content: "\f574 \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-6::after {
+ content: "\f574 \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-7::after {
+ content: "\f574 \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-8::after {
+ content: "\f574 \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-9::after {
+ content: "\f574 \f7c7";
+}
tobago-sheet .tobago-body {
overflow-y: auto;
flex: 1 1 auto;
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map
index 228322b26b..a61e8ef98b 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss", [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss", [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css
index 187a402b6e..6766861559 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#ff00be;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#ffffff;--bs-gray:#777777;--bs-gray-dark:#323232;--bs-gray-100:#f8f9fa;--bs-gray-200:#d0d0d0;--bs-gray-300:#dee2e6;--bs-gray-400:#a0a0a0;--bs-gray-500:#adb5bd;--bs-gray-600:#777777;--bs-gray-700:#495057;--bs-gray-800:#323232;--bs-gray-900:#212529;--bs-primary:#529696;-- [...]
+@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#ff00be;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#ffffff;--bs-gray:#777777;--bs-gray-dark:#323232;--bs-gray-100:#f8f9fa;--bs-gray-200:#d0d0d0;--bs-gray-300:#dee2e6;--bs-gray-400:#a0a0a0;--bs-gray-500:#adb5bd;--bs-gray-600:#777777;--bs-gray-700:#495057;--bs-gray-800:#323232;--bs-gray-900:#212529;--bs-primary:#529696;-- [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map
index 6d1a49d056..dbf72ef180 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-charlotteville/src/main/css/tobago.css"],"names":[],"mappings":"iBAuCA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAAkB,G [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-charlotteville/src/main/css/tobago.css"],"names":[],"mappings":"iBAuCA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAAkB,G [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
index af721c5453..c8e021af93 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
@@ -11486,13 +11486,67 @@ tobago-sheet .tobago-sortable:after {
opacity: 0.5;
}
tobago-sheet .tobago-sortable.tobago-ascending::after {
- content: "\f57b";
+ content: "\f57a";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-1::after {
+ content: "\f57a \f797";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-2::after {
+ content: "\f57a \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-3::after {
+ content: "\f57a \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-4::after {
+ content: "\f57a \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-5::after {
+ content: "\f57a \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-6::after {
+ content: "\f57a \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-7::after {
+ content: "\f57a \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-8::after {
+ content: "\f57a \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-9::after {
+ content: "\f57a \f7c7";
+}
tobago-sheet .tobago-sortable.tobago-descending::after {
- content: "\f575";
+ content: "\f574";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-1::after {
+ content: "\f574 \f797";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-2::after {
+ content: "\f574 \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-3::after {
+ content: "\f574 \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-4::after {
+ content: "\f574 \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-5::after {
+ content: "\f574 \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-6::after {
+ content: "\f574 \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-7::after {
+ content: "\f574 \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-8::after {
+ content: "\f574 \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-9::after {
+ content: "\f574 \f7c7";
+}
tobago-sheet .tobago-body {
overflow-y: auto;
flex: 1 1 auto;
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map
index 94e855fa24..02cec0758f 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss", [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss", [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css
index c55976f6e8..d68e4bbe97 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";@font-face{font-family:Amaranth;font-style:normal;font-weight:400;src:url("../fonts/Amaranth-Regular.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:normal;font-weight:700;src:url("../fonts/Amaranth-Bold.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;src:url("../fonts/Amaranth-Italic.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;font-weight:700;src:url("../fonts/Amaranth-BoldItalic.otf") format( [...]
+@charset "UTF-8";@font-face{font-family:Amaranth;font-style:normal;font-weight:400;src:url("../fonts/Amaranth-Regular.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:normal;font-weight:700;src:url("../fonts/Amaranth-Bold.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;src:url("../fonts/Amaranth-Italic.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;font-weight:700;src:url("../fonts/Amaranth-BoldItalic.otf") format( [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map
index 9f902a5fa8..80f5dee102 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-roxborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAiCA,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,qCAAqC,mBAE5C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,kCAAkC,mBAEzC,WACE,YAAa,SACb,WAAY,OACZ,IAAK,oCAAoC,mBAE3C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,wCAAwC,mBAE/C,mBACE,YAAa,QAAQ,CAAE,KAAK,CAAE,MAShC,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QA [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-roxborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAiCA,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,qCAAqC,mBAE5C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,kCAAkC,mBAEzC,WACE,YAAa,SACb,WAAY,OACZ,IAAK,oCAAoC,mBAE3C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,wCAAwC,mBAE/C,mBACE,YAAa,QAAQ,CAAE,KAAK,CAAE,MAShC,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QA [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
index 2fe3312bcc..836dbf7e49 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
@@ -11473,13 +11473,67 @@ tobago-sheet .tobago-sortable:after {
opacity: 0.5;
}
tobago-sheet .tobago-sortable.tobago-ascending::after {
- content: "\f57b";
+ content: "\f57a";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-1::after {
+ content: "\f57a \f797";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-2::after {
+ content: "\f57a \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-3::after {
+ content: "\f57a \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-4::after {
+ content: "\f57a \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-5::after {
+ content: "\f57a \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-6::after {
+ content: "\f57a \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-7::after {
+ content: "\f57a \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-8::after {
+ content: "\f57a \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-9::after {
+ content: "\f57a \f7c7";
+}
tobago-sheet .tobago-sortable.tobago-descending::after {
- content: "\f575";
+ content: "\f574";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-1::after {
+ content: "\f574 \f797";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-2::after {
+ content: "\f574 \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-3::after {
+ content: "\f574 \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-4::after {
+ content: "\f574 \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-5::after {
+ content: "\f574 \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-6::after {
+ content: "\f574 \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-7::after {
+ content: "\f574 \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-8::after {
+ content: "\f574 \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-9::after {
+ content: "\f574 \f7c7";
+}
tobago-sheet .tobago-body {
overflow-y: auto;
flex: 1 1 auto;
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map
index 6a4f5dbe70..686f144ce3 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modul [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modul [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css
index 962716d857..eb7be14a80 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs- [...]
+@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs- [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map
index b22c0bc036..5d69c71986 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-scarborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAuBA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAAkB,EAAE [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-scarborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAuBA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAAkB,EAAE [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
index 301889331f..47cf8e0406 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
@@ -11173,13 +11173,67 @@ tobago-sheet .tobago-sortable:after {
opacity: 0.5;
}
tobago-sheet .tobago-sortable.tobago-ascending::after {
- content: "\f57b";
+ content: "\f57a";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-1::after {
+ content: "\f57a \f797";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-2::after {
+ content: "\f57a \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-3::after {
+ content: "\f57a \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-4::after {
+ content: "\f57a \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-5::after {
+ content: "\f57a \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-6::after {
+ content: "\f57a \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-7::after {
+ content: "\f57a \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-8::after {
+ content: "\f57a \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-9::after {
+ content: "\f57a \f7c7";
+}
tobago-sheet .tobago-sortable.tobago-descending::after {
- content: "\f575";
+ content: "\f574";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-1::after {
+ content: "\f574 \f797";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-2::after {
+ content: "\f574 \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-3::after {
+ content: "\f574 \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-4::after {
+ content: "\f574 \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-5::after {
+ content: "\f574 \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-6::after {
+ content: "\f574 \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-7::after {
+ content: "\f574 \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-8::after {
+ content: "\f574 \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-9::after {
+ content: "\f574 \f7c7";
+}
tobago-sheet .tobago-body {
overflow-y: auto;
flex: 1 1 auto;
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map
index 2fcf6ef535..f38aa0bf66 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modules/bootstrap/scss/mixins/_lists.scss","../../. [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modules/bootstrap/scss/mixins/_lists.scss","../../. [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css
index 43d9b2b03d..0686c1381b 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:rgb(58, 37, 100);--bs-pink:#d63384;--bs-red:rgb(211, 0, 64);--bs-orange:#d90;--bs-yellow:#ffc107;--bs-green:rgb(29, 163, 50);--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:rgb(120, 140, 148);--bs-gray-dark:#323232;--bs-gray-100:#f7f7f7;--bs-gray-200:#e3e4e5;--bs-gray-300:#d7d7d7;--bs-gray-400:#ced4da;--bs-gray-500:#acacac;--bs-gray-600:rgb(120, 140, 148);--bs-gray-700:#55595c;--bs-gray-800:#323232;--b [...]
+@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:rgb(58, 37, 100);--bs-pink:#d63384;--bs-red:rgb(211, 0, 64);--bs-orange:#d90;--bs-yellow:#ffc107;--bs-green:rgb(29, 163, 50);--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:rgb(120, 140, 148);--bs-gray-dark:#323232;--bs-gray-100:#f7f7f7;--bs-gray-200:#e3e4e5;--bs-gray-300:#d7d7d7;--bs-gray-400:#ced4da;--bs-gray-500:#acacac;--bs-gray-600:rgb(120, 140, 148);--bs-gray-700:#55595c;--bs-gray-800:#323232;--b [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map
index 61a2923b5f..66e3b9edba 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-speyside/src/main/css/tobago.css"],"names":[],"mappings":"iBAuCA,MACE,UAAW,QACX,YAAa,QACb,YAAa,iBACb,UAAW,QACX,SAAU,gBACV,YAAa,KACb,YAAa,QACb,WAAY,iBACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,UAAW,mBACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,mBACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,gBACd,eAAgB,QAChB,aAAc,iBACd,UAAW,QACX,aAAc,QACd,YAAa,gBACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,EAAE,CAAE,GAC1B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAAkB [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-speyside/src/main/css/tobago.css"],"names":[],"mappings":"iBAuCA,MACE,UAAW,QACX,YAAa,QACb,YAAa,iBACb,UAAW,QACX,SAAU,gBACV,YAAa,KACb,YAAa,QACb,WAAY,iBACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,UAAW,mBACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,mBACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,gBACd,eAAgB,QAChB,aAAc,iBACd,UAAW,QACX,aAAc,QACd,YAAa,gBACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,EAAE,CAAE,GAC1B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAAkB [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
index 1e65ab95fb..899e6cf7c1 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
@@ -11443,13 +11443,67 @@ tobago-sheet .tobago-sortable:after {
opacity: 0.5;
}
tobago-sheet .tobago-sortable.tobago-ascending::after {
- content: "\f57b";
+ content: "\f57a";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-1::after {
+ content: "\f57a \f797";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-2::after {
+ content: "\f57a \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-3::after {
+ content: "\f57a \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-4::after {
+ content: "\f57a \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-5::after {
+ content: "\f57a \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-6::after {
+ content: "\f57a \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-7::after {
+ content: "\f57a \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-8::after {
+ content: "\f57a \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-ascending.tobago-circle-9::after {
+ content: "\f57a \f7c7";
+}
tobago-sheet .tobago-sortable.tobago-descending::after {
- content: "\f575";
+ content: "\f574";
opacity: 1;
}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-1::after {
+ content: "\f574 \f797";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-2::after {
+ content: "\f574 \f79d";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-3::after {
+ content: "\f574 \f7a3";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-4::after {
+ content: "\f574 \f7a9";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-5::after {
+ content: "\f574 \f7af";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-6::after {
+ content: "\f574 \f7b5";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-7::after {
+ content: "\f574 \f7bb";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-8::after {
+ content: "\f574 \f7c1";
+}
+tobago-sheet .tobago-sortable.tobago-descending.tobago-circle-9::after {
+ content: "\f574 \f7c7";
+}
tobago-sheet .tobago-body {
overflow-y: auto;
flex: 1 1 auto;
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map
index 4b3cd280d5..4f52e54a84 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modul [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modul [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css
index 0365bb171d..03ce8f8e23 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs- [...]
+@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs- [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map
index 2fb3e8983a..3ec532e2fd 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-standard/src/main/css/tobago.css"],"names":[],"mappings":"iBAuBA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAAkB,EAAE,CA [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-standard/src/main/css/tobago.css"],"names":[],"mappings":"iBAuBA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAAkB,EAAE,CA [...]
\ No newline at end of file