Trigger dv vars (#493)

* dv & lang

* list class

* theme

* fix: parseFilesJson

* better: 字段更新允许自引用
This commit is contained in:
RB 2022-07-27 12:32:20 +08:00 committed by GitHub
parent 3440e961c0
commit b77ca2ea20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 235 additions and 121 deletions

2
@rbv

@ -1 +1 @@
Subproject commit cfb115dfa0260de80cb8655c5023063f474595dd
Subproject commit e892886f1fafbb92e2192a3df7062d52821a0692

View file

@ -14,9 +14,9 @@ import cn.devezhao.persist4j.engine.ID;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.rebuild.core.Application;
import com.rebuild.core.cache.CacheTemplate;
import com.rebuild.core.configuration.ConfigBean;
import com.rebuild.core.metadata.easymeta.DisplayType;
import com.rebuild.core.metadata.easymeta.EasyField;
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
import com.rebuild.core.metadata.impl.EasyEntityConfigProps;
import com.rebuild.core.support.general.FieldValueHelper;
@ -24,7 +24,9 @@ import com.rebuild.utils.JSONUtils;
import org.apache.commons.lang3.StringUtils;
import java.text.MessageFormat;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* 分类数据
@ -35,24 +37,26 @@ import java.util.*;
public class DataListClass {
/**
* FIXME 不要实时查询
*
*
* @param entity
* @param user
* @return
*/
public static JSON datas(Entity entity, ID user) {
String classField = EasyMetaFactory.valueOf(entity).getExtraAttr(EasyEntityConfigProps.ADV_LIST_SHOWCLASS);
if (StringUtils.isBlank(classField) || !entity.containsField(classField)) return null;
final Field classField = getFieldOfClass(entity);
if (classField == null) return null;
Field fieldMeta = entity.getField(classField);
EasyField fieldEasy = EasyMetaFactory.valueOf(fieldMeta);
DisplayType dt = fieldEasy.getDisplayType();
final String ckey = String.format("DLC1.%s.%s", entity.getName(), classField.getName());
JSON c = (JSON) Application.getCommonsCache().getx(ckey);
if (c != null) return c;
DisplayType dt = EasyMetaFactory.getDisplayType(classField);
List<Object[]> list = new ArrayList<>();
if (dt == DisplayType.MULTISELECT || dt == DisplayType.PICKLIST) {
ConfigBean[] entries = MultiSelectManager.instance.getPickListRaw(fieldMeta, true);
ConfigBean[] entries = MultiSelectManager.instance.getPickListRaw(classField, true);
for (ConfigBean e : entries) {
Object id = e.getID("id");
if (dt == DisplayType.MULTISELECT) id = e.getLong("mask");
@ -65,10 +69,10 @@ public class DataListClass {
if (dt == DisplayType.N2NREFERENCE) {
sql = MessageFormat.format(
"select referenceId from NreferenceItem where belongEntity = ''{0}'' and belongField = ''{1}'' group by referenceId",
entity.getName(), classField);
entity.getName(), classField.getName());
} else {
sql = MessageFormat.format(
"select {0} from {1} where {0} is not null group by {0}", classField, entity.getName());
"select {0} from {1} where {0} is not null group by {0}", classField.getName(), entity.getName());
}
Query query = user == null
@ -90,6 +94,22 @@ public class DataListClass {
new String[] { "label", "id", "count" },
new Object[] { o[0], o[1], 0 } ));
}
// FIXME 1min 缓存
Application.getCommonsCache().putx(ckey, res, CacheTemplate.TS_HOUR / 60); // 1min
return res;
}
/**
* 获取分类字段若有
*
* @param entity
* @return
*/
public static Field getFieldOfClass(Entity entity) {
String classField = EasyMetaFactory.valueOf(entity).getExtraAttr(EasyEntityConfigProps.ADV_LIST_SHOWCLASS);
if (StringUtils.isBlank(classField) || !entity.containsField(classField)) return null;
return entity.getField(classField);
}
}

View file

@ -50,10 +50,8 @@ public class AttachmentAwareObserver extends OperatingObserver {
List<Record> creates = new ArrayList<>();
for (Field field : fileFields) {
if (record.hasValue(field.getName(), false)) {
Object value = record.getObjectValue(field.getName());
JSONArray filesJson = value instanceof JSON ? (JSONArray) value : parseFilesJson(value.toString());
for (Object file : filesJson) {
JSONArray files = parseFilesJson(record.getObjectValue(field.getName()));
for (Object file : files) {
Record add = createAttachment(
field, context.getAfterRecord().getPrimary(), (String) file, context.getOperator());
creates.add(add);
@ -78,8 +76,8 @@ public class AttachmentAwareObserver extends OperatingObserver {
for (Field field : fileFields) {
String fieldName = field.getName();
if (record.hasValue(fieldName)) {
JSONArray beforeFiles = parseFilesJson(before.getString(fieldName)); // 修改前
JSONArray afterFiles = parseFilesJson(record.getString(fieldName)); // 修改后
JSONArray beforeFiles = parseFilesJson(before.getObjectValue(fieldName)); // 修改前
JSONArray afterFiles = parseFilesJson(record.getObjectValue(fieldName)); // 修改后
for (Iterator<Object> iter = afterFiles.iterator(); iter.hasNext(); ) {
Object a = iter.next();
@ -150,11 +148,10 @@ public class AttachmentAwareObserver extends OperatingObserver {
updates.toArray(new Record[0]), deletes.toArray(new ID[0]), false);
}
private JSONArray parseFilesJson(String files) {
if (StringUtils.isBlank(files)) {
return JSONUtils.EMPTY_ARRAY;
}
return JSON.parseArray(files);
private JSONArray parseFilesJson(Object files) {
if (files instanceof JSON) return (JSONArray) files;
else if (files == null || StringUtils.isBlank(files.toString())) return JSONUtils.EMPTY_ARRAY;
else return JSON.parseArray(files.toString());
}
private Record createAttachment(Field field, ID recordId, String filePath, ID user) {

View file

@ -185,7 +185,7 @@ public class FieldWriteback extends FieldAggregation {
}
if (targetRecordIds.isEmpty()) {
log.warn("No target record(s) found");
log.warn("No target record(s) found : {}", actionContext.getConfigId());
return;
}
}

View file

@ -7,6 +7,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.core.support.general;
import cn.devezhao.commons.ObjectUtils;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field;
import cn.devezhao.persist4j.engine.ID;
@ -14,8 +15,10 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.core.configuration.ConfigBean;
import com.rebuild.core.configuration.general.AdvFilterManager;
import com.rebuild.core.configuration.general.DataListClass;
import com.rebuild.core.metadata.EntityHelper;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.metadata.easymeta.DisplayType;
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
import com.rebuild.core.metadata.impl.EasyFieldConfigProps;
import com.rebuild.core.service.dashboard.ChartManager;
@ -23,6 +26,7 @@ import com.rebuild.core.service.query.AdvFilterParser;
import com.rebuild.core.service.query.ParseHelper;
import com.rebuild.utils.JSONUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
@ -42,7 +46,7 @@ public class ProtocolFilterParser {
final private String protocolExpr;
/**
* @param protocolExpr via:xxx:[field] ref:xxx:[id]
* @param protocolExpr via:xxx:[field] ref:xxx:[id] class:entity:value
*/
public ProtocolFilterParser(String protocolExpr) {
this.protocolExpr = protocolExpr;
@ -60,6 +64,9 @@ public class ProtocolFilterParser {
case "ref": {
return parseRef(ps[1], ps.length > 2 ? ps[2] : null);
}
case "class": {
return parseClass(ps[1], ps[2]);
}
default: {
log.warn("Unknown protocol expr : {}", protocolExpr);
return null;
@ -147,6 +154,32 @@ public class ProtocolFilterParser {
: "( " + StringUtils.join(sqls, " and ") + " )";
}
/**
* @param entity
* @param value
* @return
* @see AdvFilterParser#parseItem(JSONObject, JSONObject)
*/
public String parseClass(String entity, String value) {
Entity rootEntity = MetadataHelper.getEntity(entity);
Field classField = DataListClass.getFieldOfClass(rootEntity);
if (classField == null) return "(9=9)";
DisplayType dt = EasyMetaFactory.getDisplayType(classField);
if (dt == DisplayType.MULTISELECT) {
return String.format("%s && %d", classField.getName(), ObjectUtils.toInt(value));
} else if (dt == DisplayType.N2NREFERENCE) {
return String.format(
"exists (select recordId from NreferenceItem where ^%s = recordId and belongField = '%s' and referenceId = '%s')",
rootEntity.getPrimaryField().getName(), classField.getName(), StringEscapeUtils.escapeSql(value));
} else {
return String.format("%s = '%s'", classField.getName(), StringEscapeUtils.escapeSql(value));
}
}
// --
/**
* 附加过滤条件
*

View file

@ -102,9 +102,8 @@ public class MetaEntityController extends BaseController {
// 扩展配置
mv.getModel().put("entityExtConfig", easyEntity.getExtraAttrs(true));
boolean isDetail = easyEntity.getRawMeta().getMainEntity() != null;
boolean isBizz = MetadataHelper.isBizzEntity(easyEntity.getRawMeta());
mv.getModel().put("useListMode", !(isDetail || isBizz));
mv.getModel().put("useListMode", !isBizz);
return mv;
}

View file

@ -55,18 +55,12 @@ public class GeneralListController extends EntityController {
throws IOException {
final ID user = getRequestUser(request);
final Entity listEntity = checkPageOfEntity(user, entity, response);
if (listEntity == null) return null;
if (listEntity == null) return null; // 404
final EasyEntity easyEntity = EasyMetaFactory.valueOf(listEntity);
// 使用主实体列表配置
final EasyEntity mainEntity = listEntity.getMainEntity() == null
? easyEntity : EasyMetaFactory.valueOf(listEntity.getMainEntity());
String listPage = listEntity.getMainEntity() != null ? "/general/detail-list" : "/general/record-list";
Integer listMode = getIntParameter(request, "forceListMode");
if (listMode == null) {
listMode = ObjectUtils.toInt(mainEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_MODE), 1);
}
int listMode = ObjectUtils.toInt(easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_MODE), 1);
if (listMode == 2) {
listPage = "/general/record-list2"; // Mode2
}
@ -87,9 +81,9 @@ public class GeneralListController extends EntityController {
listConfig = DataListManager.instance.getFieldsLayout(entity, user);
// 扩展配置
String advListHideFilters = mainEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_HIDE_FILTERS);
String advListHideCharts = mainEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_HIDE_CHARTS);
String advListShowClass = mainEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_SHOWCLASS);
String advListHideFilters = easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_HIDE_FILTERS);
String advListHideCharts = easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_HIDE_CHARTS);
String advListShowClass = easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_SHOWCLASS);
mv.getModel().put(EasyEntityConfigProps.ADV_LIST_HIDE_FILTERS, advListHideFilters);
mv.getModel().put(EasyEntityConfigProps.ADV_LIST_HIDE_CHARTS, advListHideCharts);
mv.getModel().put(EasyEntityConfigProps.ADV_LIST_SHOWCLASS, StringUtils.isNotBlank(advListShowClass));
@ -99,7 +93,7 @@ public class GeneralListController extends EntityController {
// 查询面板
String advListFilterpane = mainEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_FILTERPANE);
String advListFilterpane = easyEntity.getExtraAttr(EasyEntityConfigProps.ADV_LIST_FILTERPANE);
mv.getModel().put(EasyEntityConfigProps.ADV_LIST_FILTERPANE, advListFilterpane);
if (BooleanUtils.toBoolean(advListFilterpane)) {

View file

@ -43,12 +43,10 @@ public class FieldAggregationController extends BaseController {
public List<String[]> getTargetEntities(@EntityParam(name = "source") Entity sourceEntity) {
List<String[]> entities = new ArrayList<>();
// 我引用了谁
// 1. 我引用了谁
for (Field refFrom : MetadataSorter.sortFields(sourceEntity, DisplayType.REFERENCE)) {
if (MetadataHelper.isApprovalField(refFrom.getName())) {
continue;
}
if (MetadataHelper.isApprovalField(refFrom.getName())) continue;
Entity refEntity = refFrom.getReferenceEntity();
String entityLabel = String.format("%s (%s)",

View file

@ -48,35 +48,41 @@ public class FieldWritebackController extends BaseController {
@RequestMapping("field-writeback-entities")
public List<String[]> getTargetEntities(@EntityParam(name = "source") Entity sourceEntity) {
List<String[]> entities = new ArrayList<>();
List<String[]> temp = new ArrayList<>();
// 谁引用了我
// 1. 我引用了谁 v2.7.1
for (Field refFrom : MetadataSorter.sortFields(sourceEntity, DisplayType.REFERENCE)) {
if (MetadataHelper.isCommonsField(refFrom)) continue;
Entity refEntity = refFrom.getReferenceEntity();
String entityLabel = String.format("%s (%s)",
EasyMetaFactory.getLabel(refEntity), EasyMetaFactory.getLabel(refFrom));
temp.add(new String[] { refEntity.getName(), entityLabel, refFrom.getName(), FieldWriteback.ONE2ONE_MODE});
}
FieldAggregationController.sortEntities(temp, null);
List<String[]> entities = new ArrayList<>(temp);
temp.clear();
// 2. 谁引用了我
for (Field refTo : MetadataHelper.getReferenceToFields(sourceEntity)) {
String entityLabel = String.format("%s (%s)",
String entityLabel = String.format("%s (%s) (N)",
EasyMetaFactory.getLabel(refTo.getOwnEntity()), EasyMetaFactory.getLabel(refTo));
entities.add(new String[] {
temp.add(new String[] {
refTo.getOwnEntity().getName(), entityLabel, refTo.getName() });
}
// 我引用了谁 v2.7.1
FieldAggregationController.sortEntities(temp, null);
entities.addAll(temp);
temp.clear();
for (Field refFrom : MetadataSorter.sortFields(sourceEntity, DisplayType.REFERENCE)) {
if (MetadataHelper.isCommonsField(refFrom)) {
continue;
}
// 3. 自己
FieldAggregationController.sortEntities(temp, sourceEntity);
entities.addAll(temp);
temp.clear();
Entity refEntity = refFrom.getReferenceEntity();
if (refEntity.equals(sourceEntity)) { // 排除自引用
continue;
}
String entityLabel = String.format("%s (%s.%s)",
EasyMetaFactory.getLabel(refEntity), EasyMetaFactory.getLabel(sourceEntity), EasyMetaFactory.getLabel(refFrom));
entities.add(new String[] { refEntity.getName(), entityLabel, refFrom.getName(), FieldWriteback.ONE2ONE_MODE});
}
FieldAggregationController.sortEntities(entities, sourceEntity);
return entities;
}

View file

@ -60,6 +60,7 @@ public class GroupAggregationController extends BaseController {
sourceFields.add(buildField(field));
}
}
// 明细实体则包括主实体
if (sourceEntity.getMainEntity() != null) {
String prefixName = MetadataHelper.getDetailToMainField(sourceEntity).getName() + ".";

View file

@ -2211,5 +2211,58 @@
"未启用":"未启用",
"请至少添加 1 个更新规则":"请至少添加 1 个更新规则",
"确认移除此明细?":"确认移除此明细?",
"高度 (行数)":"高度 (行数)"
"高度 (行数)":"高度 (行数)",
"配置查询面板字段":"配置查询面板字段",
"校验未通过时的提示内容。内容支持字段变量,如 `{createdOn}` (其中 createdOn 为触发实体的字段内部标识)":"校验未通过时的提示内容。内容支持字段变量,如 `{createdOn}` (其中 createdOn 为触发实体的字段内部标识)",
"团队管理":"团队管理",
"请至少添加 1 个查询字段":"请至少添加 1 个查询字段",
"请填写固定值":"请填写固定值",
"@%s 退回了你的 %s 审批,请重新审核":"@%s 退回了你的 %s 审批,请重新审核",
"显示侧栏分类":"显示侧栏分类",
"转换明细记录需选择主记录":"转换明细记录需选择主记录",
"@%s 驳回了你的 %s 审批,请重新提交":"@%s 驳回了你的 %s 审批,请重新提交",
"如有多个类型请使用逗号或空格分开":"如有多个类型请使用逗号或空格分开",
"技术全览":"技术全览",
"启用预览模式会打开新建页面,否则将直接转换":"启用预览模式会打开新建页面,否则将直接转换",
"审批节点批次":"审批节点批次",
"选择分类字段":"选择分类字段",
"共 %d 条":"共 %d 条",
"实体构成":"实体构成",
"无法输出报表,请检查报表模板是否有误":"无法输出报表,请检查报表模板是否有误",
"允许退回到指定步骤 (否则为整体驳回)":"允许退回到指定步骤 (否则为整体驳回)",
"引用关系":"引用关系",
"无效文档预览服务地址":"无效文档预览服务地址",
"过期":"过期",
"请添加明细":"请添加明细",
"确认完成此任务?":"确认完成此任务?",
"字段回填":"字段回填",
"整体驳回":"整体驳回",
"确认取消完成此任务?":"确认取消完成此任务?",
"请求技术支持":"请求技术支持",
"预览模式":"预览模式",
"是否退回":"是否退回",
"内容 (及标题) 支持字段变量,字段变量如 `{createdOn}` (其中 createdOn 为触发实体的字段内部标识)":"内容 (及标题) 支持字段变量,字段变量如 `{createdOn}` (其中 createdOn 为触发实体的字段内部标识)",
"收缩":"收缩",
"无法获取审批状态":"无法获取审批状态",
"展开":"展开",
"无法读取审批记录":"无法读取审批记录",
"驳回时":"驳回时",
"符合过滤条件的数据才会在相关项列表中显示":"符合过滤条件的数据才会在相关项列表中显示",
"百度地图 AK":"百度地图 AK",
"查询字段":"查询字段",
"上次登录":"上次登录",
"显示顶部查询面板":"显示顶部查询面板",
"退回":"退回",
"重置":"重置",
"仅提交人可撤回审批":"仅提交人可撤回审批",
"允许上传类型":"允许上传类型",
"可使用固定值、字段变量或他们的组合。字段变量如 `{ID}` (其中 ID 为字段内部标识)":"可使用固定值、字段变量或他们的组合。字段变量如 `{ID}` (其中 ID 为字段内部标识)",
"点击复制":"点击复制",
"文件上传大小限制":"文件上传大小限制",
"默认展开":"默认展开",
"文档预览服务地址":"文档预览服务地址",
"请选择驳回方式":"请选择驳回方式",
"系统用户":"系统用户",
"下载模板":"下载模板",
"退回至":"退回至"
}

View file

@ -238,7 +238,7 @@
<label class="col-md-12 col-xl-3 col-lg-4 col-form-label text-lg-right">[[${bundle.L('编码规则')}]]</label>
<div class="col-md-12 col-xl-6 col-lg-8">
<input class="form-control form-control-sm" type="text" id="barcodeFormat" />
<p class="form-text mb-0 help" th:utext="${bundle.L('可使用固定值、内置变量或他们的组合。内置变量如 `{ID}` (其中 ID 为字段内部标识)')}"></p>
<p class="form-text mb-0 help" th:utext="${bundle.L('可使用固定值、字段变量或他们的组合。字段变量如 `{ID}` (其中 ID 为字段内部标识)')}"></p>
</div>
</div>
</div>

View file

@ -562,11 +562,12 @@ div.dataTables_filter .filter-badge {
background-color: #fff;
color: #a04100;
border: 1px solid #ddd;
padding: 6px 12px;
padding: 4px 10px;
font-size: 1rem;
font-weight: normal;
border-radius: 99px;
margin-top: 1px;
margin-top: 3px;
cursor: default;
}
div.dataTables_filter .filter-badge .close {
@ -574,7 +575,7 @@ div.dataTables_filter .filter-badge .close {
text-shadow: none;
font-weight: normal;
color: #bbb;
margin-left: 7px;
margin-left: 6px;
}
div.dataTables_filter .filter-badge:hover {
@ -1737,13 +1738,9 @@ th.column-fixed {
user-select: none;
}
.main-content > .nav-tabs-classic + .card {
.main-content > .card.card-table.card-topcolor {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-top: 2px solid #fff;
}
.main-content > .nav-tabs-classic + .card.card-table {
border-top: 2px solid #4285f4;
}
@ -3460,6 +3457,7 @@ form {
border-radius: 2px;
font-size: 1rem;
cursor: pointer;
text-transform: none;
}
#asideFilters .dropdown-item:hover,
@ -4619,8 +4617,7 @@ pre.unstyle {
margin: -12px -25px 12px -23px;
background-color: #f5f5f5;
border-bottom: 1px solid #dee2e6;
padding: 12px 18px;
padding-top: 0;
padding: 0 18px 12px;
}
.quick-filter-pane .ph-item {

View file

@ -10,38 +10,39 @@ RbForm.postAfter = function (data) {
location.href = `${rb.baseUrl}/admin/bizuser/role/${data.id}`
}
const wpc = window.__PageConfig
const roleId = wpc.recordId
let roleId = window.__PageConfig.recordId
// 自定义
let advFilters = {}
let advFilterSettings = {}
$(document).ready(function () {
$('.J_new-role').click(() => RbFormModal.create({ title: $L('新建角色'), entity: 'Role', icon: 'lock' }))
$('.J_new-role').on('click', () => RbFormModal.create({ title: $L('新建角色'), entity: 'Role', icon: 'lock' }))
loadRoles()
if (roleId) {
$('.J_save').attr('disabled', false).click(updatePrivileges)
$('.J_save').attr('disabled', false)
loadPrivileges()
}
loadRoles()
$('.J_save').on('click', updatePrivileges)
// ENTITY
// 单个操作
$('#priv-entity tbody .priv').click(function () {
$('#priv-entity tbody .priv').on('click', function () {
const $this = $(this)
clickPriv($this, $this.data('action'))
_clickPriv($this, $this.data('action'))
})
// 批量操作
$('#priv-entity thead th>a').click(function () {
$('#priv-entity thead th>a').on('click', function () {
const action = $(this).data('action')
const $items = $(`#priv-entity tbody .priv[data-action="${action}"]`)
clickPriv($items, action)
_clickPriv($items, action)
})
// 批量操作
$('#priv-entity tbody .name>a').click(function () {
$('#priv-entity tbody .name>a').on('click', function () {
const $items = $(this).parent().parent().find('.priv')
const clz = $items.eq(0).hasClass('R0') ? 'R4' : 'R0'
$items.removeClass('R0 R1 R2 R3 R4').addClass(clz)
@ -49,16 +50,16 @@ $(document).ready(function () {
// ZERO
$('#priv-zero tbody .priv').click(function () {
clickPriv($(this), 'Z')
$('#priv-zero tbody .priv').on('click', function () {
_clickPriv($(this), 'Z')
})
$('#priv-zero thead th>a').click(function () {
$('#priv-zero thead th>a').on('click', function () {
const $privZero = $('#priv-zero tbody .priv[data-action="Z"]')
clickPriv($privZero, 'Z')
_clickPriv($privZero, 'Z')
})
$('#priv-zero tbody .name>a').click(function () {
$('#priv-zero tbody .name>a').on('click', function () {
const $el = $(this).parent().next().find('i.priv')
clickPriv($el, 'Z')
_clickPriv($el, 'Z')
})
// CUSTOM
@ -71,7 +72,7 @@ $(document).ready(function () {
'S': $L('共享'),
}
$('#priv-entity tbody td>a.cp').click(function () {
$('#priv-entity tbody td>a.cp').on('click', function () {
if (rb.commercial < 1) {
RbHighbar.error(WrapHtml($L('免费版不支持自定义权限功能 [(查看详情)](https://getrebuild.com/docs/rbv-features)')))
return
@ -113,7 +114,7 @@ $(document).ready(function () {
})
})
const clickPriv = function (elements, action) {
const _clickPriv = function (elements, action) {
if (action === 'C' || action === 'Z') {
if (elements.first().hasClass('R0')) elements.removeClass('R0').addClass('R4')
else elements.removeClass('R4').addClass('R0')
@ -139,7 +140,15 @@ const loadRoles = function () {
<AsideTree
data={res.data}
activeItem={roleId}
onItemClick={(item) => (location.href = `${rb.baseUrl}/admin/bizuser/role/${item.id}`)}
onItemClick={(item) => {
location.href = `${rb.baseUrl}/admin/bizuser/role/${item.id}`
// history.pushState(item.id, null, `${rb.baseUrl}/admin/bizuser/role/${item.id}`)
// roleId = item.id
// // reset
// $('.table-priv i.priv').attr('class', 'priv R0')
// loadPrivileges()
}}
extrasAction={(item) => {
return (
<React.Fragment>

View file

@ -108,10 +108,10 @@ class DlgMode1Option extends RbFormHandler {
<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>
<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} />
<input type="checkbox" id="advListHideFilters" defaultChecked={wpc.extConfig && !wpc.extConfig.advListHideFilters} />
<span>
<label htmlFor="advListHideFilters" />
</span>
@ -119,21 +119,10 @@ class DlgMode1Option extends RbFormHandler {
</div>
</div>
<div className="form-group row">
<label className="col-sm-3 col-form-label text-sm-right">{$L('隐藏侧栏图表')}</label>
<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">
<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="advListShowClass" defaultChecked={wpc.extConfig && !!wpc.extConfig.advListShowClass} />
<input type="checkbox" id="advListShowClass" defaultChecked={wpc.extConfig && wpc.extConfig.advListShowClass} />
<span>
<label htmlFor="advListShowClass" />
</span>
@ -153,6 +142,17 @@ class DlgMode1Option extends RbFormHandler {
</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">
<label className="col-sm-3 col-form-label text-sm-right">{$L('显示顶部查询面板')}</label>
<div className="col-sm-7">
@ -214,8 +214,8 @@ class DlgMode1Option extends RbFormHandler {
save = () => {
const o = {
advListHideFilters: $val('#advListHideFilters'),
advListHideCharts: $val('#advListHideCharts'),
advListHideFilters: !$val('#advListHideFilters'),
advListHideCharts: !$val('#advListHideCharts'),
advListShowClass: this.state.advListShowClass ? $val('.J_advListShowClass select') : null,
advListFilterPane: $val('#advListFilterPane'),
}

View file

@ -682,7 +682,7 @@ const RbListCommon = {
const via = $urlp('via') || $urlp('via', location.hash)
if (via) {
wpc.protocolFilter = `via:${via}`
const $cleanVia = $(`<div class="badge filter-badge">${$L('当前数据已过滤')}<a class="close" title="${$L('查看全部数据')}">&times;</a></div>`).appendTo('.dataTables_filter')
const $cleanVia = $(`<div class="badge filter-badge J_via-filter">${$L('当前数据已过滤')}<a class="close" title="${$L('查看全部数据')}">&times;</a></div>`).appendTo('.dataTables_filter')
$cleanVia.find('a').on('click', () => {
wpc.protocolFilter = null
RbListPage.reload()

View file

@ -1224,25 +1224,32 @@ const ClassWidget = {
$('.J_load-class').on('click', () => {
this._classLoaded !== true && this.loadClass()
})
this._$wrap = $('<div></div>').appendTo('#asideClass')
$(`<div class="dropdown-item active" data-id="$ALL$">${$L('全部数据')}</div>`).appendTo(this._$wrap)
},
loadClass() {
$.get(`/app/${wpc.entity[0]}/widget-class-data`, (res) => {
this._classLoaded = true
const $wrap = $('<div></div>').appendTo('#asideClass')
$(`<div class="dropdown-item active" data-id="$ALL$">${$L('全部数据')}</div>`).appendTo($wrap)
res.data &&
res.data.forEach((item) => {
$(`<div class="dropdown-item" data-id="${item.id}">${item.label}</div>`).appendTo($wrap)
$(`<div class="dropdown-item" data-id="${item.id}">${item.label}</div>`).appendTo(this._$wrap)
})
const $items = $wrap.find('.dropdown-item').on('click', function () {
const $items = this._$wrap.find('.dropdown-item').on('click', function () {
$items.removeClass('active')
$(this).addClass('active')
console.log($(this).data('id'))
// Clean via
$('.J_via-filter').remove()
const v = $(this).data('id')
if (v === '$ALL$') wpc.protocolFilter = null
else wpc.protocolFilter = `class:${wpc.entity[0]}:${v}`
RbListPage.reload()
})
})
},

View file

@ -77,7 +77,7 @@ class ContentSendNotification extends ActionContentSpec {
<label className="col-12 col-lg-3 col-form-label text-lg-right">{$L('内容')}</label>
<div className="col-12 col-lg-8">
<textarea className="form-control form-control-sm row3x" ref={(c) => (this._content = c)} maxLength="600" />
<p className="form-text" dangerouslySetInnerHTML={{ __html: $L('内容及标题支持内置变量内置变量如 `{createdOn}` (其中 createdOn 为触发实体的字段内部标识)') }} />
<p className="form-text" dangerouslySetInnerHTML={{ __html: $L('内容 (及标题) 支持字段变量字段变量如 `{createdOn}` (其中 createdOn 为触发实体的字段内部标识)') }} />
</div>
</div>
</form>

View file

@ -48,7 +48,7 @@
<a class="nav-link active"><span class="icon zmdi" th:classappend="${'zmdi-' + detailEntityIcon}"></span> [[${detailEntityLabel}]]</a>
</li>
</ul>
<div class="card card-table">
<div class="card card-table card-topcolor">
<div class="card-body">
<div class="dataTables_wrapper container-fluid">
<div class="row rb-datatable-header">

View file

@ -48,7 +48,7 @@
<a th:href="|../${detailEntity}/list|" class="nav-link"><span class="icon zmdi" th:classappend="${'zmdi-' + detailEntityIcon}"></span> [[${detailEntityLabel}]]</a>
</li>
</ul>
<div class="card card-table">
<div class="card card-table card-topcolor">
<div class="card-body">
<div class="dataTables_wrapper container-fluid">
<div class="row rb-datatable-header">