SUPPORT-8975: add custom grid

This commit is contained in:
adel.ka 2025-03-05 18:06:13 +03:00
parent e5c7e003a0
commit 1697d8302b
21 changed files with 1013 additions and 4 deletions

View file

@ -0,0 +1,14 @@
package ru.micord.ervu.account_applications.component.exception;
/**
* @author Adel Kalimullin
*/
public class GridException extends RuntimeException{
public GridException(String message) {
super(message);
}
public GridException(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -0,0 +1,13 @@
package ru.micord.ervu.account_applications.component.field.persist.filter;
import ru.cg.webbpm.modules.standard_annotations.validation.NotNull;
import ru.cg.webbpm.modules.webkit.beans.Behavior;
/**
* @author Adel Kalimullin
*/
public class StaticFilterComponent extends Behavior {
@NotNull
public String name;
}

View file

@ -0,0 +1,49 @@
package ru.micord.ervu.account_applications.component.model;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class LoadServiceResponse<T> {
private Set<T> data;
private int page;
private int perPage;
private int totalRows;
public Set<T> getData() {
return data;
}
public void setData(Set<T> data) {
this.data = data;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getPerPage() {
return perPage;
}
public void setPerPage(int perPage) {
this.perPage = perPage;
}
public int getTotalRows() {
return totalRows;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
}
}

View file

@ -0,0 +1,55 @@
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 shortname;
private String displayName;
private String description;
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 getShortname() {
return shortname;
}
public void setShortname(String shortname) {
this.shortname = shortname;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View file

@ -0,0 +1,93 @@
package ru.micord.ervu.account_applications.component.model;
import java.util.List;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private String accountId;
private String accountFullName;
private String domainName;
private boolean enabled;
private boolean blocked;
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getAccountFullName() {
return accountFullName;
}
public void setAccountFullName(String accountFullName) {
this.accountFullName = accountFullName;
}
public String getDomainName() {
return domainName;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isBlocked() {
return blocked;
}
public void setBlocked(boolean blocked) {
this.blocked = blocked;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return enabled == user.enabled && blocked == user.blocked && Objects.equals(
accountId, user.accountId) && Objects.equals(accountFullName,
user.accountFullName
) && Objects.equals(domainName, user.domainName);
}
@Override
public int hashCode() {
int result = Objects.hashCode(accountId);
result = 31 * result + Objects.hashCode(accountFullName);
result = 31 * result + Objects.hashCode(domainName);
result = 31 * result + Boolean.hashCode(enabled);
result = 31 * result + Boolean.hashCode(blocked);
return result;
}
}

View file

@ -0,0 +1,11 @@
package ru.micord.ervu.account_applications.component.property.grid;
/**
* @author Adel Kalimullin
*/
public enum FilterType {
TEXT,
DATE,
NUMBER,
SET
}

View file

@ -0,0 +1,10 @@
package ru.micord.ervu.account_applications.component.property.grid;
/**
* @author Adel Kalimullin
*/
public class StaticColumn {
public String column;
public String type;
public FilterType filterType;
}

View file

@ -0,0 +1,88 @@
package ru.micord.ervu.account_applications.component.property.grid;
import java.util.Collection;
import java.util.Collections;
import component.field.dataconvert.DataConverter;
import component.field.dataconvert.DataConverterProvider;
import component.field.persist.filter.AbstractFilterComponent;
import component.grid.model.PinnedType;
import property.grid.Column;
import property.grid.Formatter;
import utils.GridUtils;
import ru.cg.webbpm.modules.database.bean.AggregationFunction;
import ru.cg.webbpm.modules.database.bean.entity_graph.EntityColumn;
import ru.cg.webbpm.modules.standard_annotations.editor.Visible;
import ru.cg.webbpm.modules.webkit.annotations.Exclude;
import ru.cg.webbpm.modules.webkit.annotations.Model;
/**
* @author Adel Kalimullin
*/
@Model
public class StaticGridColumn extends AbstractFilterComponent<Object, Object>
implements Column {
public StaticColumn field;
public String displayName;
public String headerTooltip;
@Visible(predicate = "displayPopup != true")
public String columnTooltip;
public Integer width;
public boolean widthFixed;
public boolean autoHeight;
public boolean hidden;
public boolean sortable;
public boolean disableHiding;
public PinnedType pinned;
public boolean filter;
@Exclude
public Formatter<?, ?> formatter;
public AggregationFunction aggregationFunction;
@Exclude
public Formatter<?, ?> aggregationFormatter;
@Exclude
public Formatter<?, ?> exportFileFormatter;
public boolean displayPopup;
public boolean suppressHeaderMenu;
public EntityColumn getField() {
return GridUtils.toEntityColumn(field.column);
}
@Override
public String getDisplayName() {
return displayName;
}
public Collection<EntityColumn> getEntityColumns() {
return Collections.singleton(getField());
}
public AggregationFunction getAggregationFunction() {
return this.aggregationFunction;
}
public Formatter<?, ?> getFormatter() {
return this.formatter;
}
public Formatter<?, ?> getAggregationFormatter() {
return this.aggregationFormatter;
}
public Formatter<?, ?> getExportFormatter() {
return exportFileFormatter;
}
public Object convertData(Object rawValue) {
if (this.dataConverter != null) {
return this.dataConverter.convertValueForSave(rawValue);
}
else {
DataConverter converter = DataConverterProvider.getDataConverter(rawValue.getClass());
return converter.convertValueForSave(rawValue);
}
}
}

View file

@ -0,0 +1,169 @@
package ru.micord.ervu.account_applications.component.service;
import java.lang.reflect.Field;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import model.FileModel;
import model.Filter;
import model.grid.GridDataExportFormat;
import model.grid.GridRow;
import model.grid.GridRows;
import model.grid.SortInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
import ru.micord.ervu.account_applications.component.exception.GridException;
import ru.micord.ervu.account_applications.component.field.persist.filter.StaticFilterComponent;
import ru.micord.ervu.account_applications.component.model.LoadServiceResponse;
import ru.micord.ervu.account_applications.component.model.Role;
import ru.micord.ervu.account_applications.component.model.User;
import ru.micord.ervu.account_applications.security.context.SecurityContext;
import ru.micord.ervu.account_applications.util.StringUtils;
import service.GridService;
import ru.cg.webbpm.modules.webkit.beans.Behavior;
/**
* @author Adel Kalimullin
*/
@Service
public class ErvuUserGridLoadService extends Behavior implements GridService {
private static final String FILTER_PATH = "/service/idm/accounts/search/filter/v1";
private final ObjectMapper objectMapper;
private final SecurityContext securityContext;
@Value("${ervu.http.timeout:10}")
private int httpTimeout;
@Value("${ervu.url:https://ervu-dev.pgs.rtlabs.ru}")
private String ervuUrl;
public ErvuUserGridLoadService(ObjectMapper objectMapper,
SecurityContext securityContext) {
this.objectMapper = objectMapper;
this.securityContext = securityContext;
}
@Override
public GridRows loadData(Integer offset, Integer limit, Filter[] filters,
SortInfo[] sortInfos) {
LoadServiceResponse<User> loadServiceResponse = loadDataFromApi(offset, limit, filters);
List<GridRow> gridRows = convertToGridRows(loadServiceResponse.getData());
return new GridRows(gridRows);
}
@Override
public GridRows loadDataWithRowCount(Integer offset, Integer limit, Filter[] filters,
SortInfo[] sortInfos) {
LoadServiceResponse<User> loadServiceResponse = loadDataFromApi(offset, limit, filters);
List<GridRow> gridRows = convertToGridRows(loadServiceResponse.getData());
return new GridRows(gridRows, loadServiceResponse.getTotalRows());
}
@Override
public FileModel exportData(String[] columnIdsToExport, GridDataExportFormat exportFormat,
Filter[] filters, SortInfo[] sortInfo) {
return GridService.super.exportData(columnIdsToExport, exportFormat, filters, sortInfo);
}
private LoadServiceResponse<User> loadDataFromApi(Integer offset, Integer limit,
Filter[] filters) {
try {
Map<String, Object> requestBodyMap = createRequestBody(offset, limit, filters);
String requestBody = objectMapper.writeValueAsString(requestBodyMap);
HttpClient httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(httpTimeout))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(UriComponentsBuilder.fromHttpUrl(ervuUrl)
.path(FILTER_PATH)
.build().toUri())
.header(HttpHeaders.CONTENT_TYPE, "application/json")
.header(HttpHeaders.AUTHORIZATION, "Bearer " + securityContext.getToken())
.timeout(Duration.ofSeconds(httpTimeout))
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString()
);
return objectMapper.readValue(response.body(),
new TypeReference<LoadServiceResponse<User>>() {
}
);
}
catch (Exception e) {
throw new GridException("Ошибка при загрузке данных", e);
}
}
private List<GridRow> convertToGridRows(Set<User> users) {
List<GridRow> gridRows = new ArrayList<>();
int rowIndex = 0;
for (User user : users) {
GridRow gridRow = new GridRow();
gridRow.put("row_uid", rowIndex++);
for (Field field : User.class.getDeclaredFields()) {
processField(field, user, gridRow);
}
gridRows.add(gridRow);
}
return gridRows;
}
private Map<String, Object> createRequestBody(Integer offset, Integer limit, Filter[] filters) {
int page = (offset / limit) + 1;
Map<String, Object> filterMap = new HashMap<>();
filterMap.put("domainId", securityContext.getDomainId());
if (filters != null && filters.length > 0) {
filterMap.putAll(Arrays.stream(filters)
.filter(filter -> filter.getFilterModels() != null && filter.getFilterModels().length > 0)
.collect(Collectors.toMap(
filter -> getScriptInObject(filter.componentGuid, StaticFilterComponent.class).name,
filter -> filter.getFilterModels()[0].value,
(existing, replacement) -> replacement
))
);
}
return Map.of(
"searchFilter", filterMap,
"page", page,
"perPage", limit
);
}
private void processField(Field field, User user, GridRow gridRow) {
field.setAccessible(true);
try {
Object value = field.get(user);
if ("accountFullName".equals(field.getName()) && value instanceof String string) {
gridRow.putAll(StringUtils.splitFio(string));
return;
}
if (value instanceof List<?> list && !list.isEmpty() && list.get(0) instanceof Role) {
value = list.stream()
.map(role -> ((Role) role).getId())
.collect(Collectors.joining(", "));
}
gridRow.put(field.getName(), value != null ? value : "");
}
catch (IllegalAccessException e) {
throw new GridException("Ошибка при получении значения поля: " + field.getName(), e);
}
}
}

View file

@ -8,6 +8,8 @@ public interface SecurityContext {
String getUserId();
String getToken();
UserSession getUserSession();
}

View file

@ -21,6 +21,12 @@ public class SecurityContextImpl
return auth != null ? auth.getUserSession().userId() : null;
}
@Override
public String getToken() {
JwtTokenAuthentication auth = (JwtTokenAuthentication) SecurityContextHolder.getContext().getAuthentication();
return auth != null ? (String) auth.getCredentials() : null;
}
@Override
public UserSession getUserSession() {
JwtTokenAuthentication auth = (JwtTokenAuthentication) SecurityContextHolder.getContext().getAuthentication();

View file

@ -9,9 +9,11 @@ import ru.micord.ervu.account_applications.security.model.jwt.UserSession;
public class JwtTokenAuthentication implements Authentication {
private final UserSession userSession;
private final String token;
public JwtTokenAuthentication(UserSession userSession) {
public JwtTokenAuthentication(UserSession userSession, String token) {
this.userSession = userSession;
this.token = token;
}
public UserSession getUserSession() {
@ -25,7 +27,7 @@ public class JwtTokenAuthentication implements Authentication {
@Override
public Object getCredentials() {
return null;
return token;
}
@Override

View file

@ -23,7 +23,7 @@ public class ErvuJwtAuthenticationProvider implements AuthenticationProvider {
JwtTokenDummy jwtTokenDummy = (JwtTokenDummy) authentication;
String jwtToken = jwtTokenDummy.getToken();
UserSession userSession = jwtTokenService.getUserSession(jwtToken);
return new JwtTokenAuthentication(userSession);
return new JwtTokenAuthentication(userSession, jwtToken);
}
@Override

View file

@ -0,0 +1,22 @@
package ru.micord.ervu.account_applications.util;
import java.util.HashMap;
import java.util.Map;
/**
* @author Adel Kalimullin
*/
public final class StringUtils {
private StringUtils() {
}
public static Map<String, String> splitFio(String fio) {
String[] parts = fio.trim().split(" ", 3);
Map<String, String> result = new HashMap<>();
result.put("lastName", parts.length > 0 ? parts[0] : "");
result.put("firstName", parts.length > 1 ? parts[1] : "");
result.put("middleName", parts.length > 2 ? parts[2] : "");
return result;
}
}

View file

@ -0,0 +1,54 @@
<div class="grid"
[ngbTooltip]="tooltip | emptyIfNull">
<ag-grid-angular [ngClass]="theme"
[ngStyle]="style"
[columnDefs]="columnDefs"
[defaultColDef]="defaultColDef"
[headerHeight]="headerHeight"
[rowHeight]="rowHeight"
[rowSelection]="rowSelection"
[rowMultiSelectWithClick]="isRowMultiSelectWithClick()"
[suppressRowClickSelection]="isSuppressRowClickSelection()"
[suppressLoadingOverlay]="isSuppressLoadingOverlay()"
[suppressNoRowsOverlay]="isSuppressNoRowsOverlay()"
[rowClassRules]="rowClassRules"
[rowModelType]="getRowModelType()"
[datasource]="datasource"
[maxConcurrentDatasourceRequests]="maxConcurrentDatasourceRequests"
[blockLoadDebounceMillis]="blockLoadDebounceMillis"
[cacheBlockSize]="getBlockSize()"
[pagination]="pagination"
[paginationPageSize]="fetchSize"
[maxBlocksInCache]="0"
[getRowId]="getRowIdFunc()"
[isRowSelectable]="isRowSelectableFunc()"
[pinnedBottomRowData]="pinnedBottomRowData"
[suppressDragLeaveHidesColumns]="true"
[suppressCopyRowsToClipboard]="true"
[processCellForClipboard]="processCellForClipboard"
[allowContextMenuWithControlKey]="allowContextMenuWithControlKey"
[localeText]="localeText"
[enableCellTextSelection]="enableCellTextSelection"
[overlayLoadingTemplate]="getLoadingOverlayTemplate()"
[overlayNoRowsTemplate]="getNoRowsOverlayTemplate()"
[tooltipShowDelay]="tooltipDelay"
[accentedSort]="true"
(gridReady)="onGridReady($event)"
(cellClicked)="onCellClicked($event)"
(rowClicked)="onRowClicked($event)"
(rowDoubleClicked)="onRowDoubleClicked($event)"
(selectionChanged)="onSelectionChanged($event)"
(sortChanged)="onSortChanged($event)"
(bodyScroll)="onBodyScroll($event)"
(columnResized)="onColumnResized($event)"
(columnMoved)="onColumnMoved($event)"
(columnVisible)="onColumnVisibilityChanged($event)"
(filterChanged)="columnFilterChanged($event)"
(componentStateChanged)="componentStateChanged($event)">
</ag-grid-angular>
<div [hidden]="true">
<ng-content></ng-content>
</div>
</div>

View file

@ -0,0 +1,26 @@
import {
FilterType
} from "../../../generated/ru/micord/ervu/account_applications/component/property/grid/FilterType";
import {DateFilter, NumberFilter, TextFilter} from "ag-grid-community";
import {SetFilter} from "./SetFilter";
export class CustomGridColumnFilterUtils {
public static columnFilter(type: FilterType) {
if (!type) {
return null;
}
switch (type) {
case FilterType.NUMBER:
return NumberFilter;
case FilterType.DATE:
return DateFilter;
case FilterType.SET:
return SetFilter;
case FilterType.TEXT:
default:
return TextFilter;
}
}
}

View file

@ -0,0 +1,95 @@
import {ChangeDetectionStrategy, Component} from "@angular/core";
import {Event, GridRpcService, GridV2, GridV2Column, Visible} from "@webbpm/base-package";
import {
StaticGridColumn
} from "../../../generated/ru/micord/ervu/account_applications/component/property/grid/StaticGridColumn";
import {
ColDef,
FilterChangedEvent,
ICellRendererParams,
ITooltipParams,
ValueFormatterParams,
ValueGetterParams
} from "ag-grid-community";
import {StaticColumnInitializer} from "./StaticColumnInitializer";
@Component({
moduleId: module.id,
selector: 'ervu-static-grid',
templateUrl: './../../../../../src/resources/template/account_applications/component/grid/ErvuStaticGrid.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ErvuStaticGrid extends GridV2 {
// todo: remove on updating platform version up to 3.188
@Visible("false")
public columnFiltersChanged: Event<any> = new Event<any>();
private rpcService: GridRpcService;
protected initGrid() {
super.initGrid();
this.rpcService = this.getScript(GridRpcService);
}
getColumns(): any[] {
return this.getScriptsInChildren(GridV2Column)
.map(columnV2 => columnV2.getScript(StaticGridColumn));
}
protected columnV2ToColumnDef(column: GridV2Column): ColDef {
let gridColumn = column.getScript(StaticGridColumn);
let colDef = this.columnToColumnDef(gridColumn);
if (column.renderer) {
colDef.cellRenderer = (params: ICellRendererParams) => column.renderer.render(params);
}
if (column.valueGetter) {
colDef.valueGetter = (params: ValueGetterParams) => column.valueGetter.get(params);
}
if (column.tooltipValueGetter) {
if (gridColumn.columnTooltip) {
throw new Error(
"Only one type of tooltip should be specified: tooltipValueGetter or columnTooltip");
}
colDef.tooltipValueGetter = (params: ITooltipParams) => column.tooltipValueGetter.get(params);
}
column.setGridRef(this);
column.setColDef(colDef);
return colDef;
}
protected columnToColumnDef(column: any): ColDef {
let colDef = StaticColumnInitializer.columnToColumnDef(this, column);
let columnComp = column.context;
colDef['columnUid'] = columnComp.getObjectId();
if (columnComp.cellCssClassRulesProvider) {
colDef.cellClassRules = columnComp.cellCssClassRulesProvider.getRules();
}
if (columnComp.valueFormatter) {
colDef.valueFormatter = (params?: ValueFormatterParams) => {
return columnComp.valueFormatter.format(params);
}
}
console.log("Создан ColDef:", colDef);
return colDef;
}
@Visible()
public getRowDataSize(): number {
return this.rowData ? this.rowData.length : 0;
}
// todo: remove on updating platform version up to 3.188
@Visible()
public hasColumnFilters(): boolean {
const filterModel: { [key: string]: any; } = this.gridApi.getFilterModel();
return !!filterModel && Object.keys(filterModel).length > 0;
}
// todo: remove on updating platform version up to 3.188
public columnFilterChanged(event: FilterChangedEvent) {
this.columnFiltersChanged.trigger(event);
super.columnFilterChanged(event);
}
}

View file

@ -0,0 +1,116 @@
import {AgPromise, IDoesFilterPassParams, IFilterComp, IFilterParams} from "ag-grid-community";
export class SetFilter implements IFilterComp {
private OPTION_TEMPLATE = `<label class="ag-set-filter-item">
<input type="checkbox" class="ag-filter-checkbox" checked/>
<span class="ag-filter-value"></span>
</label>`;
private eGui!: HTMLDivElement;
private selectAll: HTMLInputElement;
private checkboxes: HTMLInputElement[] = [];
private values: any[] = [];
private initialValues: any[] = [];
private filterActive: boolean;
private filterChangedCallback!: (additionalEventAttributes?: any) => void;
private filterParams!: IFilterParams;
private valueType: string;
init(params: IFilterParams): void {
this.eGui = document.createElement('div');
this.eGui.className = 'ag-set-filter';
let index = 0;
this.selectAll = this.initCheckBox('selectAll', 'Все', index);
this.checkboxes.push(this.selectAll);
params.api.getRenderedNodes()
.map(node => node.data[params.colDef.field])
.sort((n1, n2) => n1 > n2 ? 1 : n1 < n2 ? -1 : 0)
.forEach(value => {
if (this.values.includes(value)) {
return;
}
index++;
let id = `option-${index}`;
let checkbox = this.initCheckBox(id, value, index);
this.checkboxes.push(checkbox);
this.values.push(value);
});
this.initialValues = this.values.slice();
this.filterParams = params;
this.filterActive = false;
this.filterChangedCallback = params.filterChangedCallback;
if (this.values.length > 0) {
this.valueType = typeof this.values[0];
}
};
private initCheckBox(id: string, value: string, index: number): HTMLInputElement {
this.eGui.insertAdjacentHTML('beforeend', this.OPTION_TEMPLATE);
this.eGui.querySelectorAll('.ag-filter-value')[index].innerHTML = value;
let checkbox = this.eGui.querySelectorAll('.ag-filter-checkbox')[index] as HTMLInputElement;
checkbox.setAttribute('id', id);
checkbox.addEventListener('change', this.onCheckBoxChanged.bind(this));
return checkbox;
}
getGui(): HTMLDivElement {
return this.eGui;
};
onCheckBoxChanged(event: any) {
let checked = event.target.checked;
if (event.target === this.selectAll) {
this.checkboxes.forEach(checkbox => checkbox.checked = checked);
this.values = checked ? this.initialValues.slice() : [];
}
else {
let value = event.target.nextElementSibling.textContent;
value = this.valueType === 'number' ? +value : value;
if (checked) {
this.values.push(value);
if (this.values.length == this.initialValues.length) {
this.selectAll.checked = true;
}
}
else {
let index = this.values.indexOf(value);
this.values.splice(index, 1);
this.selectAll.checked = false;
}
}
this.filterActive = !this.selectAll.checked;
this.filterChangedCallback();
}
doesFilterPass(params: IDoesFilterPassParams): boolean {
let { field } = this.filterParams.colDef;
return this.values.includes(params.data[field]);
}
getModel(): any {
return this.isFilterActive() ? { value: this.values } : null;
}
isFilterActive(): boolean {
return this.filterActive;
}
setModel(model: any): void | AgPromise<void> {
this.values = model == null ? this.initialValues.slice() : model.value;
let predicate = checkbox => model == null ? true : model.value.includes(checkbox.value);
this.checkboxes.filter(predicate)
.forEach(checkbox => checkbox.checked = true);
this.filterActive = !this.selectAll.checked;
this.filterChangedCallback();
}
destroy(): void {
this.checkboxes.forEach(checkBox => checkBox.removeEventListener('change', this.onCheckBoxChanged.bind(this)));
}
}

View file

@ -0,0 +1,120 @@
import {
DateTimeUtil,
DefaultTooltip,
GridCellTooltipUtils,
GridColumnComparatorUtils,
GridColumnKeyboardUtils,
GridValueFormatterUtils,
GridValueRendererUtils,
PinnedType,
} from "@webbpm/base-package";
import {
ColDef,
DateFilter,
ICellRendererFunc,
SuppressKeyboardEventParams
} from "ag-grid-community";
import {
StaticGridColumn
} from "../../../generated/ru/micord/ervu/account_applications/component/property/grid/StaticGridColumn";
import {CustomGridColumnFilterUtils} from "./CustomGridColumnFilterUtils";
import {Moment} from "moment";
import * as moment from "moment-timezone";
export class StaticColumnInitializer {
public static columnToColumnDef(gridRef: any, column: StaticGridColumn) {
const columnDef: ColDef = {};
columnDef.headerName = column.displayName ? column.displayName : '';
columnDef.headerClass = "custom-header";
columnDef.width = column.width;
columnDef.suppressSizeToFit = column.widthFixed;
columnDef.hide = column.hidden;
columnDef.resizable = !column.widthFixed;
columnDef.headerComponentParams = {"disable_hiding": column.disableHiding || false};
columnDef.lockVisible = column.disableHiding;
columnDef.headerTooltip = column.headerTooltip ? column.headerTooltip : column.displayName;
columnDef.suppressMenu = column.suppressHeaderMenu;
if (column.pinned) {
columnDef.pinned = column.pinned == PinnedType.LEFT ? 'left' : 'right';
}
columnDef['gridComp'] = this;
columnDef.sortable = column.sortable;
if (column.sortable == null) {
columnDef.sortable = true;
}
if (column.autoHeight) {
columnDef.autoHeight = column.autoHeight;
columnDef.cellClass = 'ag-grid-cell-wrap-text';
}
if (column.field) {
columnDef.field = column.field.column;
let type = column.field.type;
if (type != null) {
if (gridRef.getRowModelType() == "clientSide") {
columnDef.comparator = GridColumnComparatorUtils.columnComparator(type);
}
columnDef.valueFormatter = GridValueFormatterUtils.columnFormatter(type);
columnDef.cellRenderer = gridRef.createRenderer(column);
}
if (column.filter !== false) {
columnDef.floatingFilter = gridRef.floatingFilter;
columnDef.filter = CustomGridColumnFilterUtils.columnFilter(column.field.filterType);
if (columnDef.filter === DateFilter) {
columnDef.filterParams = {
comparator: function (filterLocalDateAtMidnight, cellValue) {
if (!cellValue) {
return -1;
}
let filterMoment: Moment = moment.utc(filterLocalDateAtMidnight)
.add(-filterLocalDateAtMidnight.getTimezoneOffset(), 'm');
let cellMoment: Moment = DateTimeUtil.parseToMidnightUTC(cellValue);
if (filterMoment.isSame(cellMoment)) {
return 0;
}
if (cellMoment.isBefore(filterMoment)) {
return -1;
}
if (cellMoment.isAfter(filterMoment)) {
return 1;
}
},
browserDatePicker: true,
};
}
}
columnDef.suppressKeyboardEvent = (params: SuppressKeyboardEventParams) => {
return GridColumnKeyboardUtils.suppressHomeAndEndKeyboardEvent(params);
}
}
if (column.displayPopup) {
const renderer: ICellRendererFunc = columnDef.cellRenderer as ICellRendererFunc;
columnDef.cellRenderer = GridValueRendererUtils.tooltipValueRenderer(renderer);
}
else if (column.columnTooltip) {
columnDef.tooltipComponent = DefaultTooltip;
columnDef.tooltipValueGetter = GridCellTooltipUtils.fixedValueTooltip(column.columnTooltip);
}
else if (!gridRef.suppressColumnTooltip) {
columnDef.tooltipComponent = DefaultTooltip;
columnDef.tooltipValueGetter = GridCellTooltipUtils.defaultFormattedTooltip(
column.field ? column.field.type : null);
}
return columnDef;
}
}

View file

@ -24,6 +24,7 @@ import {TokenInterceptor} from "./interceptor/token.interceptor.service";
import {DropdownTreeViewComponent}from "../../account_applications/component/field/DropdownTreeViewComponent";
import {DropdownTreeviewSelectComponent} from "../../account_applications/component/external/ngx-treeview/dropdown-treeview-select/dropdown-treeview-select.component";
import {TreeviewModule} from "ngx-treeview";
import {ErvuStaticGrid} from "../../account_applications/component/grid/ErvuStaticGrid";
registerLocaleData(localeRu);
export const DIRECTIVES = [
@ -34,7 +35,8 @@ export const DIRECTIVES = [
forwardRef(() => VBoxLoadValues),
forwardRef(() => DropdownTreeViewComponent),
forwardRef(() => DropdownTreeviewSelectComponent),
forwardRef(() => ErvuAccountTextFieldGridEditor)
forwardRef(() => ErvuAccountTextFieldGridEditor),
forwardRef(() => ErvuStaticGrid)
];
@NgModule({

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xmlComponent>
<id>d60228dc-bcea-4942-b413-6816e2b568f1</id>
<name>StaticColumn</name>
<internal>false</internal>
<versions>
<studioVersion>3.186.1</studioVersion>
<packageVersions>
<entry>
<key>ru.cg.webbpm.packages.base.resources</key>
<value>3.192.3</value>
</entry>
</packageVersions>
</versions>
<rootObject id="d4f69cb0-864e-4895-b6fd-152072774909">
<name>StaticColumn</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="bc6afb28-7884-477d-b425-2c2001be8379">
<classRef type="TS">
<className>GridV2Column</className>
<packageName>component.grid</packageName>
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
</scripts>
<scripts id="a930059f-1e14-40ed-a4de-3dec3d03f9a7">
<classRef type="JAVA">
<className>StaticGridColumn</className>
<packageName>ru.micord.ervu.account_applications.component.property.grid</packageName>
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
<properties>
<entry>
<key>autoHeight</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>displayPopup</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>filter</key>
<value>
<simple>null</simple>
</value>
</entry>
<entry>
<key>sortable</key>
<value>
<simple>true</simple>
</value>
</entry>
</properties>
</scripts>
</rootObject>
</xmlComponent>