mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-04 12:17:41 +08:00
PL-8605 SideMenu responsive styles
This commit is contained in:
parent
e13b4c343e
commit
96c5ce3396
@ -16,6 +16,7 @@
|
||||
|
||||
package com.haulmont.cuba.gui.components.mainwindow;
|
||||
|
||||
import com.haulmont.cuba.gui.components.Button;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -34,6 +35,28 @@ public interface SideMenu extends Component.BelongToFrame {
|
||||
*/
|
||||
void loadMenuConfig();
|
||||
|
||||
/**
|
||||
* Bind show/hide side panel action to button.
|
||||
*
|
||||
* @param button button that should trigger show/hide of side panel
|
||||
*/
|
||||
void setSidePanelToggleButton(Button button);
|
||||
/**
|
||||
* @return side panel toggle button
|
||||
*/
|
||||
Button getSidePanelToggleButton();
|
||||
|
||||
/**
|
||||
* Bind side panel for show/hide action.
|
||||
*
|
||||
* @param sidePanel side panel
|
||||
*/
|
||||
void setSidePanel(Component sidePanel);
|
||||
/**
|
||||
* @return side panel
|
||||
*/
|
||||
Component getSidePanel();
|
||||
|
||||
/**
|
||||
* @return true if an item becomes selected by click
|
||||
*/
|
||||
|
@ -37,28 +37,28 @@ import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* GenericUI class holding information about the main menu structure.
|
||||
*
|
||||
*/
|
||||
@Component(MenuConfig.NAME)
|
||||
public class MenuConfig {
|
||||
private final Logger log = LoggerFactory.getLogger(MenuConfig.class);
|
||||
|
||||
public static final String NAME = "cuba_MenuConfig";
|
||||
|
||||
public static final String MENU_CONFIG_XML_PROP = "cuba.menuConfig";
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(MenuConfig.class);
|
||||
|
||||
protected List<MenuItem> rootItems = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
protected Resources resources;
|
||||
|
||||
@Inject
|
||||
protected Messages messages;
|
||||
|
||||
protected volatile boolean initialized;
|
||||
|
||||
protected ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
@ -66,14 +66,17 @@ public class MenuConfig {
|
||||
/**
|
||||
* Localized menu item caption.
|
||||
* @param id screen ID as defined in <code>screens.xml</code>
|
||||
*
|
||||
* @deprecated Use {@link MenuConfig#getItemCaption(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getMenuItemCaption(String id) {
|
||||
try {
|
||||
Messages messages = AppBeans.get(Messages.NAME);
|
||||
return messages.getMainMessage("menu-config." + id);
|
||||
} catch (MissingResourceException e) {
|
||||
return id;
|
||||
}
|
||||
MenuConfig menuConfig = AppBeans.get(MenuConfig.NAME);
|
||||
return menuConfig.getItemCaption(id);
|
||||
}
|
||||
|
||||
public String getItemCaption(String id) {
|
||||
return messages.getMainMessage("menu-config." + id);
|
||||
}
|
||||
|
||||
protected void checkInitialized() {
|
||||
@ -172,6 +175,7 @@ public class MenuConfig {
|
||||
loadIcon(element, menuItem);
|
||||
loadShortcut(menuItem, element);
|
||||
loadStylename(element, menuItem);
|
||||
loadExpanded(element, menuItem);
|
||||
loadDescription(element, menuItem);
|
||||
loadMenuItems(element, menuItem);
|
||||
|
||||
@ -210,6 +214,13 @@ public class MenuConfig {
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadExpanded(Element element, MenuItem menuItem) {
|
||||
String expanded = element.attributeValue("expanded");
|
||||
if (StringUtils.isNotEmpty(expanded)) {
|
||||
menuItem.setExpanded(Boolean.parseBoolean(expanded));
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadDescription(Element element, MenuItem menuItem) {
|
||||
String description = element.attributeValue("description");
|
||||
if (StringUtils.isNotBlank(description)) {
|
||||
|
@ -17,7 +17,6 @@
|
||||
package com.haulmont.cuba.gui.config;
|
||||
|
||||
import com.haulmont.bali.util.Dom4j;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
import com.haulmont.cuba.gui.components.KeyCombination;
|
||||
import com.haulmont.cuba.security.entity.PermissionType;
|
||||
import com.haulmont.cuba.security.global.UserSession;
|
||||
@ -29,7 +28,6 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Main menu item descriptor
|
||||
*
|
||||
*/
|
||||
public class MenuItem {
|
||||
|
||||
@ -42,6 +40,7 @@ public class MenuItem {
|
||||
private String description;
|
||||
private Element descriptor;
|
||||
private boolean separator = false;
|
||||
private boolean expanded = false;
|
||||
|
||||
private KeyCombination shortcut;
|
||||
private boolean isMenu = false;
|
||||
@ -145,4 +144,12 @@ public class MenuItem {
|
||||
public void setIcon(String icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isExpanded() {
|
||||
return expanded;
|
||||
}
|
||||
|
||||
public void setExpanded(boolean expanded) {
|
||||
this.expanded = expanded;
|
||||
}
|
||||
}
|
@ -55,6 +55,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@Component("cuba_PermissionConfig")
|
||||
public class PermissionConfig {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(PermissionConfig.class);
|
||||
|
||||
@Inject
|
||||
protected DynamicAttributes dynamicAttributes;
|
||||
|
||||
@ -106,7 +108,7 @@ public class PermissionConfig {
|
||||
|
||||
private void walkMenu(MenuItem info, Node<BasicPermissionTarget> node) {
|
||||
String id = info.getId();
|
||||
String caption = MenuConfig.getMenuItemCaption(id).replaceAll("<.+?>", "").replaceAll(">", "");
|
||||
String caption = menuConfig.getItemCaption(id).replaceAll("<.+?>", "").replaceAll(">", "");
|
||||
caption = StringEscapeUtils.unescapeHtml(caption);
|
||||
|
||||
if (info.getChildren() != null && !info.getChildren().isEmpty()) {
|
||||
@ -150,12 +152,12 @@ public class PermissionConfig {
|
||||
|
||||
Session session = metadata.getSession();
|
||||
List<MetaModel> modelList = new ArrayList<>(session.getModels());
|
||||
Collections.sort(modelList, new MetadataObjectAlphabetComparator());
|
||||
modelList.sort(new MetadataObjectAlphabetComparator());
|
||||
|
||||
for (MetaModel model : modelList) {
|
||||
|
||||
List<MetaClass> classList = new ArrayList<>(model.getClasses());
|
||||
Collections.sort(classList, new MetadataObjectAlphabetComparator());
|
||||
classList.sort(new MetadataObjectAlphabetComparator());
|
||||
|
||||
for (MetaClass metaClass : classList) {
|
||||
String name = metaClass.getName();
|
||||
@ -188,7 +190,7 @@ public class PermissionConfig {
|
||||
DynamicAttributesUtils.encodeAttributeCode(dynamicAttribute.getCode()));
|
||||
propertyList.add(metaPropertyPath.getMetaProperty());
|
||||
}
|
||||
Collections.sort(propertyList, new MetadataObjectAlphabetComparator());
|
||||
propertyList.sort(new MetadataObjectAlphabetComparator());
|
||||
|
||||
for (MetaProperty metaProperty : propertyList) {
|
||||
String metaPropertyName = metaProperty.getName();
|
||||
@ -300,8 +302,6 @@ public class PermissionConfig {
|
||||
|
||||
private List<Item> items = new CopyOnWriteArrayList<>();
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(PermissionConfig.class);
|
||||
|
||||
public PermissionConfig() {
|
||||
this.clientType = AppConfig.getClientType();
|
||||
}
|
||||
|
@ -79,6 +79,8 @@
|
||||
<xs:extension base="baseMainElement">
|
||||
<xs:attribute name="selectOnClick" type="xs:boolean"/>
|
||||
<xs:attribute name="loadMenuConfig" type="xs:boolean"/>
|
||||
<xs:attribute name="sidePanel" type="xs:string"/>
|
||||
<xs:attribute name="sidePanelToggleButton" type="xs:string"/>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
@ -17,10 +17,10 @@
|
||||
-->
|
||||
|
||||
<xs:schema targetNamespace="http://schemas.haulmont.com/cuba/menu.xsd"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.haulmont.com/cuba/menu.xsd"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.haulmont.com/cuba/menu.xsd"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xs:element name="menu-config" type="menuOrItem"/>
|
||||
|
||||
@ -41,12 +41,13 @@
|
||||
<xs:element name="separator"/>
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="id" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="insertBefore" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="insertAfter" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="description" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="stylename" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="icon" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="id"/>
|
||||
<xs:attribute type="xs:string" name="insertBefore"/>
|
||||
<xs:attribute type="xs:string" name="insertAfter"/>
|
||||
<xs:attribute type="xs:string" name="description"/>
|
||||
<xs:attribute type="xs:string" name="stylename"/>
|
||||
<xs:attribute type="xs:string" name="icon"/>
|
||||
<xs:attribute type="xs:boolean" name="expanded"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="itemType">
|
||||
@ -54,15 +55,15 @@
|
||||
<xs:element type="paramType" name="param" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element type="permissionsType" name="permissions" minOccurs="0" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="id" use="optional"/>
|
||||
<xs:attribute type="openTypeType" name="openType" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="resizable" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="shortcut" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="description" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="stylename" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="icon" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="insertBefore" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="insertAfter" use="optional"/>
|
||||
<xs:attribute type="xs:string" name="id"/>
|
||||
<xs:attribute type="openTypeType" name="openType"/>
|
||||
<xs:attribute type="xs:boolean" name="resizable"/>
|
||||
<xs:attribute type="xs:string" name="shortcut"/>
|
||||
<xs:attribute type="xs:string" name="description"/>
|
||||
<xs:attribute type="xs:string" name="stylename"/>
|
||||
<xs:attribute type="xs:string" name="icon"/>
|
||||
<xs:attribute type="xs:string" name="insertBefore"/>
|
||||
<xs:attribute type="xs:string" name="insertAfter"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="paramType">
|
||||
|
@ -450,8 +450,6 @@
|
||||
<xs:enumeration value="card"/>
|
||||
<xs:enumeration value="well"/>
|
||||
<xs:enumeration value="v-panel-caption"/>
|
||||
<xs:enumeration value="c-sidemenu-title"/>
|
||||
<xs:enumeration value="c-sidemenu-panel"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:union>
|
||||
@ -468,8 +466,6 @@
|
||||
<xs:enumeration value="well"/>
|
||||
<xs:enumeration value="v-panel-caption"/>
|
||||
<xs:enumeration value="dropzone-container"/>
|
||||
<xs:enumeration value="c-sidemenu-title"/>
|
||||
<xs:enumeration value="c-sidemenu-panel"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:union>
|
||||
@ -486,8 +482,6 @@
|
||||
<xs:enumeration value="well"/>
|
||||
<xs:enumeration value="v-component-group"/>
|
||||
<xs:enumeration value="v-panel-caption"/>
|
||||
<xs:enumeration value="c-sidemenu-title"/>
|
||||
<xs:enumeration value="c-sidemenu-panel"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:union>
|
||||
@ -2524,6 +2518,7 @@
|
||||
<xs:attributeGroup ref="hasSize"/>
|
||||
<xs:attributeGroup ref="hasStyle"/>
|
||||
<xs:attributeGroup ref="hasSpacingMargin"/>
|
||||
<xs:attributeGroup ref="hasResponsive"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
@ -95,6 +95,7 @@ public class FrameComponentLoader extends ContainerLoader<Frame> {
|
||||
loadVisible(resultComponent, element);
|
||||
|
||||
loadStyleName(resultComponent, element);
|
||||
loadResponsive(resultComponent, element);
|
||||
|
||||
loadAlign(resultComponent, element);
|
||||
|
||||
|
@ -160,6 +160,7 @@ public class FrameLoader<T extends Frame> extends ContainerLoader<T> {
|
||||
loadWidth(resultComponent, layoutElement);
|
||||
loadHeight(resultComponent, layoutElement);
|
||||
loadStyleName(resultComponent, layoutElement);
|
||||
loadResponsive(resultComponent, layoutElement);
|
||||
|
||||
ComponentLoaderContext parentContext = (ComponentLoaderContext) getContext();
|
||||
setContext(innerContext);
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
package com.haulmont.cuba.gui.xml.layout.loaders;
|
||||
|
||||
import com.haulmont.cuba.gui.GuiDevelopmentException;
|
||||
import com.haulmont.cuba.gui.components.Button;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
import com.haulmont.cuba.gui.components.mainwindow.SideMenu;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.dom4j.Element;
|
||||
@ -42,8 +45,10 @@ public class SideMenuLoader extends AbstractComponentLoader<SideMenu> {
|
||||
|
||||
loadSelectOnClick(resultComponent, element);
|
||||
loadMenuConfigIfNeeded(resultComponent, element);
|
||||
}
|
||||
|
||||
loadSidePanel(resultComponent, element);
|
||||
loadSidePanelToggleButton(resultComponent, element);
|
||||
}
|
||||
protected void loadMenuConfigIfNeeded(SideMenu component, Element element) {
|
||||
String loadMenuConfig = element.attributeValue("loadMenuConfig");
|
||||
if (StringUtils.isEmpty(loadMenuConfig) || Boolean.parseBoolean(loadMenuConfig)) {
|
||||
@ -57,4 +62,28 @@ public class SideMenuLoader extends AbstractComponentLoader<SideMenu> {
|
||||
component.setSelectOnClick(Boolean.parseBoolean(selectOnClick));
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadSidePanel(SideMenu component, Element element) {
|
||||
String sidePanelId = element.attributeValue("sidePanel");
|
||||
if (StringUtils.isNotEmpty(sidePanelId)) {
|
||||
Component sidePanel = resultComponent.getFrame().getComponent(sidePanelId);
|
||||
if (sidePanel == null) {
|
||||
throw new GuiDevelopmentException("Unable to find sidePanel component for SideMenu",
|
||||
context.getFullFrameId(), "sidePanel", sidePanelId);
|
||||
}
|
||||
component.setSidePanel(sidePanel);
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadSidePanelToggleButton(SideMenu component, Element element) {
|
||||
String toggleButtonId = element.attributeValue("sidePanelToggleButton");
|
||||
if (StringUtils.isNotEmpty(toggleButtonId)) {
|
||||
Component toggleButton = resultComponent.getFrame().getComponent(toggleButtonId);
|
||||
if (!(toggleButton instanceof Button)) {
|
||||
throw new GuiDevelopmentException("Unable to find sidePanelToggleButton for SideMenu",
|
||||
context.getFullFrameId(), "sidePanelToggleButton", toggleButtonId);
|
||||
}
|
||||
component.setSidePanelToggleButton((Button) toggleButton);
|
||||
}
|
||||
}
|
||||
}
|
@ -74,6 +74,7 @@ public class WindowLoader extends FrameLoader<Window> {
|
||||
loadWidth(resultComponent, layoutElement);
|
||||
loadHeight(resultComponent, layoutElement);
|
||||
loadStyleName(resultComponent, layoutElement);
|
||||
loadResponsive(resultComponent, layoutElement);
|
||||
loadVisible(resultComponent, layoutElement);
|
||||
|
||||
loadTimers(factory, resultComponent, element);
|
||||
|
@ -295,4 +295,16 @@ public interface WebConfig extends Config {
|
||||
@Property("cuba.web.widgetSet")
|
||||
@Default("com.haulmont.cuba.web.toolkit.ui.WidgetSet")
|
||||
String getWidgetSet();
|
||||
|
||||
@Property("cuba.web.useDeviceWidthForViewport")
|
||||
@DefaultBoolean(false)
|
||||
boolean getUseDeviceWidthForViewport();
|
||||
|
||||
@Property("cuba.web.customDeviceWidthForViewport")
|
||||
@DefaultInt(-1)
|
||||
int getCustomDeviceWidthForViewport();
|
||||
|
||||
@Property("cuba.web.pageInitialScale")
|
||||
@DefaultString("0.8")
|
||||
String getPageInitialScale();
|
||||
}
|
@ -870,16 +870,20 @@ public class WebWindow implements Window, Component.Wrapper,
|
||||
|
||||
@Override
|
||||
public boolean isResponsive() {
|
||||
if (component instanceof AbstractComponent) {
|
||||
return ((AbstractComponent) component).isResponsive();
|
||||
ComponentContainer container = getContainer();
|
||||
|
||||
if (container instanceof AbstractComponent) {
|
||||
return ((AbstractComponent) container).isResponsive();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResponsive(boolean responsive) {
|
||||
if (component instanceof AbstractComponent) {
|
||||
((AbstractComponent) component).setResponsive(responsive);
|
||||
ComponentContainer container = getContainer();
|
||||
|
||||
if (container instanceof AbstractComponent) {
|
||||
((AbstractComponent) container).setResponsive(responsive);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,12 +90,20 @@ public abstract class WebAbstractComponent<T extends com.vaadin.ui.AbstractCompo
|
||||
|
||||
@Override
|
||||
public boolean isResponsive() {
|
||||
return component.isResponsive();
|
||||
com.vaadin.ui.Component composition = getComposition();
|
||||
if (composition instanceof AbstractComponent) {
|
||||
return ((AbstractComponent) composition).isResponsive();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResponsive(boolean responsive) {
|
||||
component.setResponsive(responsive);
|
||||
com.vaadin.ui.Component composition = getComposition();
|
||||
|
||||
if (composition instanceof AbstractComponent) {
|
||||
((AbstractComponent) composition).setResponsive(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void assignAutoDebugId() {
|
||||
|
@ -16,10 +16,15 @@
|
||||
|
||||
package com.haulmont.cuba.web.gui.components.mainwindow;
|
||||
|
||||
import com.haulmont.cuba.core.global.AppBeans;
|
||||
import com.haulmont.cuba.gui.components.AbstractAction;
|
||||
import com.haulmont.cuba.gui.components.Button;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
import com.haulmont.cuba.gui.components.mainwindow.SideMenu;
|
||||
import com.haulmont.cuba.web.gui.components.WebAbstractComponent;
|
||||
import com.haulmont.cuba.web.gui.components.WebComponentsHelper;
|
||||
import com.haulmont.cuba.web.sys.SideMenuBuilder;
|
||||
import com.haulmont.cuba.web.theme.HaloTheme;
|
||||
import com.haulmont.cuba.web.toolkit.ui.CubaSideMenu;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -35,14 +40,73 @@ public class WebSideMenu extends WebAbstractComponent<CubaSideMenu> implements S
|
||||
|
||||
protected Map<String, MenuItem> allItemsIds = new HashMap<>();
|
||||
|
||||
protected Button toggleButton;
|
||||
protected Component sidePanel;
|
||||
|
||||
public WebSideMenu() {
|
||||
component = new CubaSideMenu();
|
||||
component.setBeforeMenuItemTriggeredHandler(menuItem -> {
|
||||
if (sidePanel != null) {
|
||||
sidePanel.removeStyleName(HaloTheme.SIDEMENU_PANEL_OPEN);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMenuConfig() {
|
||||
SideMenuBuilder menuBuilder = new SideMenuBuilder(this);
|
||||
menuBuilder.build();
|
||||
SideMenuBuilder menuBuilder = AppBeans.getPrototype(SideMenuBuilder.NAME);
|
||||
menuBuilder.build(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSidePanelToggleButton(Button toggleButton) {
|
||||
if (this.toggleButton != null) {
|
||||
toggleButton.setAction(null);
|
||||
}
|
||||
|
||||
if (toggleButton != null) {
|
||||
AbstractAction toggleAction = new AbstractAction("toggleSideMenu") {
|
||||
@Override
|
||||
public void actionPerform(Component component) {
|
||||
toggleSidePanel();
|
||||
}
|
||||
};
|
||||
|
||||
toggleAction.setCaption(toggleButton.getCaption());
|
||||
toggleAction.setIcon(toggleButton.getIcon());
|
||||
toggleAction.setDescription(toggleButton.getDescription());
|
||||
toggleAction.setEnabled(toggleButton.isEnabled());
|
||||
toggleAction.setVisible(toggleButton.isVisible());
|
||||
|
||||
toggleButton.setAction(toggleAction);
|
||||
}
|
||||
|
||||
this.toggleButton = toggleButton;
|
||||
}
|
||||
|
||||
protected void toggleSidePanel() {
|
||||
if (sidePanel != null) {
|
||||
if (sidePanel.getStyleName().contains(HaloTheme.SIDEMENU_PANEL_OPEN)) {
|
||||
sidePanel.removeStyleName(HaloTheme.SIDEMENU_PANEL_OPEN);
|
||||
} else {
|
||||
sidePanel.addStyleName(HaloTheme.SIDEMENU_PANEL_OPEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button getSidePanelToggleButton() {
|
||||
return toggleButton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSidePanel(Component sidePanel) {
|
||||
this.sidePanel = sidePanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getSidePanel() {
|
||||
return sidePanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -79,10 +79,13 @@ public class WebUserIndicator extends WebAbstractComponent<CubaCssLayout> implem
|
||||
|
||||
User user = uss.getUserSession().getUser();
|
||||
AppUI ui = AppUI.getCurrent();
|
||||
|
||||
String substitutedUserCaption = getSubstitutedUserCaption(user);
|
||||
|
||||
if (substitutions.isEmpty()) {
|
||||
userComboBox = null;
|
||||
|
||||
userNameLabel = new Label(getSubstitutedUserCaption(user));
|
||||
userNameLabel = new Label(substitutedUserCaption);
|
||||
userNameLabel.setStyleName("c-user-select-label");
|
||||
userNameLabel.setSizeUndefined();
|
||||
|
||||
@ -91,6 +94,7 @@ public class WebUserIndicator extends WebAbstractComponent<CubaCssLayout> implem
|
||||
}
|
||||
|
||||
component.addComponent(userNameLabel);
|
||||
component.setDescription(substitutedUserCaption);
|
||||
} else {
|
||||
userNameLabel = null;
|
||||
|
||||
@ -106,7 +110,7 @@ public class WebUserIndicator extends WebAbstractComponent<CubaCssLayout> implem
|
||||
|
||||
userComboBox.setStyleName("c-user-select-combobox");
|
||||
userComboBox.addItem(user);
|
||||
userComboBox.setItemCaption(user, getSubstitutedUserCaption(user));
|
||||
userComboBox.setItemCaption(user, substitutedUserCaption);
|
||||
|
||||
for (UserSubstitution substitution : substitutions) {
|
||||
User substitutedUser = substitution.getSubstitutedUser();
|
||||
@ -119,6 +123,7 @@ public class WebUserIndicator extends WebAbstractComponent<CubaCssLayout> implem
|
||||
userComboBox.addValueChangeListener(new SubstitutedUserChangeListener(userComboBox));
|
||||
|
||||
component.addComponent(userComboBox);
|
||||
component.setDescription(null);
|
||||
}
|
||||
|
||||
adjustWidth();
|
||||
|
@ -20,6 +20,7 @@
|
||||
app.initErrorCaption = Unexpected error
|
||||
app.initErrorMessage = Please contact system administrator
|
||||
app.initRetry = Retry
|
||||
app.menu = Menu
|
||||
|
||||
cuba.poweredBy = powered by <a href="http://cuba-platform.com" target="_blank"><span class="c-cuba-word">CUBA</span>.platform</a>
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
app.initErrorCaption = Непредвиденная ошибка
|
||||
app.initErrorMessage = Пожалуйста свяжитесь с администратором системы
|
||||
app.initRetry = Попробовать ещё раз
|
||||
app.menu = Меню
|
||||
|
||||
cuba.poweredBy = разработано на <a href="http://cuba-platform.ru" target="_blank"><span class="c-cuba-word">CUBA</span>.platform</a>
|
||||
|
||||
|
@ -17,13 +17,15 @@
|
||||
|
||||
package com.haulmont.cuba.web.sys;
|
||||
|
||||
import com.haulmont.cuba.web.WebConfig;
|
||||
import com.vaadin.server.BootstrapFragmentResponse;
|
||||
import com.vaadin.server.BootstrapListener;
|
||||
import com.vaadin.server.BootstrapPageResponse;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Event listener notified when the bootstrap HTML is about to be generated and
|
||||
* send to the client. The bootstrap HTML is first constructed as an in-memory
|
||||
@ -35,6 +37,9 @@ public class CubaBootstrapListener implements BootstrapListener {
|
||||
|
||||
public static final String NAME = "cuba_BootstrapListener";
|
||||
|
||||
@Inject
|
||||
protected WebConfig webConfig;
|
||||
|
||||
@Override
|
||||
public void modifyBootstrapFragment(BootstrapFragmentResponse response) {
|
||||
}
|
||||
@ -44,6 +49,15 @@ public class CubaBootstrapListener implements BootstrapListener {
|
||||
Element head = response.getDocument().getElementsByTag("head").get(0);
|
||||
|
||||
includeScript("VAADIN/resources/jquery/jquery-1.12.4.min.js", response, head);
|
||||
|
||||
int customDeviceWidthForViewport = webConfig.getCustomDeviceWidthForViewport();
|
||||
if (customDeviceWidthForViewport > 0) {
|
||||
includeMetaViewport("width=" + customDeviceWidthForViewport +
|
||||
", initial-scale=" + webConfig.getPageInitialScale(), response, head);
|
||||
} else if (webConfig.getUseDeviceWidthForViewport()) {
|
||||
includeMetaViewport("width=device-width" +
|
||||
", initial-scale=" + webConfig.getPageInitialScale(), response, head);
|
||||
}
|
||||
}
|
||||
|
||||
protected void includeScript(String src, BootstrapPageResponse response, Element head) {
|
||||
@ -51,4 +65,11 @@ public class CubaBootstrapListener implements BootstrapListener {
|
||||
script.attr("src", src);
|
||||
head.appendChild(script);
|
||||
}
|
||||
|
||||
protected void includeMetaViewport(String content, BootstrapPageResponse response, Element head) {
|
||||
Element meta = response.getDocument().createElement("meta");
|
||||
meta.attr("name", "viewport");
|
||||
meta.attr("content", content);
|
||||
head.appendChild(meta);
|
||||
}
|
||||
}
|
@ -17,9 +17,7 @@
|
||||
package com.haulmont.cuba.web.sys;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.haulmont.cuba.core.global.AppBeans;
|
||||
import com.haulmont.cuba.core.global.DevelopmentException;
|
||||
import com.haulmont.cuba.core.global.UserSessionSource;
|
||||
import com.haulmont.cuba.gui.ComponentsHelper;
|
||||
import com.haulmont.cuba.gui.NoSuchScreenException;
|
||||
import com.haulmont.cuba.gui.TestIdManager;
|
||||
@ -33,7 +31,11 @@ import com.vaadin.event.ShortcutListener;
|
||||
import com.vaadin.ui.AbstractComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
@ -43,27 +45,28 @@ import static com.haulmont.cuba.gui.components.KeyCombination.getShortcutModifie
|
||||
/**
|
||||
* Side menu builder.
|
||||
*/
|
||||
@Component(SideMenuBuilder.NAME)
|
||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||
public class SideMenuBuilder {
|
||||
public static final String NAME = "cuba_SideMenuBuilder";
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(SideMenuBuilder.class);
|
||||
|
||||
@Inject
|
||||
protected UserSession session;
|
||||
|
||||
protected SideMenu menu;
|
||||
@Inject
|
||||
protected MenuConfig menuConfig;
|
||||
|
||||
protected Window window;
|
||||
@Inject
|
||||
protected WindowConfig windowConfig;
|
||||
|
||||
protected MenuConfig menuConfig = AppBeans.get(MenuConfig.NAME);
|
||||
|
||||
protected UserSessionSource uss = AppBeans.get(UserSessionSource.NAME);
|
||||
|
||||
// call MenuBuilder after attaching menubar to UI
|
||||
public SideMenuBuilder(SideMenu menu) {
|
||||
this.session = uss.getUserSession();
|
||||
this.menu = menu;
|
||||
this.window = ComponentsHelper.getWindowImplementation(menu);
|
||||
public SideMenuBuilder() {
|
||||
}
|
||||
|
||||
public void build() {
|
||||
public void build(SideMenu menu) {
|
||||
Window window = ComponentsHelper.getWindowImplementation(menu);
|
||||
|
||||
if (window == null) {
|
||||
throw new IllegalStateException("SideMenu is not belong to Window");
|
||||
}
|
||||
@ -71,17 +74,19 @@ public class SideMenuBuilder {
|
||||
List<MenuItem> rootItems = menuConfig.getRootItems();
|
||||
for (MenuItem menuItem : rootItems) {
|
||||
if (menuItem.isPermitted(session)) {
|
||||
createMenuBarItem(menu, menuItem);
|
||||
createMenuBarItem(window, menu, menuItem);
|
||||
}
|
||||
}
|
||||
removeExtraSeparators(menu);
|
||||
}
|
||||
|
||||
protected void removeExtraSeparators(SideMenu menuBar) {
|
||||
for (SideMenu.MenuItem item : new ArrayList<>(menuBar.getMenuItems())) {
|
||||
List<SideMenu.MenuItem> menuItems = menuBar.getMenuItems();
|
||||
for (SideMenu.MenuItem item : menuItems.toArray(new SideMenu.MenuItem[menuItems.size()])) {
|
||||
removeExtraSeparators(item);
|
||||
if (isMenuItemEmpty(item))
|
||||
if (isMenuItemEmpty(item)) {
|
||||
menuBar.removeMenuItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,55 +111,52 @@ public class SideMenuBuilder {
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
protected void createMenuBarItem(SideMenu menuBar, MenuItem item) {
|
||||
protected void createMenuBarItem(Window webWindow, SideMenu menu, MenuItem item) {
|
||||
if (item.isPermitted(session)) {
|
||||
SideMenu.MenuItem menuItem = menuBar.createMenuItem(item.getId(),
|
||||
MenuConfig.getMenuItemCaption(item.getId()), null, createMenuBarCommand(item));
|
||||
SideMenu.MenuItem menuItem = menu.createMenuItem(item.getId(),
|
||||
menuConfig.getItemCaption(item.getId()), null, createMenuBarCommand(item));
|
||||
|
||||
createSubMenu(menuItem, item, session);
|
||||
assignTestId(menuItem, item);
|
||||
createSubMenu(webWindow, menu, menuItem, item, session);
|
||||
assignTestId(menu, menuItem, item);
|
||||
assignStyleName(menuItem, item);
|
||||
assignIcon(menuItem, item);
|
||||
assignDescription(menuItem, item);
|
||||
assignShortcut(menuItem, item);
|
||||
assignExpanded(menuItem, item);
|
||||
assignShortcut(webWindow, menuItem, item);
|
||||
|
||||
if (!isMenuItemEmpty(menuItem)) {
|
||||
menuBar.addMenuItem(menuItem);
|
||||
menu.addMenuItem(menuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void createSubMenu(SideMenu.MenuItem vItem, MenuItem parentItem, UserSession session) {
|
||||
if (parentItem.isPermitted(session) && !parentItem.getChildren().isEmpty()) {
|
||||
protected void createSubMenu(Window webWindow, SideMenu menu, SideMenu.MenuItem vItem,
|
||||
MenuItem parentItem, UserSession session) {
|
||||
if (parentItem.isPermitted(session)) {
|
||||
for (MenuItem child : parentItem.getChildren()) {
|
||||
if (child.isSeparator()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.getChildren().isEmpty()) {
|
||||
if (child.isPermitted(session)) {
|
||||
SideMenu.MenuItem menuItem = menu.createMenuItem(child.getId(),
|
||||
MenuConfig.getMenuItemCaption(child.getId()), null, createMenuBarCommand(child));
|
||||
if (child.isPermitted(session)) {
|
||||
SideMenu.MenuItem menuItem = menu.createMenuItem(child.getId(),
|
||||
menuConfig.getItemCaption(child.getId()));
|
||||
|
||||
assignTestId(menuItem, child);
|
||||
assignDescription(menuItem, child);
|
||||
assignIcon(menuItem, child);
|
||||
assignStyleName(menuItem, child);
|
||||
assignShortcut(menuItem, child);
|
||||
assignTestId(menu, menuItem, child);
|
||||
assignDescription(menuItem, child);
|
||||
assignIcon(menuItem, child);
|
||||
assignStyleName(menuItem, child);
|
||||
|
||||
if (child.getChildren().isEmpty()) {
|
||||
menuItem.setCommand(createMenuBarCommand(child));
|
||||
|
||||
assignShortcut(webWindow, menuItem, child);
|
||||
|
||||
vItem.addChildItem(menuItem);
|
||||
}
|
||||
} else {
|
||||
if (child.isPermitted(session)) {
|
||||
SideMenu.MenuItem menuItem = menu.createMenuItem(child.getId());
|
||||
menuItem.setCaption(MenuConfig.getMenuItemCaption(child.getId()));
|
||||
} else {
|
||||
createSubMenu(webWindow, menu, menuItem, child, session);
|
||||
|
||||
createSubMenu(menuItem, child, session);
|
||||
assignTestId(menuItem, child);
|
||||
assignDescription(menuItem, child);
|
||||
assignIcon(menuItem, child);
|
||||
assignStyleName(menuItem, child);
|
||||
assignShortcut(menuItem, child);
|
||||
assignExpanded(menuItem, child);
|
||||
|
||||
if (!isMenuItemEmpty(menuItem)) {
|
||||
vItem.addChildItem(menuItem);
|
||||
@ -165,12 +167,15 @@ public class SideMenuBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
protected void assignExpanded(SideMenu.MenuItem menuItem, MenuItem item) {
|
||||
menuItem.setExpanded(item.isExpanded());
|
||||
}
|
||||
|
||||
protected Consumer<SideMenu.MenuItem> createMenuBarCommand(final MenuItem item) {
|
||||
if (!item.getChildren().isEmpty() || item.isMenu()) //check item is menu
|
||||
return null;
|
||||
|
||||
WindowInfo windowInfo = null;
|
||||
final WindowConfig windowConfig = AppBeans.get(WindowConfig.NAME);
|
||||
try {
|
||||
windowInfo = windowConfig.getWindowInfo(item.getId());
|
||||
} catch (NoSuchScreenException e) {
|
||||
@ -202,7 +207,7 @@ public class SideMenuBuilder {
|
||||
return !menuItem.hasChildren() && menuItem.getCommand() == null;
|
||||
}
|
||||
|
||||
protected void assignTestId(SideMenu.MenuItem menuItem, MenuItem conf) {
|
||||
protected void assignTestId(SideMenu menu, SideMenu.MenuItem menuItem, MenuItem conf) {
|
||||
if (menu.getId() != null && !conf.isSeparator()) {
|
||||
TestIdManager testIdManager = AppUI.getCurrent().getTestIdManager();
|
||||
|
||||
@ -232,11 +237,12 @@ public class SideMenuBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
protected void assignShortcut(SideMenu.MenuItem menuItem, MenuItem item) {
|
||||
protected void assignShortcut(Window webWindow, SideMenu.MenuItem menuItem, MenuItem item) {
|
||||
KeyCombination itemShortcut = item.getShortcut();
|
||||
if (itemShortcut != null) {
|
||||
ShortcutListener shortcut = new SideMenuShortcutListener(menuItem, item);
|
||||
AbstractComponent windowImpl = window.unwrap(AbstractComponent.class);
|
||||
|
||||
AbstractComponent windowImpl = webWindow.unwrap(AbstractComponent.class);
|
||||
windowImpl.addShortcutListener(shortcut);
|
||||
|
||||
if (Strings.isNullOrEmpty(menuItem.getBadgeText())) {
|
||||
|
@ -363,4 +363,45 @@ public class HaloTheme {
|
||||
* description.
|
||||
*/
|
||||
public static final String FILEUPLOADFIELD_DROPZONE_DESCRIPTION = "dropzone-description";
|
||||
|
||||
/**
|
||||
* Style for layout tag in mainwindow with responsive {@link com.haulmont.cuba.gui.components.mainwindow.SideMenu}.
|
||||
*/
|
||||
public static final String SIDEMENU_LAYOUT_RESPONSIVE = "c-sidemenu-responsive";
|
||||
|
||||
/**
|
||||
* Style for horizontal layout that contains {@link #SIDEMENU_PANEL} and {@link com.haulmont.cuba.gui.components.mainwindow.AppWorkArea}
|
||||
* in responsive mainwindow with {@link com.haulmont.cuba.gui.components.mainwindow.SideMenu}.
|
||||
*/
|
||||
public static final String SIDEMENU_LAYOUT = "c-sidemenu-layout";
|
||||
|
||||
/**
|
||||
* Style for side panel in responsive mainwindow with {@link com.haulmont.cuba.gui.components.mainwindow.SideMenu}.
|
||||
*/
|
||||
public static final String SIDEMENU_PANEL = "c-sidemenu-panel";
|
||||
|
||||
/**
|
||||
* Style for opened side panel in responsive mainwindow with {@link com.haulmont.cuba.gui.components.mainwindow.SideMenu}.
|
||||
*/
|
||||
public static final String SIDEMENU_PANEL_OPEN = "c-sidemenu-open";
|
||||
|
||||
/**
|
||||
* Style for opened side panel content in responsive mainwindow with {@link com.haulmont.cuba.gui.components.mainwindow.SideMenu}.
|
||||
*/
|
||||
public static final String SIDEMENU_WRAP = "c-sidemenu-wrap";
|
||||
|
||||
/**
|
||||
* Style for side panel toggle button in responsive mainwindow with {@link com.haulmont.cuba.gui.components.mainwindow.SideMenu}.
|
||||
*/
|
||||
public static final String SIDEMENU_TOGGLE_BUTTON = "c-sidemenu-toggle";
|
||||
|
||||
/**
|
||||
* Style for mobile buttons in top panel in responsive mainwindow with {@link com.haulmont.cuba.gui.components.mainwindow.SideMenu}.
|
||||
*/
|
||||
public static final String SIDEMENU_MOBILE_BUTTONS = "c-sidemenu-mobile-buttons";
|
||||
|
||||
/**
|
||||
* Style for top header in responsive mainwindow with {@link com.haulmont.cuba.gui.components.mainwindow.SideMenu}.
|
||||
*/
|
||||
public static final String SIDEMENU_TITLE = "c-sidemenu-title";
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.haulmont.cuba.web.toolkit.ui;
|
||||
|
||||
import com.haulmont.cuba.web.theme.HaloTheme;
|
||||
import com.haulmont.cuba.web.toolkit.ui.client.verticalmenu.CubaSideMenuClientRpc;
|
||||
import com.haulmont.cuba.web.toolkit.ui.client.verticalmenu.CubaSideMenuServerRpc;
|
||||
import com.haulmont.cuba.web.toolkit.ui.client.verticalmenu.CubaSideMenuState;
|
||||
@ -64,6 +65,8 @@ public class CubaSideMenu extends AbstractComponent implements Component.Focusab
|
||||
|
||||
protected PropertyChangeListener itemsPropertyChangeListener = this::menuItemPropertyChanged;
|
||||
|
||||
protected Consumer<MenuItem> beforeMenuItemTriggeredHandler = null;
|
||||
|
||||
public CubaSideMenu() {
|
||||
CubaSideMenuServerRpc menuRpc = (CubaSideMenuServerRpc) itemId -> {
|
||||
MenuItem menuItem = menuItemIdMapper.get(itemId);
|
||||
@ -71,14 +74,26 @@ public class CubaSideMenu extends AbstractComponent implements Component.Focusab
|
||||
if (isSelectOnClick()) {
|
||||
this.selectedItem = menuItem;
|
||||
}
|
||||
if (beforeMenuItemTriggeredHandler != null) {
|
||||
beforeMenuItemTriggeredHandler.accept(menuItem);
|
||||
}
|
||||
if (menuItem.getCommand() != null) {
|
||||
menuItem.getCommand().accept(new MenuItemTriggeredEvent(this, menuItem));
|
||||
}
|
||||
removeStyleName(HaloTheme.SIDEMENU_PANEL_OPEN);
|
||||
}
|
||||
};
|
||||
registerRpc(menuRpc);
|
||||
}
|
||||
|
||||
public Consumer<MenuItem> getBeforeMenuItemTriggeredHandler() {
|
||||
return beforeMenuItemTriggeredHandler;
|
||||
}
|
||||
|
||||
public void setBeforeMenuItemTriggeredHandler(Consumer<MenuItem> beforeMenuItemTriggeredHandler) {
|
||||
this.beforeMenuItemTriggeredHandler = beforeMenuItemTriggeredHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CubaSideMenuState getState() {
|
||||
return (CubaSideMenuState) super.getState();
|
||||
|
@ -203,6 +203,7 @@ cuba.web.icons.upload.png = UPLOAD
|
||||
cuba.web.icons.unlock.png = UNLOCK
|
||||
cuba.web.icons.download.png = DOWNLOAD
|
||||
cuba.web.icons.question-white.png = QUESTION_CIRCLE
|
||||
cuba.web.icons.mobile-menu.png = LIST
|
||||
|
||||
cuba.web.components.pickerfield.images.clear-btn.png = TIMES
|
||||
cuba.web.components.pickerfield.images.clear-btn-readonly.png = TIMES
|
||||
|
@ -15,6 +15,124 @@
|
||||
*
|
||||
*/
|
||||
|
||||
@mixin side-menu-large-icons-style($primary-stylename: c-sidemenu) {
|
||||
$bg: $valo-menu-background-color;
|
||||
|
||||
background-color: $bg;
|
||||
|
||||
.#{$primary-stylename}-title {
|
||||
.v-label {
|
||||
line-height: 1.2;
|
||||
font-size: round($v-font-size--h2 * 0.75);
|
||||
font-weight: bold;
|
||||
}
|
||||
.v-label-undef-w {
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.c-userindicator {
|
||||
padding-left: $v-layout-margin-left/2;
|
||||
padding-right: $v-layout-margin-right/2;
|
||||
|
||||
.v-label {
|
||||
font-size: round($v-font-size * 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
.c-main-buttons {
|
||||
.v-icon {
|
||||
font-size: round($v-font-size * 1.5);
|
||||
}
|
||||
img.v-icon {
|
||||
height: round($v-font-size * 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
& > * {
|
||||
max-width: $v-unit-size * 4;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-item-action {
|
||||
display: block;
|
||||
font-size: round($v-font-size * 1.6);
|
||||
line-height: 1;
|
||||
padding: round($v-unit-size/3);
|
||||
text-align: center;
|
||||
border-top: valo-border($color: $bg, $strength: 0.2, $border: first-number($v-border) solid v-tone);
|
||||
|
||||
&:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-item-caption {
|
||||
display: block;
|
||||
width: auto;
|
||||
margin: .3em 0 0;
|
||||
padding: 0;
|
||||
font-size: round($v-font-size * 0.8);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.v-icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
span.v-icon {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-item-header {
|
||||
margin: round($v-unit-size/4) 0 0;
|
||||
padding: round($v-unit-size/5) round($v-unit-size/1.5) round($v-unit-size/5) round($v-unit-size/4);
|
||||
border: none;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
background: darken($bg, 6%);
|
||||
box-shadow: valo-bevel-and-shadow($shadow: $v-shadow);
|
||||
|
||||
.#{$primary-stylename}-item-wrap {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-item-caption {
|
||||
font-size: round($v-font-size * 0.9);
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-item-badge {
|
||||
right: round($v-unit-size/4);
|
||||
}
|
||||
|
||||
+ .#{$primary-stylename}-item {
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-item-action.#{$primary-stylename}-item-selected {
|
||||
background: if(is-dark-color($bg), darken($bg, 3%), lighten($bg, 5%));
|
||||
|
||||
.v-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-item-badge {
|
||||
border-color: darken($bg, 3%);
|
||||
}
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-item-action .#{$primary-stylename}-item-badge {
|
||||
padding-left: round($v-unit-size/9);
|
||||
padding-right: round($v-unit-size/9);
|
||||
top: round($v-unit-size/5);
|
||||
right: round($v-unit-size/5);
|
||||
border: 2px solid $bg;
|
||||
}
|
||||
}
|
||||
|
||||
$cuba-sidemenu-top-offset: floor(($v-unit-size - $v-unit-size * 0.8) / 2);
|
||||
$cuba-sidemenu-top-height: $v-unit-size + 2 * $cuba-sidemenu-top-offset;
|
||||
|
||||
@mixin halo-cuba-sidemenu($primary-stylename: c-sidemenu) {
|
||||
.#{$primary-stylename}-user {
|
||||
background: transparent;
|
||||
@ -70,8 +188,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-wrap {
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-title {
|
||||
@include valo-menu-title-style;
|
||||
@include valo-gradient($color: $v-selection-color);
|
||||
$font-color: valo-font-color($v-selection-color, 1);
|
||||
color: $font-color;
|
||||
text-shadow: valo-text-shadow($font-color: $font-color, $background-color: $v-selection-color);
|
||||
padding: round($v-unit-size/3) round($v-unit-size/2);
|
||||
|
||||
border-bottom: valo-border($color: $v-selection-color);
|
||||
@include box-shadow(valo-bevel-and-shadow($shadow: $v-shadow));
|
||||
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
@ -83,8 +212,14 @@
|
||||
|
||||
.#{$primary-stylename} {
|
||||
outline: 0;
|
||||
$bg: $valo-menu-background-color;
|
||||
|
||||
@include valo-menu-style;
|
||||
@include linear-gradient(to left, (darken($bg, valo-gradient-opacity() / 2) 0%, $bg round($v-unit-size/4)), $fallback: $bg);
|
||||
color: valo-font-color($bg, 0.5);
|
||||
font-size: round($v-font-size * 0.9);
|
||||
line-height: round($v-unit-size * 0.8);
|
||||
border-right: valo-border($color: $bg);
|
||||
white-space: nowrap;
|
||||
|
||||
font-size: $v-font-size;
|
||||
}
|
||||
@ -112,12 +247,15 @@
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-item-header {
|
||||
@include valo-menu-subtitle-style;
|
||||
color: valo-font-color($valo-menu-background-color, 0.33);
|
||||
margin: round($v-unit-size/5) 0 round($v-unit-size/5) round($v-unit-size/2);
|
||||
border-bottom: valo-border($color: $valo-menu-background-color, $strength: 0.5, $border: first-number($v-border) solid v-tone);
|
||||
|
||||
margin-left: 0;
|
||||
|
||||
.#{$primary-stylename}-item-badge {
|
||||
background: transparent;
|
||||
color: mix(valo-font-color($valo-menu-background-color), $v-selection-color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,4 +313,128 @@
|
||||
@include valo-badge-style($states: active, $active-color: $active-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-toggle,
|
||||
.#{$primary-stylename}-mobile-buttons {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-toggle {
|
||||
top: $cuba-sidemenu-top-offset;
|
||||
left: $cuba-sidemenu-top-offset;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-mobile-buttons {
|
||||
top: $cuba-sidemenu-top-offset;
|
||||
right: 0;
|
||||
|
||||
.v-button {
|
||||
color: valo-font-color($v-selection-color, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-responsive {
|
||||
.#{$primary-stylename}-panel {
|
||||
padding-bottom: $v-unit-size;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.c-app-icon {
|
||||
margin: $v-layout-spacing-vertical 0;
|
||||
}
|
||||
|
||||
.c-userindicator > .v-label,
|
||||
.c-app-icon,
|
||||
.c-welcome-text,
|
||||
.c-user-timezone-label,
|
||||
.c-main-buttons {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-panel > .#{$primary-stylename}-title {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-wrap {
|
||||
& > .#{$primary-stylename},
|
||||
& > .c-app-icon,
|
||||
& > .c-userindicator,
|
||||
& > .c-user-timezone-label,
|
||||
& > .c-fts-field-wrap,
|
||||
& > .c-main-buttons {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@include width-range($min: 801px, $max: 1100px) {
|
||||
.#{$primary-stylename}-panel {
|
||||
@include side-menu-large-icons-style;
|
||||
}
|
||||
}
|
||||
|
||||
@include width-range($max: 800px) {
|
||||
padding-top: $cuba-sidemenu-top-height;
|
||||
|
||||
.#{$primary-stylename}-panel {
|
||||
overflow: visible;
|
||||
width: 0;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-toggle,
|
||||
.#{$primary-stylename}-mobile-buttons {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.c-main-buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-title {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: $cuba-sidemenu-top-height !important;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
-webkit-backface-visibility: hidden;
|
||||
|
||||
.v-label {
|
||||
line-height: $v-unit-size;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-wrap {
|
||||
@include valo-menu-style;
|
||||
|
||||
position: fixed;
|
||||
z-index: 9000;
|
||||
top: $cuba-sidemenu-top-height;
|
||||
bottom: 0;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
padding: round($v-unit-size / 2) 0;
|
||||
@include transform(translatex(-100%));
|
||||
@include transition(all 300ms);
|
||||
}
|
||||
|
||||
.#{$primary-stylename}-panel.#{$primary-stylename}-open .#{$primary-stylename}-wrap {
|
||||
@include transform(translatex(0%));
|
||||
}
|
||||
}
|
||||
|
||||
@include width-range($max: 500px) {
|
||||
.#{$primary-stylename}-toggle .v-button-caption {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
modules/web/themes/halo/icons/mobile-menu.png
Normal file
BIN
modules/web/themes/halo/icons/mobile-menu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 504 B |
BIN
modules/web/themes/havana/icons/mobile-menu.png
Normal file
BIN
modules/web/themes/havana/icons/mobile-menu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 504 B |
Loading…
Reference in New Issue
Block a user