浏览代码

new navMenu

Crystal.Sea 4 年之前
父节点
当前提交
bde6285d2a
共有 30 个文件被更改,包括 895 次插入1315 次删除
  1. 0 42
      maxkey-core/src/main/java/org/maxkey/web/BasicController.java
  2. 7 0
      maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/AccountsMapper.java
  3. 63 0
      maxkey-persistence/src/main/java/org/maxkey/persistence/service/AccountsService.java
  4. 10 1
      maxkey-persistence/src/main/java/org/maxkey/persistence/service/GroupsService.java
  5. 36 0
      maxkey-persistence/src/main/resources/org/maxkey/persistence/mapper/xml/mysql/AccountsMapper.xml
  6. 3 3
      maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/singlelogout/LogoutType.java
  7. 2 1
      maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java
  8. 2 1
      maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java
  9. 2 1
      maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasRestV1Endpoint.java
  10. 2 2
      maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message.properties
  11. 2 2
      maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_en.properties
  12. 2 2
      maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_zh_CN.properties
  13. 52 86
      maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/layout/nav_primary.ftl
  14. 8 9
      maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/layout/top.ftl
  15. 14 9
      maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/MaxKeyMgtConfig.java
  16. 73 0
      maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/jobs/AccountsStrategyJob.java
  17. 3 9
      maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/jobs/DynamicGroupsJob.java
  18. 4 4
      maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/ApplicationsController.java
  19. 6 1
      maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/contorller/AccountsStrategyController.java
  20. 10 10
      maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/contorller/GroupPrivilegesController.java
  21. 3 3
      maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message.properties
  22. 1 1
      maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_en.properties
  23. 3 3
      maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_zh_CN.properties
  24. 14 20
      maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/layout/sidenav.ftl
  25. 11 5
      maxkey-webs/maxkey-web-resources/src/main/resources/static/css/base.css
  26. 136 274
      maxkey-webs/maxkey-web-resources/src/main/resources/static/css/menu.css
  27. 136 274
      maxkey-webs/maxkey-web-resources/src/main/resources/static/css/menu_default.css
  28. 138 274
      maxkey-webs/maxkey-web-resources/src/main/resources/static/css/menu_minty.css
  29. 137 275
      maxkey-webs/maxkey-web-resources/src/main/resources/static/css/menu_pulse.css
  30. 15 3
      maxkey-webs/maxkey-web-resources/src/main/resources/static/javascript/platform.common.js

+ 0 - 42
maxkey-core/src/main/java/org/maxkey/web/BasicController.java

@@ -1,42 +0,0 @@
-/*
- * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
- * 
- * Licensed 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.maxkey.web;
-
-import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
-import org.apache.mybatis.jpa.persistence.JpaPageResults;
-import org.maxkey.web.message.Message;
-import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.servlet.ModelAndView;
-
-public interface BasicController  <T extends JpaBaseEntity> {
-
-	public JpaPageResults<T> pageResults(@ModelAttribute("modelAttribute") T modelAttribute);
-	
-	public ModelAndView forwardAdd(@ModelAttribute("modelAttribute") T modelAttribute);
-	
-	public Message insert(@ModelAttribute("modelAttribute") T modelAttribute);
-	
-	public ModelAndView forwardUpdate(@PathVariable("id") String id);
-	
-	public Message update(@ModelAttribute("modelAttribute") T modelAttribute);
-	
-	public Message delete(@ModelAttribute("modelAttribute") T modelAttribute) ;
-	
-	
-}

+ 7 - 0
maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/AccountsMapper.java

@@ -20,8 +20,12 @@
  */
 package org.maxkey.persistence.mapper;
 
+import java.util.List;
+
 import org.apache.mybatis.jpa.persistence.IJpaBaseMapper;
 import org.maxkey.entity.Accounts;
+import org.maxkey.entity.AccountsStrategy;
+import org.maxkey.entity.UserInfo;
 
 /**
  * @author Crystal.sea
@@ -30,4 +34,7 @@ import org.maxkey.entity.Accounts;
 public  interface AccountsMapper extends IJpaBaseMapper<Accounts> {
 	
 
+    public List<UserInfo> queryUserNotInStrategy(AccountsStrategy strategy);
+    
+    public long deleteByStrategy(AccountsStrategy strategy);
 }

+ 63 - 0
maxkey-persistence/src/main/java/org/maxkey/persistence/service/AccountsService.java

@@ -17,13 +17,19 @@
 
 package org.maxkey.persistence.service;
 
+import java.util.List;
+
 import org.apache.mybatis.jpa.persistence.JpaBaseService;
+import org.maxkey.constants.ConstantsStatus;
+import org.maxkey.crypto.ReciprocalUtils;
 import org.maxkey.entity.Accounts;
+import org.maxkey.entity.AccountsStrategy;
 import org.maxkey.entity.UserInfo;
 import org.maxkey.persistence.kafka.KafkaIdentityAction;
 import org.maxkey.persistence.kafka.KafkaIdentityTopic;
 import org.maxkey.persistence.kafka.KafkaPersistService;
 import org.maxkey.persistence.mapper.AccountsMapper;
+import org.maxkey.util.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
@@ -36,6 +42,9 @@ public class AccountsService  extends JpaBaseService<Accounts>{
     @Autowired
     UserInfoService  userInfoService;
     
+    @Autowired
+    AccountsStrategyService accountsStrategyService;
+    
 	public AccountsService() {
 		super(AccountsMapper.class);
 	}
@@ -99,5 +108,59 @@ public class AccountsService  extends JpaBaseService<Accounts>{
           }
        return false;
    }
+   
+   public void refreshByStrategy(AccountsStrategy strategy) {
+       if(StringUtils.isNotBlank(strategy.getOrgIdsList())) {
+           strategy.setOrgIdsList("'"+strategy.getOrgIdsList().replace(",", "','")+"'");
+       }
+       List<UserInfo>  userList = queryUserNotInStrategy(strategy);
+       for(UserInfo user : userList) {
+           Accounts account = new Accounts();
+           account.setAppId(strategy.getAppId());
+           account.setAppName(strategy.getAppName());
+           
+           account.setUserId(user.getId());
+           account.setUsername(user.getUsername());
+           account.setDisplayName(user.getDisplayName());
+           
+           if(strategy.getMapping().equalsIgnoreCase("username")) {
+               account.setRelatedUsername(user.getUsername());
+           }else if(strategy.getMapping().equalsIgnoreCase("mobile")) {
+               account.setRelatedUsername(user.getMobile());
+           }else if(strategy.getMapping().equalsIgnoreCase("email")) {
+               account.setRelatedUsername(user.getEmail());
+           }else if(strategy.getMapping().equalsIgnoreCase("employeeNumber")) {
+               account.setRelatedUsername(user.getEmployeeNumber());
+           }else if(strategy.getMapping().equalsIgnoreCase("windowsAccount")) {
+               account.setRelatedUsername(user.getWindowsAccount());
+           }else if(strategy.getMapping().equalsIgnoreCase("idCardNo")) {
+               account.setRelatedUsername(user.getIdCardNo());
+           }else {
+               account.setRelatedUsername(user.getUsername());
+           }
+           account.setRelatedPassword(ReciprocalUtils.encode(userInfoService.randomPassword()));
+           
+           account.setCreateType("automatic");
+           account.setStatus(ConstantsStatus.ACTIVE);
+           account.setStrategyId(strategy.getId());
+           
+           insert(account);
+       }
+       deleteByStrategy(strategy);
+   }
+   public void refreshAllByStrategy() {
+       for( AccountsStrategy strategy : accountsStrategyService.query(null)) {
+           refreshByStrategy(strategy);
+       }
+   }
+   
+   
+   public List<UserInfo> queryUserNotInStrategy(AccountsStrategy strategy){
+       return getMapper().queryUserNotInStrategy(strategy);
+   }
+   
+   public long deleteByStrategy(AccountsStrategy strategy) {
+       return getMapper().deleteByStrategy(strategy);
+   }
 	
 }

+ 10 - 1
maxkey-persistence/src/main/java/org/maxkey/persistence/service/GroupsService.java

@@ -23,6 +23,7 @@ import java.time.LocalTime;
 import java.util.List;
 
 import org.apache.mybatis.jpa.persistence.JpaBaseService;
+import org.maxkey.constants.ConstantsStatus;
 import org.maxkey.entity.Groups;
 import org.maxkey.persistence.mapper.GroupsMapper;
 import org.maxkey.util.StringUtils;
@@ -72,7 +73,7 @@ public class GroupsService  extends JpaBaseService<Groups> implements Serializab
 	}
 	
 	public void refreshDynamicGroups(Groups dynamicGroup){
-	    if(dynamicGroup.getDynamic().equals("1")) {
+	    if(dynamicGroup.getDynamic().equals(ConstantsStatus.ACTIVE)) {
 	        boolean isDynamicTimeSupport = false;
 	        boolean isBetweenEffectiveTime = false;
 	        if(StringUtils.isNotBlank(dynamicGroup.getResumeTime())
@@ -119,6 +120,14 @@ public class GroupsService  extends JpaBaseService<Groups> implements Serializab
             }
 	    }
     }
+	
+	public void refreshAllDynamicGroups(){
+	    List<Groups>  groupsList = queryDynamicGroups(null);
+        for(Groups group : groupsList) {
+            _logger.debug("group " + group);
+            refreshDynamicGroups(group);
+        }
+	}
 
     public GroupMemberService getGroupMemberService() {
         return groupMemberService;

+ 36 - 0
maxkey-persistence/src/main/resources/org/maxkey/persistence/mapper/xml/mysql/AccountsMapper.xml

@@ -29,4 +29,40 @@
 		<include refid="where_statement"/>
 	</select>
 	
+	<select id="queryUserNotInStrategy" parameterType="AccountsStrategy" resultType="UserInfo">
+        select 
+            *
+        from mxk_userinfo u
+        where not exists(
+                select  1 from mxk_accounts ac 
+                where   ac.appid = #{appId}
+                    and ac.userid = u.id
+                    and ac.createtype='automatic'
+            )
+        <if test="filters != null and filters != ''">
+                and (${filters})
+        </if>
+        <if test="orgIdsList != null and orgIdsList != ''">
+                and u.departmentid in( ${orgIdsList})
+        </if>
+    </select>
+    
+	<delete id="deleteByStrategy" parameterType="AccountsStrategy" >
+        delete from mxk_accounts ac
+        where   ac.createtype = 'automatic'
+            and ac.appid = #{appId}
+            and ac.strategyid = #{id}
+            and not exists(
+                select 1
+                from mxk_userinfo u
+                where 1 = 1 
+                    and u.id=ac.userid
+                <if test="filters != null and filters != ''">
+                        and (${filters})
+                </if>
+                <if test="orgIdsList != null and orgIdsList != ''">
+                        and u.departmentid in ( ${orgIdsList})
+                </if>
+            )
+    </delete>
 </mapper>

+ 3 - 3
maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/singlelogout/LogoutType.java

@@ -22,14 +22,14 @@ public class LogoutType {
     /**
      * For no SLO.
      */
-    public static int NONE = 0;
+    public static int NONE              = 0;
     /**
      * For back channel SLO.
      */
-    public static  int BACK_CHANNEL = 1;
+    public static  int BACK_CHANNEL     = 1;
     /**
      * For front channel SLO.
      */
-    public static  int FRONT_CHANNEL = 2;
+    public static  int FRONT_CHANNEL    = 2;
 
 }

+ 2 - 1
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java

@@ -34,6 +34,7 @@ import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter;
 import org.maxkey.constants.Boolean;
 import org.maxkey.entity.UserInfo;
 import org.maxkey.util.Instance;
+import org.maxkey.util.StringUtils;
 import org.maxkey.web.HttpResponseConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -205,7 +206,7 @@ For all error codes, it is RECOMMENDED that CAS provide a more detailed message
 			String principal=authentication.getUsername();
 			_logger.debug("principal "+principal);
 			serviceResponseBuilder.success().setUser(principal);
-			if(pgtUrl != null && !pgtUrl.equalsIgnoreCase("")) {
+			if(StringUtils.isNotBlank(pgtUrl)) {
 				ProxyGrantingTicketIOUImpl proxyGrantingTicketIOUImpl =new ProxyGrantingTicketIOUImpl();
 				String proxyGrantingTicketIOU=casProxyGrantingTicketServices.createTicket(proxyGrantingTicketIOUImpl);
 				

+ 2 - 1
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java

@@ -35,6 +35,7 @@ import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter;
 import org.maxkey.constants.Boolean;
 import org.maxkey.entity.UserInfo;
 import org.maxkey.util.Instance;
+import org.maxkey.util.StringUtils;
 import org.maxkey.web.HttpResponseConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -88,7 +89,7 @@ public class Cas30AuthorizeEndpoint  extends CasBaseAuthorizeEndpoint{
 			String principal=authentication.getUsername();
 			_logger.debug("principal "+principal);
 			serviceResponseBuilder.success().setUser(principal);
-			if(pgtUrl != null && !pgtUrl.equalsIgnoreCase("")) {
+			if(StringUtils.isNotBlank(pgtUrl)) {
 				ProxyGrantingTicketIOUImpl proxyGrantingTicketIOUImpl =new ProxyGrantingTicketIOUImpl();
 				String proxyGrantingTicketIOU=casProxyGrantingTicketServices.createTicket(proxyGrantingTicketIOUImpl);
 				

+ 2 - 1
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasRestV1Endpoint.java

@@ -31,6 +31,7 @@ import org.maxkey.authz.cas.endpoint.ticket.ServiceTicketImpl;
 import org.maxkey.authz.cas.endpoint.ticket.TicketGrantingTicketImpl;
 import org.maxkey.entity.UserInfo;
 import org.maxkey.entity.apps.AppsCasDetails;
+import org.maxkey.util.StringUtils;
 import org.maxkey.web.HttpResponseConstants;
 import org.maxkey.web.WebContext;
 import org.slf4j.Logger;
@@ -76,7 +77,7 @@ public class CasRestV1Endpoint  extends CasBaseAuthorizeEndpoint{
             @RequestParam(value=CasConstants.PARAMETER.REST_USERNAME,required=true) String username,
             @RequestParam(value=CasConstants.PARAMETER.REST_PASSWORD,required=true) String password){
 	    try {
-    	    if (password == null || password.isEmpty()) {
+    	    if (StringUtils.isBlank(password)) {
                 throw new BadCredentialsException("No credentials are provided or extracted to authenticate the REST request");
             }
     	    

+ 2 - 2
maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message.properties

@@ -5,7 +5,7 @@ global.change.language.en=English
 global.change.language.zh=\u4e2d\u6587
 global.language=\u4e2d\u6587
 global.text.welcome=\u6b22\u8fce\u60a8
-global.text.manage=\u7ba1\u7406
+global.text.manage=\u540E\u53F0
 global.text.copyright=\u7248\u6743\u6240\u6709
 global.text.copyright.content=Copyright  
 global.text.copyright.license=Licensed under the Apache License, Version 2.0
@@ -275,7 +275,7 @@ message.action.delete.success=\u5220\u9664\u64cd\u4f5c\u6210\u529f
 message.action.delete.error=\u5220\u9664\u64cd\u4f5c\u5931\u8d25
 
 #navs
-navs.mypps=\u6211\u7684\u5e94\u7528
+navs.mypps=\u5e94\u7528
 navs.setting=\u8bbe\u7f6e
 navs.setting.security=\u5b89\u5168\u8bbe\u7f6e
 navs.setting.sociallink=\u8ba4\u8bc1\u5173\u8054

+ 2 - 2
maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_en.properties

@@ -5,7 +5,7 @@ global.change.language.en=English
 global.change.language.zh=\u4e2d\u6587
 global.language=English
 global.text.welcome=Welcome
-global.text.manage=Manage
+global.text.manage=Management
 global.text.copyright=CopyRight
 global.text.copyright.content=Copyright  
 global.text.copyright.license=Licensed under the Apache License, Version 2.0
@@ -274,7 +274,7 @@ message.action.delete.success=Delete Success
 message.action.delete.error=Delete Error
 
 #navs
-navs.mypps=My Apps
+navs.mypps=Apps
 
 navs.setting=Settings
 navs.setting.security=Security

+ 2 - 2
maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_zh_CN.properties

@@ -5,7 +5,7 @@ global.change.language.en=English
 global.change.language.zh=\u4e2d\u6587
 global.language=\u4e2d\u6587
 global.text.welcome=\u6b22\u8fce\u60a8
-global.text.manage=\u7ba1\u7406
+global.text.manage=\u540E\u53F0
 global.text.copyright=\u7248\u6743\u6240\u6709
 global.text.copyright.content=Copyright  
 global.text.copyright.license=Licensed under the Apache License, Version 2.0
@@ -275,7 +275,7 @@ message.action.delete.success=\u5220\u9664\u64cd\u4f5c\u6210\u529f
 message.action.delete.error=\u5220\u9664\u64cd\u4f5c\u5931\u8d25
 
 #navs
-navs.mypps=\u6211\u7684\u5e94\u7528
+navs.mypps=\u5e94\u7528
 navs.setting=\u8bbe\u7f6e
 navs.setting.security=\u5b89\u5168\u8bbe\u7f6e
 navs.setting.sociallink=\u8ba4\u8bc1\u5173\u8054

+ 52 - 86
maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/layout/nav_primary.ftl

@@ -2,104 +2,70 @@
 <div id="nav_primary" >
 <div  class="container row">
 	<div class="col-sm-8">
-	<div id="nav_primary"  class="menuprimary">
-		<ul >
-			<li  id="nav_primay_11"  class="nav_primay_level primaryleft"  xpath="">
+		<ul class="navMenu">
+			<li  id="nav_primay_11"    xpath="">
 				<!--我的应用-->
 				<a   href="<@base/>/appList"><@locale code="navs.mypps"/></a>
 			</li>
-			<li  id="nav_primay_13"  class="nav_primay_level primaryleft"  xpath="">
+            <!--会话-->
+            <li id="nav_second_12" >
+                <a   href="<@base/>/session/sessionList"><@locale code="navs.audit.loginsession"/></a>
+            </li>
+			<li  id="nav_primay_13"    xpath="">
 				<!--安全设置-->
 				<a   href="<@base/>/safe/forward/setting"><@locale code="navs.setting"/></a>
-				<div id="nav_child_1301"  class="nav_second_child">
-					<ul>
-						<!--安全设置-->
-						<li id="nav_second_1301" class="nav_second_level">
-							<a   href="<@base/>/safe/forward/setting"><@locale code="navs.setting.security"/></a>
-						</li>
-					</ul>
-					<ul>
-						<!--认证关联-->
-						<li id="nav_second_1301" class="nav_second_level">
-							<a   href="<@base/>/socialsignon/list"><@locale code="navs.setting.sociallink"/></a>
-						</li>
-					</ul>
-					<ul>
-						<!--密码修改-->
-						<li id="nav_second_1302" class="nav_second_level">
-							<a   href="<@base/>/safe/forward/changePasswod"><@locale code="navs.setting.changepassword"/></a>
-						</li>
-					</ul>
-					<ul>
-						<!--应用配置-->
-						<li id="nav_second_1304" class="nav_second_level">
-							<a   href="<@base/>/appConfigList"><@locale code="navs.setting.appaccount"/></a>
-						</li>
-					</ul>
-					<ul>
-						<!--时间令牌-->
-						<li id="nav_second_1305" class="nav_second_level">
-							<a   href="<@base/>/safe/otp/timebased"><@locale code="navs.setting.timetoken"/></a>
-						</li>
-					</ul>
-				</div>
-			</li>
-			<!--我的资料-->
-			<li  id="nav_primay_14"  class="nav_primay_level primaryleft"  xpath="">
-				<a  href="<@base/>/profile/myProfile"><@locale code="navs.myprofile"/></a>
+				<ul id="nav_child_1301"  class="dropdown" >
+					<!--安全设置-->
+					<li id="nav_second_1301" >
+						<a   href="<@base/>/safe/forward/setting"><@locale code="navs.setting.security"/></a>
+					</li>
+					<!--认证关联-->
+					<li id="nav_second_1301" >
+						<a   href="<@base/>/socialsignon/list"><@locale code="navs.setting.sociallink"/></a>
+					</li>
+					<!--密码修改-->
+					<li id="nav_second_1302" >
+						<a   href="<@base/>/safe/forward/changePasswod"><@locale code="navs.setting.changepassword"/></a>
+					</li>
+					<!--应用配置-->
+					<li id="nav_second_1304" >
+						<a   href="<@base/>/appConfigList"><@locale code="navs.setting.appaccount"/></a>
+					</li>
+					<!--时间令牌-->
+					<li id="nav_second_1305" >
+						<a   href="<@base/>/safe/otp/timebased"><@locale code="navs.setting.timetoken"/></a>
+					</li>
+				</ul>
 			</li>
 			<!--日志审计-->
-			<li  id="nav_primay_15"  class="nav_primay_level primaryleft"  xpath="">
+			<li  id="nav_primay_15"    xpath="">
 				<a   href="<@base/>/historys/loginList"><@locale code="navs.audit"/></a>
-				<div id="nav_child_1501"  class="nav_second_child">
-				    <ul>
-                        <!--登录日志-->
-                        <li id="nav_second_1501" class="nav_second_level">
-                            <a   href="<@base/>/session/sessionList"><@locale code="navs.audit.loginsession"/></a>
-                        </li>
-                    </ul>
-					<ul>
-						<!--登录日志-->
-						<li id="nav_second_1502" class="nav_second_level">
-							<a   href="<@base/>/historys/loginList"><@locale code="navs.audit.login"/></a>
-						</li>
-					</ul>
-					<ul>
-						<!--访问日志-->
-						<li id="nav_second_1503" class="nav_second_level">
-							<a   href="<@base/>/historys/loginAppsList"><@locale code="navs.audit.signon"/></a>
-						</li>
-					</ul>
-					<ul>
-						<!--操作日志-->
-						<li id="nav_second_1504" class="nav_second_level">
-							<a   href="<@base/>/historys/systemLogsList"><@locale code="navs.audit.operation"/></a>
-						</li>
-					</ul>
-				</div>
+				<ul  class="dropdown">
+					<!--登录日志-->
+					<li id="nav_second_1502" >
+						<a   href="<@base/>/historys/loginList"><@locale code="navs.audit.login"/></a>
+					</li>
+					<!--访问日志-->
+					<li id="nav_second_1503" >
+						<a   href="<@base/>/historys/loginAppsList"><@locale code="navs.audit.signon"/></a>
+					</li>
+				
+					<!--操作日志-->
+					<li id="nav_second_1504" >
+						<a   href="<@base/>/historys/systemLogsList"><@locale code="navs.audit.operation"/></a>
+					</li>
+				</ul>
 			</li>
+			<#if  Session["current_authentication"].principal.roleAdministrators==true >
+            <li  id="nav_primay_16"    xpath="">
+                <!--管理-->
+                <a target="_blank"   href="<@base/>/authz/maxkey_mgt"><@locale code="global.text.manage"/></a>
+            </li>
+            </#if>
 		</ul>
 	</div>
 	</div>
-	</div>
 </div>
 <div class="container row">
-<div id="nav_second"  class ="col-sm-8" style="clear: left"><div class='menusecond '></div><br style='clear: left' /></div>
+    <div id="nav_second"  class ="col-sm-8" style="clear: left"></div>
 </div>
-<script>
-	$(function(){
-		function displaySecondNavs(menuId){
-			if($("#"+menuId+" .nav_second_child").html()){
-				$("#nav_second").html("<div class='menusecond'>"+$("#"+menuId+" .nav_second_child").html()+"</div><br style='clear: left' />");
-			}else{
-				$("#nav_second").html("");
-			}
-		}
-		
-		displaySecondNavs('${Request["mnid"]!"nav_primay_15"}');
-		$(".menuprimary ul li").mouseover(function(){
-			displaySecondNavs(this.id);
-		});
-		
-	});
-</script>

+ 8 - 9
maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/layout/top.ftl

@@ -36,21 +36,20 @@
     						<a href="<@base/>/appList?mnid=110101020000&gridList=0" ><img class="grid_list_sel"  src='<@base/>/static/images/grid_sel.png'></a>
     					</td>
     					</#if>
+    					<!--我的资料-->
+    					<td id="myprofile" nowrap>
+                            <a  href="<@base/>/profile/myProfile">
+                                <div   >&nbsp;&nbsp;<@locale code="navs.myprofile"/>&nbsp;&nbsp;</div>
+                            </a>
+                        </td>
     					<td id="changepassword" nowrap>
     						<a  href="<@base/>/safe/forward/changePasswod">
-    							<div  style="float:right;" >&nbsp;&nbsp;<@locale code="login.password.changepassword"/>&nbsp;&nbsp;</div>
+    							<div  >&nbsp;&nbsp;<@locale code="login.password.changepassword"/>&nbsp;&nbsp;</div>
     						</a>
     					</td>
-    					<#if  Session["current_authentication"].principal.roleAdministrators==true >
-    					<td id="manage" nowrap>
-    						<a target="_blank"  href="<@base/>/authz/maxkey_mgt">
-    							<div  style="float:right;" >&nbsp;&nbsp;<@locale code="global.text.manage"/>&nbsp;&nbsp;</div>
-    						</a>
-    					</td>
-    					</#if>
     					<td id="logout" class="ui-widget-header" >
     						<a  href="<@base/>/logout?reLoginUrl=login">
-    							<div  style="float:right;" >&nbsp;&nbsp;<@locale code="global.text.logout"/>&nbsp;&nbsp;</div>
+    							<div   >&nbsp;&nbsp;<@locale code="global.text.logout"/>&nbsp;&nbsp;</div>
     						</a>
     					</td>
     				</tr>

+ 14 - 9
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/MaxKeyMgtConfig.java

@@ -35,12 +35,15 @@ import org.maxkey.persistence.service.UserInfoService;
 import org.opensaml.xml.ConfigurationException;
 import org.quartz.CronScheduleBuilder;
 import org.quartz.CronTrigger;
+import org.quartz.Job;
 import org.quartz.JobBuilder;
 import org.quartz.JobDataMap;
 import org.quartz.JobDetail;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.TriggerBuilder;
+import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
+import org.apache.mybatis.jpa.persistence.JpaBaseService;
 import org.maxkey.authn.realm.jdbc.JdbcAuthenticationRealm;
 import org.maxkey.authn.support.rememberme.AbstractRemeberMeService;
 import org.slf4j.Logger;
@@ -146,29 +149,31 @@ public class MaxKeyMgtConfig  implements InitializingBean {
     public String  schedulerJobs(
             SchedulerFactoryBean schedulerFactoryBean,
             GroupsService groupsService,
-            @Value("${maxkey.job.cron.dynamicgroups}") String cronScheduleDynamicGroups
+            @Value("${maxkey.job.cron.dynamicgroups}") String cronSchedule
             ) throws SchedulerException {
        
         Scheduler scheduler = schedulerFactoryBean.getScheduler();
-        dynamicGroupsJob(scheduler,cronScheduleDynamicGroups,groupsService);
+        //dynamicGroupsJob("DynamicGroups",DynamicGroupsJob.class,scheduler,groupsService,cronSchedule);
         
         return "schedulerJobs";
     }
     
 	
-    private void dynamicGroupsJob(Scheduler scheduler ,
-                                  String cronSchedule,
-                                  GroupsService groupsService) throws SchedulerException {
+    public void dynamicGroupsJob(String jobName,
+                                  Class<Job> cls,
+                                  Scheduler scheduler,
+                                  JpaBaseService<JpaBaseEntity> service,
+                                  String cronSchedule) throws SchedulerException {
         JobDetail jobDetail = 
-                JobBuilder.newJob(DynamicGroupsJob.class) 
-                .withIdentity("DynamicGroupsJob", "DynamicGroups")
+                JobBuilder.newJob(cls) 
+                .withIdentity(jobName + "Job", jobName)
                 .build();
         JobDataMap jobDataMap = new JobDataMap();
-        jobDataMap.put("groupsService", groupsService);
+        jobDataMap.put("service", service);
         CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronSchedule);
         CronTrigger cronTrigger = 
                 TriggerBuilder.newTrigger()
-                .withIdentity("triggerDynamicGroups", "DynamicGroups")
+                .withIdentity("trigger" + jobName, jobName)
                 .usingJobData(jobDataMap)
                 .withSchedule(scheduleBuilder)
                 .build();

+ 73 - 0
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/jobs/AccountsStrategyJob.java

@@ -0,0 +1,73 @@
+/*
+ * Copyright [2021] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed 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.maxkey.jobs;
+
+import java.io.Serializable;
+import org.maxkey.persistence.service.AccountsService;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AccountsStrategyJob   implements Job , Serializable {
+
+   /**
+     * 
+     */
+    private static final long serialVersionUID = 167999890940939820L;
+
+    final static Logger _logger = LoggerFactory.getLogger(AccountsStrategyJob.class);
+    
+    private static  AccountsService accountsService = null;
+    
+    public static class JOBSTATUS{
+        public static int STOP = 0;
+        public static int RUNNING = 1;
+        public static int FINISHED = 2;
+    }
+    
+    private static int jobStatus = JOBSTATUS.STOP;
+
+    @Override
+    public void execute(JobExecutionContext context){
+        if(jobStatus == JOBSTATUS.RUNNING) {
+            _logger.info("DynamicGroupsJob is in running . " );
+            return;
+        }
+        
+        _logger.debug("DynamicGroupsJob is running ... " );
+        jobStatus = JOBSTATUS.RUNNING;
+        try {
+            if(accountsService == null) {
+                accountsService = (AccountsService) context.getMergedJobDataMap().get("accountsService");
+            }
+
+            accountsService.refreshAllByStrategy();
+            
+            Thread.sleep(10 *1000);
+            _logger.debug("DynamicGroupsJob is success  " );
+        }catch(Exception e) {
+            _logger.error("Exception " ,e);
+            jobStatus = JOBSTATUS.STOP;
+        }
+        jobStatus = JOBSTATUS.FINISHED;
+        _logger.debug("DynamicGroupsJob is finished . " );
+    }
+
+
+}

+ 3 - 9
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/jobs/DynamicGroupsJob.java

@@ -18,9 +18,6 @@
 package org.maxkey.jobs;
 
 import java.io.Serializable;
-import java.util.List;
-
-import org.maxkey.entity.Groups;
 import org.maxkey.persistence.service.GroupsService;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
@@ -56,14 +53,11 @@ public class DynamicGroupsJob  implements Job , Serializable {
         jobStatus = JOBSTATUS.RUNNING;
         try {
             if(groupsService == null) {
-                groupsService = (GroupsService) context.getMergedJobDataMap().get("groupsService");
+                groupsService = (GroupsService) context.getMergedJobDataMap().get("service");
             }
 
-            List<Groups>  groupsList = groupsService.queryDynamicGroups(null);
-            for(Groups group : groupsList) {
-                _logger.debug("group " + group);
-                groupsService.refreshDynamicGroups(group);
-            }
+            groupsService.refreshAllDynamicGroups();
+            
             Thread.sleep(10 *1000);
             _logger.debug("DynamicGroupsJob is success  " );
         }catch(Exception e) {

+ 4 - 4
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/ApplicationsController.java

@@ -56,13 +56,13 @@ public class ApplicationsController extends BaseAppContorller {
 	@RequestMapping(value = { "/grid" })
 	@ResponseBody
 	public JpaPageResults<Apps> queryDataGrid(@ModelAttribute("applications") Apps applications) {
-		JpaPageResults<Apps> jqGridApp=appsService.queryPageResults(applications);
-		if(jqGridApp!=null&&jqGridApp.getRows()!=null){
-			for (Apps app : jqGridApp.getRows()){
+		JpaPageResults<Apps> apps=appsService.queryPageResults(applications);
+		if(apps!=null&&apps.getRows()!=null){
+			for (Apps app : apps.getRows()){
 				WebContext.setAttribute(app.getId(), app.getIcon());
 			}
 		}
-		return jqGridApp;
+		return apps;
 	}
 	
 	@RequestMapping(value = { "/forwardAdd" })

+ 6 - 1
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/contorller/AccountsStrategyController.java

@@ -21,8 +21,8 @@ import org.apache.mybatis.jpa.persistence.JpaPageResults;
 import org.maxkey.constants.ConstantsOperateMessage;
 import org.maxkey.entity.AccountsStrategy;
 import org.maxkey.entity.Roles;
+import org.maxkey.persistence.service.AccountsService;
 import org.maxkey.persistence.service.AccountsStrategyService;
-import org.maxkey.persistence.service.RolesService;
 import org.maxkey.web.WebContext;
 import org.maxkey.web.message.Message;
 import org.maxkey.web.message.MessageType;
@@ -46,6 +46,9 @@ public class AccountsStrategyController {
 	@Autowired
 	@Qualifier("accountsStrategyService")
 	AccountsStrategyService accountsStrategyService;
+	
+	@Autowired
+	AccountsService accountsService;
 
 	
 	
@@ -82,6 +85,7 @@ public class AccountsStrategyController {
 		_logger.debug("-Add  :" + accountsStrategy);
 		
 		if (accountsStrategyService.insert(accountsStrategy)) {
+		    accountsService.refreshByStrategy(accountsStrategy);
 		    //rolesService.refreshDynamicRoles(role);
 			return  new Message(WebContext.getI18nValue(ConstantsOperateMessage.INSERT_SUCCESS),MessageType.success);
 			
@@ -121,6 +125,7 @@ public class AccountsStrategyController {
 		
 		if (accountsStrategyService.update(accountsStrategy)) {
 		   // rolesService.refreshDynamicRoles(role);
+		    accountsService.refreshByStrategy(accountsStrategy);
 			return  new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_SUCCESS),MessageType.success);
 			
 		} else {

+ 10 - 10
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/contorller/GroupPrivilegesController.java

@@ -56,16 +56,16 @@ public class GroupPrivilegesController {
 	@ResponseBody
 	public JpaPageResults<GroupPrivileges> queryAppsInGroup(@ModelAttribute("groupApp") GroupPrivileges groupApp) {
 		
-		JpaPageResults<GroupPrivileges> jqGridApp;
+		JpaPageResults<GroupPrivileges> groupPrivileges;
 		
-		jqGridApp= groupPrivilegesService.queryPageResults("appsInGroup",groupApp);
+		groupPrivileges= groupPrivilegesService.queryPageResults("appsInGroup",groupApp);
 
-		if(jqGridApp!=null&&jqGridApp.getRows()!=null){
-			for (Apps app : jqGridApp.getRows()){
+		if(groupPrivileges!=null&&groupPrivileges.getRows()!=null){
+			for (Apps app : groupPrivileges.getRows()){
 				WebContext.setAttribute(app.getId(), app.getIcon());
 			}
 		}
-		return jqGridApp;
+		return groupPrivileges;
 
 	}
 	
@@ -80,16 +80,16 @@ public class GroupPrivilegesController {
 	@RequestMapping(value = { "/queryAppsNotInGroup" })
 	@ResponseBody
 	public JpaPageResults<GroupPrivileges> queryAppsNotInGroup(@ModelAttribute("groupApp") GroupPrivileges groupApp) {
-		JpaPageResults<GroupPrivileges> jqGridApp;
+		JpaPageResults<GroupPrivileges> groupPrivileges;
 		
-		jqGridApp= groupPrivilegesService.queryPageResults("appsNotInGroup",groupApp);
+		groupPrivileges= groupPrivilegesService.queryPageResults("appsNotInGroup",groupApp);
 
-		if(jqGridApp!=null&&jqGridApp.getRows()!=null){
-			for (Apps app : jqGridApp.getRows()){
+		if(groupPrivileges!=null&&groupPrivileges.getRows()!=null){
+			for (Apps app : groupPrivileges.getRows()){
 				WebContext.setAttribute(app.getId(), app.getIcon());
 			}
 		}
-		return jqGridApp;
+		return groupPrivileges;
 
 	}
 

+ 3 - 3
maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message.properties

@@ -584,7 +584,7 @@ navs.users=\u7528\u6237\u7ba1\u7406
 navs.apps=\u5e94\u7528\u7ba1\u7406
 navs.accounts=\u8d26\u53f7\u7ba1\u7406
 navs.accounts.strategy=\u8D26\u53F7\u7B56\u7565
-navs.privileges=\u8BBF\u95EE\u63A7\u5236\u7BA1\u7406
+navs.privileges=\u8BBF\u95EE\u63A7\u5236
 navs.groups=\u7ec4\u7ba1\u7406
 navs.groups.member=\u6210\u5458\u7ba1\u7406
 navs.groups.privileges=\u8bbf\u95ee\u6743\u9650\u7ba1\u7406
@@ -599,9 +599,9 @@ navs.audit.synchronizer=\u540C\u6B65\u65E5\u5FD7
 navs.audit.connector=\u8FDE\u63A5\u65E5\u5FD7
 navs.roles=\u89d2\u8272\u7ba1\u7406
 navs.role.member=\u89d2\u8272\u7528\u6237
-navs.role.permissions=\u89d2\u8272\u6743\u9650\u7ba1\u7406
+navs.role.permissions=\u6743\u9650\u7ba1\u7406
 navs.resources=\u8d44\u6e90\u7ba1\u7406
 navs.adapters=\u9002\u914D\u5668\u6CE8\u518C
 navs.notices=\u901A\u77E5\u516C\u544A
-navs.socials.provider=\u793E\u4EA4\u63D0\u4F9B\u5546
+navs.socials.provider=\u793E\u4EA4\u670D\u52A1
 navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406

+ 1 - 1
maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_en.properties

@@ -597,7 +597,7 @@ navs.accounts.strategy=AccountsStrategy
 navs.privileges=Access Control
 navs.groups=Groups
 navs.groups.member=Groups Member
-navs.groups.privileges=Access Privileges
+navs.groups.privileges=Access
 navs.conf=Conf
 navs.conf.passwordpolicy=PasswordPolicy
 navs.audit=Audit

+ 3 - 3
maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_zh_CN.properties

@@ -589,7 +589,7 @@ navs.users=\u7528\u6237\u7ba1\u7406
 navs.apps=\u5e94\u7528\u7ba1\u7406
 navs.accounts=\u8d26\u53f7\u7ba1\u7406
 navs.accounts.strategy=\u8D26\u53F7\u7B56\u7565
-navs.privileges=\u8BBF\u95EE\u63A7\u5236\u7BA1\u7406
+navs.privileges=\u8BBF\u95EE\u63A7\u5236
 navs.groups=\u7ec4\u7ba1\u7406
 navs.groups.member=\u6210\u5458\u7ba1\u7406
 navs.groups.privileges=\u8bbf\u95ee\u6743\u9650\u7ba1\u7406
@@ -604,9 +604,9 @@ navs.audit.synchronizer=\u540C\u6B65\u65E5\u5FD7
 navs.audit.connector=\u8FDE\u63A5\u65E5\u5FD7
 navs.roles=\u89d2\u8272\u7ba1\u7406
 navs.role.member=\u89d2\u8272\u7528\u6237
-navs.role.permissions=\u89d2\u8272\u6743\u9650\u7ba1\u7406
+navs.role.permissions=\u6743\u9650\u7ba1\u7406
 navs.resources=\u8d44\u6e90\u7ba1\u7406
 navs.adapters=\u9002\u914D\u5668\u6CE8\u518C
 navs.notices=\u901A\u77E5\u516C\u544A
-navs.socials.provider=\u793E\u4EA4\u63D0\u4F9B\u5546
+navs.socials.provider=\u793E\u4EA4\u670D\u52A1
 navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406

+ 14 - 20
maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/layout/sidenav.ftl

@@ -27,14 +27,25 @@
        		<span class="fa fa-fw fa-vcard  fa-lg"></span>
      	</a>
    	</li>  	
-   	
+   	<li>
+        <a class="side-nav-menu" href="<@base />/apps/list/">
+            <@locale code="navs.apps"/>
+            <span class="fa fa-fw fa-globe fa-lg"></span>
+        </a>
+    </li>
    	<li>
      	<a class="side-nav-menu has-arrow" href="#">
        		<@locale code="navs.privileges"/>
        		<span class="fa fa-fw fa-cubes fa-lg"></span>
      	</a>
      	<ul>
-     		<li>
+     	   <li>
+             <a class="side-nav-menu" href="<@base/>/session/sessionList/">
+                <@locale code="navs.audit.loginsession"/>
+                <span class="fa fa-fw fa-eye"></span>
+             </a>
+           </li>
+     	   <li>
 	         <a class="side-nav-menu" href="<@base />/groups/list/">
 	         	<@locale code="navs.groups"/>	
 	         	<span class="fa fa-fw fa-address-book"></span>
@@ -94,12 +105,6 @@
      	</a>
      	<ul>
             <li>
-                <a class="side-nav-menu" href="<@base />/apps/list/">
-                    <@locale code="navs.apps"/>
-                    <span class="fa fa-fw fa-globe fa-lg"></span>
-                </a>
-            </li>
-            <li>
                 <a class="side-nav-menu" href="<@base />/accountsstrategy/list/">
                     <@locale code="navs.accounts.strategy"/>
                     <span class="fa fa-fw fa-superpowers fa-lg"></span>
@@ -144,12 +149,7 @@
        		<span class="fa fa-fw fa-eye fa-lg"></span>
      	</a> 
      	<ul>
-     		<li>
-	         <a class="side-nav-menu" href="<@base/>/session/sessionList/">
-	         	<@locale code="navs.audit.loginsession"/>
-	         	<span class="fa fa-fw fa-eye"></span>
-	         </a>
-	       </li>
+     		
 	       <li>
 	         <a class="side-nav-menu" href="<@base />/historys/loginHistoryList/">
 	         	<@locale code="navs.audit.login"/>
@@ -184,11 +184,5 @@
    	</li>
    	
  </ul>
-
-<script type="text/javascript"> 
-$(function(){
-	$('#side-nav-menu').metisMenu();
-});
-</script>
 </div>
 <!--side navigation end-->

+ 11 - 5
maxkey-webs/maxkey-web-resources/src/main/resources/static/css/base.css

@@ -51,10 +51,15 @@ body{
 #nav_second{
 	height:35px;
 }
+
 #nav_third{
 	/*border-top: 1px solid #e5e5e5;*/
 }
 
+#topBar{
+    min-height: 65px;
+}
+
 #topBar .grid_list_sel{
     width: 31px;
     height: 31px;
@@ -138,14 +143,14 @@ body{
 }
 
 #logout{
-	width: 45px;
+	width: 75px;
   	background: #c00 ;
   	color: #fff;
   	font-weight: bold;	
 }
 
-#manage{
-	width: 50px;
+#myprofile{
+	width: 75px;
 	background-color: #2AA9A9;
 	font-weight: bold;	
 }
@@ -156,8 +161,9 @@ body{
 	font-weight: bold;	
 }
 
-#manage a,#logout a,#changepassword a{
-	  color: #fff;
+#myprofile a,#logout a,#changepassword a{
+	color: #fff;
+	text-decoration: none;
 }
 
 .form_radio_label, .form_checkbox_label{

+ 136 - 274
maxkey-webs/maxkey-web-resources/src/main/resources/static/css/menu.css

@@ -1,279 +1,141 @@
 #nav_primary{
     background: #414141;
 }
-.menuprimary {
-	font: bold 12px Verdana;
-	margin: auto;
-	height: 41px;
-}
-
-.menucontainer {
-	float: left;
-	margin-top: -2px;
-}
-
-.menuprimary ul {
-	z-index: 100;
-	margin: 0;
-	padding: 0;
-	list-style-type: none;
-}
-
-/*Top level list items*/
-.menuprimary ul li {
-	position: relative;
-	display: inline;
-	float: left;
-}
-
-.menuprimary ul .primaryleft {
-	border-left: 1px solid white;
-}
-
-/*Top level menu link items style*/
-.menuprimary ul li a {
-	display: block;
-	background: #414141; /*background of menu items (default state)*/
-	color: white;
-	padding: 10px 20px;
-	border-right: 1px solid white;
-	color: #2d2b2b;
-	text-decoration: none;
-	height: 40px;
-	font-size: 13px;
-}
-
-* html .menuprimary ul li a {
-	/*IE6 hack to get sub menu links to behave correctly*/
-	display: inline-block;
-}
-
-.menuprimary ul li a:link,.menuprimary ul li a:visited {
-	color: white;
-}
-
-.menuprimary ul li a.selected {
-	/*CSS class that's dynamically added to the currently active menu items' LI A element*/
-	background: #0769AD !important;
-	color: white;
-}
-
-.menuprimary ul li a:hover {
-	background: #0769AD;
-	/*background of menu items during onmouseover (hover state)*/
-	color: white;
-}
-
-/* sub menus */
-.menuprimary ul li ul {
-	position: absolute;
-	left: -3000px;
-	display: none; /*collapse all sub menus to begin with*/
-	visibility: hidden;
-}
-
-/*Sub level menu list items (alters style from Top level List Items)*/
-.menuprimary ul li ul li {
-	display: list-item;
-	float: none;
-}
-
-/*All subsequent sub menu levels vertical offset after 1st level sub menu */
-.menuprimary ul li ul li ul {
-	top: 0;
-}
-
-/* Sub level menu links style */
-.menuprimary ul li ul li a {
-	font: normal 13px Verdana;
-	width: 160px; /*width of sub menus*/
-	padding: 5px;
-	margin: 0;
-	border-top-width: 0;
-	border-bottom: 1px solid gray;
-	height: 90%;
-}
-
-/* Holly Hack for IE \*/
-* html .menuprimary {
-	height: 1%;
-} /*Holly Hack for IE7 and below*/
-
-/* ######### CSS classes applied to down and right arrow images  ######### */
-.downarrowclass {
-	position: absolute;
-	top: 12px;
-	right: 7px;
-}
-
-.rightarrowclass {
-	position: absolute;
-	top: 6px;
-	right: 5px;
-}
-
-/* ######### CSS for shadow added to sub menus  ######### */
-.ddshadow {
-	position: absolute;
-	left: 0;
-	top: 0;
-	width: 0;
-	height: 0;
-	background-color: #ccc;
-	/* generally should be just a little lighter than the box-shadow color for CSS3 capable browsers */
-}
-
-.toplevelshadow {
-	margin: 5px 0 0 5px;
-	/* in NON CSS3 capable browsers gives the offset of the shadow */
-	opacity: 0.8;
-	/* shadow opacity mostly for NON CSS3 capable browsers. Doesn't work in IE */
-}
-
-.ddcss3support .ddshadow.toplevelshadow {
-	margin: 0;
-	/* in CSS3 capable browsers overrides offset from NON CSS3 capable browsers, allowing the box-shadow values in the next selector to govern that */
-	/* opacity: 1; */
-	/* optionally uncomment this to remove partial opacity for browsers supporting a box-shadow property which has its own slight gradient opacity */
-}
-
-.ddcss3support .ddshadow {
-	background-color: transparent;
-	box-shadow: 5px 5px 5px #aaa;
-	/* box-shadow color generally should be a little darker than that for the NON CSS3 capable browsers background-color */
-	-moz-box-shadow: 5px 5px 5px #aaa;
-	-webkit-box-shadow: 5px 5px 5px #aaa;
-}
-
-/************************************************************************************************************/
-.menusecond {
-	font: bold 12px Verdana;
-	background: white; /*background of menu bar (default state)*/
-	margin: auto;
-}
-
-.menusecond ul {
-	z-index: 100;
-	margin: 0;
-	padding: 0;
-	list-style-type: none;
-}
-
-/*Top level list items*/
-.menusecond ul li {
-	position: relative;
-	display: inline;
-	float: left;
-}
-
-/*Top level menu link items style*/
-.menusecond ul li a {
-	display: block;
-	background: white; /*background of menu items (default state)*/
-	color: #414141;
-	padding: 8px 10px;
-	border-right: 1px solid #778;
-	color: #2d2b2b;
-	text-decoration: none;
-}
-
-* html .menusecond ul li a {
-	/*IE6 hack to get sub menu links to behave correctly*/
-	display: inline-block;
-}
-
-.menusecond ul li a:link,.menusecond ul li a:visited {
-	color: #414141;
-}
-
-.menusecond ul li a.selected {
-	/*CSS class that's dynamically added to the currently active menu items' LI A element*/
-	background: #F0F0F0 !important;
-	color: #414141;
-}
-
-.menusecond ul li a:hover {
-	background: #F0F0F0;
-	/*background of menu items during onmouseover (hover state)*/
-	color: #414141;
-}
-
-/* sub menus */
-.menusecond ul li ul {
-	position: absolute;
-	left: -3000px;
-	display: none; /*collapse all sub menus to begin with*/
-	visibility: hidden;
-}
-
-/*Sub level menu list items (alters style from Top level List Items)*/
-.menusecond ul li ul li {
-	display: list-item;
-	float: none;
-}
-
-/*All subsequent sub menu levels vertical offset after 1st level sub menu */
-.menusecond ul li ul li ul {
-	top: 0;
-}
-
-/* Sub level menu links style */
-.menusecond ul li ul li a {
-	font: normal 13px Verdana;
-	width: 160px; /*width of sub menus*/
-	padding: 5px;
-	margin: 0;
-	border-top-width: 0;
-	border-bottom: 1px solid gray;
-}
-
-/* Holly Hack for IE \*/
-* html .menusecond {
-	height: 1%;
-} /*Holly Hack for IE7 and below*/
-
-/* ######### CSS classes applied to down and right arrow images  ######### */
-.downarrowclass {
-	position: absolute;
-	top: 12px;
-	right: 7px;
-}
-
-.rightarrowclass {
-	position: absolute;
-	top: 6px;
-	right: 5px;
-}
-
-/* ######### CSS for shadow added to sub menus  ######### */
-.ddshadow {
-	position: absolute;
-	left: 0;
-	top: 0;
-	width: 0;
-	height: 0;
-	background-color: #ccc;
-	/* generally should be just a little lighter than the box-shadow color for CSS3 capable browsers */
-}
-
-.toplevelshadow {
-	margin: 5px 0 0 5px;
-	/* in NON CSS3 capable browsers gives the offset of the shadow */
-	opacity: 0.8;
-	/* shadow opacity mostly for NON CSS3 capable browsers. Doesn't work in IE */
-}
-
-.ddcss3support .ddshadow.toplevelshadow {
-	margin: 0;
-	/* in CSS3 capable browsers overrides offset from NON CSS3 capable browsers, allowing the box-shadow values in the next selector to govern that */
-	/* opacity: 1; */
-	/* optionally uncomment this to remove partial opacity for browsers supporting a box-shadow property which has its own slight gradient opacity */
-}
 
-.ddcss3support .ddshadow {
-	background-color: transparent;
-	box-shadow: 5px 5px 5px #aaa;
-	/* box-shadow color generally should be a little darker than that for the NON CSS3 capable browsers background-color */
-	-moz-box-shadow: 5px 5px 5px #aaa;
-	-webkit-box-shadow: 5px 5px 5px #aaa;
+/*navMenu menu dropdown*/
+ul.navMenu {
+  display: flex;
+  position: relative;
+  flex-direction: row;
+  align-items: center;
+  /*max-width: 70%;*/
+  margin: 0 auto;
+  padding: 0;
+  list-style: none;
+  background: #414141;
+  border-top-left-radius: 6px;
+  border-top-right-radius: 6px;
+}
+ul.navMenu > li {
+  position: relative;
+  flex-grow: 1;
+  flex-shrink: 0;
+  height: 45px;
+  font-size: 14px;
+  text-align: center;
+  text-transform: uppercase;
+  line-height: 45px;
+  letter-spacing: 1px;
+  color: #e7e6f1;
+  cursor: pointer;
+  border-right: 1px solid white;
+}
+ul.navMenu > li:hover {
+  background: #0769AD;
+}
+ul.navMenu > li:hover ul.dropdown {
+  visibility: visible;
+  transform: translate(0, 0);
+  opacity: 1;
+  z-index: 0;
+}
+ul.navMenu > li:hover ul.dropdown > li {
+  -webkit-animation-name: slideInLeft;
+          animation-name: slideInLeft;
+  -webkit-animation-duration: 0.3s;
+          animation-duration: 0.3s;
+  -webkit-animation-timing-function: ease-in-out;
+          animation-timing-function: ease-in-out;
+  -webkit-animation-fill-mode: backwards;
+          animation-fill-mode: backwards;
+}
+ul.navMenu > li:first-child {
+  /*border-top-left-radius: 6px;*/
+  border-left: 1px solid white;
+}
+ul.navMenu > li:last-child {
+  /*border-top-right-radius: 6px;*/
+  border-right: 1px solid white;
+}
+
+ul.navMenu > li a {
+    display: block;
+    color: white;
+    text-decoration: none;
+    height: 40px;
+    font-size: 13px;
+    font-weight: bold;
+}
+
+ul.navMenu > li a {
+    /*IE6 hack to get sub menu links to behave correctly*/
+    display: inline-block;
+}
+
+ul.navMenu > li a:link,ul.navMenu > li a:visited {
+    color: white;
+}
+
+ul.navMenu > li a.selected {
+    /*CSS class that's dynamically added to the currently active menu items' LI A element*/
+    color: white;
+}
+
+ul.navMenu > li a:hover {
+    /*background of menu items during onmouseover (hover state)*/
+    color: white;
+}
+
+ul.navMenu > li ul.dropdown {
+  visibility: hidden;
+  display: flex;
+  position: absolute;
+  top: 100%;
+  left: 0;
+  right: 0;
+  flex-direction: column;
+  margin: 0;
+  padding: 5px 0 0px;
+  list-style: none;
+  color: #333;
+  background: #414141;
+  /*
+  border-bottom-left-radius: 6px;
+  border-bottom-right-radius: 6px;
+  */
+  box-shadow: 1px 2px 5px -1px rgba(0, 0, 0, 0.15), 0px 4px 14px -1px rgba(0, 0, 0, 0.1);
+  transform: translate(0, -60px);
+  transition: transform 0.2s ease-out, opacity 0.2s, z-index 0s 0.2s;
+  opacity: 0;
+  z-index: -1;
+}
+ul.navMenu > li ul.dropdown > li {
+  font-size: 14px;
+  cursor: pointer;
+  border-top: 1px solid white;
+}
+ul.navMenu > li ul.dropdown > li:hover {
+  background: #0769AD;
+}
+
+@-webkit-keyframes slideInLeft {
+  from {
+    transform: translate(-25%, 0);
+    opacity: 0;
+  }
+  to {
+    transform: translate(0, 0);
+    opacity: 1;
+  }
+}
+
+@keyframes slideInLeft {
+  from {
+    transform: translate(-25%, 0);
+    opacity: 0;
+  }
+  to {
+    transform: translate(0, 0);
+    opacity: 1;
+  }
 }

+ 136 - 274
maxkey-webs/maxkey-web-resources/src/main/resources/static/css/menu_default.css

@@ -1,279 +1,141 @@
 #nav_primary{
     background: #414141;
 }
-.menuprimary {
-	font: bold 12px Verdana;
-	margin: auto;
-	height: 41px;
-}
-
-.menucontainer {
-	float: left;
-	margin-top: -2px;
-}
-
-.menuprimary ul {
-	z-index: 100;
-	margin: 0;
-	padding: 0;
-	list-style-type: none;
-}
-
-/*Top level list items*/
-.menuprimary ul li {
-	position: relative;
-	display: inline;
-	float: left;
-}
-
-.menuprimary ul .primaryleft {
-	border-left: 1px solid white;
-}
-
-/*Top level menu link items style*/
-.menuprimary ul li a {
-	display: block;
-	background: #414141; /*background of menu items (default state)*/
-	color: white;
-	padding: 10px 20px;
-	border-right: 1px solid white;
-	color: #2d2b2b;
-	text-decoration: none;
-	height: 40px;
-	font-size: 13px;
-}
-
-* html .menuprimary ul li a {
-	/*IE6 hack to get sub menu links to behave correctly*/
-	display: inline-block;
-}
-
-.menuprimary ul li a:link,.menuprimary ul li a:visited {
-	color: white;
-}
-
-.menuprimary ul li a.selected {
-	/*CSS class that's dynamically added to the currently active menu items' LI A element*/
-	background: #0769AD !important;
-	color: white;
-}
-
-.menuprimary ul li a:hover {
-	background: #0769AD;
-	/*background of menu items during onmouseover (hover state)*/
-	color: white;
-}
-
-/* sub menus */
-.menuprimary ul li ul {
-	position: absolute;
-	left: -3000px;
-	display: none; /*collapse all sub menus to begin with*/
-	visibility: hidden;
-}
-
-/*Sub level menu list items (alters style from Top level List Items)*/
-.menuprimary ul li ul li {
-	display: list-item;
-	float: none;
-}
-
-/*All subsequent sub menu levels vertical offset after 1st level sub menu */
-.menuprimary ul li ul li ul {
-	top: 0;
-}
-
-/* Sub level menu links style */
-.menuprimary ul li ul li a {
-	font: normal 13px Verdana;
-	width: 160px; /*width of sub menus*/
-	padding: 5px;
-	margin: 0;
-	border-top-width: 0;
-	border-bottom: 1px solid gray;
-	height: 90%;
-}
-
-/* Holly Hack for IE \*/
-* html .menuprimary {
-	height: 1%;
-} /*Holly Hack for IE7 and below*/
-
-/* ######### CSS classes applied to down and right arrow images  ######### */
-.downarrowclass {
-	position: absolute;
-	top: 12px;
-	right: 7px;
-}
-
-.rightarrowclass {
-	position: absolute;
-	top: 6px;
-	right: 5px;
-}
-
-/* ######### CSS for shadow added to sub menus  ######### */
-.ddshadow {
-	position: absolute;
-	left: 0;
-	top: 0;
-	width: 0;
-	height: 0;
-	background-color: #ccc;
-	/* generally should be just a little lighter than the box-shadow color for CSS3 capable browsers */
-}
-
-.toplevelshadow {
-	margin: 5px 0 0 5px;
-	/* in NON CSS3 capable browsers gives the offset of the shadow */
-	opacity: 0.8;
-	/* shadow opacity mostly for NON CSS3 capable browsers. Doesn't work in IE */
-}
-
-.ddcss3support .ddshadow.toplevelshadow {
-	margin: 0;
-	/* in CSS3 capable browsers overrides offset from NON CSS3 capable browsers, allowing the box-shadow values in the next selector to govern that */
-	/* opacity: 1; */
-	/* optionally uncomment this to remove partial opacity for browsers supporting a box-shadow property which has its own slight gradient opacity */
-}
-
-.ddcss3support .ddshadow {
-	background-color: transparent;
-	box-shadow: 5px 5px 5px #aaa;
-	/* box-shadow color generally should be a little darker than that for the NON CSS3 capable browsers background-color */
-	-moz-box-shadow: 5px 5px 5px #aaa;
-	-webkit-box-shadow: 5px 5px 5px #aaa;
-}
-
-/************************************************************************************************************/
-.menusecond {
-	font: bold 12px Verdana;
-	background: white; /*background of menu bar (default state)*/
-	margin: auto;
-}
-
-.menusecond ul {
-	z-index: 100;
-	margin: 0;
-	padding: 0;
-	list-style-type: none;
-}
-
-/*Top level list items*/
-.menusecond ul li {
-	position: relative;
-	display: inline;
-	float: left;
-}
-
-/*Top level menu link items style*/
-.menusecond ul li a {
-	display: block;
-	background: white; /*background of menu items (default state)*/
-	color: #414141;
-	padding: 8px 10px;
-	border-right: 1px solid #778;
-	color: #2d2b2b;
-	text-decoration: none;
-}
-
-* html .menusecond ul li a {
-	/*IE6 hack to get sub menu links to behave correctly*/
-	display: inline-block;
-}
-
-.menusecond ul li a:link,.menusecond ul li a:visited {
-	color: #414141;
-}
-
-.menusecond ul li a.selected {
-	/*CSS class that's dynamically added to the currently active menu items' LI A element*/
-	background: #F0F0F0 !important;
-	color: #414141;
-}
-
-.menusecond ul li a:hover {
-	background: #F0F0F0;
-	/*background of menu items during onmouseover (hover state)*/
-	color: #414141;
-}
-
-/* sub menus */
-.menusecond ul li ul {
-	position: absolute;
-	left: -3000px;
-	display: none; /*collapse all sub menus to begin with*/
-	visibility: hidden;
-}
-
-/*Sub level menu list items (alters style from Top level List Items)*/
-.menusecond ul li ul li {
-	display: list-item;
-	float: none;
-}
-
-/*All subsequent sub menu levels vertical offset after 1st level sub menu */
-.menusecond ul li ul li ul {
-	top: 0;
-}
-
-/* Sub level menu links style */
-.menusecond ul li ul li a {
-	font: normal 13px Verdana;
-	width: 160px; /*width of sub menus*/
-	padding: 5px;
-	margin: 0;
-	border-top-width: 0;
-	border-bottom: 1px solid gray;
-}
-
-/* Holly Hack for IE \*/
-* html .menusecond {
-	height: 1%;
-} /*Holly Hack for IE7 and below*/
-
-/* ######### CSS classes applied to down and right arrow images  ######### */
-.downarrowclass {
-	position: absolute;
-	top: 12px;
-	right: 7px;
-}
-
-.rightarrowclass {
-	position: absolute;
-	top: 6px;
-	right: 5px;
-}
-
-/* ######### CSS for shadow added to sub menus  ######### */
-.ddshadow {
-	position: absolute;
-	left: 0;
-	top: 0;
-	width: 0;
-	height: 0;
-	background-color: #ccc;
-	/* generally should be just a little lighter than the box-shadow color for CSS3 capable browsers */
-}
-
-.toplevelshadow {
-	margin: 5px 0 0 5px;
-	/* in NON CSS3 capable browsers gives the offset of the shadow */
-	opacity: 0.8;
-	/* shadow opacity mostly for NON CSS3 capable browsers. Doesn't work in IE */
-}
-
-.ddcss3support .ddshadow.toplevelshadow {
-	margin: 0;
-	/* in CSS3 capable browsers overrides offset from NON CSS3 capable browsers, allowing the box-shadow values in the next selector to govern that */
-	/* opacity: 1; */
-	/* optionally uncomment this to remove partial opacity for browsers supporting a box-shadow property which has its own slight gradient opacity */
-}
 
-.ddcss3support .ddshadow {
-	background-color: transparent;
-	box-shadow: 5px 5px 5px #aaa;
-	/* box-shadow color generally should be a little darker than that for the NON CSS3 capable browsers background-color */
-	-moz-box-shadow: 5px 5px 5px #aaa;
-	-webkit-box-shadow: 5px 5px 5px #aaa;
+/*navMenu menu dropdown*/
+ul.navMenu {
+  display: flex;
+  position: relative;
+  flex-direction: row;
+  align-items: center;
+  /*max-width: 70%;*/
+  margin: 0 auto;
+  padding: 0;
+  list-style: none;
+  background: #414141;
+  border-top-left-radius: 6px;
+  border-top-right-radius: 6px;
+}
+ul.navMenu > li {
+  position: relative;
+  flex-grow: 1;
+  flex-shrink: 0;
+  height: 45px;
+  font-size: 14px;
+  text-align: center;
+  text-transform: uppercase;
+  line-height: 45px;
+  letter-spacing: 1px;
+  color: #e7e6f1;
+  cursor: pointer;
+  border-right: 1px solid white;
+}
+ul.navMenu > li:hover {
+  background: #0769AD;
+}
+ul.navMenu > li:hover ul.dropdown {
+  visibility: visible;
+  transform: translate(0, 0);
+  opacity: 1;
+  z-index: 0;
+}
+ul.navMenu > li:hover ul.dropdown > li {
+  -webkit-animation-name: slideInLeft;
+          animation-name: slideInLeft;
+  -webkit-animation-duration: 0.3s;
+          animation-duration: 0.3s;
+  -webkit-animation-timing-function: ease-in-out;
+          animation-timing-function: ease-in-out;
+  -webkit-animation-fill-mode: backwards;
+          animation-fill-mode: backwards;
+}
+ul.navMenu > li:first-child {
+  /*border-top-left-radius: 6px;*/
+  border-left: 1px solid white;
+}
+ul.navMenu > li:last-child {
+  /*border-top-right-radius: 6px;*/
+  border-right: 1px solid white;
+}
+
+ul.navMenu > li a {
+    display: block;
+    color: white;
+    text-decoration: none;
+    height: 40px;
+    font-size: 13px;
+    font-weight: bold;
+}
+
+ul.navMenu > li a {
+    /*IE6 hack to get sub menu links to behave correctly*/
+    display: inline-block;
+}
+
+ul.navMenu > li a:link,ul.navMenu > li a:visited {
+    color: white;
+}
+
+ul.navMenu > li a.selected {
+    /*CSS class that's dynamically added to the currently active menu items' LI A element*/
+    color: white;
+}
+
+ul.navMenu > li a:hover {
+    /*background of menu items during onmouseover (hover state)*/
+    color: white;
+}
+
+ul.navMenu > li ul.dropdown {
+  visibility: hidden;
+  display: flex;
+  position: absolute;
+  top: 100%;
+  left: 0;
+  right: 0;
+  flex-direction: column;
+  margin: 0;
+  padding: 5px 0 0px;
+  list-style: none;
+  color: #333;
+  background: #414141;
+  /*
+  border-bottom-left-radius: 6px;
+  border-bottom-right-radius: 6px;
+  */
+  box-shadow: 1px 2px 5px -1px rgba(0, 0, 0, 0.15), 0px 4px 14px -1px rgba(0, 0, 0, 0.1);
+  transform: translate(0, -60px);
+  transition: transform 0.2s ease-out, opacity 0.2s, z-index 0s 0.2s;
+  opacity: 0;
+  z-index: -1;
+}
+ul.navMenu > li ul.dropdown > li {
+  font-size: 14px;
+  cursor: pointer;
+  border-top: 1px solid white;
+}
+ul.navMenu > li ul.dropdown > li:hover {
+  background: #0769AD;
+}
+
+@-webkit-keyframes slideInLeft {
+  from {
+    transform: translate(-25%, 0);
+    opacity: 0;
+  }
+  to {
+    transform: translate(0, 0);
+    opacity: 1;
+  }
+}
+
+@keyframes slideInLeft {
+  from {
+    transform: translate(-25%, 0);
+    opacity: 0;
+  }
+  to {
+    transform: translate(0, 0);
+    opacity: 1;
+  }
 }

+ 138 - 274
maxkey-webs/maxkey-web-resources/src/main/resources/static/css/menu_minty.css

@@ -1,279 +1,143 @@
+
+/**/
 #nav_primary{
     background: #31402a;
 }
-.menuprimary {
-	font: bold 12px Verdana;
-	margin: auto;
-	height: 41px;
-}
-
-.menucontainer {
-	float: left;
-	margin-top: -2px;
-}
-
-.menuprimary ul {
-	z-index: 100;
-	margin: 0;
-	padding: 0;
-	list-style-type: none;
-}
-
-/*Top level list items*/
-.menuprimary ul li {
-	position: relative;
-	display: inline;
-	float: left;
-}
-
-.menuprimary ul .primaryleft {
-	border-left: 1px solid white;
-}
-
-/*Top level menu link items style*/
-.menuprimary ul li a {
-	display: block;
-	background: #31402a; /*background of menu items (default state)*/
-	color: white;
-	padding: 10px 20px;
-	border-right: 1px solid white;
-	color: #2d2b2b;
-	text-decoration: none;
-	height: 40px;
-	font-size: 13px;
-}
-
-* html .menuprimary ul li a {
-	/*IE6 hack to get sub menu links to behave correctly*/
-	display: inline-block;
-}
-
-.menuprimary ul li a:link,.menuprimary ul li a:visited {
-	color: white;
-}
-
-.menuprimary ul li a.selected {
-	/*CSS class that's dynamically added to the currently active menu items' LI A element*/
-	background: #ef8200 !important;
-	color: white;
-}
-
-.menuprimary ul li a:hover {
-	background: #ef8200;
-	/*background of menu items during onmouseover (hover state)*/
-	color: white;
-}
-
-/* sub menus */
-.menuprimary ul li ul {
-	position: absolute;
-	left: -3000px;
-	display: none; /*collapse all sub menus to begin with*/
-	visibility: hidden;
-}
-
-/*Sub level menu list items (alters style from Top level List Items)*/
-.menuprimary ul li ul li {
-	display: list-item;
-	float: none;
-}
-
-/*All subsequent sub menu levels vertical offset after 1st level sub menu */
-.menuprimary ul li ul li ul {
-	top: 0;
-}
-
-/* Sub level menu links style */
-.menuprimary ul li ul li a {
-	font: normal 13px Verdana;
-	width: 160px; /*width of sub menus*/
-	padding: 5px;
-	margin: 0;
-	border-top-width: 0;
-	border-bottom: 1px solid gray;
-	height: 90%;
-}
-
-/* Holly Hack for IE \*/
-* html .menuprimary {
-	height: 1%;
-} /*Holly Hack for IE7 and below*/
-
-/* ######### CSS classes applied to down and right arrow images  ######### */
-.downarrowclass {
-	position: absolute;
-	top: 12px;
-	right: 7px;
-}
-
-.rightarrowclass {
-	position: absolute;
-	top: 6px;
-	right: 5px;
-}
-
-/* ######### CSS for shadow added to sub menus  ######### */
-.ddshadow {
-	position: absolute;
-	left: 0;
-	top: 0;
-	width: 0;
-	height: 0;
-	background-color: #ccc;
-	/* generally should be just a little lighter than the box-shadow color for CSS3 capable browsers */
-}
-
-.toplevelshadow {
-	margin: 5px 0 0 5px;
-	/* in NON CSS3 capable browsers gives the offset of the shadow */
-	opacity: 0.8;
-	/* shadow opacity mostly for NON CSS3 capable browsers. Doesn't work in IE */
-}
-
-.ddcss3support .ddshadow.toplevelshadow {
-	margin: 0;
-	/* in CSS3 capable browsers overrides offset from NON CSS3 capable browsers, allowing the box-shadow values in the next selector to govern that */
-	/* opacity: 1; */
-	/* optionally uncomment this to remove partial opacity for browsers supporting a box-shadow property which has its own slight gradient opacity */
-}
-
-.ddcss3support .ddshadow {
-	background-color: transparent;
-	box-shadow: 5px 5px 5px #aaa;
-	/* box-shadow color generally should be a little darker than that for the NON CSS3 capable browsers background-color */
-	-moz-box-shadow: 5px 5px 5px #aaa;
-	-webkit-box-shadow: 5px 5px 5px #aaa;
-}
-
-/************************************************************************************************************/
-.menusecond {
-	font: bold 12px Verdana;
-	background: white; /*background of menu bar (default state)*/
-	margin: auto;
-}
-
-.menusecond ul {
-	z-index: 100;
-	margin: 0;
-	padding: 0;
-	list-style-type: none;
-}
-
-/*Top level list items*/
-.menusecond ul li {
-	position: relative;
-	display: inline;
-	float: left;
-}
-
-/*Top level menu link items style*/
-.menusecond ul li a {
-	display: block;
-	background: white; /*background of menu items (default state)*/
-	color: #31402a;
-	padding: 8px 10px;
-	border-right: 1px solid #778;
-	color: #2d2b2b;
-	text-decoration: none;
-}
-
-* html .menusecond ul li a {
-	/*IE6 hack to get sub menu links to behave correctly*/
-	display: inline-block;
-}
-
-.menusecond ul li a:link,.menusecond ul li a:visited {
-	color: #31402a;
-}
-
-.menusecond ul li a.selected {
-	/*CSS class that's dynamically added to the currently active menu items' LI A element*/
-	background: #F0F0F0 !important;
-	color: #31402a;
-}
-
-.menusecond ul li a:hover {
-	background: #F0F0F0;
-	/*background of menu items during onmouseover (hover state)*/
-	color: #31402a;
-}
-
-/* sub menus */
-.menusecond ul li ul {
-	position: absolute;
-	left: -3000px;
-	display: none; /*collapse all sub menus to begin with*/
-	visibility: hidden;
-}
-
-/*Sub level menu list items (alters style from Top level List Items)*/
-.menusecond ul li ul li {
-	display: list-item;
-	float: none;
-}
-
-/*All subsequent sub menu levels vertical offset after 1st level sub menu */
-.menusecond ul li ul li ul {
-	top: 0;
-}
-
-/* Sub level menu links style */
-.menusecond ul li ul li a {
-	font: normal 13px Verdana;
-	width: 160px; /*width of sub menus*/
-	padding: 5px;
-	margin: 0;
-	border-top-width: 0;
-	border-bottom: 1px solid gray;
-}
-
-/* Holly Hack for IE \*/
-* html .menusecond {
-	height: 1%;
-} /*Holly Hack for IE7 and below*/
-
-/* ######### CSS classes applied to down and right arrow images  ######### */
-.downarrowclass {
-	position: absolute;
-	top: 12px;
-	right: 7px;
-}
-
-.rightarrowclass {
-	position: absolute;
-	top: 6px;
-	right: 5px;
-}
-
-/* ######### CSS for shadow added to sub menus  ######### */
-.ddshadow {
-	position: absolute;
-	left: 0;
-	top: 0;
-	width: 0;
-	height: 0;
-	background-color: #ccc;
-	/* generally should be just a little lighter than the box-shadow color for CSS3 capable browsers */
-}
-
-.toplevelshadow {
-	margin: 5px 0 0 5px;
-	/* in NON CSS3 capable browsers gives the offset of the shadow */
-	opacity: 0.8;
-	/* shadow opacity mostly for NON CSS3 capable browsers. Doesn't work in IE */
-}
-
-.ddcss3support .ddshadow.toplevelshadow {
-	margin: 0;
-	/* in CSS3 capable browsers overrides offset from NON CSS3 capable browsers, allowing the box-shadow values in the next selector to govern that */
-	/* opacity: 1; */
-	/* optionally uncomment this to remove partial opacity for browsers supporting a box-shadow property which has its own slight gradient opacity */
-}
 
-.ddcss3support .ddshadow {
-	background-color: transparent;
-	box-shadow: 5px 5px 5px #aaa;
-	/* box-shadow color generally should be a little darker than that for the NON CSS3 capable browsers background-color */
-	-moz-box-shadow: 5px 5px 5px #aaa;
-	-webkit-box-shadow: 5px 5px 5px #aaa;
+/*navMenu menu dropdown*/
+ul.navMenu {
+  display: flex;
+  position: relative;
+  flex-direction: row;
+  align-items: center;
+  /*max-width: 70%;*/
+  margin: 0 auto;
+  padding: 0;
+  list-style: none;
+  background: #31402a;
+  border-top-left-radius: 6px;
+  border-top-right-radius: 6px;
+}
+ul.navMenu > li {
+  position: relative;
+  flex-grow: 1;
+  flex-shrink: 0;
+  height: 45px;
+  font-size: 14px;
+  text-align: center;
+  text-transform: uppercase;
+  line-height: 45px;
+  letter-spacing: 1px;
+  color: #e7e6f1;
+  cursor: pointer;
+  border-right: 1px solid white;
+}
+ul.navMenu > li:hover {
+  background: #ef8200;
+}
+ul.navMenu > li:hover ul.dropdown {
+  visibility: visible;
+  transform: translate(0, 0);
+  opacity: 1;
+  z-index: 0;
+}
+ul.navMenu > li:hover ul.dropdown > li {
+  -webkit-animation-name: slideInLeft;
+          animation-name: slideInLeft;
+  -webkit-animation-duration: 0.3s;
+          animation-duration: 0.3s;
+  -webkit-animation-timing-function: ease-in-out;
+          animation-timing-function: ease-in-out;
+  -webkit-animation-fill-mode: backwards;
+          animation-fill-mode: backwards;
+}
+ul.navMenu > li:first-child {
+  /*border-top-left-radius: 6px;*/
+  border-left: 1px solid white;
+}
+ul.navMenu > li:last-child {
+  /*border-top-right-radius: 6px;*/
+  border-right: 1px solid white;
+}
+
+ul.navMenu > li a {
+    display: block;
+    color: white;
+    text-decoration: none;
+    height: 40px;
+    font-size: 13px;
+    font-weight: bold;
+}
+
+ul.navMenu > li a {
+    /*IE6 hack to get sub menu links to behave correctly*/
+    display: inline-block;
+}
+
+ul.navMenu > li a:link,ul.navMenu > li a:visited {
+    color: white;
+}
+
+ul.navMenu > li a.selected {
+    /*CSS class that's dynamically added to the currently active menu items' LI A element*/
+    color: white;
+}
+
+ul.navMenu > li a:hover {
+    /*background of menu items during onmouseover (hover state)*/
+    color: white;
+}
+
+ul.navMenu > li ul.dropdown {
+  visibility: hidden;
+  display: flex;
+  position: absolute;
+  top: 100%;
+  left: 0;
+  right: 0;
+  flex-direction: column;
+  margin: 0;
+  padding: 5px 0 0px;
+  list-style: none;
+  color: #333;
+  background: #31402a;
+  /*
+  border-bottom-left-radius: 6px;
+  border-bottom-right-radius: 6px;
+  */
+  box-shadow: 1px 2px 5px -1px rgba(0, 0, 0, 0.15), 0px 4px 14px -1px rgba(0, 0, 0, 0.1);
+  transform: translate(0, -60px);
+  transition: transform 0.2s ease-out, opacity 0.2s, z-index 0s 0.2s;
+  opacity: 0;
+  z-index: -1;
+}
+ul.navMenu > li ul.dropdown > li {
+  font-size: 14px;
+  cursor: pointer;
+  border-top: 1px solid white;
+}
+ul.navMenu > li ul.dropdown > li:hover {
+  background: #ef8200;
+}
+
+@-webkit-keyframes slideInLeft {
+  from {
+    transform: translate(-25%, 0);
+    opacity: 0;
+  }
+  to {
+    transform: translate(0, 0);
+    opacity: 1;
+  }
+}
+
+@keyframes slideInLeft {
+  from {
+    transform: translate(-25%, 0);
+    opacity: 0;
+  }
+  to {
+    transform: translate(0, 0);
+    opacity: 1;
+  }
 }

+ 137 - 275
maxkey-webs/maxkey-web-resources/src/main/resources/static/css/menu_pulse.css

@@ -1,280 +1,142 @@
+/**/
 #nav_primary{
     background: #721170;
 }
 
-.menuprimary {
-	font: bold 12px Verdana;
-	margin: auto;
-	height: 41px;
-}
-
-.menucontainer {
-	float: left;
-	margin-top: -2px;
-}
-
-.menuprimary ul {
-	z-index: 100;
-	margin: 0;
-	padding: 0;
-	list-style-type: none;
-}
-
-/*Top level list items*/
-.menuprimary ul li {
-	position: relative;
-	display: inline;
-	float: left;
-}
-
-.menuprimary ul .primaryleft {
-	border-left: 1px solid white;
-}
-
-/*Top level menu link items style*/
-.menuprimary ul li a {
-	display: block;
-	background: #721170; /*background of menu items (default state)*/
-	color: white;
-	padding: 10px 20px;
-	border-right: 1px solid white;
-	color: #2d2b2b;
-	text-decoration: none;
-	height: 40px;
-	font-size: 13px;
-}
-
-* html .menuprimary ul li a {
-	/*IE6 hack to get sub menu links to behave correctly*/
-	display: inline-block;
-}
-
-.menuprimary ul li a:link,.menuprimary ul li a:visited {
-	color: white;
-}
-
-.menuprimary ul li a.selected {
-	/*CSS class that's dynamically added to the currently active menu items' LI A element*/
-	background: #63065f !important;
-	color: white;
-}
-
-.menuprimary ul li a:hover {
-	background: #63065f;
-	/*background of menu items during onmouseover (hover state)*/
-	color: white;
-}
-
-/* sub menus */
-.menuprimary ul li ul {
-	position: absolute;
-	left: -3000px;
-	display: none; /*collapse all sub menus to begin with*/
-	visibility: hidden;
-}
-
-/*Sub level menu list items (alters style from Top level List Items)*/
-.menuprimary ul li ul li {
-	display: list-item;
-	float: none;
-}
-
-/*All subsequent sub menu levels vertical offset after 1st level sub menu */
-.menuprimary ul li ul li ul {
-	top: 0;
-}
-
-/* Sub level menu links style */
-.menuprimary ul li ul li a {
-	font: normal 13px Verdana;
-	width: 160px; /*width of sub menus*/
-	padding: 5px;
-	margin: 0;
-	border-top-width: 0;
-	border-bottom: 1px solid gray;
-	height: 90%;
-}
-
-/* Holly Hack for IE \*/
-* html .menuprimary {
-	height: 1%;
-} /*Holly Hack for IE7 and below*/
-
-/* ######### CSS classes applied to down and right arrow images  ######### */
-.downarrowclass {
-	position: absolute;
-	top: 12px;
-	right: 7px;
-}
-
-.rightarrowclass {
-	position: absolute;
-	top: 6px;
-	right: 5px;
-}
-
-/* ######### CSS for shadow added to sub menus  ######### */
-.ddshadow {
-	position: absolute;
-	left: 0;
-	top: 0;
-	width: 0;
-	height: 0;
-	background-color: #ccc;
-	/* generally should be just a little lighter than the box-shadow color for CSS3 capable browsers */
-}
-
-.toplevelshadow {
-	margin: 5px 0 0 5px;
-	/* in NON CSS3 capable browsers gives the offset of the shadow */
-	opacity: 0.8;
-	/* shadow opacity mostly for NON CSS3 capable browsers. Doesn't work in IE */
-}
-
-.ddcss3support .ddshadow.toplevelshadow {
-	margin: 0;
-	/* in CSS3 capable browsers overrides offset from NON CSS3 capable browsers, allowing the box-shadow values in the next selector to govern that */
-	/* opacity: 1; */
-	/* optionally uncomment this to remove partial opacity for browsers supporting a box-shadow property which has its own slight gradient opacity */
-}
-
-.ddcss3support .ddshadow {
-	background-color: transparent;
-	box-shadow: 5px 5px 5px #aaa;
-	/* box-shadow color generally should be a little darker than that for the NON CSS3 capable browsers background-color */
-	-moz-box-shadow: 5px 5px 5px #aaa;
-	-webkit-box-shadow: 5px 5px 5px #aaa;
-}
-
-/************************************************************************************************************/
-.menusecond {
-	font: bold 12px Verdana;
-	background: white; /*background of menu bar (default state)*/
-	margin: auto;
-}
-
-.menusecond ul {
-	z-index: 100;
-	margin: 0;
-	padding: 0;
-	list-style-type: none;
-}
-
-/*Top level list items*/
-.menusecond ul li {
-	position: relative;
-	display: inline;
-	float: left;
-}
-
-/*Top level menu link items style*/
-.menusecond ul li a {
-	display: block;
-	background: white; /*background of menu items (default state)*/
-	color: #721170;
-	padding: 8px 10px;
-	border-right: 1px solid #778;
-	color: #2d2b2b;
-	text-decoration: none;
-}
-
-* html .menusecond ul li a {
-	/*IE6 hack to get sub menu links to behave correctly*/
-	display: inline-block;
-}
-
-.menusecond ul li a:link,.menusecond ul li a:visited {
-	color: #721170;
-}
-
-.menusecond ul li a.selected {
-	/*CSS class that's dynamically added to the currently active menu items' LI A element*/
-	background: #F0F0F0 !important;
-	color: #414141;
-}
-
-.menusecond ul li a:hover {
-	background: #F0F0F0;
-	/*background of menu items during onmouseover (hover state)*/
-	color: #414141;
-}
-
-/* sub menus */
-.menusecond ul li ul {
-	position: absolute;
-	left: -3000px;
-	display: none; /*collapse all sub menus to begin with*/
-	visibility: hidden;
-}
-
-/*Sub level menu list items (alters style from Top level List Items)*/
-.menusecond ul li ul li {
-	display: list-item;
-	float: none;
-}
-
-/*All subsequent sub menu levels vertical offset after 1st level sub menu */
-.menusecond ul li ul li ul {
-	top: 0;
-}
-
-/* Sub level menu links style */
-.menusecond ul li ul li a {
-	font: normal 13px Verdana;
-	width: 160px; /*width of sub menus*/
-	padding: 5px;
-	margin: 0;
-	border-top-width: 0;
-	border-bottom: 1px solid gray;
-}
-
-/* Holly Hack for IE \*/
-* html .menusecond {
-	height: 1%;
-} /*Holly Hack for IE7 and below*/
-
-/* ######### CSS classes applied to down and right arrow images  ######### */
-.downarrowclass {
-	position: absolute;
-	top: 12px;
-	right: 7px;
-}
-
-.rightarrowclass {
-	position: absolute;
-	top: 6px;
-	right: 5px;
-}
-
-/* ######### CSS for shadow added to sub menus  ######### */
-.ddshadow {
-	position: absolute;
-	left: 0;
-	top: 0;
-	width: 0;
-	height: 0;
-	background-color: #ccc;
-	/* generally should be just a little lighter than the box-shadow color for CSS3 capable browsers */
-}
-
-.toplevelshadow {
-	margin: 5px 0 0 5px;
-	/* in NON CSS3 capable browsers gives the offset of the shadow */
-	opacity: 0.8;
-	/* shadow opacity mostly for NON CSS3 capable browsers. Doesn't work in IE */
-}
-
-.ddcss3support .ddshadow.toplevelshadow {
-	margin: 0;
-	/* in CSS3 capable browsers overrides offset from NON CSS3 capable browsers, allowing the box-shadow values in the next selector to govern that */
-	/* opacity: 1; */
-	/* optionally uncomment this to remove partial opacity for browsers supporting a box-shadow property which has its own slight gradient opacity */
-}
-
-.ddcss3support .ddshadow {
-	background-color: transparent;
-	box-shadow: 5px 5px 5px #aaa;
-	/* box-shadow color generally should be a little darker than that for the NON CSS3 capable browsers background-color */
-	-moz-box-shadow: 5px 5px 5px #aaa;
-	-webkit-box-shadow: 5px 5px 5px #aaa;
+/*navMenu menu dropdown*/
+ul.navMenu {
+  display: flex;
+  position: relative;
+  flex-direction: row;
+  align-items: center;
+  /*max-width: 70%;*/
+  margin: 0 auto;
+  padding: 0;
+  list-style: none;
+  background: #721170;
+  border-top-left-radius: 6px;
+  border-top-right-radius: 6px;
+}
+ul.navMenu > li {
+  position: relative;
+  flex-grow: 1;
+  flex-shrink: 0;
+  height: 45px;
+  font-size: 14px;
+  text-align: center;
+  text-transform: uppercase;
+  line-height: 45px;
+  letter-spacing: 1px;
+  color: #e7e6f1;
+  cursor: pointer;
+  border-right: 1px solid white;
+}
+ul.navMenu > li:hover {
+  background: #63065f;
+}
+ul.navMenu > li:hover ul.dropdown {
+  visibility: visible;
+  transform: translate(0, 0);
+  opacity: 1;
+  z-index: 0;
+}
+ul.navMenu > li:hover ul.dropdown > li {
+  -webkit-animation-name: slideInLeft;
+          animation-name: slideInLeft;
+  -webkit-animation-duration: 0.3s;
+          animation-duration: 0.3s;
+  -webkit-animation-timing-function: ease-in-out;
+          animation-timing-function: ease-in-out;
+  -webkit-animation-fill-mode: backwards;
+          animation-fill-mode: backwards;
+}
+ul.navMenu > li:first-child {
+  /*border-top-left-radius: 6px;*/
+  border-left: 1px solid white;
+}
+ul.navMenu > li:last-child {
+  /*border-top-right-radius: 6px;*/
+  border-right: 1px solid white;
+}
+
+ul.navMenu > li a {
+    display: block;
+    color: white;
+    text-decoration: none;
+    height: 40px;
+    font-size: 13px;
+    font-weight: bold;
+}
+
+ul.navMenu > li a {
+    /*IE6 hack to get sub menu links to behave correctly*/
+    display: inline-block;
+}
+
+ul.navMenu > li a:link,ul.navMenu > li a:visited {
+    color: white;
+}
+
+ul.navMenu > li a.selected {
+    /*CSS class that's dynamically added to the currently active menu items' LI A element*/
+    color: white;
+}
+
+ul.navMenu > li a:hover {
+    /*background of menu items during onmouseover (hover state)*/
+    color: white;
+}
+
+ul.navMenu > li ul.dropdown {
+  visibility: hidden;
+  display: flex;
+  position: absolute;
+  top: 100%;
+  left: 0;
+  right: 0;
+  flex-direction: column;
+  margin: 0;
+  padding: 5px 0 0px;
+  list-style: none;
+  color: #333;
+  background: #721170;
+  /*
+  border-bottom-left-radius: 6px;
+  border-bottom-right-radius: 6px;
+  */
+  box-shadow: 1px 2px 5px -1px rgba(0, 0, 0, 0.15), 0px 4px 14px -1px rgba(0, 0, 0, 0.1);
+  transform: translate(0, -60px);
+  transition: transform 0.2s ease-out, opacity 0.2s, z-index 0s 0.2s;
+  opacity: 0;
+  z-index: -1;
+}
+ul.navMenu > li ul.dropdown > li {
+  font-size: 14px;
+  cursor: pointer;
+  border-top: 1px solid white;
+}
+ul.navMenu > li ul.dropdown > li:hover {
+  background: #63065f;
+}
+
+@-webkit-keyframes slideInLeft {
+  from {
+    transform: translate(-25%, 0);
+    opacity: 0;
+  }
+  to {
+    transform: translate(0, 0);
+    opacity: 1;
+  }
+}
+
+@keyframes slideInLeft {
+  from {
+    transform: translate(-25%, 0);
+    opacity: 0;
+  }
+  to {
+    transform: translate(0, 0);
+    opacity: 1;
+  }
 }

+ 15 - 3
maxkey-webs/maxkey-web-resources/src/main/resources/static/javascript/platform.common.js

@@ -17,9 +17,21 @@ $(function(){
 	$(".datetimepicker").datetimepicker({format:'Y-m-d H:i'});
 	$(".datepicker").datetimepicker({timepicker:false,format:'Y-m-d'});
 	$(".timepicker").datetimepicker({datepicker:false,format:'H:i',step:10});
-	
-	//$(".multipleselect").multipleSelect({}); 
-			
+    
+	//maxkey navMenu
+    $('.navMenu').children('ul').children('li').each(function(indexCount){
+        // loop through each dropdown, count children and apply a animation delay based on their index value
+        $(this).children('ul.dropdown').children('li').each(function(index){
+            // Turn the index value into a reasonable animation delay
+            var delay = 0.1 + index*0.03;
+            // Apply the animation delay
+             $(this).css("animation-delay", delay + "s")         
+        });
+    });
+    
+	//side navigation
+    $('#side-nav-menu').metisMenu();
+    		
 	//on captcha image click ,new a captcha code
 	$('.captcha-image').click(function () {//
 		$(this).attr("src", webContextPath + "/captcha?"+(new Date()).getTime());