mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 15:35:55 +08:00
AutoReadonlyFields
This commit is contained in:
parent
481dce4de4
commit
65c30a58dd
2
pom.xml
2
pom.xml
|
@ -257,7 +257,7 @@
|
|||
<dependency>
|
||||
<groupId>com.github.devezhao</groupId>
|
||||
<artifactId>persist4j</artifactId>
|
||||
<version>6957ebec45</version>
|
||||
<version>f98b9513b0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
|
|
|
@ -24,12 +24,10 @@ import com.rebuild.core.metadata.easymeta.EasyFile;
|
|||
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
|
||||
import com.rebuild.core.metadata.easymeta.MixValue;
|
||||
import com.rebuild.utils.JSONUtils;
|
||||
import org.apache.commons.collections4.map.CaseInsensitiveMap;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 表单自动回填
|
||||
|
@ -174,5 +172,46 @@ public class AutoFillinManager implements ConfigManager {
|
|||
Field field2 = (Field) field;
|
||||
final String cKey = "AutoFillinManager-" + field2.getOwnEntity().getName() + "." + field2.getName();
|
||||
Application.getCommonsCache().evict(cKey);
|
||||
Application.getCommonsCache().evict(CKEY_AFARF);
|
||||
}
|
||||
|
||||
private static final String CKEY_AFARF = "AutoFillinReadonlyFields";
|
||||
/**
|
||||
* 自动回填中涉及的自动只读字段
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<String> getAutoReadonlyFields(String entity) {
|
||||
Map<String, Set<String>> fieldsMap = (Map<String, Set<String>>) Application.getCommonsCache().getx(CKEY_AFARF);
|
||||
if (fieldsMap == null) {
|
||||
fieldsMap = this.initAutoReadonlyFields();
|
||||
}
|
||||
return Collections.unmodifiableSet(fieldsMap.getOrDefault(entity, Collections.emptySet()));
|
||||
}
|
||||
|
||||
synchronized
|
||||
private Map<String, Set<String>> initAutoReadonlyFields() {
|
||||
Object[][] array = Application.createQueryNoFilter(
|
||||
"select extConfig,belongEntity,targetField from AutoFillinConfig")
|
||||
.array();
|
||||
|
||||
CaseInsensitiveMap<String, Set<String>> fieldsMap = new CaseInsensitiveMap<>();
|
||||
for (Object[] o : array) {
|
||||
JSONObject extConfig = JSON.parseObject((String) o[0]);
|
||||
if (extConfig == null || !extConfig.getBooleanValue("readonlyTargetField")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String belongEntity = (String) o[1];
|
||||
String targetField = (String) o[2];
|
||||
|
||||
Set<String> fields = fieldsMap.computeIfAbsent(belongEntity, k -> new HashSet<>());
|
||||
fields.add(targetField);
|
||||
}
|
||||
|
||||
Application.getCommonsCache().putx(CKEY_AFARF, fieldsMap);
|
||||
return fieldsMap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,11 @@ import com.rebuild.core.privileges.bizz.User;
|
|||
import com.rebuild.core.service.NoRecordFoundException;
|
||||
import com.rebuild.core.service.approval.ApprovalState;
|
||||
import com.rebuild.core.service.approval.RobotApprovalManager;
|
||||
import com.rebuild.core.service.trigger.RobotTriggerManager;
|
||||
import com.rebuild.core.support.ConfigurationItem;
|
||||
import com.rebuild.core.support.RebuildConfiguration;
|
||||
import com.rebuild.core.support.general.FieldValueHelper;
|
||||
import com.rebuild.core.support.i18n.Language;
|
||||
import com.rebuild.core.support.state.StateManager;
|
||||
import com.rebuild.utils.JSONUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -173,11 +171,11 @@ public class FormsBuilder extends FormsManager {
|
|||
}
|
||||
}
|
||||
|
||||
// 触发器自动只读
|
||||
Set<String> roViaTriggers = RobotTriggerManager.instance.getAutoReadonlyFields(entity);
|
||||
// 自动只读
|
||||
Set<String> roAutos = EasyMetaFactory.getAutoReadonlyFields(entity);
|
||||
for (Object o : elements) {
|
||||
JSONObject field = (JSONObject) o;
|
||||
if (roViaTriggers.contains(field.getString("field"))) {
|
||||
if (roAutos.contains(field.getString("field"))) {
|
||||
field.put("readonly", true);
|
||||
}
|
||||
}
|
||||
|
@ -191,6 +189,7 @@ public class FormsBuilder extends FormsManager {
|
|||
// 主/明细实体处理
|
||||
if (entityMeta.getMainEntity() != null) {
|
||||
model.set("isDetail", true);
|
||||
model.set("mainMeta", EasyMetaFactory.toJSON(entityMeta.getMainEntity()));
|
||||
} else if (entityMeta.getDetailEntity() != null) {
|
||||
model.set("isMain", true);
|
||||
model.set("detailMeta", EasyMetaFactory.toJSON(entityMeta.getDetailEntity()));
|
||||
|
@ -253,7 +252,7 @@ public class FormsBuilder extends FormsManager {
|
|||
* @param user
|
||||
*/
|
||||
public void buildModelElements(JSONArray elements, Entity entity, Record data, ID user) {
|
||||
final User currentUser = Application.getUserStore().getUser(user);
|
||||
final User formUser = Application.getUserStore().getUser(user);
|
||||
final Date now = CalendarUtils.now();
|
||||
final boolean hideUncreate = RebuildConfiguration.getBool(ConfigurationItem.FormHideUncreateField) && data == null;
|
||||
|
||||
|
@ -351,11 +350,11 @@ public class FormsBuilder extends FormsManager {
|
|||
case EntityHelper.CreatedBy:
|
||||
case EntityHelper.ModifiedBy:
|
||||
case EntityHelper.OwningUser:
|
||||
el.put("value", FieldValueHelper.wrapMixValue(currentUser.getId(), currentUser.getFullName()));
|
||||
el.put("value", FieldValueHelper.wrapMixValue(formUser.getId(), formUser.getFullName()));
|
||||
break;
|
||||
case EntityHelper.OwningDept:
|
||||
Department dept = currentUser.getOwningDept();
|
||||
Assert.notNull(dept, "Department of user is unset : " + currentUser.getId());
|
||||
Department dept = formUser.getOwningDept();
|
||||
Assert.notNull(dept, "Department of user is unset : " + formUser.getId());
|
||||
el.put("value", FieldValueHelper.wrapMixValue((ID) dept.getIdentity(), dept.getName()));
|
||||
break;
|
||||
case EntityHelper.ApprovalId:
|
||||
|
@ -477,8 +476,9 @@ public class FormsBuilder extends FormsManager {
|
|||
final DisplayType dt = field.getDisplayType();
|
||||
final Object fieldValue = data.getObjectValue(fieldName);
|
||||
|
||||
if (dt == DisplayType.MULTISELECT || dt == DisplayType.PICKLIST || dt == DisplayType.AVATAR
|
||||
|| dt == DisplayType.STATE || dt == DisplayType.LOCATION) {
|
||||
if (dt == DisplayType.MULTISELECT || dt == DisplayType.PICKLIST
|
||||
|| dt == DisplayType.AVATAR || dt == DisplayType.STATE
|
||||
|| dt == DisplayType.LOCATION) {
|
||||
return fieldValue.toString();
|
||||
} else if (dt == DisplayType.BOOL) {
|
||||
return (Boolean) fieldValue ? BoolEditor.TRUE : BoolEditor.FALSE;
|
||||
|
|
|
@ -17,9 +17,9 @@ import cn.devezhao.persist4j.engine.NullValue;
|
|||
import cn.devezhao.persist4j.record.JsonRecordCreator;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.rebuild.core.Application;
|
||||
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.easymeta.DisplayType;
|
||||
import com.rebuild.core.privileges.bizz.User;
|
||||
import com.rebuild.core.service.DataSpecificationException;
|
||||
import com.rebuild.core.service.trigger.RobotTriggerManager;
|
||||
|
@ -69,55 +69,27 @@ public class EntityRecordCreator extends JsonRecordCreator {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void afterCreate(Record record, boolean isNew) {
|
||||
super.afterCreate(record, isNew);
|
||||
bindCommonsFieldsValue(record, isNew);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定公用/权限字段值
|
||||
*
|
||||
* @param r
|
||||
* @param isNew
|
||||
*/
|
||||
protected static void bindCommonsFieldsValue(Record r, boolean isNew) {
|
||||
final Date now = CalendarUtils.now();
|
||||
final Entity entity = r.getEntity();
|
||||
|
||||
if (entity.containsField(EntityHelper.ModifiedOn)) {
|
||||
r.setDate(EntityHelper.ModifiedOn, now);
|
||||
}
|
||||
if (entity.containsField(EntityHelper.ModifiedBy)) {
|
||||
r.setID(EntityHelper.ModifiedBy, r.getEditor());
|
||||
}
|
||||
|
||||
if (isNew) {
|
||||
if (entity.containsField(EntityHelper.CreatedOn)) {
|
||||
r.setDate(EntityHelper.CreatedOn, now);
|
||||
}
|
||||
if (entity.containsField(EntityHelper.CreatedBy)) {
|
||||
r.setID(EntityHelper.CreatedBy, r.getEditor());
|
||||
}
|
||||
if (entity.containsField(EntityHelper.OwningUser)) {
|
||||
r.setID(EntityHelper.OwningUser, r.getEditor());
|
||||
}
|
||||
if (entity.containsField(EntityHelper.OwningDept)) {
|
||||
User user = Application.getUserStore().getUser(r.getEditor());
|
||||
r.setID(EntityHelper.OwningDept, (ID) user.getOwningDept().getIdentity());
|
||||
}
|
||||
}
|
||||
public boolean onSetFieldValueWarn(Field field, String value, Record record) {
|
||||
// TODO 非系统级字段是否予以通过
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verify(Record record, boolean isNew) {
|
||||
protected void afterCreate(Record record) {
|
||||
bindCommonsFieldsValue(record, record.getPrimary() == null);
|
||||
verify(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verify(Record record) {
|
||||
List<String> notAllowed = new ArrayList<>();
|
||||
// 新建
|
||||
if (isNew) {
|
||||
if (record.getPrimary() == null) {
|
||||
// 自动只读字段可以忽略非空检查
|
||||
final Set<String> roFieldsByTrigger = RobotTriggerManager.instance.getAutoReadonlyFields(record.getEntity().getName());
|
||||
final Set<String> roAutos = EasyMetaFactory.getAutoReadonlyFields(record.getEntity().getName());
|
||||
|
||||
for (Field field : entity.getFields()) {
|
||||
if (MetadataHelper.isSystemField(field) || roFieldsByTrigger.contains(field.getName())) {
|
||||
if (MetadataHelper.isSystemField(field) || roAutos.contains(field.getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -164,4 +136,38 @@ public class EntityRecordCreator extends JsonRecordCreator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定公用/权限字段值
|
||||
*
|
||||
* @param r
|
||||
* @param isNew
|
||||
*/
|
||||
protected static void bindCommonsFieldsValue(Record r, boolean isNew) {
|
||||
final Date now = CalendarUtils.now();
|
||||
final Entity entity = r.getEntity();
|
||||
|
||||
if (entity.containsField(EntityHelper.ModifiedOn)) {
|
||||
r.setDate(EntityHelper.ModifiedOn, now);
|
||||
}
|
||||
if (entity.containsField(EntityHelper.ModifiedBy)) {
|
||||
r.setID(EntityHelper.ModifiedBy, r.getEditor());
|
||||
}
|
||||
|
||||
if (isNew) {
|
||||
if (entity.containsField(EntityHelper.CreatedOn)) {
|
||||
r.setDate(EntityHelper.CreatedOn, now);
|
||||
}
|
||||
if (entity.containsField(EntityHelper.CreatedBy)) {
|
||||
r.setID(EntityHelper.CreatedBy, r.getEditor());
|
||||
}
|
||||
if (entity.containsField(EntityHelper.OwningUser)) {
|
||||
r.setID(EntityHelper.OwningUser, r.getEditor());
|
||||
}
|
||||
if (entity.containsField(EntityHelper.OwningDept)) {
|
||||
User user = Application.getUserStore().getUser(r.getEditor());
|
||||
r.setID(EntityHelper.OwningDept, (ID) user.getOwningDept().getIdentity());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,13 +12,10 @@ import cn.devezhao.persist4j.Field;
|
|||
import cn.devezhao.persist4j.dialect.FieldType;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.rebuild.core.metadata.MetadataHelper;
|
||||
import com.rebuild.core.service.trigger.RobotTriggerManager;
|
||||
import com.rebuild.utils.JSONUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author devezhao
|
||||
* @since 2020/11/17
|
||||
|
@ -38,17 +35,14 @@ public abstract class EasyField extends BaseEasyMeta<Field> {
|
|||
return getRawMeta().getType() == FieldType.PRIMARY ? "ID" : super.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
if (!getRawMeta().isUpdatable()) return false;
|
||||
|
||||
Field field = getRawMeta();
|
||||
if (field.getType() == FieldType.REFERENCE) {
|
||||
Set<String> set = RobotTriggerManager.instance.getAutoReadonlyFields(field.getOwnEntity().getName());
|
||||
return !set.contains(field.getName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// @Override
|
||||
// public boolean isUpdatable() {
|
||||
// if (!getRawMeta().isUpdatable()) return false;
|
||||
//
|
||||
// Set<String> roViaTriggers = RobotTriggerManager.instance.getAutoReadonlyFields(
|
||||
// getRawMeta().getOwnEntity().getName());
|
||||
// return !roViaTriggers.contains(getName());
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
|
|
|
@ -57,6 +57,6 @@ public class EasyID extends EasyField {
|
|||
|
||||
@Override
|
||||
public Object exprDefaultValue() {
|
||||
throw new UnsupportedOperationException();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,16 @@ import cn.devezhao.persist4j.metadata.BaseMeta;
|
|||
import cn.devezhao.persist4j.metadata.MetadataException;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.rebuild.core.RebuildException;
|
||||
import com.rebuild.core.configuration.general.AutoFillinManager;
|
||||
import com.rebuild.core.metadata.EntityHelper;
|
||||
import com.rebuild.core.metadata.MetadataHelper;
|
||||
import com.rebuild.core.service.trigger.RobotTriggerManager;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.rebuild.core.metadata.easymeta.DisplayType.*;
|
||||
|
||||
|
@ -178,4 +183,19 @@ public class EasyMetaFactory {
|
|||
public static JSONObject toJSON(Field field) {
|
||||
return (JSONObject) valueOf(field).toJSON();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自动只读的字段
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
* @see RobotTriggerManager#getAutoReadonlyFields(String)
|
||||
* @see AutoFillinManager#getAutoReadonlyFields(String)
|
||||
*/
|
||||
public static Set<String> getAutoReadonlyFields(String entity) {
|
||||
Set<String> set = new HashSet<>();
|
||||
set.addAll(RobotTriggerManager.instance.getAutoReadonlyFields(entity));
|
||||
set.addAll(AutoFillinManager.instance.getAutoReadonlyFields(entity));
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ public class DataImporter extends HeavyTask<Integer> {
|
|||
// Verify new record
|
||||
if (record.getPrimary() == null) {
|
||||
EntityRecordCreator verifier = new EntityRecordCreator(rule.getToEntity(), JSONUtils.EMPTY_OBJECT, null);
|
||||
verifier.verify(record, true);
|
||||
verifier.verify(record);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,8 @@ public class RestoreRecordCreator extends JsonRecordCreator {
|
|||
if (ignoreNullValue && (value == null || StringUtils.isEmpty(value.toString()))) {
|
||||
continue;
|
||||
}
|
||||
setValue(field, value == null ? null : value.toString(), record);
|
||||
|
||||
setFieldValue(field, value == null ? null : value.toString(), record);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
|
|
@ -157,7 +157,6 @@ public class RobotTriggerManager implements ConfigManager {
|
|||
}
|
||||
|
||||
private static final String CKEY_TARF = "TriggersAutoReadonlyFields";
|
||||
|
||||
/**
|
||||
* 获取触发器中涉及的自动只读字段
|
||||
*
|
||||
|
@ -170,12 +169,10 @@ public class RobotTriggerManager implements ConfigManager {
|
|||
if (fieldsMap == null) {
|
||||
fieldsMap = this.initAutoReadonlyFields();
|
||||
}
|
||||
return fieldsMap.getOrDefault(entity, Collections.emptySet());
|
||||
return Collections.unmodifiableSet(fieldsMap.getOrDefault(entity, Collections.emptySet()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
synchronized
|
||||
private Map<String, Set<String>> initAutoReadonlyFields() {
|
||||
Object[][] array = Application.createQueryNoFilter(
|
||||
"select actionContent from RobotTriggerConfig where (actionType = ? or actionType = ?) and isDisabled = 'F'")
|
||||
|
|
|
@ -681,7 +681,7 @@
|
|||
"AggregationMethod": "Aggregation Method",
|
||||
"AggregationFilter": "Aggregate Data Conditions",
|
||||
"AggregationFilterTips": "Only data that meets the filter criteria will be aggregated",
|
||||
"AutoSetTargetFieldReadonly": "Automatically set target field to read-only",
|
||||
"SetTargetFieldReadonly": "Automatically set target field to read-only",
|
||||
"TargetAndSourceNotSame": "Target field and source field cannot be the same field",
|
||||
"PlsAdd1AggregationRuleLeast": "Please add at least 1 aggregation rules",
|
||||
"DataFilter": "Data filtering conditions",
|
||||
|
@ -1216,6 +1216,7 @@
|
|||
"SomeUnConf": "{0} not configured",
|
||||
"RecentlyUsed": "Recently Used",
|
||||
"EtcXItems": "etc. %d items",
|
||||
"TargetFieldReadonly": "Target field is read-only",
|
||||
|
||||
"s.__": "STATE",
|
||||
"s.ApprovalState.DRAFT": "Draft",
|
||||
|
|
|
@ -681,7 +681,7 @@
|
|||
"AggregationMethod": "聚合方式",
|
||||
"AggregationFilter": "聚合数据条件",
|
||||
"AggregationFilterTips": "仅会聚合符合过滤条件的数据",
|
||||
"AutoSetTargetFieldReadonly": "自动设置目标字段为只读",
|
||||
"SetTargetFieldReadonly": "设置目标字段为只读",
|
||||
"TargetAndSourceNotSame": "目标字段与源字段不能为同一字段",
|
||||
"PlsAdd1AggregationRuleLeast": "请至少添加 1 个聚合规则",
|
||||
"DataFilter": "数据过滤条件",
|
||||
|
@ -1216,6 +1216,7 @@
|
|||
"SomeUnConf": "{0}未配置",
|
||||
"RecentlyUsed": "最近使用",
|
||||
"EtcXItems": "等 %d 项",
|
||||
"TargetFieldReadonly": "目标字段只读",
|
||||
|
||||
"s.__": "状态",
|
||||
"s.ApprovalState.DRAFT": "草稿",
|
||||
|
|
|
@ -681,7 +681,7 @@
|
|||
"AggregationMethod": "聚合管道",
|
||||
"AggregationFilter": "聚合數據條件",
|
||||
"AggregationFilterTips": "僅會聚合符合過濾條件的數據",
|
||||
"AutoSetTargetFieldReadonly": "自動設定目標字段為只讀",
|
||||
"SetTargetFieldReadonly": "自動設定目標字段為只讀",
|
||||
"TargetAndSourceNotSame": "目標字段與源字段不能為同一字段",
|
||||
"PlsAdd1AggregationRuleLeast": "請至少添加1個聚合規則",
|
||||
"DataFilter": "數據過濾條件",
|
||||
|
@ -1216,6 +1216,7 @@
|
|||
"SomeUnConf": "{0}未配置",
|
||||
"RecentlyUsed": "最近使用",
|
||||
"EtcXItems": "等 %d 項",
|
||||
"TargetFieldReadonly": "目標字段只讀",
|
||||
|
||||
"s.__": "狀態",
|
||||
"s.ApprovalState.DRAFT": "草稿",
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
<tr>
|
||||
<th>[[${bundle.L('TargetField')}]]</th>
|
||||
<th>[[${bundle.L('SourceField')}]]</th>
|
||||
<th width="30%">[[${bundle.L('FillbackRule')}]]</th>
|
||||
<th width="35%">[[${bundle.L('FillbackRule')}]]</th>
|
||||
<th width="100"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
|
@ -6,8 +6,8 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
*/
|
||||
|
||||
.rb-right-sidebar {
|
||||
width: 480px;
|
||||
right: -480px;
|
||||
width: 520px;
|
||||
right: -520px;
|
||||
}
|
||||
|
||||
.rb-right-sidebar .sb-content,
|
||||
|
|
|
@ -716,6 +716,10 @@ body.view-body {
|
|||
right: 10px;
|
||||
}
|
||||
|
||||
.user-selector.select2-container--default .select2-selection--multiple::after {
|
||||
content: '';
|
||||
}
|
||||
|
||||
textarea.row2x {
|
||||
height: 52px !important;
|
||||
resize: none;
|
||||
|
|
|
@ -198,7 +198,7 @@ class SimpleNode extends NodeSpec {
|
|||
|
||||
const descs = data.users && data.users.length > 0 ? [UTs[data.users[0]] || `${$L('SpecUser')}(${data.users.length})`] : [NT[2]]
|
||||
|
||||
if (data.selfSelecting) descs.push($L('AllowSelfSelect'))
|
||||
if (data.selfSelecting && data.users.length > 0) descs.push($L('AllowSelfSelect'))
|
||||
if (data.ccAutoShare) descs.push($L('AutoShare'))
|
||||
if (this.nodeType === 'approver') descs.push($L(data.signMode === 'AND' ? 'SignAnd' : data.signMode === 'ALL' ? 'SignAll' : 'SignOr'))
|
||||
|
||||
|
@ -580,7 +580,7 @@ class ApproverNodeConfig extends StartNodeConfig {
|
|||
)}
|
||||
<div className="form-group mb-0">
|
||||
<label className="custom-control custom-control-sm custom-checkbox">
|
||||
<input className="custom-control-input" type="checkbox" name="selfSelecting" checked={this.state.selfSelecting} onChange={this.handleChange} />
|
||||
<input className="custom-control-input" type="checkbox" name="selfSelecting" checked={this.state.selfSelecting === true} onChange={this.handleChange} />
|
||||
<span className="custom-control-label">{$L('AllowSelfSelectYet')}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -610,7 +610,7 @@ class ApproverNodeConfig extends StartNodeConfig {
|
|||
<td>{this.__fieldLabel(item.field)}</td>
|
||||
<td width="100">
|
||||
<label className="custom-control custom-control-sm custom-checkbox">
|
||||
<input className="custom-control-input" type="checkbox" name="notNull" defaultChecked={item.notNull} data-field={item.field} />
|
||||
<input className="custom-control-input" type="checkbox" name="notNull" defaultChecked={item.notNull === true} data-field={item.field} />
|
||||
<span className="custom-control-label">{$L('Required')}</span>
|
||||
</label>
|
||||
</td>
|
||||
|
@ -716,11 +716,11 @@ class CCNodeConfig extends StartNodeConfig {
|
|||
</div>
|
||||
<div className="form-group mb-0">
|
||||
<label className="custom-control custom-control-sm custom-checkbox mb-2">
|
||||
<input className="custom-control-input" type="checkbox" name="selfSelecting" checked={this.state.selfSelecting} onChange={(e) => this.handleChange(e)} />
|
||||
<input className="custom-control-input" type="checkbox" name="selfSelecting" checked={this.state.selfSelecting === true} onChange={(e) => this.handleChange(e)} />
|
||||
<span className="custom-control-label">{$L('AllowSelfSelectYet')}</span>
|
||||
</label>
|
||||
<label className="custom-control custom-control-sm custom-checkbox">
|
||||
<input className="custom-control-input" type="checkbox" name="ccAutoShare" checked={this.state.ccAutoShare} onChange={(e) => this.handleChange(e)} />
|
||||
<input className="custom-control-input" type="checkbox" name="ccAutoShare" checked={this.state.ccAutoShare === true} onChange={(e) => this.handleChange(e)} />
|
||||
<span className="custom-control-label">{$L('ApprovalCcAutoShare')}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -19,26 +19,29 @@ const loadRules = () => {
|
|||
$.get(`../auto-fillin-list?field=${wpc.fieldName}`, (res) => {
|
||||
const $tbody = $('#dataList tbody').empty()
|
||||
$(res.data).each(function () {
|
||||
let tr = $('<tr></tr>').appendTo($tbody)
|
||||
$('<td><div>' + this.targetFieldLabel + '</div></td>').appendTo(tr)
|
||||
$('<td>' + this.sourceFieldLabel + '</div></td>').appendTo(tr)
|
||||
const extc = this.extConfig
|
||||
let extcLabel = []
|
||||
if (extc.whenCreate) extcLabel.push($L('WhenCreate'))
|
||||
if (extc.whenUpdate) extcLabel.push($L('WhenUpdate'))
|
||||
if (extc.fillinForce) extcLabel.push($L('ForceFillback'))
|
||||
$('<td>' + extcLabel.join(', ') + '</div></td>').appendTo(tr)
|
||||
const $act = $('<td class="actions"><a class="icon"><i class="zmdi zmdi-settings"></i></a><a class="icon danger-hover"><i class="zmdi zmdi-delete"></i></a></td>').appendTo(tr)
|
||||
$act.find('a:eq(0)').click(() => {
|
||||
renderRbcomp(<DlgRuleEdit {...bProps} {...extc} id={this.id} sourceField={this.sourceField} targetField={this.targetField} />)
|
||||
const $tr = $('<tr></tr>').appendTo($tbody)
|
||||
$('<td><div>' + this.targetFieldLabel + '</div></td>').appendTo($tr)
|
||||
$('<td>' + this.sourceFieldLabel + '</div></td>').appendTo($tr)
|
||||
|
||||
const ruleLabels = []
|
||||
if (this.extConfig.whenCreate) ruleLabels.push($L('WhenCreate'))
|
||||
if (this.extConfig.whenUpdate) ruleLabels.push($L('WhenUpdate'))
|
||||
if (this.extConfig.fillinForce) ruleLabels.push($L('ForceFillback'))
|
||||
if (this.extConfig.readonlyTargetField) ruleLabels.push($L('TargetFieldReadonly'))
|
||||
$('<td>' + ruleLabels.join(', ') + '</div></td>').appendTo($tr)
|
||||
|
||||
const $btns = $('<td class="actions"><a class="icon"><i class="zmdi zmdi-settings"></i></a><a class="icon danger-hover"><i class="zmdi zmdi-delete"></i></a></td>').appendTo($tr)
|
||||
$btns.find('a:eq(0)').click(() => {
|
||||
renderRbcomp(<DlgRuleEdit {...bProps} {...this.extConfig} id={this.id} sourceField={this.sourceField} targetField={this.targetField} />)
|
||||
})
|
||||
const configId = this.id
|
||||
$act.find('a:eq(1)').click(() => {
|
||||
|
||||
const cfgid = this.id
|
||||
$btns.find('a:eq(1)').click(() => {
|
||||
RbAlert.create($L('DeleteSomeConfirm,FillbackRule'), {
|
||||
type: 'danger',
|
||||
confirm: function () {
|
||||
this.disabled(true)
|
||||
$.post(`/app/entity/common-delete?id=${configId}`, (res) => {
|
||||
$.post(`/app/entity/common-delete?id=${cfgid}`, (res) => {
|
||||
if (res.error_code === 0) {
|
||||
this.hide()
|
||||
loadRules()
|
||||
|
@ -115,6 +118,15 @@ class DlgRuleEdit extends RbFormHandler {
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group row pt-1">
|
||||
<label className="col-sm-3 col-form-label text-sm-right pt-1"></label>
|
||||
<div className="col-sm-7">
|
||||
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline mb-0">
|
||||
<input className="custom-control-input" type="checkbox" checked={this.state.readonlyTargetField === true} data-id="readonlyTargetField" onChange={this.handleChange} />
|
||||
<span className="custom-control-label">{$L('SetTargetFieldReadonly')}</span>
|
||||
</label>
|
||||
</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}>
|
||||
|
@ -184,14 +196,6 @@ class DlgRuleEdit extends RbFormHandler {
|
|||
})
|
||||
}
|
||||
|
||||
handleChange(e) {
|
||||
super.handleChange(e, () => {
|
||||
if (this.state.whenCreate === false && this.state.whenUpdate === false) {
|
||||
this.setState({ whenCreate: true })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
save = () => {
|
||||
const _data = {
|
||||
field: this.props.field,
|
||||
|
@ -204,6 +208,7 @@ class DlgRuleEdit extends RbFormHandler {
|
|||
whenCreate: this.state.whenCreate,
|
||||
whenUpdate: this.state.whenUpdate,
|
||||
fillinForce: this.state.fillinForce,
|
||||
readonlyTargetField: this.state.readonlyTargetField,
|
||||
}
|
||||
if (this.props.id) _data.id = this.props.id
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@ $(document).ready(function () {
|
|||
if (this.field === DIVIDER_LINE) {
|
||||
render_item({ fieldName: this.field, fieldLabel: this.label || '', isFull: true }, '.form-preview')
|
||||
} else if (!field) {
|
||||
const $item = $(
|
||||
`<div class="dd-item"><div class="dd-handle J_field J_missed"><span class="text-danger">[${this.field.toUpperCase()}] ${$L('SomeDeleted,Field')}</span></div></div>`
|
||||
).appendTo('.form-preview')
|
||||
const $item = $(`<div class="dd-item"><div class="dd-handle J_field J_missed"><span class="text-danger">[${this.field.toUpperCase()}] ${$L('SomeDeleted,Field')}</span></div></div>`).appendTo(
|
||||
'.form-preview'
|
||||
)
|
||||
const $action = $('<div class="dd-action"><a><i class="zmdi zmdi-close"></i></a></div>').appendTo($item.find('.dd-handle'))
|
||||
$action.find('a').click(function () {
|
||||
$item.remove()
|
||||
|
@ -222,7 +222,15 @@ class DlgEditField extends RbAlert {
|
|||
<form className="field-attr">
|
||||
<div className="form-group">
|
||||
<label>{$L('InputTips')}</label>
|
||||
<input type="text" className="form-control form-control-sm" name="fieldTips" value={this.state.fieldTips || ''} onChange={this.handleChange} placeholder={$L('InputSome,InputTips')} />
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
name="fieldTips"
|
||||
value={this.state.fieldTips || ''}
|
||||
onChange={this.handleChange}
|
||||
placeholder={$L('InputSome,InputTips')}
|
||||
maxLength="200"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>
|
||||
|
@ -235,6 +243,7 @@ class DlgEditField extends RbAlert {
|
|||
value={this.state.fieldLabel || ''}
|
||||
onChange={this.handleChange}
|
||||
placeholder={this.props.fieldLabelOld || $L('ModifySome,FieldName')}
|
||||
maxLength="100"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
|
@ -270,14 +279,7 @@ class DlgEditDivider extends DlgEditField {
|
|||
<form className="field-attr">
|
||||
<div className="form-group">
|
||||
<label>{$L('DividerName')}</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
name="dividerName"
|
||||
value={this.state.dividerName || ''}
|
||||
onChange={this.handleChange}
|
||||
placeholder={$L('InputSome,DividerName')}
|
||||
/>
|
||||
<input type="text" className="form-control form-control-sm" name="dividerName" value={this.state.dividerName || ''} onChange={this.handleChange} placeholder={$L('InputSome,DividerName')} />
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<button type="button" className="btn btn-space btn-primary" onClick={this.confirm}>
|
||||
|
|
|
@ -139,7 +139,7 @@ class ContentFieldAggregation extends ActionContentSpec {
|
|||
<div className="col-md-12 col-lg-9">
|
||||
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline mb-0">
|
||||
<input className="custom-control-input" type="checkbox" ref={(c) => (this._readonlyFields = c)} />
|
||||
<span className="custom-control-label">{$L('AutoSetTargetFieldReadonly')}</span>
|
||||
<span className="custom-control-label">{$L('SetTargetFieldReadonly')}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -115,7 +115,7 @@ class ContentFieldWriteback extends ActionContentSpec {
|
|||
<div className="col-md-12 col-lg-9">
|
||||
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline mb-0">
|
||||
<input className="custom-control-input" type="checkbox" ref={(c) => (this._readonlyFields = c)} />
|
||||
<span className="custom-control-label">{$L('AutoSetTargetFieldReadonly')}</span>
|
||||
<span className="custom-control-label">{$L('SetTargetFieldReadonly')}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue