Merge pull request #174 from getrebuild/dept-tree-collapse-563

RB-563 Dept tree collapse
This commit is contained in:
devezhao 2020-06-04 12:24:40 +08:00 committed by GitHub
commit 25d6cd35a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 143 additions and 158 deletions

View file

@ -232,15 +232,6 @@ public final class Application {
return serversReady;
}
/**
* 添加服务停止钩子
* @param hook
*/
public static void addShutdownHook(Thread hook) {
LOG.info("Add shutdown hook : " + hook.getName());
Runtime.getRuntime().addShutdownHook(hook);
}
/**
* SPRING Context
* @return

View file

@ -14,6 +14,7 @@ import com.rebuild.server.helper.ConfigurableItem;
import com.rebuild.server.helper.License;
import com.rebuild.server.helper.SysConfiguration;
import com.rebuild.server.helper.setup.InstallState;
import com.rebuild.server.helper.task.TaskExecutors;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -82,8 +83,9 @@ public class ServerListener extends ContextCleanupListener implements InstallSta
@Override
public void contextDestroyed(ServletContextEvent event) {
LOG.info("Rebuild shutdown ...");
super.contextDestroyed(event);
Application.getBean(TaskExecutors.class).shutdown();
((ClassPathXmlApplicationContext) Application.getApplicationContext()).close();
super.contextDestroyed(event);
}
// --

View file

@ -91,7 +91,7 @@ public class RobotTriggerObserver extends OperatingObserver {
}
}
// 异步执行注意这会开启新事物
// 异步执行
for (TriggerAction action : actions) {
if (!action.useAsync()) continue;
LOG.info("Trigger [ " + action.getType() + " ] by record : " + context.getAnyRecord().getPrimary());

View file

@ -52,7 +52,7 @@ public interface TriggerAction {
void prepare(OperatingContext operatingContext) throws TriggerException;
/**
* 异步执行注意异步执行会开启新事物所以如果依赖主事物的数据可能存在
* 异步执行注意由于异步执行可能会开启新事物所以如果依赖主事物的数据可能存在
*
* @return
*/

View file

@ -47,7 +47,6 @@ public class SendNotification implements TriggerAction {
private static final Log LOG = LogFactory.getLog(SendNotification.class);
// 通知
@SuppressWarnings("unused")
private static final int TYPE_NOTIFICATION = 1;
// 邮件
private static final int TYPE_MAIL = 2;
@ -104,7 +103,7 @@ public class SendNotification implements TriggerAction {
SMSender.sendSMS(mobile, message);
}
} else {
} else if (type == TYPE_NOTIFICATION) {
Message m = MessageBuilder.createMessage(user, message, context.getSourceRecord());
Application.getNotifications().send(m);
@ -124,44 +123,39 @@ public class SendNotification implements TriggerAction {
* @return
*/
protected String formatMessage(String message, ID recordId) {
ThreadPool.waitFor(200);
Map<String, String> vars = null;
Map<String, String> fieldVars = new HashMap<>();
if (recordId != null) {
Entity entity = MetadataHelper.getEntity(recordId.getEntityCode());
vars = new HashMap<>();
Matcher m = PATT_FIELD.matcher(message);
while (m.find()) {
String field = m.group(1);
if (MetadataHelper.getLastJoinField(entity, field) == null) {
continue;
String fieldName = m.group(1);
if (MetadataHelper.checkAndWarnField(entity, fieldName)) {
fieldVars.put(fieldName, null);
}
vars.put(field, null);
}
if (!vars.isEmpty()) {
if (!fieldVars.isEmpty()) {
String sql = String.format("select %s from %s where %s = ?",
StringUtils.join(vars.keySet(), ","), entity.getName(), entity.getPrimaryField().getName());
StringUtils.join(fieldVars.keySet(), ","), entity.getName(), entity.getPrimaryField().getName());
Record o = Application.createQueryNoFilter(sql)
.setParameter(1, recordId)
.record();
ThreadPool.waitFor(500);
Record o = Application.createQueryNoFilter(sql).setParameter(1, recordId).record();
if (o != null) {
for (String field : vars.keySet()) {
for (String field : fieldVars.keySet()) {
Object value = o.getObjectValue(field);
value = FieldValueWrapper.instance.wrapFieldValue(
value, MetadataHelper.getLastJoinField(entity, field), true);
if (value != null) {
vars.put(field, value.toString());
fieldVars.put(field, value.toString());
}
}
}
}
}
if (vars != null) {
for (Map.Entry<String, String> e : vars.entrySet()) {
if (!fieldVars.isEmpty()) {
for (Map.Entry<String, String> e : fieldVars.entrySet()) {
message = message.replaceAll(
"\\{" + e.getKey() + "}", StringUtils.defaultIfBlank(e.getValue(), StringUtils.EMPTY));
}
@ -169,6 +163,8 @@ public class SendNotification implements TriggerAction {
return message;
}
// 这里使用异步可能存在脏读问题
// 但考虑到具体的业务消息短信邮件发送后也不能撤销提升速度
@Override
public boolean useAsync() {
return true;

View file

@ -18,13 +18,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
package com.rebuild.server.helper.cache;
import com.rebuild.server.Application;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import java.io.Serializable;
@ -94,12 +92,4 @@ public class EhcacheDriver<V extends Serializable> implements CacheTemplate<V> {
public Cache cache() {
return ehcacheManager.getCache("rebuild");
}
/**
* 关闭 Ehcache 以便将缓存持久化到硬盘
*/
public void shutdown() {
Application.LOG.info("Ehcache shutdown ...");
((EhCacheCacheManager) ehcacheManager).getCacheManager().shutdown();
}
}

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
package com.rebuild.server.helper.task;
@ -21,12 +10,14 @@ package com.rebuild.server.helper.task;
import cn.devezhao.commons.CodecUtils;
import cn.devezhao.commons.ThreadPool;
import cn.devezhao.persist4j.engine.ID;
import com.rebuild.server.Application;
import com.rebuild.server.RebuildException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
@ -39,9 +30,13 @@ import java.util.concurrent.TimeUnit;
*
* @author devezhao
* @since 09/29/2018
* @see org.springframework.core.task.SyncTaskExecutor
* @see org.springframework.core.task.AsyncTaskExecutor
*/
public class TaskExecutors extends QuartzJobBean {
private static final Log LOG = LogFactory.getLog(TaskExecutors.class);
private static final int MAX_TASK = Runtime.getRuntime().availableProcessors() / 2;
private static final int MAX_QUEUE = MAX_TASK * 10;
@ -122,8 +117,17 @@ public class TaskExecutors extends QuartzJobBean {
long leftTime = (System.currentTimeMillis() - task.getCompletedTime().getTime()) / 1000;
if (leftTime > 60 * 120) {
TASKS.remove(e.getKey());
Application.LOG.info("HeavyTask self-destroying : " + e.getKey());
LOG.info("HeavyTask self-destroying : " + e.getKey());
}
}
}
/**
*/
public void shutdown() {
List<Runnable> runs = EXECS.shutdownNow();
if (!runs.isEmpty()) {
LOG.warn(runs.size() + " tasks interrupted");
}
}
}

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
package com.rebuild.server.service;
@ -30,6 +19,7 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
*
* @author devezhao
* @since 2019/8/21
* @see org.springframework.transaction.support.TransactionSynchronizationManager
*/
public class TransactionManual {

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
package com.rebuild.web;
@ -33,6 +22,7 @@ import com.rebuild.web.user.signin.LoginControll;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
@ -58,7 +48,13 @@ public class OnlineSessionStore extends CurrentCaller implements HttpSessionList
private static final Set<HttpSession> ONLINE_SESSIONS = new CopyOnWriteArraySet<>();
private static final Map<ID, HttpSession> ONLINE_USERS = new ConcurrentHashMap<>();
private static final ThreadLocal<String> LOCALE = new ThreadLocal<>();
private static final ThreadLocal<String> LOCALE = new NamedThreadLocal<>("Current session user");
/**
* 最近访问 [时间, 路径]
* @see #storeLastActive(HttpServletRequest)
*/
public static final String SK_LASTACTIVE = WebUtils.KEY_PREFIX + "Session-LastActive";
@Override
public void sessionCreated(HttpSessionEvent event) {
@ -94,16 +90,7 @@ public class OnlineSessionStore extends CurrentCaller implements HttpSessionList
Application.getCommonService().update(logout);
}
}
/**
* 最近访问时间
*/
public static final String SK_LASTACTIVE = WebUtils.KEY_PREFIX + "Session-LastActive";
/**
* 最近访问路径
*/
public static final String SK_LASTACCESS = WebUtils.KEY_PREFIX + "Session-LastAccess";
/**
* 所有会话
*
@ -130,10 +117,10 @@ public class OnlineSessionStore extends CurrentCaller implements HttpSessionList
* @param request
*/
public void storeLastActive(HttpServletRequest request) {
HttpSession s = request.getSession(true);
s.setAttribute(SK_LASTACTIVE, CalendarUtils.now());
HttpSession s = request.getSession();
s.setAttribute(SK_LASTACTIVE, new Object[] { System.currentTimeMillis(), request.getRequestURI() } );
}
/**
* @param request
*/

View file

@ -1,27 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>EMAIL TEMPLATE</title>
</head>
<body>
<div style="background-color:#f5f5f5;margin:0;font-size:0.9rem;padding:20px 30px;color:#333;font-family:Roboto,Helvetica,'Microsoft YaHei','宋体',sans-serif;line-height:1.5">
<div style="border:1px solid #eee;padding:30px 20px;background-color:#fff;border-radius:3px;border-top:3px solid #4285f4;max-width:720px;margin:10px 0">
<h2 class="rb-title" style="font-size:1.4rem;margin:0;font-weight:400">%TITLE%</h2>
<div class="rb-content" style="margin-top:10px">%CONTETN%</div>
</div>
<div>
<div class="rb-footer" style="margin:0;color:#888;font-size:12px;max-width:760px">
<div style="float:left">
本消息由 REBUILD 系统自动发送,请不要直接回复。<br>
<div style="background-color:#f5f5f5;margin:0;font-size:0.9rem;padding:20px;color:#333;font-family:Roboto,Helvetica,'Microsoft YaHei','宋体',sans-serif;line-height:1.5">
<div>
<a href="https://getrebuild.com/" target="_blank"><img src="https://getrebuild.com/img/logo.png" alt="REBUILD" style="width:134px;display:inline-block;font-size:0" /></a>
</div>
<div style="border:1px solid #eee;padding:30px 20px;background-color:#fff;border-radius:3px;border-top:3px solid #4285f4;max-width:720px;margin:10px 0">
<h2 class="rb-title" style="font-size:1.3rem;margin:0;font-weight:400">%TITLE%</h2>
<div class="rb-content" style="margin-top:10px">%CONTETN%</div>
</div>
<div>
<div class="rb-footer" style="margin:0;color:#888;font-size:12px;max-width:760px">
本消息由 REBUILD 系统自动发送,请不要直接回复。
<br>
<em>This email was sent to %TO% at %TIME%</em>
</div>
<div style="float:right">
<a href="https://getrebuild.com/" target="_blank"><img src="https://getrebuild.com/img/logo.png" alt="REBUILD" style="width:134px;display:inline-block;margin-top:3px"/></a>
</div>
<div style="clear:both;font-size:0"></div>
</div>
</div>
</div>
</body>
</html>

View file

@ -17,7 +17,7 @@
<div class="rb-content">
<aside class="page-aside">
<div class="rb-scroller">
<div class="dept-tree">
<div class="aside-tree">
<div class="ph-item rb">
<div class="ph-col-12 p-0">
<div class="ph-row">

View file

@ -77,7 +77,7 @@
<div class="rb-content">
<aside class="page-aside">
<div class="rb-scroller">
<div class="dept-tree">
<div class="aside-tree">
<div class="ph-item rb">
<div class="ph-col-12 p-0">
<div class="ph-row">

View file

@ -17,7 +17,7 @@
<div class="rb-content">
<aside class="page-aside">
<div class="rb-scroller">
<div class="dept-tree">
<div class="aside-tree">
<div class="ph-item rb">
<div class="ph-col-12 p-0">
<div class="ph-row">

View file

@ -17,7 +17,7 @@
<div class="rb-content">
<aside class="page-aside">
<div class="rb-scroller">
<div class="dept-tree">
<div class="aside-tree">
<h5 class="config-title">应用实体</h5>
<ul class="list-unstyled">
<li class="active"><a>所有实体</a></li>

View file

@ -18,7 +18,7 @@
<div class="rb-content">
<aside class="page-aside">
<div class="rb-scroller">
<div class="dept-tree">
<div class="aside-tree">
<h5 class="config-title">应用实体</h5>
<ul class="list-unstyled">
<li class="active"><a>所有实体</a></li>

View file

@ -18,7 +18,7 @@
<div class="rb-content">
<aside class="page-aside">
<div class="rb-scroller">
<div class="dept-tree">
<div class="aside-tree">
<h5 class="config-title">源实体</h5>
<ul class="list-unstyled">
<li class="active"><a>所有实体</a></li>

View file

@ -419,7 +419,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
padding-bottom: 5px;
}
.side-wrapper .dept-tree {
.side-wrapper .aside-tree {
padding: 0;
max-height: 240px;
}

View file

@ -156,13 +156,13 @@
margin-right: 0;
}
.dept-tree li>a>.icon {
.aside-tree li>a>.icon {
font-size: 12px;
color: #aaa;
margin-left: 6px;
cursor: help;
}
.dept-tree li.active>a>.icon {
.aside-tree li.active>a>.icon {
color: #fff;
}

View file

@ -13,13 +13,13 @@ See LICENSE and COMMERCIAL in the project root for license information.
}
html.dev .dev-show,
html.admin .admin-show
html.admin .admin-show,
html.rbv .rbv-show {
display: block;
}
html.dev .dev-show.row,
html.admin .admin-show.row
html.admin .admin-show.row,
html.rbv .rbv-show.row {
display: flex;
}
@ -1686,11 +1686,11 @@ th.column-fixed {
box-shadow: 0 1px 0 rgba(0, 0, 0, .1);
}
.dept-tree {
.aside-tree {
padding: 25px 18px;
}
.dept-tree .config-title {
.aside-tree .config-title {
margin-bottom: 16px;
margin-top: 17px;
border-bottom: 1px solid #eee;
@ -1698,49 +1698,49 @@ th.column-fixed {
color: #777;
}
.dept-tree .list-unstyled {
.aside-tree .list-unstyled {
margin: 0
}
.dept-tree .list-unstyled ul {
.aside-tree .list-unstyled ul {
padding-left: 1rem;
}
.dept-tree li {
.aside-tree li {
position: relative;
}
.dept-tree li>a {
.aside-tree li>a {
display: block;
padding: 7px 10px;
cursor: pointer;
color: #444;
}
.dept-tree li>a.text-disabled {
.aside-tree li>a.text-disabled {
color: #aaa;
}
.dept-tree li>a.text-disabled>small::after {
.aside-tree li>a.text-disabled>small::after {
content: '[已停用]';
}
.dept-tree>ul>li>a {
.aside-tree>ul>li>a {
margin-left: 0;
}
.dept-tree li>a:hover {
.aside-tree li>a:hover {
background-color: #eee;
border-radius: 2px
}
.dept-tree li.active>a {
.aside-tree li.active>a {
color: #fff !important;
background-color: #4285f4 !important;
border-radius: 2px;
}
.dept-tree li>div.action,
.aside-tree li>div.action,
.adv-search .dropdown-item div.action {
position: absolute;
right: 0;
@ -1750,7 +1750,7 @@ th.column-fixed {
}
.dept-tree li>div.action a,
.aside-tree li>div.action a,
.adv-search .dropdown-item div.action a {
display: inline-block;
height: 34px;
@ -1762,20 +1762,36 @@ th.column-fixed {
margin-left: 1px;
}
.dept-tree li>div.action a:hover {
.aside-tree li>div.action a:hover {
background-color: rgba(0, 0, 0, 0.2);
}
.dept-tree ul>li.active:hover>div.action,
.aside-tree ul>li.active:hover>div.action,
.adv-search .dropdown-item:hover div.action {
display: block;
}
.dept-tree li.nodata {
.aside-tree li.nodata {
padding-left: 10px;
color: #999;
}
.aside-tree li>span.toggle {
position: absolute;
left: -10px;
height: 34px;
line-height: 34px;
width: 12px;
font-size: 1.45rem;
color: #999;
text-align: center;
cursor: default;
}
.aside-tree li>span.toggle:hover {
color: #4285f4;
}
.adv-search .dropdown-item div.action a {
height: 34px;
line-height: 34px;
@ -3441,7 +3457,7 @@ a.icon-link>.zmdi {
/* text overflow */
.aside-header .title,
.dept-tree ul li a,
.aside-tree ul li a,
.dropdown-item,
.modal-header .modal-title,
.view-header .title {

View file

@ -90,7 +90,7 @@ class ConfigList extends React.Component {
$(this.state.data).each(function () {
ues[this[1]] = this[2]
})
const dest = $('.dept-tree ul')
const dest = $('.aside-tree ul')
for (let k in ues) {
$(`<li data-entity="${k}"><a class="text-truncate">${ues[k]}</a></li>`).appendTo(dest)
}

View file

@ -8,8 +8,8 @@ See LICENSE and COMMERCIAL in the project root for license information.
var loadDeptTree = function () {
$.get('/admin/bizuser/dept-tree', function (res) {
$('.dept-tree').empty()
let root = $('<ul class="list-unstyled"></ul>').appendTo('.dept-tree')
$('.aside-tree').empty()
let root = $('<ul class="list-unstyled"></ul>').appendTo('.aside-tree')
renderDeptTree({ id: '$ALL$', name: '所有部门' }, root).addClass('active')
$(res.data).each(function () {
renderDeptTree(this, root)
@ -20,7 +20,7 @@ var loadDeptTree = function () {
const renderDeptTree = function (dept, target) {
let child = $(`<li data-id="${dept.id}"><a href="#dept=${dept.id}" class="text-truncate ${dept.disabled && ' text-disabled'}">${dept.name} ${dept.disabled ? '<small></small>' : ''}</a></li>`).appendTo(target)
child.find('a').click(function () {
$('.dept-tree li').removeClass('active')
$('.aside-tree li').removeClass('active')
child.addClass('active')
let ids = [child.data('id')]

View file

@ -73,11 +73,11 @@ const clickPriv = function (elements, action) {
}
const loadRoles = function () {
$.get('/admin/bizuser/role-list', function (res) {
$('.dept-tree .ph-item').remove()
$('.dept-tree ul').empty()
$('.aside-tree .ph-item').remove()
$('.aside-tree ul').empty()
$(res.data).each(function () {
let _id = this.id
let item = $('<li><a class="text-truncate' + (this.disabled ? ' text-disabled' : '') + '" href="' + rb.baseUrl + '/admin/bizuser/role/' + _id + '">' + this.name + (this.disabled ? '<small></small>' : '') + '</a></li>').appendTo('.dept-tree ul')
let item = $('<li><a class="text-truncate' + (this.disabled ? ' text-disabled' : '') + '" href="' + rb.baseUrl + '/admin/bizuser/role/' + _id + '">' + this.name + (this.disabled ? '<small></small>' : '') + '</a></li>').appendTo('.aside-tree ul')
let action = $('<div class="action"><a class="J_edit"><i class="zmdi zmdi-edit"></i></a><a class="J_del"><i class="zmdi zmdi-delete"></i></a></div>').appendTo(item)
if (role_id === this.id) item.addClass('active')
if (this.id === '003-0000000000000001') action.remove()

View file

@ -86,8 +86,8 @@ $(document).ready(function () {
if (gs) $('.search-input-gs, .J_search-key').val($decode(gs))
renderRbcomp(<RbFeeds />, 'rb-feeds', function () { rbFeeds = this })
renderRbcomp(<GroupList hasAction={true} />, $('#collapseGroup .dept-tree'), function () { rbGroupList = this })
renderRbcomp(<UserList />, $('#collapseUser .dept-tree'), function () { rbUserList = this })
renderRbcomp(<GroupList hasAction={true} />, $('#collapseGroup .aside-tree'), function () { rbGroupList = this })
renderRbcomp(<UserList />, $('#collapseUser .aside-tree'), function () { rbUserList = this })
let rbGroupListLoaded = false,
rbUserListLoaded = false

View file

@ -15,7 +15,7 @@ class EntityTree extends React.Component {
state = { activeItem: 1, ...this.props }
render() {
return <div className="dept-tree p-0">
return <div className="aside-tree p-0">
<ul className="list-unstyled">
{(this.state.list || []).map((item) => {
return <li key={`entity-${item.id}`} className={this.state.activeItem === item.id ? 'active' : ''}>

View file

@ -224,7 +224,7 @@ class FolderTree extends React.Component {
state = { activeItem: __DEFAULT_ALL, ...this.props }
render() {
return <div className="dept-tree p-0">
return <div className="aside-tree p-0">
<ul className="list-unstyled">
{(this.state.list || []).map((item) => { return this._renderItem(item) })}
</ul>

View file

@ -28,7 +28,7 @@ window.__PageConfig = {
}
</script>
<script type="text/babel">
__RESIZE_CALLS = null // No need
window.__ONRESIZE_CALLS = []
$(document).ready(function() {
const ph = (parent && parent.RbViewModal) ? parent.RbViewModal.holder(window.__PageConfig.id) : null
if (ph) $('.J_close').click(() => ph.hide())

View file

@ -62,7 +62,7 @@
</div>
<div class="collapse" id="collapseFeedsType">
<div class="card-body">
<div class="dept-tree rb-scroller">
<div class="aside-tree rb-scroller">
<ul class="list-unstyled">
<li data-type="1"><a>动态</a></li>
<li data-type="2"><a>跟进</a></li>
@ -81,7 +81,7 @@
<div class="collapse" id="collapseGroup">
<div class="card-body">
<div class="search-member"><input type="text" placeholder="搜索团队" /></div>
<div class="dept-tree rb-scroller">
<div class="aside-tree rb-scroller">
</div>
</div>
</div>
@ -93,7 +93,7 @@
<div class="collapse" id="collapseUser">
<div class="card-body pb-3">
<div class="search-member"><input type="text" placeholder="搜索用户" /></div>
<div class="dept-tree rb-scroller">
<div class="aside-tree rb-scroller">
</div>
</div>
</div>

View file

@ -7,6 +7,7 @@
<%@ page import="com.rebuild.server.Application"%>
<%@ page import="com.rebuild.server.ServerStatus"%>
<%@ page import="com.rebuild.server.ServerStatus.Status"%>
<%@ page import="java.util.Map" %>
<!DOCTYPE html>
<html>
<head>
@ -90,6 +91,14 @@
<th>Temp Directory</th>
<td><%=SysConfiguration.getFileOfTemp("/")%></td>
</tr>
<tr class="<%=request.getParameter("jvm") == null ? "hide" : ""%>">
<th>JVM Arguments</th>
<td>
<div style="word-break:break-all;word-wrap:break-word;">
<% for (Map.Entry<String, String> e : System.getenv().entrySet()) out.print(e.getKey() + "=" + e.getValue() + "<br>"); %>
</div>
</td>
</tr>
</tbody>
</table>
</div>