From 05a1b218494f0f0f0897bb7590dac59be94abc97 Mon Sep 17 00:00:00 2001 From: "adel.ka" Date: Fri, 7 Mar 2025 14:54:47 +0300 Subject: [PATCH] SUPPORT-8982:add new form services --- .../field/persist/ErvuFormLoadComponent.java | 10 + .../component/model/Account.java | 132 ++ .../component/model/Credential.java | 46 + .../component/model/Person.java | 140 ++ .../component/model/Role.java | 74 + .../component/model/UserDomain.java | 264 +++ .../service/ErvuUserFormLoadService.java | 70 + .../component/util/FormUtils.java | 49 + .../service/AbstractUserDataService.java | 57 + .../service/AccountServiceImpl.java | 102 ++ .../service/RoleServiceImpl.java | 79 + .../service/UserCredentialsServiceIpml.java | 78 + .../service/UserDataService.java | 11 + .../service/constant/PathConstant.java | 12 + .../component/grid/ErvuStaticGrid.ts | 17 +- .../Создать заявку на изменение.page | 1450 ++++++++++++++++- 16 files changed, 2567 insertions(+), 24 deletions(-) create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/component/field/persist/ErvuFormLoadComponent.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/component/model/Account.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/component/model/Credential.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/component/model/Person.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/component/model/Role.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/component/model/UserDomain.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/component/service/ErvuUserFormLoadService.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/component/util/FormUtils.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/service/AbstractUserDataService.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/service/AccountServiceImpl.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/service/RoleServiceImpl.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/service/UserCredentialsServiceIpml.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/service/UserDataService.java create mode 100644 backend/src/main/java/ru/micord/ervu/account_applications/service/constant/PathConstant.java diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/field/persist/ErvuFormLoadComponent.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/field/persist/ErvuFormLoadComponent.java new file mode 100644 index 00000000..5afe1362 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/field/persist/ErvuFormLoadComponent.java @@ -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; +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Account.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Account.java new file mode 100644 index 00000000..a95f5fe8 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Account.java @@ -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; + } +} \ No newline at end of file diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Credential.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Credential.java new file mode 100644 index 00000000..3041c75a --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Credential.java @@ -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; + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Person.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Person.java new file mode 100644 index 00000000..f977d182 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Person.java @@ -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 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 getIpAddresses() { + return ipAddresses; + } + + public void setIpAddresses(List ipAddresses) { + this.ipAddresses = ipAddresses; + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Role.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Role.java new file mode 100644 index 00000000..b4dc1f6b --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/Role.java @@ -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; + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/model/UserDomain.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/UserDomain.java new file mode 100644 index 00000000..b9f4a0af --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/UserDomain.java @@ -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; + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/service/ErvuUserFormLoadService.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/service/ErvuUserFormLoadService.java new file mode 100644 index 00000000..5a508587 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/service/ErvuUserFormLoadService.java @@ -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 loadData(Object id) { + try { + Map> componentNameToIdMap = FormUtils.getComponentNameToIdMap(this); + Map fieldNameAndValueMap = userDataService.fetchDataById(id); + return FormUtils.createFieldData(componentNameToIdMap, fieldNameAndValueMap); + } + catch (Exception e) { + throw new UserDataLoadException("Ошибка при загрузке данных", e); + } + } + + @Override + public Object saveData(String s, List list, Boolean aBoolean, + List list1) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + public Object saveData(Object o, List list) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + public List loadData() { + throw new UnsupportedOperationException(); + } + + @Override + public Object deleteData(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public Object deleteData(String s, List list) { + throw new UnsupportedOperationException(); + } + + @Override + public Object parseId(String id) { + return id; + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/util/FormUtils.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/util/FormUtils.java new file mode 100644 index 00000000..47cc2e09 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/util/FormUtils.java @@ -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 createFieldData(Map> fieldNameAndGuidsMap, + Map fieldNameAndValueMap) { + List fieldData = new ArrayList<>(); + + fieldNameAndValueMap.forEach((fieldName, value) -> { + List guids = fieldNameAndGuidsMap.get(fieldName); + if (guids != null) { + guids.forEach(guid -> fieldData.add(new FieldData(guid, value))); + } + }); + + return fieldData; + } + + public static Map> 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 merged = new ArrayList<>(existing); + merged.addAll(newValue); + return merged; + } + )); + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/service/AbstractUserDataService.java b/backend/src/main/java/ru/micord/ervu/account_applications/service/AbstractUserDataService.java new file mode 100644 index 00000000..9b9672dd --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/service/AbstractUserDataService.java @@ -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 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 response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() != 200) { + throw new IllegalStateException("Некорректный статус ответа: " + response.statusCode()); + } + + return response; + } + + + protected abstract Map objectToMap(Object object); +} \ No newline at end of file diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/service/AccountServiceImpl.java b/backend/src/main/java/ru/micord/ervu/account_applications/service/AccountServiceImpl.java new file mode 100644 index 00000000..ebd69613 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/service/AccountServiceImpl.java @@ -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 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 response = sendGetRequest(url); + return objectMapper.readValue(response.body(), Account.class); + } + + @Override + protected Map objectToMap(Object object) { + Map 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 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; + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/service/RoleServiceImpl.java b/backend/src/main/java/ru/micord/ervu/account_applications/service/RoleServiceImpl.java new file mode 100644 index 00000000..413f1c48 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/service/RoleServiceImpl.java @@ -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 fetchDataById(Object accountId) throws IOException, InterruptedException { + List roles = fetchRolesByAccountId(accountId); + return objectToMap(roles); + } + + private List fetchRolesByAccountId(Object accountId) throws IOException, InterruptedException { + String url = UriComponentsBuilder.fromHttpUrl(ervuUrl) + .pathSegment(PathConstant.ACCOUNTS_PATH) + .pathSegment(accountId.toString()) + .pathSegment(ROLES) + .toUriString(); + + HttpResponse response = sendGetRequest(url); + CollectionType collectionType = objectMapper.getTypeFactory() + .constructCollectionType(List.class, Role.class); + + return objectMapper.readValue(response.body(), collectionType); + } + + @Override + protected Map objectToMap(Object object) { + Map map = new HashMap<>(); + if (object == null) { + return map; + } + + if (object instanceof List credentialList) { + List 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; + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/service/UserCredentialsServiceIpml.java b/backend/src/main/java/ru/micord/ervu/account_applications/service/UserCredentialsServiceIpml.java new file mode 100644 index 00000000..7f8fda2d --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/service/UserCredentialsServiceIpml.java @@ -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 fetchDataById(Object personId) throws IOException, InterruptedException { + List credentials = fetchCredentialsByPersonId(personId); + return objectToMap(credentials); + } + + private List fetchCredentialsByPersonId(Object personId) throws IOException, InterruptedException { + String url = UriComponentsBuilder.fromHttpUrl(ervuUrl) + .pathSegment(PathConstant.PERSONS_PATH) + .pathSegment(personId.toString()) + .pathSegment(CREDENTIALS) + .toUriString(); + + HttpResponse response = sendGetRequest(url); + CollectionType collectionType = objectMapper.getTypeFactory() + .constructCollectionType(List.class, Credential.class); + + return objectMapper.readValue(response.body(), collectionType); + } + + @Override + protected Map objectToMap(Object object) { + Map map = new HashMap<>(); + if (object == null) { + return map; + } + + if (object instanceof List credentialList) { + List 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; + } +} \ No newline at end of file diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/service/UserDataService.java b/backend/src/main/java/ru/micord/ervu/account_applications/service/UserDataService.java new file mode 100644 index 00000000..f5a98c9d --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/service/UserDataService.java @@ -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 fetchDataById(Object id) throws IOException, InterruptedException; +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/service/constant/PathConstant.java b/backend/src/main/java/ru/micord/ervu/account_applications/service/constant/PathConstant.java new file mode 100644 index 00000000..64e3acf8 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/service/constant/PathConstant.java @@ -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() { + } +} diff --git a/frontend/src/ts/account_applications/component/grid/ErvuStaticGrid.ts b/frontend/src/ts/account_applications/component/grid/ErvuStaticGrid.ts index 610c3329..b8f75fd5 100644 --- a/frontend/src/ts/account_applications/component/grid/ErvuStaticGrid.ts +++ b/frontend/src/ts/account_applications/component/grid/ErvuStaticGrid.ts @@ -1,5 +1,5 @@ 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 { 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', changeDetection: ChangeDetectionStrategy.OnPush }) -export class ErvuStaticGrid extends GridV2 { +export class ErvuStaticGrid extends GridV2 implements CustomLoadingComponent { @Visible("false") public columnFiltersChanged: Event = new Event(); + public disableLoad: boolean; getColumns(): any[] { return this.getScriptsInChildren(GridV2Column) .map(columnV2 => columnV2.getScript(StaticGridColumn)); } + load(): void { + if (this.disableLoad) { + return; + } + super.load(); + } + + setKeyValue(value: any): Promise { + this.setValue(value); + return Promise.resolve(); + } + protected columnV2ToColumnDef(column: GridV2Column): ColDef { let gridColumn = column.getScript(StaticGridColumn); let colDef = this.columnToColumnDef(gridColumn); diff --git a/resources/src/main/resources/business-model/Список заявок на пользователя/Создать заявку на изменение.page b/resources/src/main/resources/business-model/Список заявок на пользователя/Создать заявку на изменение.page index 662257b6..88ba5365 100644 --- a/resources/src/main/resources/business-model/Список заявок на пользователя/Создать заявку на изменение.page +++ b/resources/src/main/resources/business-model/Список заявок на пользователя/Создать заявку на изменение.page @@ -4032,12 +4032,6 @@ service - - columnSorts - - - - loadDao @@ -4045,13 +4039,7 @@ graph - {"conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"nodeByIndex":{"0":{"tableName":"link_user_application_ip_address","schemaName":"public","x":260.0,"y":227.0,"alias":"link_user_application_ip_address","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"nodes":[{"tableName":"link_user_application_ip_address","schemaName":"public","x":260.0,"y":227.0,"alias":"link_user_application_ip_address","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}],"nodeByEntityName":{"link_user_application_ip_address":{"tableName":"link_user_application_ip_address","schemaName":"public","x":260.0,"y":227.0,"alias":"link_user_application_ip_address","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"matrix":[[null]],"mainNodeIndex":0} - - - - uniqueResult - - true + {"conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"nodeByIndex":{"0":{"tableName":"link_user_application_ip_address","schemaName":"public","x":236.0,"y":208.0,"alias":"link_user_application_ip_address","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"nodes":[{"tableName":"link_user_application_ip_address","schemaName":"public","x":236.0,"y":208.0,"alias":"link_user_application_ip_address","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}],"nodeByEntityName":{"link_user_application_ip_address":{"tableName":"link_user_application_ip_address","schemaName":"public","x":236.0,"y":208.0,"alias":"link_user_application_ip_address","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"matrix":[[null]],"mainNodeIndex":0} @@ -4062,19 +4050,20 @@ - - - - false + + true - - false + + true - - false + + + + + true - + true service @@ -7786,6 +7775,56 @@ thenActions + + + + + behavior + + {"objectId":"b03ad48b-3708-41ca-b347-fdbe50ed0143","packageName":"component.container","className":"Form","type":"TS"} + + + + method + + "loadById" + + + + value + + + + objectValue + + + + argument + + null + + + + behavior + + {"objectId":"dd940221-7f07-4556-8925-9b6e1187e072","packageName":"component.grid","className":"GridV2","type":"TS"} + + + + method + + "getSelectedRowId" + + + + + + + + + + + @@ -8026,6 +8065,30 @@ + + + + + + + behavior + + {"objectId":"b03ad48b-3708-41ca-b347-fdbe50ed0143","packageName":"component.container","className":"Form","type":"TS"} + + + + method + + "clearChildComponents" + + + + value + + null + + + @@ -8034,4 +8097,1347 @@ + + be95ef58-ee04-413f-be0f-e8cd4af25faf + b03ad48b-3708-41ca-b347-fdbe50ed0143 + Форма + true + false + + + + loadOnStart + + null + + + + + + + + formService + + + +mode + + "SIMPLE" + + + +userDataService + + + AccountServiceImpl + ru.micord.ervu.account_applications.service + + + + + + ErvuUserFormLoadService + ru.micord.ervu.account_applications.component.service + + + + + + + + + + + d7d54cfb-26b5-4dba-b56f-b6247183c24d + 2d7863e6-5f14-4260-8813-0d40e2c1af11 + Hbox_подгрузка данных + true + false + + + + disabled + + true + + + + + + + + + + 9d1b5af1-0b8f-4b1b-b9a5-c2e6acf72d91 + 976e36ed-605f-403b-a481-a03e05944879 + Vbox_1-2 + true + false + + + + style + + + + minWidth + + null + + + + width + + "67%" + + + + + + + + + + + + + d7d54cfb-26b5-4dba-b56f-b6247183c24d + e66025d1-094f-4805-b838-16d818e3c72c + Hbox + true + false + + + + + + + 9d1b5af1-0b8f-4b1b-b9a5-c2e6acf72d91 + 097f3ae8-6bd0-4b63-9d9b-0a8c4bbea33c + Vbox_1 + true + false + + + + style + + + + width + + "50%" + + + + + + + + + + + + + 133ca212-09a6-413a-ac66-e2f6ce188f1f + d8737278-86ad-4c40-8eab-2772f0ef81e8 + Фамилия + false + false + + + + cssClasses + + + + "width-full" + + + + + + errorTooltipStyle + + + + padding + + null + + + + + + + label + + "Фамилия" + + + + pattern + + "^(?!.*\\\\s{2})([А-Я Ё а-я ё])+([\\\\(][А-Я Ё а-я ё]+[\\\\)])?([\\\\s\\u0027`\\\\-]?[А-Я Ё а-я ё]+){0,5}" + + + + + + + + + defaultValueColumn + + {"schema":"public","table":"user_list","entity":"user_list","name":"secondname"} + + + + loadType + + null + + + + + + +false + + + columnForSave + + null + + + + + + + + ErvuFormLoadComponent + ru.micord.ervu.account_applications.component.field.persist + +true +true + + + fieldName + + "surname" + + + + + + + 133ca212-09a6-413a-ac66-e2f6ce188f1f + 9193c996-b6e2-494e-949d-85573bc2872b + Имя + false + false + false + + + + cssClasses + + + + "width-full" + + + + + + errorTooltipStyle + + + + padding + + null + + + + + + + label + + "Имя" + + + + pattern + + "^(?!.*\\\\s{2})([А-Я Ё а-я ё])+([\\\\(][А-Я Ё а-я ё]+[\\\\)])?([\\\\s\\u0027`\\\\-]?[А-Я Ё а-я ё]+){0,5}" + + + + + + + + + defaultValueColumn + + {"schema":"public","table":"user_list","entity":"user_list","name":"firstname"} + + + + loadType + + null + + + + + + +false + + + columnForSave + + null + + + + + + + + ErvuFormLoadComponent + ru.micord.ervu.account_applications.component.field.persist + +true +true + + + fieldName + + "firstname" + + + + + + + 133ca212-09a6-413a-ac66-e2f6ce188f1f + 33784a53-defc-4b13-8abe-45fb14db62ed + Отчество + false + false + false + + + + cssClasses + + + + "width-full" + + + + + + errorTooltipStyle + + + + padding + + null + + + + + + + label + + "Отчество" + + + + pattern + + "^(?!.*\\\\s{2})([А-Я Ё а-я ё])+([\\\\(][А-Я Ё а-я ё]+[\\\\)])?([\\\\s\\u0027`\\\\-]?[А-Я Ё а-я ё]+){0,5}" + + + + + + + + + defaultValueColumn + + {"schema":"public","table":"user_list","entity":"user_list","name":"middlename"} + + + + loadType + + null + + + + + + +false + + + columnForSave + + null + + + + + + + + ErvuFormLoadComponent + ru.micord.ervu.account_applications.component.field.persist + +true +true + + + fieldName + + "middlename" + + + + + + + bce312bd-0c82-45e5-89dc-a1af90431c18 + 7fcc4453-49e5-4b99-a1da-ea176b168eb1 + Пол + false + false + false + + + + cssClasses + + + + "width-full" + + + + + + label + + "Пол" + + + + values + + + + + + label + +"Мужской" + + + + value + +"MALE" + + + + + + + + + + label + +"Женский" + + + + value + +"FEMALE" + + + + + + + + + + + + + +false + + + columnForSave + + null + + + + + + + c6a4e38d-d0b3-46dd-960b-36c7e8beba36 + 24a5cf00-aa69-4096-938b-da2f281f3e06 + Дата рождения + false + true + + + + 9d1b5af1-0b8f-4b1b-b9a5-c2e6acf72d91 + af2e3c5d-3534-46e4-a1b0-e50ad71d81c0 + Vbox_2 + true + false + + + + style + + + + width + + "50%" + + + + + + + + + + + + + c6a4e38d-d0b3-46dd-960b-36c7e8beba36 + 24a5cf00-aa69-4096-938b-da2f281f3e06 + Дата рождения + false + false + false + + + + cssClasses + + + + "width-full" + + + + + + dateValueFormat + + "DATE" + + + + label + + "Дата рождения" + + + + maxDateType + + "CURRENT" + + + + + + + + +false + + + columnForSave + + null + + + + + + + ErvuFormLoadComponent + ru.micord.ervu.account_applications.component.field.persist + +true +true + + + fieldName + + "birthdate" + + + + + + + 133ca212-09a6-413a-ac66-e2f6ce188f1f + af6e4a05-fbd7-42ca-9e36-b9f7a36caadd + Логин + false + false + false + + + + cssClasses + + + + "width-full" + + + + + + label + + "Логин" + + + + mask + + null + + + + pattern + + "^[a-zA-Z][a-zA-Z0-9]{0,49}" + + + + patternErrorMessage + + "Логин не должен начинаться с цифры, содержать спецсимволы, буквы кирилицы и быть не более 50 символов" + + + + + + + + + defaultValueColumn + + {"schema":"public","table":"user_list","entity":"user_list","name":"user_login"} + + + + loadType + + null + + + + + + +false + + + columnForSave + + null + + + + + + + + b310f98a-69c6-4e7b-8cdb-f1ab9f9c0d94 + 5b744b36-bfd4-471a-b081-b23330f3bc9f + Должность + false + true + + + 133ca212-09a6-413a-ac66-e2f6ce188f1f + c321c2f5-e186-4026-9ae5-523f99d765fa + Должность + false + false + false + + + + cssClasses + + + + "width-full" + + + + + + label + + "Должность" + + + + + + + + + defaultValueColumn + + {"schema":"public","table":"user_list","entity":"user_list","name":"middlename"} + + + + loadType + + null + + + + + + +false + + + columnForSave + + null + + + + + + + + 133ca212-09a6-413a-ac66-e2f6ce188f1f + 06817186-d1d1-4844-b9be-c5f92aa8391c + СНИЛС + false + false + false + + + + cssClasses + + + + "width-full" + + + + + + label + + "СНИЛС" + + + + mask + + "999-999-999 99" + + + + unMaskValue + + false + + + + + + + + + defaultValueColumn + + {"schema":"public","table":"user_list","entity":"user_list","name":"phone"} + + + + loadType + + null + + + + + + +false + + + columnForSave + + null + + + + + + + + b310f98a-69c6-4e7b-8cdb-f1ab9f9c0d94 + 1b858065-0944-4cba-b022-c782a2ec50fc + Combo box_Организация + false + true + + + + + b310f98a-69c6-4e7b-8cdb-f1ab9f9c0d94 + 1b858065-0944-4cba-b022-c782a2ec50fc + Combo box_Организация + false + true + + + 8174c549-4b94-4c3e-9168-09610ade4c6e + 4a7bb4df-b4cb-49a6-9879-2ba491002eb5 + DropdownTreeView + false + true + + + f9a38417-9ad0-412a-9b5f-bbeb450dddd6 + 87e289d7-35ad-41b5-8135-bc4c438b97f6 + Организация + false + false + + + +cssClasses + + + + "width-full" + + + + + +disabled + + true + + + +label + + "Организация" + + + + + + + +autocompleteService + + + + businessIdColumn + + {"schema":"public","table":"recruitment","entity":"recruitment","name":"fullname"} + + + + displayColumn + + {"schema":"public","table":"recruitment","entity":"recruitment","name":"fullname"} + + + + loadDao + + + + graph + + {"conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"nodeByIndex":{"0":{"tableName":"recruitment","schemaName":"public","x":334.0,"y":161.0,"alias":"recruitment","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"nodes":[{"tableName":"recruitment","schemaName":"public","x":334.0,"y":161.0,"alias":"recruitment","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}],"nodeByEntityName":{"recruitment":{"tableName":"recruitment","schemaName":"public","x":334.0,"y":161.0,"alias":"recruitment","conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"matrix":[[null]],"mainNodeIndex":0} + + + + + + + parentControlReference + + null + + + + + + + + + + +variable + + "org_unit_id" + + + + + + + + false + + +columnForSave + + null + + + + + + + 133ca212-09a6-413a-ac66-e2f6ce188f1f + 3b6c2f12-2ed5-4e1f-8a46-f67c53de66d7 + person_id + false + false + + + +cssClasses + + + + "width-full" + + + + + +label + + "person_id" + + + +visible + + false + + + + + + + + +defaultValueColumn + + {"schema":"public","table":"user_list","entity":"user_list","name":"middlename"} + + + +loadType + + null + + + + + + + false + + +columnForSave + + null + + + + + + + + 133ca212-09a6-413a-ac66-e2f6ce188f1f + 7ff74e3a-1235-434c-8edb-1c67be649acb + user_account_id + false + false + + + +cssClasses + + + + "width-full" + + + + + +label + + "user_account_id" + + + +visible + + false + + + + + + + + +defaultValueColumn + + {"schema":"public","table":"user_list","entity":"user_list","name":"middlename"} + + + +loadType + + null + + + + + + + false + + +columnForSave + + null + + + + + + + + 69af9ec9-d640-499a-bf05-cda6ce64a81f + 7e354106-6356-4d05-bf25-8f10545d5979 + Примечание + false + true + + + 5ebd2885-0972-4e51-8376-1fa66aed9a90 + 736dd597-5026-4087-a93f-af4ef5e15516 + File upload + false + true + + + + 9d1b5af1-0b8f-4b1b-b9a5-c2e6acf72d91 + 01e849fc-a084-4519-b607-a7728403ea73 + Vbox_3 + true + false + + + + disabled + +true + + + + style + + + + height + + null + + + + width + + "33%" + + + + + + + + + + + + + 27912fc5-0be7-4d4c-ae46-a82979253599 + 818520df-f732-44b0-9af5-127d85fd9a59 + Filter group_gr + true + true + + + 27912fc5-0be7-4d4c-ae46-a82979253599 + ccce097d-04d3-4ad0-854e-2806b4283dc2 + Filter group_ip + true + true + + + 67605d63-1081-423b-b6b5-727ecfce2ca1 + 458e4d8c-fcef-40e9-b2e2-d45f2e96dad4 + Many to many + true + true + + + 76e91ef4-d2ef-4662-96ad-84c0dae0ecff + 3222668d-81e8-4772-841b-b90274727ddb + IP- адреса + true + true + + + d7d54cfb-26b5-4dba-b56f-b6247183c24d + fbdbc0d7-4688-46a4-af4f-c7b691efe411 + Hbox + true + true + + + 16071adb-3bdf-4c33-b29b-886876016415 + 5f067770-653f-469f-8b42-6389e96be4dc + Grid_roles + true + false + + + +autoStretchColumns + + true + + + +checkboxColumn + + true + + + +checkboxHeader + + false + + + +disabled + + true + + + +loadOnInit + + false + + + +rowModelType + + "CLIENT_SIDE" + + + +style + + + + maxHeight + + "130px" + + + + + + + + + + +gridService + + + ErvuUserGridLoadService + ru.micord.ervu.account_applications.component.service + + + + + + + + 364c8faa-5e56-46cd-9203-d2ec6ef2dc74 + a0e23612-4cc0-4f6a-a123-d9e67ad54e54 + Column + false + false + + + false + + + displayName + + "Роли пользователя" + + + + displayType + + "ONE_COLUMN" + + + + field + + {"schema":"public","table":"user_application_role","entity":"user_application_role","name":"role_name"} + + + + + + + + 16071adb-3bdf-4c33-b29b-886876016415 + a1692a5e-365c-4add-8d4e-896506cc03ca + Grid_ip + true + false + + + +autoStretchColumns + + true + + + +loadOnInit + + false + + + +style + + + + maxHeight + + "130px" + + + + + + + + + + +gridService + + + ErvuUserGridLoadService + ru.micord.ervu.account_applications.component.service + + + + + + + + 364c8faa-5e56-46cd-9203-d2ec6ef2dc74 + e0eafcbb-e49d-4832-a0aa-17abc7705689 + Column + false + false + + + false + + + displayName + + "IP адрес" + + + + displayType + + "ONE_COLUMN" + + + + field + + {"schema":"public","table":"link_user_application_ip_address","entity":"link_user_application_ip_address","name":"ip_address"} + + + + + + + + +