mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 15:35:55 +08:00
Merge pull request #269 from getrebuild/related-expand-612
Related expand 612
This commit is contained in:
commit
d4202951c2
|
@ -28,9 +28,13 @@ import java.util.Set;
|
|||
*/
|
||||
public abstract class ShareToManager implements ConfigManager {
|
||||
|
||||
// 共享给全部
|
||||
/**
|
||||
* 共享给全部
|
||||
*/
|
||||
public static final String SHARE_ALL = "ALL";
|
||||
// 私有
|
||||
/**
|
||||
* 私有
|
||||
*/
|
||||
public static final String SHARE_SELF = "SELF";
|
||||
|
||||
/**
|
||||
|
@ -72,9 +76,7 @@ public abstract class ShareToManager implements ConfigManager {
|
|||
*/
|
||||
public ID detectUseConfig(ID user, String belongEntity, String applyType) {
|
||||
final Object[][] alls = getAllConfig(belongEntity, applyType);
|
||||
if (alls.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (alls.length == 0) return null;
|
||||
|
||||
// 1.优先使用自己的
|
||||
for (Object[] d : alls) {
|
||||
|
@ -134,7 +136,8 @@ public abstract class ShareToManager implements ConfigManager {
|
|||
sqlWhere.add(String.format("applyType = '%s'", applyType));
|
||||
}
|
||||
|
||||
String ql = String.format("select %s from %s where (1=1) order by modifiedOn desc", getConfigFields(), getConfigEntity());
|
||||
String ql = String.format(
|
||||
"select %s from %s where (1=1) order by modifiedOn desc", getConfigFields(), getConfigEntity());
|
||||
if (!sqlWhere.isEmpty()) {
|
||||
ql = ql.replace("(1=1)", StringUtils.join(sqlWhere.iterator(), " and "));
|
||||
}
|
||||
|
|
|
@ -20,8 +20,13 @@ import com.rebuild.core.configuration.ConfigBean;
|
|||
import com.rebuild.core.metadata.EntityHelper;
|
||||
import com.rebuild.core.metadata.MetadataHelper;
|
||||
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
|
||||
import com.rebuild.core.support.i18n.Language;
|
||||
import com.rebuild.utils.JSONUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 视图-相关项/新建相关
|
||||
|
@ -43,12 +48,14 @@ public class ViewAddonsManager extends BaseLayoutManager {
|
|||
public static final String EF_SPLIT = ".";
|
||||
|
||||
/**
|
||||
* 显示项
|
||||
*
|
||||
* @param entity
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public JSON getViewTab(String entity, ID user) {
|
||||
JSON tabs = getViewAddons(entity, user, TYPE_TAB);
|
||||
public JSONObject getViewTab(String entity, ID user) {
|
||||
JSONObject vtabs = getViewAddons(entity, user, TYPE_TAB);
|
||||
|
||||
// 添加明细实体到第一个
|
||||
Entity entityMeta = MetadataHelper.getEntity(entity);
|
||||
|
@ -56,18 +63,20 @@ public class ViewAddonsManager extends BaseLayoutManager {
|
|||
JSON detail = EasyMetaFactory.toJSON(entityMeta.getDetailEntity());
|
||||
JSONArray tabsFluent = new JSONArray();
|
||||
tabsFluent.add(detail);
|
||||
tabsFluent.fluentAddAll((Collection<?>) tabs);
|
||||
tabs = tabsFluent;
|
||||
tabsFluent.fluentAddAll(vtabs.getJSONArray("items"));
|
||||
vtabs.put("items", tabsFluent);
|
||||
}
|
||||
return tabs;
|
||||
return vtabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建项
|
||||
*
|
||||
* @param entity
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public JSON getViewAdd(String entity, ID user) {
|
||||
public JSONObject getViewAdd(String entity, ID user) {
|
||||
return getViewAddons(entity, user, TYPE_ADD);
|
||||
}
|
||||
|
||||
|
@ -77,35 +86,35 @@ public class ViewAddonsManager extends BaseLayoutManager {
|
|||
* @param applyType
|
||||
* @return
|
||||
*/
|
||||
private JSON getViewAddons(String entity, ID user, String applyType) {
|
||||
private JSONObject getViewAddons(String entity, ID user, String applyType) {
|
||||
final ConfigBean config = getLayout(user, entity, applyType);
|
||||
final Permission useAction = TYPE_TAB.equals(applyType) ? BizzPermission.READ : BizzPermission.CREATE;
|
||||
|
||||
final Entity entityMeta = MetadataHelper.getEntity(entity);
|
||||
final Set<Entity> mfRefs = hasMultiFieldsReferenceTo(entityMeta);
|
||||
|
||||
// 未配置则使用全部相关项
|
||||
// 未配置则使用全部
|
||||
if (config == null) {
|
||||
JSONArray refs = new JSONArray();
|
||||
JSONArray useRefs = new JSONArray();
|
||||
for (Field field : entityMeta.getReferenceToFields(true)) {
|
||||
Entity e = field.getOwnEntity();
|
||||
if (e.getMainEntity() == null &&
|
||||
Application.getPrivilegesManager().allow(user, e.getEntityCode(), useAction)) {
|
||||
refs.add(getEntityShow(field, mfRefs, applyType));
|
||||
useRefs.add(getEntityShow(field, mfRefs, applyType));
|
||||
}
|
||||
}
|
||||
|
||||
// 动态(跟进)
|
||||
// if (TYPE_TAB.equalsIgnoreCase(applyType)) {
|
||||
// Field relatedRecordOfFeeds = MetadataHelper.getField("Feeds", "relatedRecord");
|
||||
// refs.add(getEntityShow(relatedRecordOfFeeds, Collections.emptySet(), applyType));
|
||||
// }
|
||||
return JSONUtils.toJSONObject("items", useRefs);
|
||||
}
|
||||
|
||||
return refs;
|
||||
// fix: v2.2 兼容
|
||||
JSON configJson = config.getJSON("config");
|
||||
if (configJson instanceof JSONArray) {
|
||||
configJson = JSONUtils.toJSONObject("items", configJson);
|
||||
}
|
||||
|
||||
JSONArray addons = new JSONArray();
|
||||
for (Object o : (JSONArray) config.getJSON("config")) {
|
||||
for (Object o : ((JSONObject) configJson).getJSONArray ("items")) {
|
||||
// Entity.Field (v1.9)
|
||||
String[] e = ((String) o).split("\\.");
|
||||
if (!MetadataHelper.containsEntity(e[0])) {
|
||||
|
@ -125,7 +134,10 @@ public class ViewAddonsManager extends BaseLayoutManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
return addons;
|
||||
|
||||
return JSONUtils.toJSONObject(
|
||||
new String[] { "items", "autoExpand" },
|
||||
new Object[] { addons, ((JSONObject) configJson).getBooleanValue("autoExpand") });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,10 +169,6 @@ public class ViewAddonsManager extends BaseLayoutManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param field
|
||||
* @param mfRefs
|
||||
* @param applyType
|
||||
* @return
|
||||
* @see EasyMetaFactory#toJSON(Entity)
|
||||
*/
|
||||
private JSONObject getEntityShow(Field field, Set<Entity> mfRefs, String applyType) {
|
||||
|
@ -174,7 +182,7 @@ public class ViewAddonsManager extends BaseLayoutManager {
|
|||
: String.format("%s (%s)", show.getString("entityLabel"), EasyMetaFactory.getLabel(field));
|
||||
show.put("entityLabel", entityLabel);
|
||||
} else if (fieldEntity.getEntityCode() == EntityHelper.Feeds) {
|
||||
show.put("entityLabel", "跟进");
|
||||
show.put("entityLabel", Language.L("e.Feeds"));
|
||||
}
|
||||
return show;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import cn.devezhao.persist4j.Field;
|
|||
import cn.devezhao.persist4j.Record;
|
||||
import cn.devezhao.persist4j.engine.ID;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.rebuild.api.RespBody;
|
||||
import com.rebuild.core.Application;
|
||||
import com.rebuild.core.configuration.ConfigBean;
|
||||
import com.rebuild.core.configuration.general.LayoutConfigService;
|
||||
|
@ -20,16 +22,12 @@ import com.rebuild.core.configuration.general.ViewAddonsManager;
|
|||
import com.rebuild.core.metadata.EntityHelper;
|
||||
import com.rebuild.core.metadata.MetadataHelper;
|
||||
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
|
||||
import com.rebuild.core.support.i18n.Language;
|
||||
import com.rebuild.utils.JSONUtils;
|
||||
import com.rebuild.web.BaseController;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -39,18 +37,18 @@ import java.util.Set;
|
|||
* @author devezhao
|
||||
* @since 10/23/2018
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping("/admin/entity/")
|
||||
public class ViewAddonsController extends BaseController {
|
||||
|
||||
@PostMapping("{entity}/view-addons")
|
||||
public void sets(@PathVariable String entity,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
ID user = getRequestUser(request);
|
||||
public RespBody sets(@PathVariable String entity, HttpServletRequest request) {
|
||||
final ID user = getRequestUser(request);
|
||||
String applyType = getParameter(request, "type", ViewAddonsManager.TYPE_TAB);
|
||||
JSON config = ServletUtils.getRequestJson(request);
|
||||
|
||||
ID configId = ViewAddonsManager.instance.detectUseConfig(user, entity, applyType);
|
||||
|
||||
Record record;
|
||||
if (configId == null) {
|
||||
record = EntityHelper.forNew(EntityHelper.LayoutConfig, user);
|
||||
|
@ -63,18 +61,22 @@ public class ViewAddonsController extends BaseController {
|
|||
record.setString("config", config.toJSONString());
|
||||
Application.getBean(LayoutConfigService.class).createOrUpdate(record);
|
||||
|
||||
writeSuccess(response);
|
||||
return RespBody.ok();
|
||||
}
|
||||
|
||||
@GetMapping("{entity}/view-addons")
|
||||
public void gets(@PathVariable String entity,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
ID user = getRequestUser(request);
|
||||
public JSON gets(@PathVariable String entity, HttpServletRequest request) {
|
||||
final ID user = getRequestUser(request);
|
||||
String applyType = getParameter(request, "type", ViewAddonsManager.TYPE_TAB);
|
||||
|
||||
Entity entityMeta = MetadataHelper.getEntity(entity);
|
||||
ConfigBean config = ViewAddonsManager.instance.getLayout(user, entity, applyType);
|
||||
// fix: v2.2 兼容
|
||||
JSON configJson = config == null ? null : config.getJSON("config");
|
||||
if (configJson instanceof JSONArray) {
|
||||
configJson = JSONUtils.toJSONObject("items", configJson);
|
||||
}
|
||||
|
||||
Entity entityMeta = MetadataHelper.getEntity(entity);
|
||||
Set<Entity> mfRefs = ViewAddonsManager.hasMultiFieldsReferenceTo(entityMeta);
|
||||
|
||||
Set<String[]> refs = new HashSet<>();
|
||||
|
@ -88,17 +90,16 @@ public class ViewAddonsController extends BaseController {
|
|||
if (mfRefs.contains(e)) {
|
||||
label = EasyMetaFactory.getLabel(field) + " (" + label + ")";
|
||||
}
|
||||
refs.add(new String[]{e.getName() + ViewAddonsManager.EF_SPLIT + field.getName(), label});
|
||||
refs.add(new String[] { e.getName() + ViewAddonsManager.EF_SPLIT + field.getName(), label });
|
||||
}
|
||||
|
||||
// 跟进(动态)
|
||||
if (ViewAddonsManager.TYPE_TAB.equalsIgnoreCase(applyType)) {
|
||||
refs.add(new String[]{"Feeds.relatedRecord", "跟进"});
|
||||
refs.add(new String[] { "Feeds.relatedRecord", Language.L("e.Feeds") });
|
||||
}
|
||||
|
||||
JSON ret = JSONUtils.toJSONObject(
|
||||
new String[]{"config", "refs"},
|
||||
new Object[]{config == null ? null : config.getJSON("config"), refs});
|
||||
writeSuccess(response, ret);
|
||||
return JSONUtils.toJSONObject(
|
||||
new String[] { "config", "refs" },
|
||||
new Object[] { configJson, refs });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,10 +60,11 @@ public class GeneralModelController extends EntityController {
|
|||
} else {
|
||||
mv = createModelAndView("/general/record-view", id, user);
|
||||
|
||||
JSON vtab = ViewAddonsManager.instance.getViewTab(entity, user);
|
||||
mv.getModel().put("ViewTabs", vtab);
|
||||
JSON vadd = ViewAddonsManager.instance.getViewAdd(entity, user);
|
||||
mv.getModel().put("ViewAdds", vadd);
|
||||
JSONObject vtab = ViewAddonsManager.instance.getViewTab(entity, user);
|
||||
mv.getModel().put("ViewTabs", vtab.getJSONArray("items"));
|
||||
mv.getModel().put("ViewTabsAutoExpand", vtab.getBooleanValue("autoExpand"));
|
||||
JSONObject vadd = ViewAddonsManager.instance.getViewAdd(entity, user);
|
||||
mv.getModel().put("ViewAdds", vadd.getJSONArray("items"));
|
||||
}
|
||||
|
||||
// 记录转换
|
||||
|
|
|
@ -1274,6 +1274,7 @@
|
|||
"BadOrDeleteApproval": "Invalid approval, may have been deleted",
|
||||
"FormCalcFormula": "Form Calculation Formula",
|
||||
"FormCalcFormulaTips": "If the fields used in the formula are not layout/displayed, calculations cannot be performed. More powerful calculation rules can be achieved through [Trigger (Data Aggregation)](/admin/robot/triggers)",
|
||||
"RelatedAutoExpand": "Automatically expand tab records",
|
||||
|
||||
"s.__": "STATE",
|
||||
"s.ApprovalState.DRAFT": "Draft",
|
||||
|
|
|
@ -1274,6 +1274,7 @@
|
|||
"BadOrDeleteApproval": "无效审批流程,可能已被删除",
|
||||
"FormCalcFormula": "表单计算公式",
|
||||
"FormCalcFormulaTips": "如公式中所用字段未布局/未显示,则无法进行计算。通过 [触发器 (数据聚合)](/admin/robot/triggers) 可以实现更加强大的计算规则",
|
||||
"RelatedAutoExpand": "自动展开显示项记录",
|
||||
|
||||
"s.__": "状态",
|
||||
"s.ApprovalState.DRAFT": "草稿",
|
||||
|
|
|
@ -1274,6 +1274,7 @@
|
|||
"BadOrDeleteApproval": "無效審批流程,可能已被刪除",
|
||||
"FormCalcFormula": "表單計算公式",
|
||||
"FormCalcFormulaTips": "如公式中所用字段未佈局/未顯示,則無法進行計算。通過 [觸發器(數據聚合](/admin/robot/triggers) 可以實現更加強大的計算規則",
|
||||
"RelatedAutoExpand": "自動展開顯示項記錄",
|
||||
|
||||
"s.__": "狀態",
|
||||
"s.ApprovalState.DRAFT": "草稿",
|
||||
|
|
|
@ -22,6 +22,12 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="dialog-footer">
|
||||
<span th:if="${param.type[0] == 'TAB'}" class="float-left">
|
||||
<label class="custom-control custom-control-sm custom-checkbox custom-control-inline">
|
||||
<input class="custom-control-input" type="checkbox" id="relatedAutoExpand" />
|
||||
<span class="custom-control-label">[[${bundle.L('RelatedAutoExpand')}]]</span>
|
||||
</label>
|
||||
</span>
|
||||
<button class="btn btn-primary J_save" type="button">[[${bundle.L('Save')}]]</button>
|
||||
<button class="btn btn-secondary" onclick="parent.RbModal.hide()" type="button">[[${bundle.L('Cancel')}]]</button>
|
||||
</div>
|
||||
|
@ -32,28 +38,40 @@
|
|||
$(document).ready(function () {
|
||||
const entity = $urlp('entity'),
|
||||
type = $urlp('type')
|
||||
const _url = '/admin/entity/' + entity + '/view-addons?type=' + type
|
||||
const _url = `/admin/entity/${entity}/view-addons?type=${type}`
|
||||
|
||||
$.get(_url, function (res) {
|
||||
$(res.data.refs).each(function () {
|
||||
render_unset(this)
|
||||
})
|
||||
$(res.data.config).each(function () {
|
||||
$('.unset-list li[data-key="' + this + '"]').trigger('click')
|
||||
})
|
||||
if (!res.data.refs || res.data.refs.length === 0) $(`<li class="dd-item nodata">${$L('NoData')}</li>`).appendTo('.unset-list')
|
||||
|
||||
if (res.data.config) {
|
||||
$(res.data.config.items).each(function () {
|
||||
$('.unset-list li[data-key="' + this + '"]').trigger('click')
|
||||
})
|
||||
$('#relatedAutoExpand').attr('checked', res.data.config.autoExpand === true)
|
||||
}
|
||||
|
||||
if (!res.data.refs || res.data.refs.length === 0) {
|
||||
$(`<li class="dd-item nodata">${$L('NoData')}</li>`).appendTo('.unset-list')
|
||||
}
|
||||
})
|
||||
|
||||
const $btn = $('.J_save').click(function () {
|
||||
const config = []
|
||||
let config = []
|
||||
$('.J_config>li').each(function () {
|
||||
config.push($(this).data('key'))
|
||||
})
|
||||
config = {
|
||||
items: config,
|
||||
autoExpand: $val('#relatedAutoExpand'),
|
||||
}
|
||||
|
||||
$btn.button('loading')
|
||||
$.post(_url, JSON.stringify(config), function (res) {
|
||||
$btn.button('reset')
|
||||
if (res.error_code === 0) parent.location.reload()
|
||||
else RbHighbar.error(res.error_msg)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -140,13 +140,12 @@ body {
|
|||
|
||||
.related-list .card {
|
||||
border: 1px solid #ebebeb;
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.04);
|
||||
padding: 0;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.related-list .card:hover {
|
||||
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
|
||||
.related-list .card .header-title {
|
||||
|
|
|
@ -249,7 +249,7 @@ class RelatedList extends React.Component {
|
|||
)}
|
||||
{(this.state.list || []).map((item) => {
|
||||
return (
|
||||
<div className={`card ${this.state.viewOpens[item[0]] ? 'active' : ''}`} key={`rr-${item[0]}`}>
|
||||
<div className={`card ${this.state.viewOpens[item[0]] ? 'active' : ''}`} key={item[0]} ref={`item-${item[0]}`}>
|
||||
<div className="row header-title" onClick={() => this._toggleInsideView(item[0])}>
|
||||
<div className="col-10">
|
||||
<a href={`#!/View/${this.props.entity.split('.')[0]}/${item[0]}`} onClick={(e) => this._handleView(e)} title={$L('Open')}>
|
||||
|
@ -284,11 +284,21 @@ class RelatedList extends React.Component {
|
|||
fetchList(append) {
|
||||
this.__pageNo = this.__pageNo || 1
|
||||
if (append) this.__pageNo += append
|
||||
const pageSize = 20
|
||||
const pageSize = 5
|
||||
|
||||
$.get(`/app/entity/related-list?mainid=${this.props.main}&related=${this.props.entity}&pageNo=${this.__pageNo}&pageSize=${pageSize}`, (res) => {
|
||||
const _data = res.data.data || []
|
||||
const _list = (this.state.list || []).concat(_data)
|
||||
this.setState({ list: _list, showMores: _data.length >= pageSize })
|
||||
const data = res.data.data || []
|
||||
const list = (this.state.list || []).concat(data)
|
||||
|
||||
this.setState({ list: list, showMores: data.length >= pageSize }, () => {
|
||||
if (this.props.autoExpand) {
|
||||
data.forEach((item) => {
|
||||
// eslint-disable-next-line react/no-string-refs
|
||||
const $H = $(this.refs[`item-${item[0]}`]).find('.header-title')
|
||||
if ($H.length > 0) $H[0].click()
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -551,7 +561,7 @@ const RbViewPage = {
|
|||
const tabNav = $(`<li class="nav-item"><a class="nav-link" href="#${tabId}" data-toggle="tab" title="${this.entityLabel}">${this.entityLabel}</a></li>`).appendTo('.nav-tabs')
|
||||
const tabPane = $(`<div class="tab-pane" id="${tabId}"></div>`).appendTo('.tab-content')
|
||||
tabNav.find('a').click(function () {
|
||||
tabPane.find('.related-list').length === 0 && renderRbcomp(<MixRelatedList entity={entity} main={that.__id} />, tabPane)
|
||||
tabPane.find('.related-list').length === 0 && renderRbcomp(<MixRelatedList entity={entity} main={that.__id} autoExpand={$isTrue(wpc.viewTabsAutoExpand)} />, tabPane)
|
||||
})
|
||||
})
|
||||
this.updateVTabs()
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
entity: ['[[${entityName}]]', '[[${entityLabel}]]', '[[${entityIcon}]]'],
|
||||
privileges: _$unthy('[[${entityPrivileges}]]'),
|
||||
viewTabs: _$unthy('[[${ViewTabs}]]'),
|
||||
viewTabsAutoExpand: '[[${ViewTabsAutoExpand}]]',
|
||||
viewAdds: _$unthy('[[${ViewAdds}]]'),
|
||||
transformTos: _$unthy('[[${TransformTos}]]'),
|
||||
recordId: '[[${id}]]',
|
||||
|
|
Loading…
Reference in a new issue