mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 15:35:55 +08:00
commit
d64598ce90
|
@ -67,10 +67,11 @@ module.exports = {
|
|||
RbAlertBox: true,
|
||||
RbModal: true,
|
||||
RbModalHandler: true,
|
||||
RbFrom: true,
|
||||
RbForm: true,
|
||||
RbFormHandler: true,
|
||||
RbFormElement: true,
|
||||
RbList: true,
|
||||
RbListCommon: true,
|
||||
RbListPage: true,
|
||||
RbViewPage: true,
|
||||
CellRenders: true,
|
||||
|
|
2
@rbv
2
@rbv
|
@ -1 +1 @@
|
|||
Subproject commit e89ef908305fc51bb0bdff02609303b9900e46ca
|
||||
Subproject commit c66321900f7c9abc786e9585f7cf59baf1674c12
|
|
@ -16,6 +16,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
@ -46,7 +47,8 @@ import java.util.Set;
|
|||
JdbcRepositoriesAutoConfiguration.class,
|
||||
JdbcTemplateAutoConfiguration.class,
|
||||
RedisAutoConfiguration.class,
|
||||
CacheAutoConfiguration.class})
|
||||
CacheAutoConfiguration.class,
|
||||
H2ConsoleAutoConfiguration.class})
|
||||
@ImportResource("classpath:application-bean.xml")
|
||||
@EnableScheduling
|
||||
@Slf4j
|
||||
|
|
|
@ -78,15 +78,15 @@ public class DataListManager extends BaseLayoutManager {
|
|||
if (config == null) {
|
||||
columnList.add(formatField(namedField));
|
||||
|
||||
String namedFieldName = namedField.getName();
|
||||
if (!StringUtils.equalsIgnoreCase(namedFieldName, EntityHelper.CreatedBy)
|
||||
if (!StringUtils.equalsIgnoreCase(namedField.getName(), EntityHelper.CreatedBy)
|
||||
&& entityMeta.containsField(EntityHelper.CreatedBy)) {
|
||||
columnList.add(formatField(entityMeta.getField(EntityHelper.CreatedBy)));
|
||||
}
|
||||
if (!StringUtils.equalsIgnoreCase(namedFieldName, EntityHelper.CreatedOn)
|
||||
if (!StringUtils.equalsIgnoreCase(namedField.getName(), EntityHelper.CreatedOn)
|
||||
&& entityMeta.containsField(EntityHelper.CreatedOn)) {
|
||||
columnList.add(formatField(entityMeta.getField(EntityHelper.CreatedOn)));
|
||||
}
|
||||
|
||||
} else {
|
||||
for (Object o : (JSONArray) config.getJSON("config")) {
|
||||
JSONObject item = (JSONObject) o;
|
||||
|
@ -202,4 +202,21 @@ public class DataListManager extends BaseLayoutManager {
|
|||
}
|
||||
return e.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO 自定义字段 MODE2
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public JSON getFieldsLayoutMode2(Entity entity) {
|
||||
JSONObject emptyConfig = (JSONObject) formatFieldsLayout(entity.getName(), null, true, null);
|
||||
JSONArray fields = emptyConfig.getJSONArray("fields");
|
||||
|
||||
if (entity.containsField(EntityHelper.ApprovalState)) {
|
||||
fields.add(formatField(entity.getField(EntityHelper.ApprovalState)));
|
||||
}
|
||||
|
||||
return emptyConfig;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ public abstract class BaseEasyMeta<T extends BaseMeta> implements BaseMeta, JSON
|
|||
* @param name
|
||||
* @return
|
||||
* @see EasyFieldConfigProps
|
||||
* @see com.rebuild.core.metadata.impl.EasyEntityConfigProps
|
||||
*/
|
||||
public String getExtraAttr(String name) {
|
||||
return getExtraAttrs(false).getString(name);
|
||||
|
|
|
@ -13,6 +13,11 @@ package com.rebuild.core.metadata.impl;
|
|||
*/
|
||||
public class EasyEntityConfigProps {
|
||||
|
||||
/**
|
||||
* 快速查询字段
|
||||
*/
|
||||
public static final String QUICK_FIELDS = "quickFields";
|
||||
|
||||
/**
|
||||
* 隐藏常用查询面板
|
||||
*/
|
||||
|
@ -21,4 +26,8 @@ public class EasyEntityConfigProps {
|
|||
* 隐藏图表面板
|
||||
*/
|
||||
public static final String ADV_LIST_HIDE_CHARTS = "advListHideCharts";
|
||||
/**
|
||||
* 列表模式
|
||||
*/
|
||||
public static final String ADV_LIST_MODE = "advListMode";
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.rebuild.core.metadata.MetadataHelper;
|
|||
import com.rebuild.core.metadata.MetadataSorter;
|
||||
import com.rebuild.core.metadata.easymeta.DisplayType;
|
||||
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
|
||||
import com.rebuild.core.metadata.impl.EasyEntityConfigProps;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
|
@ -224,7 +225,7 @@ public class ParseHelper {
|
|||
|
||||
// 未指定则使用系统配置的
|
||||
if (StringUtils.isBlank(quickFields)) {
|
||||
quickFields = EasyMetaFactory.valueOf(entity).getExtraAttr("quickFields");
|
||||
quickFields = EasyMetaFactory.valueOf(entity).getExtraAttr(EasyEntityConfigProps.QUICK_FIELDS);
|
||||
}
|
||||
|
||||
// 验证
|
||||
|
|
|
@ -215,15 +215,13 @@ public class QueryParser {
|
|||
|
||||
String sortNode = queryExpr.getString("sort");
|
||||
if (StringUtils.isNotBlank(sortNode)) {
|
||||
sqlSort.append(parseSort(sortNode));
|
||||
sqlSort.append(StringUtils.defaultString(parseSort(sortNode), ""));
|
||||
} else if (entity.containsField(EntityHelper.ModifiedOn)) {
|
||||
sqlSort.append(EntityHelper.ModifiedOn + " desc");
|
||||
} else if (entity.containsField(EntityHelper.CreatedOn)) {
|
||||
sqlSort.append(EntityHelper.CreatedOn + " desc");
|
||||
}
|
||||
if (sqlSort.length() > 10) {
|
||||
fullSql.append(sqlSort);
|
||||
}
|
||||
if (sqlSort.length() >= 18) fullSql.append(sqlSort);
|
||||
|
||||
this.sql = fullSql.toString();
|
||||
this.countSql = this.buildCountSql(pkName) + sqlWhere;
|
||||
|
@ -242,9 +240,10 @@ public class QueryParser {
|
|||
* @return
|
||||
*/
|
||||
private String parseSort(String sort) {
|
||||
String[] sort_s = sort.split(":");
|
||||
String sortField = sort_s[0];
|
||||
return sortField + ("desc".equalsIgnoreCase(sort_s[1]) ? " desc" : " asc");
|
||||
String[] sorts = sort.split(":");
|
||||
if (sorts.length != 2) return null;
|
||||
String sortField = sorts[0];
|
||||
return sortField + ("desc".equalsIgnoreCase(sorts[1]) ? " desc" : " asc");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -70,7 +70,7 @@ public class MetaEntityController extends BaseController {
|
|||
}
|
||||
|
||||
ModelAndView mv = createModelAndView("/admin/metadata/entity-edit");
|
||||
setEntityBase(mv, entity);
|
||||
EasyEntity easyEntity = setEntityBase(mv, entity);
|
||||
|
||||
mv.getModel().put("nameField", metaEntity.getNameField().getName());
|
||||
|
||||
|
@ -83,7 +83,7 @@ public class MetaEntityController extends BaseController {
|
|||
}
|
||||
|
||||
// 扩展配置
|
||||
mv.getModel().put("entityExtConfig", EasyMetaFactory.valueOf(metaEntity).getExtraAttrs(true));
|
||||
mv.getModel().put("entityExtConfig", easyEntity.getExtraAttrs(true));
|
||||
|
||||
return mv;
|
||||
}
|
||||
|
@ -92,7 +92,11 @@ public class MetaEntityController extends BaseController {
|
|||
public ModelAndView pageAdvanced(@PathVariable String entity, HttpServletRequest request) {
|
||||
ModelAndView mv = createModelAndView("/admin/metadata/entity-advanced");
|
||||
mv.getModel().put("isSuperAdmin", UserHelper.isSuperAdmin(getRequestUser(request)));
|
||||
setEntityBase(mv, entity);
|
||||
EasyEntity easyEntity = setEntityBase(mv, entity);
|
||||
|
||||
// 扩展配置
|
||||
mv.getModel().put("entityExtConfig", easyEntity.getExtraAttrs(true));
|
||||
|
||||
return mv;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
|
||||
package com.rebuild.web.general;
|
||||
|
||||
import cn.devezhao.commons.ObjectUtils;
|
||||
import cn.devezhao.commons.web.ServletUtils;
|
||||
import cn.devezhao.persist4j.Entity;
|
||||
import cn.devezhao.persist4j.engine.ID;
|
||||
|
@ -46,18 +47,21 @@ public class GeneralListController extends EntityController {
|
|||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException {
|
||||
final ID user = getRequestUser(request);
|
||||
final Entity useEntity = checkPageOfEntity(user, entity, response);
|
||||
if (useEntity == null) return null;
|
||||
final Entity listEntity = checkPageOfEntity(user, entity, response);
|
||||
if (listEntity == null) return null;
|
||||
|
||||
ModelAndView mv;
|
||||
if (useEntity.getMainEntity() != null) {
|
||||
mv = createModelAndView("/general/detail-list", entity, user);
|
||||
} else {
|
||||
mv = createModelAndView("/general/record-list", entity, user);
|
||||
final EasyEntity easyEntity = EasyMetaFactory.valueOf(listEntity);
|
||||
|
||||
String listPage = listEntity.getMainEntity() != null ? "/general/detail-list" : "/general/record-list";
|
||||
Integer listMode = getIntParameter(request, "forceListMode");
|
||||
if (listMode == null) {
|
||||
listMode = ObjectUtils.toInt(easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_MODE), 1);
|
||||
}
|
||||
if (listMode == 2) {
|
||||
listPage = "/general/record-list-2"; // Mode2
|
||||
}
|
||||
|
||||
JSON config = DataListManager.instance.getFieldsLayout(entity, user);
|
||||
mv.getModel().put("DataListConfig", JSON.toJSONString(config));
|
||||
ModelAndView mv = createModelAndView(listPage, entity, user);
|
||||
|
||||
// 列表相关权限
|
||||
mv.getModel().put(ZeroEntry.AllowCustomDataList.name(),
|
||||
|
@ -67,14 +71,27 @@ public class GeneralListController extends EntityController {
|
|||
mv.getModel().put(ZeroEntry.AllowBatchUpdate.name(),
|
||||
Application.getPrivilegesManager().allow(user, ZeroEntry.AllowBatchUpdate));
|
||||
|
||||
// 扩展配置
|
||||
EasyEntity easyEntity = EasyMetaFactory.valueOf(useEntity);
|
||||
String advListHideFilters = easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_HIDE_FILTERS);
|
||||
String advListHideCharts = easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_HIDE_CHARTS);
|
||||
mv.getModel().put(EasyEntityConfigProps.ADV_LIST_HIDE_FILTERS, advListHideFilters);
|
||||
mv.getModel().put(EasyEntityConfigProps.ADV_LIST_HIDE_CHARTS, advListHideCharts);
|
||||
mv.getModel().put("hideAside",
|
||||
BooleanUtils.toBoolean(advListHideFilters) && BooleanUtils.toBoolean(advListHideCharts));
|
||||
JSON listConfig = null;
|
||||
|
||||
if (listMode == 1) {
|
||||
listConfig = DataListManager.instance.getFieldsLayout(entity, user);
|
||||
|
||||
// 扩展配置
|
||||
String advListHideFilters = easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_HIDE_FILTERS);
|
||||
String advListHideCharts = easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_HIDE_CHARTS);
|
||||
mv.getModel().put(EasyEntityConfigProps.ADV_LIST_HIDE_FILTERS, advListHideFilters);
|
||||
mv.getModel().put(EasyEntityConfigProps.ADV_LIST_HIDE_CHARTS, advListHideCharts);
|
||||
mv.getModel().put("hideAside",
|
||||
BooleanUtils.toBoolean(advListHideFilters) && BooleanUtils.toBoolean(advListHideCharts));
|
||||
|
||||
} else if (listMode == 2) {
|
||||
listConfig = DataListManager.instance.getFieldsLayoutMode2(listEntity);
|
||||
|
||||
// 明细列表
|
||||
if (listEntity.getMainEntity() != null) mv.getModel().put("DataListType", "DetailList");
|
||||
}
|
||||
|
||||
mv.getModel().put("DataListConfig", JSON.toJSONString(listConfig));
|
||||
|
||||
return mv;
|
||||
}
|
||||
|
|
|
@ -173,6 +173,8 @@ public class ModelExtrasController extends BaseController {
|
|||
if (!MetadataHelper.containsEntity(e)) continue;
|
||||
|
||||
EasyEntity easyEntity = EasyMetaFactory.valueOf(e);
|
||||
if (!MetadataHelper.hasPrivilegesField(easyEntity.getRawMeta())) continue;
|
||||
|
||||
if (Application.getPrivilegesManager()
|
||||
.allow(user, easyEntity.getRawMeta().getEntityCode(), BizzPermission.CREATE)) {
|
||||
allowed.add(easyEntity.toJSON());
|
||||
|
|
|
@ -4,6 +4,32 @@
|
|||
<th:block th:replace="~{/_include/header}" />
|
||||
<meta name="page-help" content="https://getrebuild.com/docs/admin/meta-entity" />
|
||||
<title>[[${bundle.L('高级配置')}]]</title>
|
||||
<style>
|
||||
.card-body {
|
||||
padding-bottom: 25px;
|
||||
}
|
||||
.row.ph {
|
||||
width: 195px;
|
||||
height: 130px;
|
||||
border: 1px solid #eee;
|
||||
padding: 2px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.row.ph .block {
|
||||
background-color: #eee;
|
||||
height: 100%;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
.row.ph .block .block-item {
|
||||
background-color: #ccc;
|
||||
height: 4px;
|
||||
margin: 2px 5px;
|
||||
}
|
||||
.form-group .switch-button-xs {
|
||||
margin-top: 7px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="rb-wrapper rb-fixed-sidebar rb-collapsible-sidebar rb-collapsible-sidebar-hide-logo rb-aside rb-color-header" th:classappend="${sideCollapsedClazz}">
|
||||
|
@ -35,6 +61,57 @@
|
|||
<div class="page-head-title">[[${bundle.L('高级配置')}]]</div>
|
||||
</div>
|
||||
<div class="main-content container-fluid pt-1">
|
||||
<div class="card">
|
||||
<div class="card-header">[[${bundle.L('列表模式')}]] <sup class="rbv"></sup></div>
|
||||
<div class="card-body mode-select">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row ph">
|
||||
<div class="col-2 p-0">
|
||||
<div class="block"></div>
|
||||
</div>
|
||||
<div class="col-10 p-0">
|
||||
<div class="block" style="height: 10%"></div>
|
||||
<div class="block" style="height: 90%">
|
||||
<div class="block-item mt-1"></div>
|
||||
<div class="block-item"></div>
|
||||
<div class="block-item"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<h5 class="font-weight-bold">标准模式</h5>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-secondary J_mode-select" type="button" data-mode="1">[[${bundle.L('使用')}]]</button>
|
||||
<button class="btn btn-secondary J_mode1-option w-auto" type="button"><i class="icon zmdi zmdi-settings"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row ph">
|
||||
<div class="col-3 p-0">
|
||||
<div class="block">
|
||||
<div class="block-item mt-1"></div>
|
||||
<div class="block-item"></div>
|
||||
<div class="block-item"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-9 p-0">
|
||||
<div class="block"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<h5 class="font-weight-bold">详情模式</h5>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-secondary J_mode-select" type="button" data-mode="2">[[${bundle.L('使用')}]]</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">[[${bundle.L('删除实体')}]]</div>
|
||||
<div class="card-body">
|
||||
|
@ -49,7 +126,7 @@
|
|||
<input class="custom-control-input J_drop-force" type="checkbox" /><span class="custom-control-label"> [[${bundle.L('强制删除')}]]</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<div>
|
||||
<button type="button" class="btn btn-danger J_drop-confirm" disabled="disabled"><i class="zmdi zmdi-delete icon"></i> [[${bundle.L('确定')}]]</button>
|
||||
<div class="alert alert-warning alert-icon hide col-sm-6 mb-0">
|
||||
<div class="icon"><span class="zmdi zmdi-alert-triangle"></span></div>
|
||||
|
@ -62,7 +139,7 @@
|
|||
<div class="card-header">[[${bundle.L('导出实体')}]]</div>
|
||||
<div class="card-body">
|
||||
<p class="link" th:utext="${bundle.L('将实体的元数据导出,方便与其他实例间共享。你也可以将导出文件发布到 [RB 仓库](https://github.com/getrebuild/rebuild-datas)。')}"></p>
|
||||
<div class="mb-1">
|
||||
<div>
|
||||
<a th:href="|../entity-export?id=${entityMetaId}|" target="_blank" class="btn btn-primary"><i class="zmdi zmdi-cloud-download icon"></i> [[${bundle.L('导出')}]]</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -76,51 +153,10 @@
|
|||
id: '[[${entityMetaId}]]',
|
||||
isSuperAdmin: '[[${isSuperAdmin}]]' === 'true',
|
||||
entityName: '[[${entityName}]]',
|
||||
extConfig: [(${entityExtConfig ?:'null'})],
|
||||
}
|
||||
</script>
|
||||
<script th:src="@{/assets/js/metadata/entity-switch.js}" type="text/babel"></script>
|
||||
<script type="text/babel">
|
||||
$(document).ready(function () {
|
||||
const metaid = window.__PageConfig.id
|
||||
if (!!!metaid) {
|
||||
$('.J_drop-confirm').next().removeClass('hide')
|
||||
$('.J_drop-confirm').remove()
|
||||
$('.J_drop-check').parent().parent().remove()
|
||||
return
|
||||
}
|
||||
|
||||
$('.J_drop-check').click(function () {
|
||||
$('.J_drop-confirm').attr('disabled', !$(this).prop('checked'))
|
||||
})
|
||||
|
||||
const $drop = $('.J_drop-confirm').click(() => {
|
||||
if (!$('.J_drop-check').prop('checked')) return
|
||||
if (!window.__PageConfig.isSuperAdmin) {
|
||||
RbHighbar.error($L('仅超级管理员可删除实体'))
|
||||
return
|
||||
}
|
||||
|
||||
RbAlert.create($L('实体删除后将无法恢复,请务必谨慎操作。确认删除吗?'), $L('删除实体'), {
|
||||
type: 'danger',
|
||||
confirmText: $L('删除'),
|
||||
confirm: function () {
|
||||
$drop.button('loading')
|
||||
this.disabled(true)
|
||||
$.post(`../entity-drop?id=${metaid}&force=${$('.J_drop-force').prop('checked')}`, (res) => {
|
||||
if (res.error_code === 0) {
|
||||
RbHighbar.success($L('实体已删除'))
|
||||
setTimeout(() => location.replace('../../entities'), 1500)
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
call: function () {
|
||||
$countdownButton($(this._dlg).find('.btn-danger'))
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<script th:src="@{/assets/js/metadata/entity-advanced.js}" type="text/babel"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -80,19 +80,6 @@
|
|||
<textarea class="form-control form-control-sm row2x" id="comments" th:data-o="${comments}" th:placeholder="${bundle.L('(选填)')}">[[${comments}]]</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row bosskey-show">
|
||||
<label class="col-md-12 col-xl-3 col-lg-4 col-form-label text-lg-right pt-1">[[${bundle.L('高级配置')}]]</label>
|
||||
<div class="col-md-12 col-xl-6 col-lg-8">
|
||||
<label class="custom-control custom-control-sm custom-checkbox">
|
||||
<input class="custom-control-input" type="checkbox" id="advListHideFilters" />
|
||||
<span class="custom-control-label"> [[${bundle.L('隐藏列表页侧栏常用查询')}]]</span>
|
||||
</label>
|
||||
<label class="custom-control custom-control-sm custom-checkbox mb-0">
|
||||
<input class="custom-control-input" type="checkbox" id="advListHideCharts" />
|
||||
<span class="custom-control-label"> [[${bundle.L('隐藏列表页侧栏图表')}]]</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row footer">
|
||||
<div class="col-md-12 col-xl-6 col-lg-8 offset-xl-3 offset-lg-4">
|
||||
<div class="J_action hide">
|
||||
|
|
|
@ -258,7 +258,7 @@ a.link.inline {
|
|||
}
|
||||
|
||||
a.btn {
|
||||
line-height: 2.7rem;
|
||||
line-height: 2.68rem;
|
||||
}
|
||||
|
||||
.input-group .btn,
|
||||
|
@ -4365,4 +4365,4 @@ pre.unstyle {
|
|||
background-color: transparent;
|
||||
font-size: 1rem;
|
||||
font-family: inherit;
|
||||
}
|
||||
}
|
||||
|
|
155
src/main/resources/web/assets/js/metadata/entity-advanced.js
Normal file
155
src/main/resources/web/assets/js/metadata/entity-advanced.js
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights reserved.
|
||||
|
||||
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
|
||||
See LICENSE and COMMERCIAL in the project root for license information.
|
||||
*/
|
||||
/* eslint-disable react/no-string-refs */
|
||||
|
||||
const wpc = window.__PageConfig
|
||||
|
||||
$(document).ready(function () {
|
||||
modeAction()
|
||||
|
||||
const metaid = wpc.id
|
||||
if (!metaid) {
|
||||
$('.J_drop-confirm').next().removeClass('hide')
|
||||
$('.J_drop-confirm').remove()
|
||||
$('.J_drop-check').parent().parent().remove()
|
||||
return
|
||||
}
|
||||
|
||||
$('.J_drop-check').click(function () {
|
||||
$('.J_drop-confirm').attr('disabled', !$(this).prop('checked'))
|
||||
})
|
||||
|
||||
const $drop = $('.J_drop-confirm').click(() => {
|
||||
if (!$('.J_drop-check').prop('checked')) return
|
||||
if (!window.__PageConfig.isSuperAdmin) {
|
||||
RbHighbar.error($L('仅超级管理员可删除实体'))
|
||||
return
|
||||
}
|
||||
|
||||
RbAlert.create($L('实体删除后将无法恢复,请务必谨慎操作。确认删除吗?'), $L('删除实体'), {
|
||||
type: 'danger',
|
||||
confirmText: $L('删除'),
|
||||
confirm: function () {
|
||||
$drop.button('loading')
|
||||
this.disabled(true)
|
||||
$.post(`../entity-drop?id=${metaid}&force=${$('.J_drop-force').prop('checked')}`, (res) => {
|
||||
if (res.error_code === 0) {
|
||||
RbHighbar.success($L('实体已删除'))
|
||||
setTimeout(() => location.replace('../../entities'), 1500)
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
call: function () {
|
||||
$countdownButton($(this._dlg).find('.btn-danger'))
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function modeAction() {
|
||||
if (rb.commercial < 10) {
|
||||
$('.mode-select .btn').on('click', () => RbHighbar.create($L('免费版不支持列表模式功能 [(查看详情)](https://getrebuild.com/docs/rbv-features)')))
|
||||
return
|
||||
}
|
||||
|
||||
if (!wpc.id) {
|
||||
$('.mode-select .btn').on('click', () => RbHighbar.create($L('系统内置实体暂不支持')))
|
||||
return
|
||||
}
|
||||
|
||||
if (wpc.extConfig && wpc.extConfig.advListMode) {
|
||||
$('.mode-select .btn[data-mode=' + wpc.extConfig.advListMode + ']')
|
||||
.addClass('active')
|
||||
.text($L('当前模式'))
|
||||
}
|
||||
|
||||
$('.mode-select .J_mode-select').on('click', function () {
|
||||
const $btn = $(this)
|
||||
RbAlert.create($L('确认切换到此列表模式?'), {
|
||||
onConfirm: function () {
|
||||
this.disabled(true)
|
||||
const mode = $btn.data('mode')
|
||||
modeSave({ advListMode: mode }, () => location.reload())
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// Mode-1 Option
|
||||
$('.mode-select .J_mode1-option').on('click', () => renderRbcomp(<DlgMode1Option />))
|
||||
}
|
||||
|
||||
function modeSave(newOption, next) {
|
||||
const extConfig = wpc.extConfig ? { ...wpc.extConfig, ...newOption } : { ...newOption }
|
||||
const data = {
|
||||
metadata: { entity: 'MetaEntity', id: wpc.id },
|
||||
extConfig: extConfig,
|
||||
}
|
||||
|
||||
$.post('../entity-update', JSON.stringify(data), function (res) {
|
||||
if (res.error_code === 0) typeof next === 'function' && next()
|
||||
else RbHighbar.error(res.error_msg)
|
||||
})
|
||||
}
|
||||
|
||||
// 添加仪表盘
|
||||
class DlgMode1Option extends RbFormHandler {
|
||||
render() {
|
||||
return (
|
||||
<RbModal title={$L('标准模式选项')} ref="dlg" disposeOnHide>
|
||||
<div className="form">
|
||||
<div className="form-group row">
|
||||
<label className="col-sm-3 col-form-label text-sm-right">{$L('隐藏侧栏常用查询')}</label>
|
||||
<div className="col-sm-7">
|
||||
<div className="switch-button switch-button-xs">
|
||||
<input type="checkbox" id="advListHideFilters" defaultChecked={wpc.extConfig && wpc.extConfig.advListHideFilters} />
|
||||
<span>
|
||||
<label htmlFor="advListHideFilters" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group row">
|
||||
<label className="col-sm-3 col-form-label text-sm-right">{$L('隐藏侧栏图表')}</label>
|
||||
<div className="col-sm-7">
|
||||
<div className="switch-button switch-button-xs">
|
||||
<input type="checkbox" id="advListHideCharts" defaultChecked={wpc.extConfig && wpc.extConfig.advListHideCharts} />
|
||||
<span>
|
||||
<label htmlFor="advListHideCharts" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group row footer">
|
||||
<div className="col-sm-7 offset-sm-3" ref={(c) => (this._btns = c)}>
|
||||
<button className="btn btn-primary" type="button" onClick={this.save}>
|
||||
{$L('确定')}
|
||||
</button>
|
||||
<a className="btn btn-link" onClick={this.hide}>
|
||||
{$L('取消')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</RbModal>
|
||||
)
|
||||
}
|
||||
|
||||
save = () => {
|
||||
const o = {
|
||||
advListHideFilters: $val('#advListHideFilters'),
|
||||
advListHideCharts: $val('#advListHideCharts'),
|
||||
}
|
||||
|
||||
this.disabled(true)
|
||||
modeSave(o, () => {
|
||||
this.hide()
|
||||
location.reload()
|
||||
})
|
||||
}
|
||||
}
|
|
@ -35,12 +35,11 @@ $(document).ready(function () {
|
|||
const icon = $val('#entityIcon')
|
||||
if (icon) data.icon = icon
|
||||
|
||||
const extConfigNew = {
|
||||
let extConfig = {
|
||||
quickFields: $('#quickFields').val().join(','),
|
||||
advListHideFilters: $val('#advListHideFilters'),
|
||||
advListHideCharts: $val('#advListHideCharts'),
|
||||
}
|
||||
if (!$same(extConfigNew, wpc.extConfig)) data.extConfig = extConfigNew
|
||||
extConfig = wpc.extConfig ? { ...wpc.extConfig, ...extConfig } : extConfig
|
||||
if (!$same(extConfig, wpc.extConfig)) data.extConfig = extConfig
|
||||
|
||||
data = $cleanMap(data)
|
||||
if (Object.keys(data).length === 0) {
|
||||
|
@ -144,7 +143,4 @@ $(document).ready(function () {
|
|||
$('#quickFields').val(wpc.extConfig.quickFields.split(',')).trigger('change')
|
||||
}
|
||||
})
|
||||
|
||||
if (wpc.extConfig.advListHideFilters) $('#advListHideFilters').attr('checked', true)
|
||||
if (wpc.extConfig.advListHideCharts) $('#advListHideCharts').attr('checked', true)
|
||||
})
|
||||
|
|
|
@ -12,7 +12,7 @@ let _entity_data = {}
|
|||
$(document).ready(function () {
|
||||
$('.J_add-menu').click(() => render_item({}, true))
|
||||
|
||||
$.get('/commons/metadata/entities', function (res) {
|
||||
$.get('/commons/metadata/entities?detail=true', function (res) {
|
||||
$(res.data).each(function () {
|
||||
$(`<option value="${this.name}">${this.label}</option>`).appendTo('.J_menuEntity optgroup:eq(0)')
|
||||
_entity_data[this.name] = this
|
||||
|
|
|
@ -5,7 +5,172 @@ rebuild is dual-licensed under commercial and open source licenses (GPLv3).
|
|||
See LICENSE and COMMERCIAL in the project root for license information.
|
||||
*/
|
||||
/* global FieldValueSet */
|
||||
// 列表附加操作,可在其他页面独立引入
|
||||
// 列表公共操作
|
||||
|
||||
// ~~ 高级查询操作类
|
||||
|
||||
const AdvFilters = {
|
||||
/**
|
||||
* @param {Element} el 控件
|
||||
* @param {String} entity 实体
|
||||
*/
|
||||
init(el, entity) {
|
||||
this.__el = $(el)
|
||||
this.__entity = entity
|
||||
|
||||
this.__el.find('.J_advfilter').click(() => {
|
||||
this.showAdvFilter(null, this.current)
|
||||
this.current = null
|
||||
})
|
||||
const $all = $('.adv-search .dropdown-item:eq(0)')
|
||||
$all.click(() => this._effectFilter($all, 'aside'))
|
||||
|
||||
this.loadFilters()
|
||||
},
|
||||
|
||||
loadFilters() {
|
||||
const lastFilter = $storage.get(RbListPage._RbList.__defaultFilterKey)
|
||||
|
||||
const that = this
|
||||
let $defaultFilter
|
||||
|
||||
$.get(`/app/${this.__entity}/advfilter/list`, function (res) {
|
||||
$('.adv-search .J_custom').each(function () {
|
||||
$(this).remove()
|
||||
})
|
||||
|
||||
const $menu = $('.adv-search .dropdown-menu')
|
||||
$(res.data).each(function () {
|
||||
const item = this
|
||||
const $item = $(`<div class="dropdown-item J_custom" data-id="${item.id}"><a class="text-truncate">${item.name}</a></div>`).appendTo($menu)
|
||||
$item.click(() => that._effectFilter($item, 'aside'))
|
||||
|
||||
if (lastFilter === item.id) $defaultFilter = $item
|
||||
|
||||
// 可修改
|
||||
if (item.editable) {
|
||||
const $action = $(
|
||||
`<div class="action"><a title="${$L('修改')}"><i class="zmdi zmdi-edit"></i></a><a title="${$L('删除')}" class="danger-hover"><i class="zmdi zmdi-delete"></i></a></div>`
|
||||
).appendTo($item)
|
||||
|
||||
$action.find('a:eq(0)').click(function () {
|
||||
that.showAdvFilter(item.id)
|
||||
$('.adv-search .btn.dropdown-toggle').dropdown('toggle')
|
||||
return false
|
||||
})
|
||||
|
||||
$action.find('a:eq(1)').click(function () {
|
||||
RbAlert.create($L('确认删除此高级查询?'), {
|
||||
type: 'danger',
|
||||
confirmText: $L('删除'),
|
||||
confirm: function () {
|
||||
this.disabled(true)
|
||||
$.post(`/app/entity/common-delete?id=${item.id}`, (res) => {
|
||||
if (res.error_code === 0) {
|
||||
this.hide()
|
||||
that.loadFilters()
|
||||
if (lastFilter === item.id) {
|
||||
RbListPage._RbList.setAdvFilter(null)
|
||||
$('.adv-search .J_name').text($L('全部数据'))
|
||||
}
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
return false
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// ASIDE
|
||||
if ($('#asideFilters').length > 0) {
|
||||
const $ghost = $('.adv-search .dropdown-menu').clone()
|
||||
$ghost.removeAttr('class')
|
||||
$ghost.removeAttr('style')
|
||||
$ghost.removeAttr('data-ps-id')
|
||||
$ghost.find('.ps-scrollbar-x-rail, .ps-scrollbar-y-rail').remove()
|
||||
$ghost.find('.dropdown-item').click(function () {
|
||||
$ghost.find('.dropdown-item').removeClass('active')
|
||||
$(this).addClass('active')
|
||||
that._effectFilter($(this), 'aside')
|
||||
})
|
||||
$ghost.appendTo($('#asideFilters').empty())
|
||||
}
|
||||
|
||||
if (!$defaultFilter) $defaultFilter = $('.adv-search .dropdown-item:eq(0)')
|
||||
$defaultFilter.trigger('click')
|
||||
})
|
||||
},
|
||||
|
||||
_effectFilter(item, rel) {
|
||||
this.current = item.data('id')
|
||||
$('.adv-search .J_name').text(item.find('>a').text())
|
||||
if (rel === 'aside') {
|
||||
const current_id = this.current
|
||||
$('#asideFilters .dropdown-item')
|
||||
.removeClass('active')
|
||||
.each(function () {
|
||||
if ($(this).data('id') === current_id) {
|
||||
$(this).addClass('active')
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (this.current === '$ALL$') this.current = null
|
||||
RbListPage._RbList.setAdvFilter(this.current)
|
||||
},
|
||||
|
||||
showAdvFilter(id, useCopyId) {
|
||||
const props = { entity: this.__entity, inModal: true, fromList: true, confirm: this.saveFilter }
|
||||
if (!id) {
|
||||
if (this.__customAdv) {
|
||||
this.__customAdv.show()
|
||||
} else {
|
||||
const that = this
|
||||
if (useCopyId) {
|
||||
this._getFilter(useCopyId, (res) => {
|
||||
renderRbcomp(<AdvFilter {...props} filter={res.filter} />, null, function () {
|
||||
that.__customAdv = this
|
||||
})
|
||||
})
|
||||
} else {
|
||||
renderRbcomp(<AdvFilter {...props} />, null, function () {
|
||||
that.__customAdv = this
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.current = id
|
||||
this._getFilter(id, (res) => {
|
||||
renderRbcomp(<AdvFilter {...props} title={$L('修改高级查询')} filter={res.filter} filterName={res.name} shareTo={res.shareTo} />)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
saveFilter(filter, name, shareTo) {
|
||||
if (!filter) return
|
||||
const that = AdvFilters
|
||||
let url = `/app/${that.__entity}/advfilter/post?id=${that.current || ''}`
|
||||
if (name) url += '&name=' + $encode(name)
|
||||
if (shareTo) url += '&shareTo=' + $encode(shareTo)
|
||||
|
||||
$.post(url, JSON.stringify(filter), (res) => {
|
||||
if (res.error_code === 0) {
|
||||
$storage.set(RbListPage._RbList.__defaultFilterKey, res.data.id)
|
||||
that.loadFilters()
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
_getFilter(id, call) {
|
||||
$.get(`/app/entity/advfilter/get?id=${id}`, (res) => call(res.data))
|
||||
},
|
||||
}
|
||||
|
||||
// ~~ 列表记录批量操作
|
||||
|
||||
|
@ -369,3 +534,48 @@ class BatchUpdateEditor extends React.Component {
|
|||
else return d
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const RbListCommon = {
|
||||
inUrlViewId: null,
|
||||
|
||||
init: function (wpc) {
|
||||
// 全局搜索
|
||||
const gs = $urlp('gs', location.hash)
|
||||
if (gs) $('.search-input-gs, .input-search>input').val($decode(gs))
|
||||
|
||||
// 快速查询
|
||||
const $btn = $('.input-search .btn'),
|
||||
$input = $('.input-search input')
|
||||
$btn.click(() => RbListPage._RbList.searchQuick())
|
||||
$input.keydown((e) => (e.which === 13 ? $btn.trigger('click') : true))
|
||||
|
||||
// via 过滤
|
||||
const via = $urlp('via', location.hash)
|
||||
if (via) {
|
||||
wpc.protocolFilter = `via:${via}`
|
||||
const $cleanVia = $(`<div class="badge filter-badge">${$L('当前数据已过滤')}<a class="close" title="${$L('查看全部数据')}">×</a></div>`).appendTo('.dataTables_filter')
|
||||
$cleanVia.find('a').click(() => {
|
||||
wpc.protocolFilter = null
|
||||
RbListPage.reload()
|
||||
$cleanVia.remove()
|
||||
})
|
||||
}
|
||||
|
||||
// 自动打开新建
|
||||
if (location.hash === '#!/New') $('.J_new').trigger('click')
|
||||
|
||||
const entity = wpc.entity
|
||||
|
||||
// 新建
|
||||
$('.J_new').click(() => RbFormModal.create({ title: $L('新建%s', entity[1]), entity: entity[0], icon: entity[2] }))
|
||||
// 导出
|
||||
$('.J_export').click(() => renderRbcomp(<DataExport listRef={RbListPage._RbList} entity={entity[0]} />))
|
||||
// 批量修改
|
||||
$('.J_batch').click(() => renderRbcomp(<BatchUpdate listRef={RbListPage._RbList} entity={entity[0]} />))
|
||||
|
||||
RbListPage.init(wpc.listConfig, entity, wpc.privileges)
|
||||
|
||||
if (wpc.advFilter !== false) AdvFilters.init('.adv-search', entity[0])
|
||||
},
|
||||
}
|
|
@ -15,6 +15,7 @@ const COLUMN_DEF_WIDTH = 130
|
|||
const supportFixedColumns = !($.browser.msie || $.browser.msedge) && $(window).width() > 767
|
||||
|
||||
// ~~ 数据列表
|
||||
|
||||
class RbList extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -115,7 +116,7 @@ class RbList extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{this.state.rowsData.length > 0 && <RbListPagination ref={(c) => (this._pagination = c)} pageSize={this.pageSize} $$$parent={this} />}
|
||||
{this.state.rowsData.length > 0 && <RbListPagination ref={(c) => (this._Pagination = c)} pageSize={this.pageSize} $$$parent={this} />}
|
||||
{this.state.inLoad === true && <RbSpinner />}
|
||||
</React.Fragment>
|
||||
)
|
||||
|
@ -191,9 +192,12 @@ class RbList extends React.Component {
|
|||
fields.push(item.field)
|
||||
if (item.sort) fieldSort = item.field + ':' + item.sort.replace('sort-', '')
|
||||
})
|
||||
this.lastFilter = filter || this.lastFilter
|
||||
|
||||
const entity = this.props.config.entity
|
||||
this.lastFilter = filter || this.lastFilter
|
||||
const reload = this._forceReload || this.pageNo === 1
|
||||
this._forceReload = false
|
||||
|
||||
const query = {
|
||||
entity: entity,
|
||||
fields: fields,
|
||||
|
@ -203,7 +207,7 @@ class RbList extends React.Component {
|
|||
advFilter: this.advFilterId,
|
||||
protocolFilter: wpc.protocolFilter,
|
||||
sort: fieldSort,
|
||||
reload: this.pageNo === 1,
|
||||
reload: reload,
|
||||
}
|
||||
this.__lastQueryEntry = query
|
||||
|
||||
|
@ -219,8 +223,8 @@ class RbList extends React.Component {
|
|||
$(this._rblistScroller).scrollTop(0)
|
||||
})
|
||||
|
||||
if (res.data.total > 0) {
|
||||
this._pagination.setState({ rowsTotal: res.data.total, rowsStats: res.data.stats, pageNo: this.pageNo })
|
||||
if (reload && this._Pagination) {
|
||||
this._Pagination.setState({ rowsTotal: res.data.total, rowsStats: res.data.stats, pageNo: this.pageNo })
|
||||
}
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
|
@ -308,7 +312,7 @@ class RbList extends React.Component {
|
|||
}
|
||||
|
||||
// 分页组件
|
||||
this._pagination && this._pagination.setState({ selectedTotal: chkSelected })
|
||||
this._Pagination && this._Pagination.setState({ selectedTotal: chkSelected })
|
||||
}
|
||||
|
||||
_clearSelected() {
|
||||
|
@ -386,6 +390,14 @@ class RbList extends React.Component {
|
|||
else $storage.remove(this.__defaultFilterKey)
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载
|
||||
*/
|
||||
reload() {
|
||||
this._forceReload = true
|
||||
this.fetchList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
*/
|
||||
|
@ -401,9 +413,6 @@ class RbList extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
// Alias `fetchList`
|
||||
reload = () => this.fetchList()
|
||||
|
||||
// @el - search element
|
||||
searchQuick = (el) => this.search(this.__buildQuick(el))
|
||||
|
||||
|
@ -439,7 +448,7 @@ class RbList extends React.Component {
|
|||
* 获取最后查询记录总数
|
||||
*/
|
||||
getLastQueryTotal() {
|
||||
return this._pagination ? this._pagination.state.rowsTotal : 0
|
||||
return this._Pagination ? this._Pagination.state.rowsTotal : 0
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -697,6 +706,7 @@ CellRenders.addRender('AVATAR', function (v, s, k) {
|
|||
})
|
||||
|
||||
// ~ 分页组件
|
||||
|
||||
class RbListPagination extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -816,7 +826,8 @@ class RbListPagination extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
// 列表页操作类
|
||||
// ~~ 列表操作
|
||||
|
||||
const RbListPage = {
|
||||
_RbList: null,
|
||||
|
||||
|
@ -835,7 +846,6 @@ const RbListPage = {
|
|||
|
||||
const that = this
|
||||
|
||||
$('.J_new').click(() => RbFormModal.create({ title: $L('新建%s', entity[1]), entity: entity[0], icon: entity[2] }))
|
||||
$('.J_edit').click(() => {
|
||||
const ids = this._RbList.getSelectedIds()
|
||||
if (ids.length >= 1) {
|
||||
|
@ -859,6 +869,7 @@ const RbListPage = {
|
|||
RbViewModal.create({ id: ids[0], entity: entity[0] })
|
||||
}
|
||||
})
|
||||
|
||||
$('.J_columns').click(() => RbModal.create(`/p/general/show-fields?entity=${entity[0]}`, $L('设置列显示')))
|
||||
|
||||
// 权限实体才有
|
||||
|
@ -878,12 +889,6 @@ const RbListPage = {
|
|||
ids.length > 0 && DlgUnshare.create({ entity: entity[0], ids: ids })
|
||||
})
|
||||
|
||||
// in `rb-datalist.append.js`
|
||||
// eslint-disable-next-line react/jsx-no-undef
|
||||
$('.J_export').click(() => renderRbcomp(<DataExport listRef={RbListPage._RbList} entity={entity[0]} />))
|
||||
// eslint-disable-next-line react/jsx-no-undef
|
||||
$('.J_batch').click(() => renderRbcomp(<BatchUpdate listRef={RbListPage._RbList} entity={entity[0]} />))
|
||||
|
||||
// Privileges
|
||||
if (ep) {
|
||||
if (ep.C === false) $('.J_new').remove()
|
||||
|
@ -893,12 +898,6 @@ const RbListPage = {
|
|||
if (ep.S !== true) $('.J_share, .J_unshare').remove()
|
||||
$cleanMenu('.J_action')
|
||||
}
|
||||
|
||||
// Quick search
|
||||
const $btn = $('.input-search .btn'),
|
||||
$input = $('.input-search input')
|
||||
$btn.click(() => this._RbList.searchQuick())
|
||||
$input.keydown((e) => (e.which === 13 ? $btn.trigger('click') : true))
|
||||
},
|
||||
|
||||
reload() {
|
||||
|
@ -906,191 +905,8 @@ const RbListPage = {
|
|||
},
|
||||
}
|
||||
|
||||
// 高级查询操作类
|
||||
const AdvFilters = {
|
||||
/**
|
||||
* @param {Element} el 控件
|
||||
* @param {String} entity 实体
|
||||
*/
|
||||
init(el, entity) {
|
||||
this.__el = $(el)
|
||||
this.__entity = entity
|
||||
// ~~ 视图
|
||||
|
||||
this.__el.find('.J_advfilter').click(() => {
|
||||
this.showAdvFilter(null, this.current)
|
||||
this.current = null
|
||||
})
|
||||
const $all = $('.adv-search .dropdown-item:eq(0)')
|
||||
$all.click(() => this.__effectFilter($all, 'aside'))
|
||||
|
||||
this.loadFilters()
|
||||
},
|
||||
|
||||
loadFilters() {
|
||||
const lastFilter = $storage.get(RbListPage._RbList.__defaultFilterKey)
|
||||
|
||||
const that = this
|
||||
let $defaultFilter
|
||||
|
||||
$.get(`/app/${this.__entity}/advfilter/list`, function (res) {
|
||||
$('.adv-search .J_custom').each(function () {
|
||||
$(this).remove()
|
||||
})
|
||||
|
||||
const $menu = $('.adv-search .dropdown-menu')
|
||||
$(res.data).each(function () {
|
||||
const item = this
|
||||
const $item = $(`<div class="dropdown-item J_custom" data-id="${item.id}"><a class="text-truncate">${item.name}</a></div>`).appendTo($menu)
|
||||
$item.click(() => that.__effectFilter($item, 'aside'))
|
||||
|
||||
if (lastFilter === item.id) $defaultFilter = $item
|
||||
|
||||
// 可修改
|
||||
if (item.editable) {
|
||||
const $action = $(`<div class="action"><a title="${$L('修改')}"><i class="zmdi zmdi-edit"></i></a><a title="${$L('删除')}" class="danger-hover"><i class="zmdi zmdi-delete"></i></a></div>`).appendTo($item)
|
||||
|
||||
$action.find('a:eq(0)').click(function () {
|
||||
that.showAdvFilter(item.id)
|
||||
$('.adv-search .btn.dropdown-toggle').dropdown('toggle')
|
||||
return false
|
||||
})
|
||||
|
||||
$action.find('a:eq(1)').click(function () {
|
||||
RbAlert.create($L('确认删除此高级查询?'), {
|
||||
type: 'danger',
|
||||
confirmText: $L('删除'),
|
||||
confirm: function () {
|
||||
this.disabled(true)
|
||||
$.post(`/app/entity/common-delete?id=${item.id}`, (res) => {
|
||||
if (res.error_code === 0) {
|
||||
this.hide()
|
||||
that.loadFilters()
|
||||
if (lastFilter === item.id) {
|
||||
RbListPage._RbList.setAdvFilter(null)
|
||||
$('.adv-search .J_name').text($L('全部数据'))
|
||||
}
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
return false
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// ASIDE
|
||||
if ($('#asideFilters').length > 0) {
|
||||
const $ghost = $('.adv-search .dropdown-menu').clone()
|
||||
$ghost.removeAttr('class')
|
||||
$ghost.removeAttr('style')
|
||||
$ghost.removeAttr('data-ps-id')
|
||||
$ghost.find('.ps-scrollbar-x-rail, .ps-scrollbar-y-rail').remove()
|
||||
$ghost.find('.dropdown-item').click(function () {
|
||||
$ghost.find('.dropdown-item').removeClass('active')
|
||||
$(this).addClass('active')
|
||||
that.__effectFilter($(this), 'aside')
|
||||
})
|
||||
$ghost.appendTo($('#asideFilters').empty())
|
||||
}
|
||||
|
||||
if (!$defaultFilter) $defaultFilter = $('.adv-search .dropdown-item:eq(0)')
|
||||
$defaultFilter.trigger('click')
|
||||
})
|
||||
},
|
||||
|
||||
__effectFilter(item, rel) {
|
||||
this.current = item.data('id')
|
||||
$('.adv-search .J_name').text(item.find('>a').text())
|
||||
if (rel === 'aside') {
|
||||
const current_id = this.current
|
||||
$('#asideFilters .dropdown-item')
|
||||
.removeClass('active')
|
||||
.each(function () {
|
||||
if ($(this).data('id') === current_id) {
|
||||
$(this).addClass('active')
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (this.current === '$ALL$') this.current = null
|
||||
RbListPage._RbList.setAdvFilter(this.current)
|
||||
},
|
||||
|
||||
showAdvFilter(id, useCopyId) {
|
||||
const props = { entity: this.__entity, inModal: true, fromList: true, confirm: this.saveFilter }
|
||||
if (!id) {
|
||||
if (this.__customAdv) {
|
||||
this.__customAdv.show()
|
||||
} else {
|
||||
const that = this
|
||||
if (useCopyId) {
|
||||
this.__getFilter(useCopyId, (res) => {
|
||||
renderRbcomp(<AdvFilter {...props} filter={res.filter} />, null, function () {
|
||||
that.__customAdv = this
|
||||
})
|
||||
})
|
||||
} else {
|
||||
renderRbcomp(<AdvFilter {...props} />, null, function () {
|
||||
that.__customAdv = this
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.current = id
|
||||
this.__getFilter(id, (res) => {
|
||||
renderRbcomp(<AdvFilter {...props} title={$L('修改高级查询')} filter={res.filter} filterName={res.name} shareTo={res.shareTo} />)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
saveFilter(filter, name, shareTo) {
|
||||
if (!filter) return
|
||||
const that = AdvFilters
|
||||
let url = `/app/${that.__entity}/advfilter/post?id=${that.current || ''}`
|
||||
if (name) url += '&name=' + $encode(name)
|
||||
if (shareTo) url += '&shareTo=' + $encode(shareTo)
|
||||
|
||||
$.post(url, JSON.stringify(filter), (res) => {
|
||||
if (res.error_code === 0) {
|
||||
$storage.set(RbListPage._RbList.__defaultFilterKey, res.data.id)
|
||||
that.loadFilters()
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
__getFilter(id, call) {
|
||||
$.get(`/app/entity/advfilter/get?id=${id}`, (res) => call(res.data))
|
||||
},
|
||||
}
|
||||
|
||||
// init: DataList
|
||||
$(document).ready(() => {
|
||||
const via = $urlp('via', location.hash)
|
||||
if (via) {
|
||||
wpc.protocolFilter = `via:${via}`
|
||||
const $cleanVia = $(`<div class="badge filter-badge">${$L('当前数据已过滤')}<a class="close" title="${$L('查看全部数据')}">×</a></div>`).appendTo('.dataTables_filter')
|
||||
$cleanVia.find('a').click(() => {
|
||||
wpc.protocolFilter = null
|
||||
RbListPage.reload()
|
||||
$cleanVia.remove()
|
||||
})
|
||||
}
|
||||
|
||||
const gs = $urlp('gs', location.hash)
|
||||
if (gs) $('.search-input-gs, .input-search>input').val($decode(gs))
|
||||
if (wpc.entity) {
|
||||
RbListPage.init(wpc.listConfig, wpc.entity, wpc.privileges)
|
||||
if (wpc.advFilter !== false) AdvFilters.init('.adv-search', wpc.entity[0])
|
||||
}
|
||||
})
|
||||
|
||||
// -- for View
|
||||
// ~~视图窗口(右侧滑出)
|
||||
class RbViewModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -1244,6 +1060,7 @@ class RbViewModal extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
// 复写
|
||||
window.chart_remove = function (box) {
|
||||
box.parent().animate({ opacity: 0 }, function () {
|
||||
box.parent().remove()
|
||||
|
@ -1318,17 +1135,12 @@ const ChartsWidget = {
|
|||
}
|
||||
|
||||
$(document).ready(() => {
|
||||
// 自动打开 View
|
||||
let viewHash = location.hash
|
||||
if (viewHash && viewHash.startsWith('#!/View/') && (wpc.type === 'RecordList' || wpc.type === 'DetailList')) {
|
||||
viewHash = viewHash.split('/')
|
||||
if (viewHash.length === 4 && viewHash[3].length === 20) {
|
||||
setTimeout(() => {
|
||||
RbViewModal.create({ entity: viewHash[2], id: viewHash[3] })
|
||||
}, 500)
|
||||
}
|
||||
} else if (viewHash === '#!/New') {
|
||||
$('.J_new').trigger('click')
|
||||
// eslint-disable-next-line no-undef
|
||||
RbListCommon.init(wpc)
|
||||
|
||||
const viewHash = (location.hash || '').split('/')
|
||||
if ((wpc.type === 'RecordList' || wpc.type === 'DetailList') && viewHash.length === 4 && viewHash[1] === 'View' && viewHash[3].length === 20) {
|
||||
setTimeout(() => RbViewModal.create({ entity: viewHash[2], id: viewHash[3] }), 500)
|
||||
}
|
||||
|
||||
// ASIDE
|
||||
|
|
|
@ -337,7 +337,7 @@ class RbForm extends React.Component {
|
|||
RbHighbar.success($L('保存成功'))
|
||||
setTimeout(() => {
|
||||
this.props.$$$parent.hide(true)
|
||||
RbForm.postAfter(res.data, next)
|
||||
RbForm.postAfter({ ...res.data, _isNew: !this.state.id }, next)
|
||||
|
||||
if (next === RbForm.__NEXT_ADD) {
|
||||
const pstate = this.props.$$$parent.state
|
||||
|
@ -369,8 +369,7 @@ class RbForm extends React.Component {
|
|||
return true
|
||||
}
|
||||
|
||||
// 保存前调用,返回 false 则不继续保存
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// 保存前调用(返回 false 则不继续保存)
|
||||
static postBefore(data) {
|
||||
if (window.FrontJS) {
|
||||
const ret = window.FrontJS.Form._trigger('saveBefore', [data])
|
||||
|
|
|
@ -307,7 +307,7 @@ class EntityRelatedList extends RelatedList {
|
|||
this.__entity = props.entity.split('.')[0]
|
||||
const openListUrl = `${rb.baseUrl}/app/${this.__entity}/list?via=${this.props.mainid}:${this.props.entity}`
|
||||
this.__listExtraLink = (
|
||||
<a className="btn btn-link w-auto" href={openListUrl} target="_blank" title={$L('列表页查看')}>
|
||||
<a className="btn btn-light w-auto" href={openListUrl} target="_blank" title={$L('列表页查看')}>
|
||||
<i className="icon zmdi zmdi-open-in-new" />
|
||||
</a>
|
||||
)
|
||||
|
@ -562,7 +562,7 @@ const RbViewPage = {
|
|||
}
|
||||
|
||||
// Clean buttons
|
||||
that.cleanViewActionButton()
|
||||
that._cleanViewActionButton()
|
||||
|
||||
that.initRecordMeta()
|
||||
that.initHistory()
|
||||
|
@ -585,13 +585,13 @@ const RbViewPage = {
|
|||
if ($el.length === 0) continue
|
||||
|
||||
if (k === 'owningUser') {
|
||||
renderRbcomp(<UserShow id={v[0]} name={v[1]} showName={true} deptName={v[2]} onClick={() => this.clickViewUser(v[0])} />, $el[0])
|
||||
renderRbcomp(<UserShow id={v[0]} name={v[1]} showName={true} deptName={v[2]} onClick={() => this._clickViewUser(v[0])} />, $el[0])
|
||||
} else if (k === 'sharingList') {
|
||||
const $list = $('<ul class="list-unstyled list-inline mb-0"></ul>').appendTo($('.J_sharingList').empty())
|
||||
$(v).each(function () {
|
||||
const _this = this
|
||||
const $item = $('<li class="list-inline-item"></li>').appendTo($list)
|
||||
renderRbcomp(<UserShow id={_this[0]} name={_this[1]} onClick={() => that.clickViewUser(_this[0])} />, $item[0])
|
||||
renderRbcomp(<UserShow id={_this[0]} name={_this[1]} onClick={() => that._clickViewUser(_this[0])} />, $item[0])
|
||||
})
|
||||
|
||||
if (this.__ep && this.__ep.S === true) {
|
||||
|
@ -779,12 +779,12 @@ const RbViewPage = {
|
|||
return false
|
||||
},
|
||||
|
||||
clickViewUser(id) {
|
||||
_clickViewUser(id) {
|
||||
return this.clickView('#!/View/User/' + id)
|
||||
},
|
||||
|
||||
// 清理操作按钮
|
||||
cleanViewActionButton() {
|
||||
_cleanViewActionButton() {
|
||||
$setTimeout(
|
||||
() => {
|
||||
$cleanMenu('.view-action .J_mores')
|
||||
|
@ -796,11 +796,11 @@ const RbViewPage = {
|
|||
if ($('.view-action').children().length === 0) $('.view-action').addClass('empty').empty()
|
||||
},
|
||||
100,
|
||||
'cleanViewActionButton'
|
||||
'_cleanViewActionButton'
|
||||
)
|
||||
},
|
||||
|
||||
// 隐藏划出的 View
|
||||
// 隐藏
|
||||
hide(reload) {
|
||||
if (parent && parent !== window) {
|
||||
parent && parent.RbViewModal && parent.RbViewModal.holder(this.__id, 'HIDE')
|
||||
|
@ -823,12 +823,21 @@ const RbViewPage = {
|
|||
setReadonly() {
|
||||
$(this._RbViewForm._viewForm).addClass('readonly')
|
||||
$('.J_edit, .J_delete, .J_add-detail').remove()
|
||||
this.cleanViewActionButton()
|
||||
this._cleanViewActionButton()
|
||||
},
|
||||
}
|
||||
|
||||
// init
|
||||
$(document).ready(function () {
|
||||
// 无关闭按钮
|
||||
if (parent && parent.RbViewModal && parent.RbViewModal.hideClose) $('.J_close').remove()
|
||||
|
||||
// iframe 点击穿透
|
||||
if (parent) {
|
||||
$(document).on('click', () => parent.$(parent.document).trigger('_clickEventHandler'))
|
||||
window._clickEventHandler = () => $(document).trigger('click')
|
||||
}
|
||||
|
||||
if (wpc.entity) {
|
||||
RbViewPage.init(wpc.recordId, wpc.entity, wpc.privileges)
|
||||
if (wpc.viewTabs) RbViewPage.initVTabs(wpc.viewTabs)
|
||||
|
|
|
@ -114,14 +114,15 @@
|
|||
</script>
|
||||
<script th:src="@{/assets/lib/charts/echarts.min.js}"></script>
|
||||
<script th:src="@{/assets/js/charts/charts.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-datalist.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/metadata/field-compatible.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/metadata/field-valueset.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-datalist.append.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-forms.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-forms.append.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-advfilter.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-assignshare.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-approval.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/settings-share2.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-datalist.common.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-datalist.js}" type="text/babel"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -118,15 +118,15 @@
|
|||
</script>
|
||||
<script th:src="@{/assets/lib/charts/echarts.min.js}"></script>
|
||||
<script th:src="@{/assets/js/charts/charts.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-datalist.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/metadata/field-compatible.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/metadata/field-valueset.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-datalist.append.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-forms.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-forms.append.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-advfilter.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-assignshare.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-approval.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/settings-share2.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-datalist.common.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-datalist.js}" type="text/babel"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
}
|
||||
</script>
|
||||
<script th:src="@{/assets/js/rb-datalist.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-datalist.common.js}" type="text/babel"></script>
|
||||
<script type="text/babel">
|
||||
RbList.renderAfter = function () {
|
||||
parent && parent.referenceSearch__dlg && parent.referenceSearch__dlg.resize()
|
||||
|
|
Loading…
Reference in a new issue