bug5288: Cleaned up selectTab workflow in AdminConsolePanel, changed

token-selection: deselect old selections in table, select exactly
matching filtered elements or all filtered elements, find match based on
same logic as search-filter
This commit is contained in:
Sarah Dohren committed 2020-11-10 18:06:40 +01:00
1 parent f88a0846b2
commit adef4f3bb8
25 files changed
+9998 -117

No files matched your search

+2 -1
View File
@@ -56,5 +56,6 @@ bin.includes = META-INF/,\
PairingList.html,\
com.sap.sailing.gwt.ui.PairingList/,\
src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/,\
src/main/resources/com/sap/sailing/gwt/home/shared/
src/main/resources/com/sap/sailing/gwt/home/shared/,\
AdminConsolePwa.html
output.. = WEB-INF/classes/
@@ -112,6 +112,8 @@ public abstract class AbstractLeaderboardConfigPanel extends FormPanel
protected UserService userService;
private String searchString;
public static class RaceColumnDTOAndFleetDTOWithNameBasedEquality
extends Triple<RaceColumnDTO, FleetDTO, StrippedLeaderboardDTOWithSecurity> {
private static final long serialVersionUID = -8742476113296862662L;
@@ -391,6 +393,8 @@ public abstract class AbstractLeaderboardConfigPanel extends FormPanel
filterLeaderboardPanel.updateAll(availableLeaderboardList); // also maintains the filtered leaderboardList
leaderboardSelectionChanged();
leaderboardRaceColumnSelectionChanged();
searchAndSelect();
}
/**
@@ -912,8 +916,12 @@ public abstract class AbstractLeaderboardConfigPanel extends FormPanel
}
@Override
public void select(String searchString) {
filter(searchString);
filterLeaderboardPanel.selectMatchingOrFirstVisibleItem(StrippedLeaderboardDTOWithSecurity::getName);
public void setSearchStringForSelection(String searchString) {
this.searchString = searchString;
}
private void searchAndSelect() {
filterLeaderboardPanel.searchAndSelect(searchString);
this.searchString = null;
}
}
@@ -82,6 +82,7 @@ public class RegattaListComposite extends Composite implements RegattasDisplayer
private final UserService userService;
private List<RegattaDTO> allRegattas;
private String searchString;
protected static AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
@@ -146,9 +147,13 @@ public class RegattaListComposite extends Composite implements RegattasDisplayer
filterablePanelRegattas.search(searchString);
}
public void searchAndSelect(String searchString) {
search(searchString);
filterablePanelRegattas.selectMatchingOrFirstVisibleItem(RegattaDTO::getName);
public void setSearchStringForSelection(String searchString) {
this.searchString = searchString;
}
private void searchAndSelect() {
filterablePanelRegattas.searchAndSelect(searchString);
searchString = null;
}
/**
@@ -418,6 +423,8 @@ public class RegattaListComposite extends Composite implements RegattasDisplayer
Util.addAll(regattas, newAllRegattas);
allRegattas = newAllRegattas;
filterablePanelRegattas.updateAll(allRegattas);
searchAndSelect();
}
private void handleBoatCertificateAssignment(RegattaDTO regatta) {
@@ -175,7 +175,7 @@ public class RegattaManagementPanel extends SimplePanel implements RegattasDispl
}
@Override
public void select(String searchString) {
regattaListComposite.searchAndSelect(searchString);
public void setSearchStringForSelection(String searchString) {
regattaListComposite.setSearchStringForSelection(searchString);
}
}
@@ -25,10 +25,6 @@ public interface AdminConsoleView extends IsWidget {
HeaderPanel createUI(final ServerInfoDTO serverInfo);
void selectTabByNames(String verticalTabName, String horizontalTabName);
void goToTabByNames(String menu, String tab);
void selectTabByPlace(AdminConsolePlace place);
void setRedirectToPlace(AdminConsolePlace redirectoPlace);
@@ -142,9 +142,6 @@ public class AdminConsoleViewImpl extends Composite implements AdminConsoleView
private Set<RegattasDisplayer> regattasDisplayers;
private Set<LeaderboardsDisplayer<StrippedLeaderboardDTOWithSecurity>> leaderboardsDisplayers;
private Set<LeaderboardGroupsDisplayer> leaderboardGroupsDisplayers;
private String verticalTabName;
private String horizontalTabName;
private AdminConsolePlace defaultPlace;
@@ -196,19 +193,6 @@ public class AdminConsoleViewImpl extends Composite implements AdminConsoleView
return headerPanel;
}
@Override
public void selectTabByNames(final String verticalTabName, final String horizontalTabName) {
this.verticalTabName = verticalTabName;
this.horizontalTabName = horizontalTabName;
}
@Override
public void goToTabByNames(final String verticalTabName, final String horizontalTabName) {
this.verticalTabName = verticalTabName;
this.horizontalTabName = horizontalTabName;
adminConsolePanel.selectTabByNamesWithoutSetup(verticalTabName, horizontalTabName);
}
@Override
public void selectTabByPlace(AdminConsolePlace place) {
adminConsolePanel.selectTabByPlace(place);
@@ -573,15 +557,16 @@ public class AdminConsoleViewImpl extends Composite implements AdminConsoleView
}
}, getStringMessages().markRoles(), new MarkRolesPlace(),
SecuredDomainType.MARK_ROLE.getPermission(DefaultActions.MUTATION_ACTIONS));
adminConsolePanel.initUI(verticalTabName, horizontalTabName);
if (defaultPlace == null) {
adminConsolePanel.initUI();
} else {
adminConsolePanel.initUI(defaultPlace);
}
presenter.fillRegattas();
presenter.fillLeaderboardGroups();
presenter.fillLeaderboards();
if (defaultPlace != null) {
adminConsolePanel.selectTabByPlace(defaultPlace);
}
return adminConsolePanel;
}
@@ -0,0 +1,189 @@
@charset "UTF-8";
@def TEXT_COLOR_PRIMARY #ffffff;
@def TEXT_COLOR_SECONDARY #b8b8b8;
@def TEXT_COLOR_HIGHLIGHT #e6ad29;
@def BORDER_COLOR_HIGHLIGHT #e6ad29;
@def BUTTON_COLOR_PRIMARY #245370;
@def BACKGROUND_COLOR #384b57;
@def EVENT_CARD_BACKGROUND_COLOR #1e2d39;
@def TEXT_COLOR #b8b8b8 ;
html, body {
height: 100%;
}
html {
background: resourceUrl("backdropGeneralSized") no-repeat center center
fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-color: BACKGROUND_COLOR;
}
body {
font-family: 'Open Sans', sans-serif;
color: TEXT_COLOR;
font-size: 12px;
}
h1 {
color: TEXT_COLOR_PRIMARY;
font-size: 28px;
font-weight: bold;
margin: 0;
padding-left: 40px;
text-align: left;
}
h2, p, span {
color: TEXT_COLOR_SECONDARY;
font-size: 12px;
font-weight: normal;
margin: 0;
padding-left: 40px;
text-align: left;
}
button {
font-weight: bold;
font-size: 16px;
border-radius: 10px;
width: 100%;
padding: 16px;
border: 1px;
border-style: solid;
outline: none;
color: TEXT_COLOR_PRIMARY;
margin-bottom: 1em;
}
label {
color: TEXT_COLOR_PRIMARY;
font-size: 12px;
font-weight: bold;
margin: 10px 0 20px 0;
width: 100%;
display: inline-block;
outline: none;
}
input {
color: TEXT_COLOR_PRIMARY;
font-style: italic;
font-size: 18px;
border-bottom: 1px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom-style: solid;
border-bottom-color: TEXT_COLOR_PRIMARY;
padding: 0 0 16px 0;
margin: 0 0 30px 0;
width: 100%;
background: none;
display: inline-block;
outline: none;
}
input::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
color: TEXT_COLOR_SECONDARY;
opacity: 1; /* Firefox */
}
input:-ms-input-placeholder { /* Internet Explorer 10-11 */
color: TEXT_COLOR_SECONDARY;
}
input::-ms-input-placeholder { /* Microsoft Edge */
color: TEXT_COLOR_SECONDARY;
}
.primaryButton {
background-color: BUTTON_COLOR_PRIMARY;
border-color: BUTTON_COLOR_PRIMARY;
}
.secondaryButton {
background: none;
border-color: BORDER_COLOR_HIGHLIGHT;
}
.secondaryCtaButton div {
width: 100%
}
.secondaryCtaButton button {
text-align: right;
font-size: 14px;
color: TEXT_COLOR_HIGHLIGHT;
border: none;
background: none;
width: auto;
float: right;
outline: none;
}
.eventCard {
border-style: solid;
border-radius: 10px;
padding: 10px;
border-width: 1px;
outline: none;
background-color: EVENT_CARD_BACKGROUND_COLOR;
border-color: EVENT_CARD_BACKGROUND_COLOR;
margin-bottom: 1em;
}
.eventCard h1 {
margin: 0;
font-weight: 600;
font-size: 16px;
color: TEXT_COLOR_PRIMARY;
}
.eventCard h2 {
font-weight: normal;
font-size: 12px;
color: TEXT_COLOR_SECONDARY;
}
.eventCard .featuredMarker {
font-size: 12px;
text-align: center;
border-radius: 5px;
border: 1px;
border-style: solid;
outline: none;
background-color: TEXT_COLOR_HIGHLIGHT;
border-color: TEXT_COLOR_HIGHLIGHT;
color: TEXT_COLOR_PRIMARY;
}
.eventCard .details {
}
.eventCard .location {
padding-left: 3em;
background: resourceUrl("navGlobal") no-repeat;
background-size: contain;
background-position: 1em 0;
}
@media (min-width: 45em) {
.eventCard {
height: 300px;
background: resourceUrl("eventBackdrop") no-repeat center center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.eventCard .eventCardContainer {
position: absolute;
bottom: 2em;
}
}
@@ -0,0 +1,44 @@
package com.sap.sailing.gwt.ui.pwa.mobile;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.resources.client.DataResource.MimeType;
public interface AdminConsoleMobileResources extends ClientBundle {
public static final AdminConsoleMobileResources INSTANCE = GWT.create(AdminConsoleMobileResources.class);
@Source("AdminConsoleMobile.gss")
LocalCss css();
@Source("Image-BackdropGeneralSized.png")
ImageResource backdropGeneralSized();
@Source("Image-EventBackdrop.png")
ImageResource eventBackdrop();
@Source("Icon-NavGlobal.svg")
@MimeType("image/svg+xml")
DataResource navGlobal();
public interface LocalCss extends CssResource {
String primaryButton();
String secondaryButton();
String secondaryCtaButton();
String featuredMarker();
String eventCard();
String details();
String eventCardContainer();
String location();
}
}
@@ -4,10 +4,12 @@ import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.event.shared.EventBus;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.pwa.mobile.footer.Footer;
import com.sap.sailing.gwt.ui.pwa.mobile.header.Header;
@@ -20,32 +22,37 @@ import com.sap.sse.gwt.client.mvp.TopLevelView;
* {@link AdminConsoleMobileView} will add its content of the target inside the {@code mainContantPanel}.
*/
public class AdminConsoleMobileView extends Composite implements TopLevelView {
interface AdminConsoleMobileViewUiBinder extends UiBinder<Widget, AdminConsoleMobileView> {
}
private static AdminConsoleMobileViewUiBinder uiBinder = GWT.create(AdminConsoleMobileViewUiBinder.class);
private static ErrorReporter errorReporter = new DefaultErrorReporter<StringMessages>(StringMessages.INSTANCE);
@UiField
Header header;
@UiField
Footer footer;
@UiField
SimplePanel content;
public AdminConsoleMobileView(final EventBus eventBus) {
@UiField
Button settingsButton;
public AdminConsoleMobileView(final EventBus eventBus) {
SharedResources.INSTANCE.mediaCss().ensureInjected();
AdminConsoleMobileResources.INSTANCE.css().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
}
@Override
public AcceptsOneWidget getContent() {
return content;
}
@Override
public ErrorReporter getErrorReporter() {
return errorReporter;
@@ -1,18 +1,194 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:mobile="urn:import:com.sap.sailing.gwt.ui.pwa.mobile"
xmlns:sse="urn:import:com.sap.sse.gwt.client">
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="res"
type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res"
type="com.sap.sailing.gwt.ui.pwa.mobile.AdminConsoleMobileResources" />
<ui:with field="i18n"
type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:style>
.mainContent {
height: 100%;
}
</ui:style>
<g:HTMLPanel addStyleNames="{style.mainContent}">
<mobile:header.Header ui:field="header" />
<g:SimplePanel ui:field="content" />
<g:HTMLPanel addStyleNames="{style.mainContent}">
<mobile:header.Header ui:field="header" />
<g:SimplePanel ui:field="content" />
<div class="{res.mediaCss.grid}">
<div
class="{res.mediaCss.small12} {res.mediaCss.medium6} {res.mediaCss.column}">
<h1>
Example Page
</h1>
</div>
<div
class="{res.mediaCss.small12} {res.mediaCss.medium6} {res.mediaCss.column}">
<p>
Based on new UI design.
</p>
</div>
</div>
<div class="{res.mediaCss.grid}">
<div
class="{res.mediaCss.small12} {res.mediaCss.medium6} {res.mediaCss.column}">
<label for="username">
USERNAME
</label>
<input id="username" placeholder="Username" />
</div>
<div
class="{res.mediaCss.small12} {res.mediaCss.medium6} {res.mediaCss.column}">
<label for="password">
PASSWORD
</label>
<input id="password" placeholder="Password"
type="password" />
</div>
</div>
<div class="{res.mediaCss.grid}">
<div
class="{res.mediaCss.small12} {res.mediaCss.mediumoffset4} {res.mediaCss.medium4} {res.mediaCss.largeoffset6} {res.mediaCss.large3} {res.mediaCss.column}">
<g:Button ui:field="settingsButton"
text="{i18n.releaseNotes}"
styleName="{local_res.css.primaryButton}" />
</div>
<div
class="{res.mediaCss.small12} {res.mediaCss.medium4} {res.mediaCss.large3} {res.mediaCss.column}">
<g:Button
ui:field="createRegattaLeaderboardButton"
text="{i18n.ok}"
styleName="{local_res.css.secondaryButton}" />
</div>
<div
class="{res.mediaCss.small12} {res.mediaCss.column}">
<div class="{local_res.css.secondaryCtaButton}">
<g:Button ui:field="forgotPasswordButton"
text="{i18n.forgotPassword}" />
</div>
</div>
</div>
<div class="{res.mediaCss.grid}">
<div
class="{res.mediaCss.small12} {res.mediaCss.medium6} {res.mediaCss.large4} {res.mediaCss.column}">
<div class="{local_res.css.eventCard}">
<div class="{res.mediaCss.grid} {local_res.css.eventCardContainer}">
<div
class="{res.mediaCss.hideonsmall} {res.mediaCss.medium4} {res.mediaCss.column}">
<div
class="{local_res.css.featuredMarker}">
Featured
</div>
</div>
<h1
class="{res.mediaCss.small8} {res.mediaCss.medium12} {res.mediaCss.column}">
LYC Mittwochsregatta YS 2020
</h1>
<div
class="{res.mediaCss.small4} {res.mediaCss.showonsmall} {res.mediaCss.column}">
<div
class="{local_res.css.featuredMarker}">
Featured
</div>
</div>
<h2
class="{local_res.css.details} {local_res.css.location} {res.mediaCss.small12} {res.mediaCss.column}">
Travemünde, May 6 - October 31, 2020
</h2>
</div>
</div>
</div>
<div
class="{res.mediaCss.small12} {res.mediaCss.medium6} {res.mediaCss.large4} {res.mediaCss.column}">
<div class="{local_res.css.eventCard}">
<div class="{res.mediaCss.grid} {local_res.css.eventCardContainer}">
<div
class="{res.mediaCss.hideonsmall} {res.mediaCss.medium4} {res.mediaCss.column}">
<div
class="{local_res.css.featuredMarker}">
Featured
</div>
</div>
<h1
class="{res.mediaCss.small8} {res.mediaCss.medium12} {res.mediaCss.column}">
LYC Mittwochsregatta YS 2020
</h1>
<div
class="{res.mediaCss.small4} {res.mediaCss.showonsmall} {res.mediaCss.column}">
<div
class="{local_res.css.featuredMarker}">
Featured
</div>
</div>
<h2
class="{local_res.css.details} {local_res.css.location} {res.mediaCss.small12} {res.mediaCss.column}">
Travemünde, May 6 - October 31, 2020
</h2>
</div>
</div>
</div>
<div
class="{res.mediaCss.small12} {res.mediaCss.medium6} {res.mediaCss.large4} {res.mediaCss.column}">
<div class="{local_res.css.eventCard}">
<div class="{res.mediaCss.grid} {local_res.css.eventCardContainer}">
<div
class="{res.mediaCss.hideonsmall} {res.mediaCss.medium4} {res.mediaCss.column}">
<div
class="{local_res.css.featuredMarker}">
Featured
</div>
</div>
<h1
class="{res.mediaCss.small8} {res.mediaCss.medium12} {res.mediaCss.column}">
LYC Mittwochsregatta YS 2020
</h1>
<div
class="{res.mediaCss.small4} {res.mediaCss.showonsmall} {res.mediaCss.column}">
<div
class="{local_res.css.featuredMarker}">
Featured
</div>
</div>
<h2
class="{local_res.css.details} {local_res.css.location} {res.mediaCss.small12} {res.mediaCss.column}">
Travemünde, May 6 - October 31, 2020
</h2>
</div>
</div>
</div>
<div
class="{res.mediaCss.small12} {res.mediaCss.medium6} {res.mediaCss.large4} {res.mediaCss.column}">
<div class="{local_res.css.eventCard}">
<div class="{res.mediaCss.grid} {local_res.css.eventCardContainer}">
<div
class="{res.mediaCss.hideonsmall} {res.mediaCss.medium4} {res.mediaCss.column}">
<div
class="{local_res.css.featuredMarker}">
Featured
</div>
</div>
<h1
class="{res.mediaCss.small8} {res.mediaCss.medium12} {res.mediaCss.column}">
LYC Mittwochsregatta YS 2020
</h1>
<div
class="{res.mediaCss.small4} {res.mediaCss.showonsmall} {res.mediaCss.column}">
<div
class="{local_res.css.featuredMarker}">
Featured
</div>
</div>
<h2
class="{local_res.css.details} {local_res.css.location} {res.mediaCss.small12} {res.mediaCss.column}">
Travemünde, May 6 - October 31, 2020
</h2>
</div>
</div>
</div>
</div>
<mobile:footer.Footer ui:field="footer" />
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,3 @@
<svg width="31" height="24" viewBox="0 0 31 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.5417 17H6.45833C5.03362 17 3.875 17.897 3.875 19C3.875 20.103 5.03362 21 6.45833 21H24.5417C25.9664 21 27.125 20.103 27.125 19C27.125 17.897 25.9664 17 24.5417 17ZM24.5417 10H6.45833C5.03362 10 3.875 10.897 3.875 12C3.875 13.103 5.03362 14 6.45833 14H24.5417C25.9664 14 27.125 13.103 27.125 12C27.125 10.897 25.9664 10 24.5417 10ZM24.5417 3H6.45833C5.03362 3 3.875 3.897 3.875 5C3.875 6.103 5.03362 7 6.45833 7H24.5417C25.9664 7 27.125 6.103 27.125 5C27.125 3.897 25.9664 3 24.5417 3Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

@@ -2,6 +2,5 @@
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTMLPanel tag="header" ui:field="headerPanel">
</g:HTMLPanel>
</ui:UiBinder>
@@ -21,7 +21,7 @@ public abstract class AbstractKeywordFilter<T> implements Filter<T> {
};
private final Set<String> keywords = new HashSet<>();
/**
* Sets the keywords to use for matching of domain objects.
*/
@@ -44,4 +44,8 @@ public abstract class AbstractKeywordFilter<T> implements Filter<T> {
public String getName() {
return getClass().getSimpleName();
}
public boolean matchesExactly(T t) {
return matcher.matchesExactly(keywords, t);
}
}
@@ -27,22 +27,32 @@ public abstract class KeywordMatcher<T> {
return matchesOrNoKeywords;
}
public boolean matchesExactly(Iterable<String> keywords, T t) {
return keywords != null && matches(t, keywords, true);
}
private boolean containsText(T obj, Iterable<String> keywords) {
return matches(obj, keywords, false);
}
/**
* Returns <code>true</code> if for each of the <code>keywords</code> any of the {@link #getStrings(Object) values
* to check} contains that keyword.
*
* @param keywords
* the words to filter on
* @param exactMatch
* returns <code>true</code> only if a string matches exactly (still ignores differences in upper/lower case letters)
* @return <code>true</code> if the <code>valuesToCheck</code> contains all <code>wordsToFilter</code>,
* <code>false</code> if not
*/
private boolean containsText(T obj, Iterable<String> keywords) {
private boolean matches(T obj, Iterable<String> keywords, boolean exactMatch) {
boolean failed = false;
for (String word : keywords) {
String textAsUppercase = word.toUpperCase();
failed = true;
for (String s : getStrings(obj)) {
if (s != null && s.toUpperCase().contains(textAsUppercase)) {
if (matches(s, textAsUppercase, exactMatch)) {
failed = false;
break;
}
@@ -53,4 +63,12 @@ public abstract class KeywordMatcher<T> {
}
return true;
}
private boolean matches(String s, String keyword, boolean exactMatch) {
if (s == null) {
return false;
}
return exactMatch ? s.equalsIgnoreCase(keyword) : s.toUpperCase().contains(keyword);
}
}
@@ -117,13 +117,13 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
private class TabSelectionHandler implements SelectionHandler<Integer> {
@Override
public void onSelection(SelectionEvent<Integer> event) {
Object source = event.getSource();
if (source != null) {
if (source instanceof HorizontalTabLayoutPanel) {
final HorizontalTabLayoutPanel tabPanel = ((HorizontalTabLayoutPanel) source);
final Widget selectedPanel = tabPanel.getWidget(event.getSelectedItem());
refreshDataAndUpdatePlace(selectedPanel);
final Widget selectedPanel = tabPanel.getWidget(event.getSelectedItem());
goToWidgetsPlace(selectedPanel);
} else if (source instanceof VerticalTabLayoutPanel) {
final VerticalTabLayoutPanel verticalTabLayoutPanel = (VerticalTabLayoutPanel) source;
Widget widgetAssociatedToVerticalTab = verticalTabLayoutPanel.getWidget(verticalTabLayoutPanel.getSelectedIndex());
@@ -134,13 +134,12 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
widgetAssociatedToVerticalTab = selectedTabLayoutPanel.getWidget(selectedIndex);
}
}
refreshDataAndUpdatePlace(widgetAssociatedToVerticalTab);
goToWidgetsPlace(widgetAssociatedToVerticalTab);
}
}
}
private void refreshDataAndUpdatePlace(Widget widget) {
refreshDataFor(widget);
private void goToWidgetsPlace(Widget widget) {
Place gotoPlace = null;
if (widgetPlacesMap.containsKey(widget)) {
gotoPlace = widgetPlacesMap.get(widget);
@@ -149,13 +148,6 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
placeController.goTo(gotoPlace);
}
}
private void refreshDataFor(Widget target) {
RefreshableAdminConsolePanel refreshTarget = panelsByWidget.get(unwrapScrollPanel(target));
if (refreshTarget != null) {
refreshTarget.refreshAfterBecomingVisible(); // gotoSelectedPlace
}
}
}
/**
@@ -222,6 +214,11 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
public void selectTab(int index) {
topLevelTabPanel.selectTab(index);
}
@Override
public void selectTab(int index, boolean fireEvent) {
topLevelTabPanel.selectTab(index, fireEvent);
}
@Override
public int getWidgetIndex(Widget child) {
@@ -262,16 +259,17 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
* this method, but then this method needs to be invoked again to ensure that all all tabs are properly displayed
* for the current panel's state.
*/
public void initUI(final String menu, final String tab) {
public void initUI() {
updateTabDisplayForCurrentUser(getUserService().getCurrentUser(), false);
if (topLevelTabPanel.getWidgetCount() > 0) {
if (menu != null && tab != null) {
selectTabByNamesWithoutSetup(menu, tab);
} else {
topLevelTabPanel.selectTab(0);
}
topLevelTabPanel.selectTab(0);
}
}
public void initUI(final AdminConsolePlace place) {
updateTabDisplayForCurrentUser(getUserService().getCurrentUser(), false);
selectTabByPlace(place, false);
}
private UserService getUserService() {
return userService;
@@ -289,6 +287,8 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
void selectTab(int index);
void selectTab(int index, boolean fireEvent);
int getWidgetIndex(Widget child);
}
@@ -379,6 +379,11 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
public void selectTab(int index) {
tabPanel.selectTab(index);
}
@Override
public void selectTab(int index, boolean fireEvent) {
tabPanel.selectTab(index, fireEvent);
}
@Override
public int getWidgetIndex(Widget child) {
@@ -417,6 +422,11 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
public void selectTab(int index) {
tabPanel.selectTab(index);
}
@Override
public void selectTab(int index, boolean fireEvent) {
tabPanel.selectTab(index, fireEvent);
}
@Override
public int getWidgetIndex(Widget child) {
@@ -525,6 +535,10 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
}
public void selectTabByPlace(AdminConsolePlace place) {
selectTabByPlace(place, true);
}
public void selectTabByPlace(AdminConsolePlace place, boolean fireEvent) {
String verticalTabTitle = null;
String placeVerticalTabName = place.getVerticalTabName();
if (placeVerticalTabName != null && verticalTabNameToTitleMap.containsKey(placeVerticalTabName)) {
@@ -537,12 +551,20 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
if (isWidgetForPlace(place, panelWidgetName, verticalTabTitle)) {
int index = panel.getWidgetIndex(currentWidget);
currentPlace = place;
panel.selectTab(index);
panel.selectTab(index, fireEvent);
filterOrSelect(place, unwrapScrollPanel(currentWidget));
refreshDataFor(currentWidget);
}
}
}
private void refreshDataFor(Widget target) {
RefreshableAdminConsolePanel refreshTarget = panelsByWidget.get(unwrapScrollPanel(target));
if (refreshTarget != null) {
refreshTarget.refreshAfterBecomingVisible();
}
}
private boolean isWidgetForPlace(final AdminConsolePlace place, final Triple<VerticalOrHorizontalTabLayoutPanel, Widget, String> panelWidgetName, final String verticalTabTitle) {
Widget currentWidget = panelWidgetName.getB();
boolean isHorizontalMenu = widgetPlacesMap.containsKey(currentWidget) && place.isSamePlace(widgetPlacesMap.get(currentWidget));
@@ -559,28 +581,7 @@ public class AdminConsolePanel extends HeaderPanel implements HandleTabSelectabl
if (widget instanceof FilterablePanel && place instanceof FilterableAdminConsolePlace && ((FilterableAdminConsolePlace)place).getFilter() != null) {
((FilterablePanel)widget).filter(((FilterableAdminConsolePlace)place).getFilter());
} else if (widget instanceof SelectablePanel && place instanceof SelectableAdminConsolePlace && ((SelectableAdminConsolePlace)place).getSelect() != null) {
((SelectablePanel)widget).select(((SelectableAdminConsolePlace)place).getSelect());
}
}
@Override
public void selectTabByNamesWithoutSetup(String verticalTabName, String horizontalTabName) {
if (verticalTabName != null) {
for (Triple<VerticalOrHorizontalTabLayoutPanel, Widget, String> e : roleSpecificTabs) {
VerticalOrHorizontalTabLayoutPanel panel = e.getA();
Widget currentWidget = e.getB();
String verticalPanelName = e.getC();
if (panel == topLevelTabPanelWrapper && verticalTabName.equals(verticalPanelName)) { // for vertical panel
int index = panel.getWidgetIndex(currentWidget);
panel.selectTab(index);
if (horizontalTabName == null || horizontalTabName.isEmpty()) { // If we don't have horizontal tab will setup vertical tab.
return;
}
} else if (horizontalTabName != null && horizontalTabName.equals(e.getC())) { // for horizontal panel
int index = panel.getWidgetIndex(currentWidget);
panel.selectTab(index);
}
}
((SelectablePanel)widget).setSearchStringForSelection(((SelectableAdminConsolePlace)place).getSelect());
}
}
@@ -10,6 +10,4 @@ public interface HandleTabSelectable {
* @param params - map of strings parameters
*/
void selectTabByNames(String verticalTabName, String horizontalTabName, Map<String, String> params);
void selectTabByNamesWithoutSetup(String verticalTabName, String horizontalTabName);
}
@@ -1,5 +1,5 @@
package com.sap.sse.gwt.adminconsole;
public interface SelectablePanel {
void select(String select);
void setSearchStringForSelection(String searchString);
}
@@ -1,6 +1,7 @@
package com.sap.sse.gwt.client.panels;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -97,6 +98,13 @@ public abstract class AbstractFilterablePanel<T> extends HorizontalPanel {
}
};
protected final AbstractKeywordFilter<T> selectionFilter = new AbstractKeywordFilter<T>() {
@Override
public Iterable<String> getStrings(T t) {
return getSearchableStrings(t);
}
};
/**
* @param all
* the sequence of all objects that may be displayed in the table and from which the filter may choose.
@@ -238,6 +246,58 @@ public abstract class AbstractFilterablePanel<T> extends HorizontalPanel {
Util.addAll(filteredElements, filtered.getList());
}
public void searchAndSelect(String searchString) {
if (searchString != null) {
search(searchString);
selectExactMatchesOrAllFiltered();
}
}
private void selectExactMatchesOrAllFiltered() {
if (!selectExactlyMatchingFilteredItems()) {
selectAllFiltered();
}
}
private void selectAllFiltered() {
select(filtered.getList());
}
private void select(T item, boolean select) {
getCellTable().getSelectionModel().setSelected(item, select);
}
private void select(T item) {
select(item, true);
}
private void select(List<T> items) {
for (T item : items) {
select(item);
}
}
private boolean selectExactlyMatchingFilteredItems() {
boolean foundExactMatch = false;
for (T t : all.getList()) {
boolean matches = matchesExactly(t);
select(t, matches);
if (matches) {
foundExactMatch = true;
}
}
return foundExactMatch;
}
private boolean matchesExactly(T t) {
selectionFilter.setKeywords(Arrays.asList(getTextBox().getText()));
if (!selectionFilter.matchesExactly(t)) {
return false;
}
return matches(t);
}
private boolean matches(T t) {
for (Filter<T> filter : filters) {
if (!filter.matches(t)) {
@@ -1,9 +1,6 @@
package com.sap.sse.gwt.client.panels;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.client.ui.Label;
@@ -38,24 +35,4 @@ public abstract class LabeledAbstractFilterablePanel<T> extends AbstractFilterab
insert(label, 0);
}
public void selectMatchingOrFirstVisibleItem(Function<T, String> matchesExactly) {
Optional<T> firstItemMatchingSearch = filtered.getList().stream().filter
(item -> matchesExactly.apply(item).equals(getTextBox().getValue())).findFirst();
if (firstItemMatchingSearch.isPresent()) {
select(firstItemMatchingSearch.get());
} else {
selectFirstVisible();
}
}
private void selectFirstVisible() {
final Collection<T> visibleRegattas = filtered.getList();
if (!visibleRegattas.isEmpty()) {
select(visibleRegattas.iterator().next());
}
}
private void select(T item) {
getCellTable().getSelectionModel().setSelected(item, true);
}
}
File diff suppressed because it is too large. Load diff
+54
View File
@@ -0,0 +1,54 @@
!SESSION 2020-11-06 12:38:21.621 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.8.0_261
java.vendor=Oracle Corporation
BootLoader constants: OS=macosx, ARCH=x86_64, WS=cocoa, NL=de_DE
Command-line arguments: -dev file:/Users/udowessels/git/java/target/dev.properties -os macosx -ws cocoa -arch x86_64 -consoleLog -console -clean
!ENTRY com.sap.sailing.polars 4 0 2020-11-06 18:30:12.071
!MESSAGE FrameworkEvent ERROR
!STACK 0
org.osgi.framework.BundleException: Exception in com.sap.sailing.polars.impl.Activator.stop() of bundle com.sap.sailing.polars.
at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:855)
at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314)
at org.eclipse.osgi.container.Module.doStop(Module.java:636)
at org.eclipse.osgi.container.Module.stop(Module.java:498)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1675)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1594)
at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270)
at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147)
at org.eclipse.osgi.container.Module.doStop(Module.java:636)
at org.eclipse.osgi.container.Module.stop(Module.java:498)
at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202)
at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: The service has been unregistered
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.unregister(ServiceRegistrationImpl.java:206)
at com.sap.sailing.polars.impl.Activator.stop(Activator.java:92)
at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835)
at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828)
... 13 more
Root exception:
java.lang.IllegalStateException: The service has been unregistered
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.unregister(ServiceRegistrationImpl.java:206)
at com.sap.sailing.polars.impl.Activator.stop(Activator.java:92)
at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835)
at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828)
at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314)
at org.eclipse.osgi.container.Module.doStop(Module.java:636)
at org.eclipse.osgi.container.Module.stop(Module.java:498)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1675)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1594)
at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270)
at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147)
at org.eclipse.osgi.container.Module.doStop(Module.java:636)
at org.eclipse.osgi.container.Module.stop(Module.java:498)
at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202)
at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165)
at java.lang.Thread.run(Thread.java:748)
@@ -0,0 +1,6 @@
#encoding=UTF-8
#version=1
org.apache.shiro.core.source,1.2.2,file:/Users/udowessels/git/java/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool/plugins/org.apache.shiro.core.source_1.2.2.jar,-1,false
org.apache.shiro.ehcache.source,1.2.3,file:/Users/udowessels/git/java/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool/plugins/org.apache.shiro.ehcache.source_1.2.3.jar,-1,false
org.apache.shiro.web.source,1.2.2,file:/Users/udowessels/git/java/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool/plugins/org.apache.shiro.web.source_1.2.2.jar,-1,false
org.mongodb.mongo-java-driver.source,3.6.4,file:/Users/udowessels/git/java/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool/plugins/org.mongodb.mongo-java-driver.source_3.6.4.jar,-1,false