SUPPORT-8982:add new form services
This commit is contained in:
parent
f527b92827
commit
05a1b21849
16 changed files with 2567 additions and 24 deletions
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ru.micord.ervu.account_applications.component.field.persist;
|
||||||
|
|
||||||
|
import ru.cg.webbpm.modules.webkit.beans.Behavior;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public class ErvuFormLoadComponent extends Behavior {
|
||||||
|
public String fieldName;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
package ru.micord.ervu.account_applications.component.model;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
public class Account {
|
||||||
|
private String id;
|
||||||
|
private int version;
|
||||||
|
private long modified;
|
||||||
|
private long createDate;
|
||||||
|
private String start;
|
||||||
|
private String finish;
|
||||||
|
private boolean enabled;
|
||||||
|
private String position;
|
||||||
|
private String fio;
|
||||||
|
private String workMail;
|
||||||
|
private boolean esiaAccount;
|
||||||
|
@JsonProperty("user-domain")
|
||||||
|
private UserDomain userDomain;
|
||||||
|
private Person person;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(int version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getModified() {
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModified(long modified) {
|
||||||
|
this.modified = modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCreateDate() {
|
||||||
|
return createDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateDate(long createDate) {
|
||||||
|
this.createDate = createDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStart(String start) {
|
||||||
|
this.start = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFinish() {
|
||||||
|
return finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFinish(String finish) {
|
||||||
|
this.finish = finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(String position) {
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFio() {
|
||||||
|
return fio;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFio(String fio) {
|
||||||
|
this.fio = fio;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkMail() {
|
||||||
|
return workMail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkMail(String workMail) {
|
||||||
|
this.workMail = workMail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEsiaAccount() {
|
||||||
|
return esiaAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEsiaAccount(boolean esiaAccount) {
|
||||||
|
this.esiaAccount = esiaAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserDomain getUserDomain() {
|
||||||
|
return userDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserDomain(UserDomain userDomain) {
|
||||||
|
this.userDomain = userDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person getPerson() {
|
||||||
|
return person;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPerson(Person person) {
|
||||||
|
this.person = person;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package ru.micord.ervu.account_applications.component.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class Credential {
|
||||||
|
private String id;
|
||||||
|
private long modified;
|
||||||
|
private String userName;
|
||||||
|
private boolean blocked;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getModified() {
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModified(long modified) {
|
||||||
|
this.modified = modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserName(String userName) {
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBlocked() {
|
||||||
|
return blocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlocked(boolean blocked) {
|
||||||
|
this.blocked = blocked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
package ru.micord.ervu.account_applications.component.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class Person {
|
||||||
|
@JsonProperty("id")
|
||||||
|
private String personId;
|
||||||
|
private long modified;
|
||||||
|
private long createDate;
|
||||||
|
private String birthdate;
|
||||||
|
private String firstname;
|
||||||
|
private String middlename;
|
||||||
|
private String surname;
|
||||||
|
private String sex;
|
||||||
|
private String email;
|
||||||
|
private String photo;
|
||||||
|
private String phone;
|
||||||
|
private String snils;
|
||||||
|
private boolean secondFactorEnabled;
|
||||||
|
private List<String> ipAddresses;
|
||||||
|
|
||||||
|
public String getPersonId() {
|
||||||
|
return personId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonId(String personId) {
|
||||||
|
this.personId = personId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getModified() {
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModified(long modified) {
|
||||||
|
this.modified = modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCreateDate() {
|
||||||
|
return createDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateDate(long createDate) {
|
||||||
|
this.createDate = createDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBirthdate() {
|
||||||
|
return birthdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBirthdate(String birthdate) {
|
||||||
|
this.birthdate = birthdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstname() {
|
||||||
|
return firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstname(String firstname) {
|
||||||
|
this.firstname = firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMiddlename() {
|
||||||
|
return middlename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMiddlename(String middlename) {
|
||||||
|
this.middlename = middlename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSurname(String surname) {
|
||||||
|
this.surname = surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSex() {
|
||||||
|
return sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSex(String sex) {
|
||||||
|
this.sex = sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhoto() {
|
||||||
|
return photo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhoto(String photo) {
|
||||||
|
this.photo = photo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSnils() {
|
||||||
|
return snils;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSnils(String snils) {
|
||||||
|
this.snils = snils;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSecondFactorEnabled() {
|
||||||
|
return secondFactorEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecondFactorEnabled(boolean secondFactorEnabled) {
|
||||||
|
this.secondFactorEnabled = secondFactorEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getIpAddresses() {
|
||||||
|
return ipAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIpAddresses(List<String> ipAddresses) {
|
||||||
|
this.ipAddresses = ipAddresses;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
package ru.micord.ervu.account_applications.component.model;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class Role {
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String displayName;
|
||||||
|
private String parentId;
|
||||||
|
private boolean ervuRole;
|
||||||
|
private String finish;
|
||||||
|
private int sessionsLimit;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParentId() {
|
||||||
|
return parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentId(String parentId) {
|
||||||
|
this.parentId = parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isErvuRole() {
|
||||||
|
return ervuRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setErvuRole(boolean ervuRole) {
|
||||||
|
this.ervuRole = ervuRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFinish() {
|
||||||
|
return finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFinish(String finish) {
|
||||||
|
this.finish = finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSessionsLimit() {
|
||||||
|
return sessionsLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSessionsLimit(int sessionsLimit) {
|
||||||
|
this.sessionsLimit = sessionsLimit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,264 @@
|
||||||
|
package ru.micord.ervu.account_applications.component.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class UserDomain {
|
||||||
|
@JsonProperty("id")
|
||||||
|
private String domainId;
|
||||||
|
private String name;
|
||||||
|
private String shortname;
|
||||||
|
private String fullname;
|
||||||
|
private String dns;
|
||||||
|
private String email;
|
||||||
|
private String phone;
|
||||||
|
private String address;
|
||||||
|
private String postalAddress;
|
||||||
|
private String addressId;
|
||||||
|
private String postalAddressId;
|
||||||
|
private String militaryCode;
|
||||||
|
private String timezone;
|
||||||
|
private boolean reportsEnabled;
|
||||||
|
private String ogrn;
|
||||||
|
private boolean enabled;
|
||||||
|
private String aliasKey;
|
||||||
|
private String oktmo;
|
||||||
|
private boolean esiaEmployeeAuthorization;
|
||||||
|
private String regionId;
|
||||||
|
private String passKey;
|
||||||
|
private String govOrganizationType;
|
||||||
|
private String inn;
|
||||||
|
private String certificate;
|
||||||
|
private String kpp;
|
||||||
|
private String tnsDepartmentId;
|
||||||
|
private String region;
|
||||||
|
private String leg;
|
||||||
|
|
||||||
|
public String getDomainId() {
|
||||||
|
return domainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomainId(String domainId) {
|
||||||
|
this.domainId = domainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShortname() {
|
||||||
|
return shortname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShortname(String shortname) {
|
||||||
|
this.shortname = shortname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullname() {
|
||||||
|
return fullname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFullname(String fullname) {
|
||||||
|
this.fullname = fullname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDns() {
|
||||||
|
return dns;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDns(String dns) {
|
||||||
|
this.dns = dns;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPostalAddress() {
|
||||||
|
return postalAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPostalAddress(String postalAddress) {
|
||||||
|
this.postalAddress = postalAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddressId() {
|
||||||
|
return addressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddressId(String addressId) {
|
||||||
|
this.addressId = addressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPostalAddressId() {
|
||||||
|
return postalAddressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPostalAddressId(String postalAddressId) {
|
||||||
|
this.postalAddressId = postalAddressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMilitaryCode() {
|
||||||
|
return militaryCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMilitaryCode(String militaryCode) {
|
||||||
|
this.militaryCode = militaryCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimezone() {
|
||||||
|
return timezone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimezone(String timezone) {
|
||||||
|
this.timezone = timezone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReportsEnabled() {
|
||||||
|
return reportsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReportsEnabled(boolean reportsEnabled) {
|
||||||
|
this.reportsEnabled = reportsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOgrn() {
|
||||||
|
return ogrn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOgrn(String ogrn) {
|
||||||
|
this.ogrn = ogrn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAliasKey() {
|
||||||
|
return aliasKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAliasKey(String aliasKey) {
|
||||||
|
this.aliasKey = aliasKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOktmo() {
|
||||||
|
return oktmo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOktmo(String oktmo) {
|
||||||
|
this.oktmo = oktmo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEsiaEmployeeAuthorization() {
|
||||||
|
return esiaEmployeeAuthorization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEsiaEmployeeAuthorization(boolean esiaEmployeeAuthorization) {
|
||||||
|
this.esiaEmployeeAuthorization = esiaEmployeeAuthorization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRegionId() {
|
||||||
|
return regionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegionId(String regionId) {
|
||||||
|
this.regionId = regionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassKey() {
|
||||||
|
return passKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassKey(String passKey) {
|
||||||
|
this.passKey = passKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGovOrganizationType() {
|
||||||
|
return govOrganizationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGovOrganizationType(String govOrganizationType) {
|
||||||
|
this.govOrganizationType = govOrganizationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInn() {
|
||||||
|
return inn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInn(String inn) {
|
||||||
|
this.inn = inn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCertificate() {
|
||||||
|
return certificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCertificate(String certificate) {
|
||||||
|
this.certificate = certificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKpp() {
|
||||||
|
return kpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKpp(String kpp) {
|
||||||
|
this.kpp = kpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTnsDepartmentId() {
|
||||||
|
return tnsDepartmentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTnsDepartmentId(String tnsDepartmentId) {
|
||||||
|
this.tnsDepartmentId = tnsDepartmentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRegion() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegion(String region) {
|
||||||
|
this.region = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLeg() {
|
||||||
|
return leg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeg(String leg) {
|
||||||
|
this.leg = leg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
package ru.micord.ervu.account_applications.component.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import model.BpmnVariableForSave;
|
||||||
|
import model.FieldData;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.micord.ervu.account_applications.component.exception.UserDataLoadException;
|
||||||
|
import ru.micord.ervu.account_applications.component.util.FormUtils;
|
||||||
|
import ru.micord.ervu.account_applications.service.UserDataService;
|
||||||
|
import service.container.FormMode;
|
||||||
|
import service.container.FormService;
|
||||||
|
|
||||||
|
import ru.cg.webbpm.modules.webkit.annotations.RpcSharedProperty;
|
||||||
|
import ru.cg.webbpm.modules.webkit.beans.Behavior;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ErvuUserFormLoadService extends Behavior implements FormService {
|
||||||
|
public UserDataService userDataService;
|
||||||
|
@RpcSharedProperty
|
||||||
|
public FormMode mode = FormMode.SIMPLE;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FieldData> loadData(Object id) {
|
||||||
|
try {
|
||||||
|
Map<String, List<String>> componentNameToIdMap = FormUtils.getComponentNameToIdMap(this);
|
||||||
|
Map<String, Object> fieldNameAndValueMap = userDataService.fetchDataById(id);
|
||||||
|
return FormUtils.createFieldData(componentNameToIdMap, fieldNameAndValueMap);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new UserDataLoadException("Ошибка при загрузке данных", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object saveData(String s, List<FieldData> list, Boolean aBoolean,
|
||||||
|
List<BpmnVariableForSave> list1) throws Exception {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object saveData(Object o, List<FieldData> list) throws Exception {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FieldData> loadData() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object deleteData(Object o) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object deleteData(String s, List<BpmnVariableForSave> list) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object parseId(String id) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package ru.micord.ervu.account_applications.component.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import model.FieldData;
|
||||||
|
import ru.micord.ervu.account_applications.component.field.persist.ErvuFormLoadComponent;
|
||||||
|
|
||||||
|
import ru.cg.webbpm.modules.webkit.beans.Behavior;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public final class FormUtils {
|
||||||
|
|
||||||
|
private FormUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<FieldData> createFieldData(Map<String, List<String>> fieldNameAndGuidsMap,
|
||||||
|
Map<String, Object> fieldNameAndValueMap) {
|
||||||
|
List<FieldData> fieldData = new ArrayList<>();
|
||||||
|
|
||||||
|
fieldNameAndValueMap.forEach((fieldName, value) -> {
|
||||||
|
List<String> guids = fieldNameAndGuidsMap.get(fieldName);
|
||||||
|
if (guids != null) {
|
||||||
|
guids.forEach(guid -> fieldData.add(new FieldData(guid, value)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return fieldData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, List<String>> getComponentNameToIdMap(Behavior behavior) {
|
||||||
|
return utils.FormUtils.getFormComponents(behavior, ErvuFormLoadComponent.class)
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
component -> component.fieldName,
|
||||||
|
component -> Collections.singletonList(component.getObjectId()),
|
||||||
|
(existing, newValue) -> {
|
||||||
|
List<String> merged = new ArrayList<>(existing);
|
||||||
|
merged.addAll(newValue);
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package ru.micord.ervu.account_applications.service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.google.common.net.HttpHeaders;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import ru.micord.ervu.account_applications.security.context.SecurityContext;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public abstract class AbstractUserDataService implements UserDataService {
|
||||||
|
protected final ObjectMapper objectMapper;
|
||||||
|
protected final SecurityContext securityContext;
|
||||||
|
@Value("${ervu.http.timeout:30}")
|
||||||
|
protected int httpTimeout;
|
||||||
|
@Value("${ervu.url}")
|
||||||
|
protected String ervuUrl;
|
||||||
|
|
||||||
|
protected AbstractUserDataService(ObjectMapper objectMapper, SecurityContext securityContext) {
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
this.securityContext = securityContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HttpResponse<String> sendGetRequest(String url)
|
||||||
|
throws IOException, InterruptedException {
|
||||||
|
HttpClient httpClient = HttpClient.newBuilder()
|
||||||
|
.connectTimeout(Duration.ofSeconds(httpTimeout))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(url))
|
||||||
|
.header(HttpHeaders.CONTENT_TYPE, "application/json")
|
||||||
|
.header(HttpHeaders.AUTHORIZATION, "Bearer " + securityContext.getToken())
|
||||||
|
.timeout(Duration.ofSeconds(httpTimeout))
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
if (response.statusCode() != 200) {
|
||||||
|
throw new IllegalStateException("Некорректный статус ответа: " + response.statusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected abstract Map<String, Object> objectToMap(Object object);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
package ru.micord.ervu.account_applications.service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import model.grid.GridRow;
|
||||||
|
import model.grid.GridRows;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
import ru.micord.ervu.account_applications.component.exception.UserDataLoadException;
|
||||||
|
import ru.micord.ervu.account_applications.component.model.Account;
|
||||||
|
import ru.micord.ervu.account_applications.security.context.SecurityContext;
|
||||||
|
import ru.micord.ervu.account_applications.service.constant.PathConstant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class AccountServiceImpl extends AbstractUserDataService {
|
||||||
|
|
||||||
|
public AccountServiceImpl(ObjectMapper objectMapper, SecurityContext securityContext) {
|
||||||
|
super(objectMapper, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> fetchDataById(Object id) throws IOException, InterruptedException {
|
||||||
|
Account account = fetchAccountById(id);
|
||||||
|
return objectToMap(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Account fetchAccountById(Object id) throws IOException, InterruptedException {
|
||||||
|
String url = UriComponentsBuilder.fromHttpUrl(ervuUrl)
|
||||||
|
.pathSegment(PathConstant.ACCOUNTS_PATH)
|
||||||
|
.pathSegment(id.toString())
|
||||||
|
.queryParam("expand", "person,user-domain,region")
|
||||||
|
.toUriString();
|
||||||
|
|
||||||
|
HttpResponse<String> response = sendGetRequest(url);
|
||||||
|
return objectMapper.readValue(response.body(), Account.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Map<String, Object> objectToMap(Object object) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
if (object == null) {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
Field[] fields = object.getClass().getDeclaredFields();
|
||||||
|
for (Field field : fields) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
try {
|
||||||
|
Object value = field.get(object);
|
||||||
|
|
||||||
|
if (value == null || (value instanceof String string && string.isEmpty())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ("ipAddresses".equals(field.getName())) {
|
||||||
|
List<?> ipList = (List<?>) value;
|
||||||
|
if (ipList != null && !ipList.isEmpty()) {
|
||||||
|
map.put(field.getName(), convertIpAddressesToGridRows(ipList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isSimple(value.getClass())) {
|
||||||
|
map.put(field.getName(), value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
map.putAll(objectToMap(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
throw new UserDataLoadException("Ошибка при получении значения поля: " + field.getName(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridRows convertIpAddressesToGridRows(List<?> ipList) {
|
||||||
|
List<GridRow> rows = new ArrayList<>();
|
||||||
|
int i = 0;
|
||||||
|
for (Object ip : ipList) {
|
||||||
|
GridRow row = new GridRow();
|
||||||
|
row.put("row_uid", i++);
|
||||||
|
row.put("ipAddresses", ip);
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
return new GridRows(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSimple(Class<?> type) {
|
||||||
|
return ClassUtils.isPrimitiveOrWrapper(type) || type == String.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
package ru.micord.ervu.account_applications.service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||||
|
import model.grid.GridRow;
|
||||||
|
import model.grid.GridRows;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
import ru.micord.ervu.account_applications.component.model.Role;
|
||||||
|
import ru.micord.ervu.account_applications.security.context.SecurityContext;
|
||||||
|
import ru.micord.ervu.account_applications.service.constant.PathConstant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public class RoleServiceImpl extends AbstractUserDataService {
|
||||||
|
private static final String ROLES = "roles";
|
||||||
|
|
||||||
|
protected RoleServiceImpl(ObjectMapper objectMapper,
|
||||||
|
SecurityContext securityContext) {
|
||||||
|
super(objectMapper, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> fetchDataById(Object accountId) throws IOException, InterruptedException {
|
||||||
|
List<Role> roles = fetchRolesByAccountId(accountId);
|
||||||
|
return objectToMap(roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Role> fetchRolesByAccountId(Object accountId) throws IOException, InterruptedException {
|
||||||
|
String url = UriComponentsBuilder.fromHttpUrl(ervuUrl)
|
||||||
|
.pathSegment(PathConstant.ACCOUNTS_PATH)
|
||||||
|
.pathSegment(accountId.toString())
|
||||||
|
.pathSegment(ROLES)
|
||||||
|
.toUriString();
|
||||||
|
|
||||||
|
HttpResponse<String> response = sendGetRequest(url);
|
||||||
|
CollectionType collectionType = objectMapper.getTypeFactory()
|
||||||
|
.constructCollectionType(List.class, Role.class);
|
||||||
|
|
||||||
|
return objectMapper.readValue(response.body(), collectionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Map<String, Object> objectToMap(Object object) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
if (object == null) {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object instanceof List<?> credentialList) {
|
||||||
|
List<GridRow> rows = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Object item : credentialList) {
|
||||||
|
if (item instanceof Role role && role.isErvuRole()) {
|
||||||
|
GridRow row = new GridRow();
|
||||||
|
row.put("row_uid", role.getId());
|
||||||
|
row.put("name", role.getName());
|
||||||
|
row.put("displayName", role.getDisplayName());
|
||||||
|
row.put("parentId", role.getParentId());
|
||||||
|
row.put("finish", role.getFinish());
|
||||||
|
row.put("sessionLimit", role.getSessionsLimit());
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridRows gridRows = new GridRows(rows);
|
||||||
|
map.put(ROLES, gridRows);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package ru.micord.ervu.account_applications.service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||||
|
import model.grid.GridRow;
|
||||||
|
import model.grid.GridRows;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
import ru.micord.ervu.account_applications.component.model.Credential;
|
||||||
|
import ru.micord.ervu.account_applications.security.context.SecurityContext;
|
||||||
|
import ru.micord.ervu.account_applications.service.constant.PathConstant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class UserCredentialsServiceIpml extends AbstractUserDataService {
|
||||||
|
private static final String CREDENTIALS = "credentials";
|
||||||
|
|
||||||
|
public UserCredentialsServiceIpml(ObjectMapper objectMapper, SecurityContext securityContext) {
|
||||||
|
super(objectMapper, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> fetchDataById(Object personId) throws IOException, InterruptedException {
|
||||||
|
List<Credential> credentials = fetchCredentialsByPersonId(personId);
|
||||||
|
return objectToMap(credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Credential> fetchCredentialsByPersonId(Object personId) throws IOException, InterruptedException {
|
||||||
|
String url = UriComponentsBuilder.fromHttpUrl(ervuUrl)
|
||||||
|
.pathSegment(PathConstant.PERSONS_PATH)
|
||||||
|
.pathSegment(personId.toString())
|
||||||
|
.pathSegment(CREDENTIALS)
|
||||||
|
.toUriString();
|
||||||
|
|
||||||
|
HttpResponse<String> response = sendGetRequest(url);
|
||||||
|
CollectionType collectionType = objectMapper.getTypeFactory()
|
||||||
|
.constructCollectionType(List.class, Credential.class);
|
||||||
|
|
||||||
|
return objectMapper.readValue(response.body(), collectionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Map<String, Object> objectToMap(Object object) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
if (object == null) {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object instanceof List<?> credentialList) {
|
||||||
|
List<GridRow> rows = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Object item : credentialList) {
|
||||||
|
if (item instanceof Credential credential) {
|
||||||
|
GridRow row = new GridRow();
|
||||||
|
row.put("row_uid", credential.getId());
|
||||||
|
row.put("userName", credential.getUserName());
|
||||||
|
row.put("modified", credential.getModified());
|
||||||
|
row.put("blocked", credential.isBlocked());
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridRows gridRows = new GridRows(rows);
|
||||||
|
map.put(CREDENTIALS, gridRows);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ru.micord.ervu.account_applications.service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public interface UserDataService{
|
||||||
|
Map<String, Object> fetchDataById(Object id) throws IOException, InterruptedException;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package ru.micord.ervu.account_applications.service.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public final class PathConstant {
|
||||||
|
public static final String ACCOUNTS_PATH = "service/idm/accounts";
|
||||||
|
public static final String PERSONS_PATH = "service/idm/persons";
|
||||||
|
|
||||||
|
private PathConstant() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {ChangeDetectionStrategy, Component} from "@angular/core";
|
import {ChangeDetectionStrategy, Component} from "@angular/core";
|
||||||
import {Event, GridV2, GridV2Column, Visible} from "@webbpm/base-package";
|
import {CustomLoadingComponent, Event, GridV2, GridV2Column, Visible} from "@webbpm/base-package";
|
||||||
import {
|
import {
|
||||||
StaticGridColumn
|
StaticGridColumn
|
||||||
} from "../../../generated/ru/micord/ervu/account_applications/component/property/grid/StaticGridColumn";
|
} from "../../../generated/ru/micord/ervu/account_applications/component/property/grid/StaticGridColumn";
|
||||||
|
|
@ -20,15 +20,28 @@ import {StaticGridColumnAdapter} from "./StaticGridColumnAdapter";
|
||||||
templateUrl: './../../../../../src/resources/template/account_applications/component/grid/ErvuStaticGrid.html',
|
templateUrl: './../../../../../src/resources/template/account_applications/component/grid/ErvuStaticGrid.html',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ErvuStaticGrid extends GridV2 {
|
export class ErvuStaticGrid extends GridV2 implements CustomLoadingComponent {
|
||||||
@Visible("false")
|
@Visible("false")
|
||||||
public columnFiltersChanged: Event<any> = new Event<any>();
|
public columnFiltersChanged: Event<any> = new Event<any>();
|
||||||
|
public disableLoad: boolean;
|
||||||
|
|
||||||
getColumns(): any[] {
|
getColumns(): any[] {
|
||||||
return this.getScriptsInChildren(GridV2Column)
|
return this.getScriptsInChildren(GridV2Column)
|
||||||
.map(columnV2 => columnV2.getScript(StaticGridColumn));
|
.map(columnV2 => columnV2.getScript(StaticGridColumn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
load(): void {
|
||||||
|
if (this.disableLoad) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
setKeyValue(value: any): Promise<void> {
|
||||||
|
this.setValue(value);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
protected columnV2ToColumnDef(column: GridV2Column): ColDef {
|
protected columnV2ToColumnDef(column: GridV2Column): ColDef {
|
||||||
let gridColumn = column.getScript(StaticGridColumn);
|
let gridColumn = column.getScript(StaticGridColumn);
|
||||||
let colDef = this.columnToColumnDef(gridColumn);
|
let colDef = this.columnToColumnDef(gridColumn);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue