Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
5080d50
#2224 First steps to Entity Centre named configuration execution API.
jhou-pro Dec 17, 2025
0a5af40
#2224 Temporary changes to make testing easier.
jhou-pro Jan 6, 2026
2e121fd
#2224 Use saved version of [already updated from upstream] configurat…
jhou-pro Jan 6, 2026
e92667e
#2224 Avoid PREVIOUS_RUN surrogate centre alteration during API running.
jhou-pro Jan 6, 2026
d3edfcf
#2224 Ensure repeated API running with up-to-date configuration chang…
jhou-pro Jan 6, 2026
666c0a8
#2224 Prohibit links configs from API running.
jhou-pro Jan 6, 2026
f9bb547
#2224 Adjust as per simplified issue requirements.
jhou-pro Feb 2, 2026
fe8cb6f
#2224 Preliminary change to find owner's fresh centre for API running.
jhou-pro Feb 2, 2026
df5c018
#2224 Automatically determine miType from config UUID to reduce API c…
jhou-pro Feb 3, 2026
bf65008
#2224 Automatically determine device from config UUID, i.e. allow run…
jhou-pro Feb 3, 2026
f59b5e5
#2224 Reduce unnecessary method visibility.
jhou-pro Feb 3, 2026
273bc70
#2224 Preliminary changes to include dynamic columns into API result-…
jhou-pro Feb 3, 2026
03af44b
Merge branch '2.3.0-SNAPSHOT' into Issue-#2224
jhou-pro Feb 10, 2026
a5043ec
#2224 Unify before-run criteria validation.
jhou-pro Feb 11, 2026
a6fde3d
#2224 #2517 Simplify property authorisation by removing unused token …
jhou-pro Feb 11, 2026
fe6aea9
Merge branch '2.3.0-SNAPSHOT' into Issue-#2224
jhou-pro Feb 19, 2026
c2f2bbc
#2224 Reuse generation logic in API and standard centre running.
jhou-pro Feb 19, 2026
3049b19
Merge branch 'refs/heads/2.3.0-SNAPSHOT' into Issue-#2224
jhou-pro Feb 21, 2026
44f9532
#2224 Added basic unit test for Entity Centre API execution.
jhou-pro Feb 21, 2026
797d089
#2224 Temporarily comment out data-based default values in Entity Cen…
jhou-pro Feb 21, 2026
01b6646
#2224 Remove data-based default values in Entity Centre configuration…
jhou-pro Feb 21, 2026
b02a87c
#2224 Enhance test to support all databases (not only SQL Server).
jhou-pro Feb 21, 2026
cee610a
#2224 Minor simplifications.
jhou-pro Feb 22, 2026
91ce98a
#2224 Abstract out centre running logic with the option of simplified…
jhou-pro Feb 22, 2026
4101f36
#2224 Reduce exposure of internal methods that are not needed anymore.
jhou-pro Feb 22, 2026
658c81f
#2224 Refactor further to improve comprehension.
jhou-pro Feb 22, 2026
5133bea
#2224 Reduce miType complexity.
jhou-pro Feb 22, 2026
4cdeb40
#2224 Reduce centre config determination complexity.
jhou-pro Feb 22, 2026
807ce99
#2224 Further reduce complexity by using ConfigSettings more.
jhou-pro Feb 22, 2026
371612d
#2224 Reduce methods visibility back. Minor re-factoring and docs.
jhou-pro Feb 23, 2026
aa7370f
#2224 More docs, re-factoring and minor improvements.
jhou-pro Feb 23, 2026
8871999
#2224 Further docs, re-factoring. Add generic handler of exceptions d…
jhou-pro Feb 23, 2026
6954eb9
#2224 Add 'exists' API method (+test). Remove unnecessary API type pa…
jhou-pro Feb 23, 2026
0cdaf0f
#2224 Correct import.
jhou-pro Feb 23, 2026
cfa11da
#2224 Rename API, its methods and implementation.
jhou-pro Feb 23, 2026
c0fa36f
#2224 Add tests for no data and for present data, but custom criteria.
jhou-pro Feb 24, 2026
1a93d19
#2224 Cover unexpected exception handling also at the stage of config…
jhou-pro Feb 24, 2026
2bcf291
#2224 Misc improvements for validation (+tests).
jhou-pro Feb 24, 2026
0123c2d
#2224 Misc minor improvements, suggested by IDE, including reduced me…
jhou-pro Feb 25, 2026
1e3af44
#2224 Fix regression for centres with IGenerator during refresh / nav…
jhou-pro Feb 25, 2026
f7b1dbd
#2224 Temp changes to test broader range of centres.
jhou-pro Feb 27, 2026
682275e
#2224 Remove temporary code.
jhou-pro Feb 27, 2026
9571c3f
#2224 Add API docs.
jhou-pro Feb 27, 2026
8403a51
#2224 Temporarily revert some enhancements to simplify further confli…
jhou-pro Feb 27, 2026
e1dfe76
#2224 Extend / enhance docs.
jhou-pro Feb 27, 2026
b138849
Merge branch '2.3.0-SNAPSHOT' into Issue-#2224
jhou-pro Feb 28, 2026
ec1af55
#2224 Further changes to resolve conflicts / compilation errors.
jhou-pro Feb 28, 2026
642a7ac
#2224 Minor improvement.
jhou-pro Feb 28, 2026
bb385f9
#2224 Slight doc modernisation.
jhou-pro Feb 28, 2026
7559bf8
#2224 Further older code modernisation.
jhou-pro Feb 28, 2026
da909f0
#2224 Revert temporary code.
jhou-pro Feb 28, 2026
f6d653f
#2224 Fix test after upstream merging.
jhou-pro Feb 28, 2026
367e114
#2224 a. Improve error reporting / recovery for Entity Centre RUN / D…
jhou-pro Mar 10, 2026
8ada633
#2224 b. Temporal workaround to allow 'EntityCentreConfig / MainMenuI…
jhou-pro Mar 11, 2026
b8185c6
#2224 New API method for config validation.
jhou-pro Mar 11, 2026
01551ea
#2224 Move ConfigSettings to pojo-bl to re-use in EntityCentreProcessor.
jhou-pro Mar 11, 2026
9869457
#2224 Default impl for new API method for config validation.
jhou-pro Mar 11, 2026
3680a1a
#2224 Expose standard Entity Centre messages.
jhou-pro Mar 12, 2026
32ae851
Merge branch '2.3.0-SNAPSHOT' into Issue-#2224
jhou-pro Mar 19, 2026
bd7d376
Merge branch '2.3.0-SNAPSHOT' into Issue-#2224
jhou-pro Mar 27, 2026
3929148
Merge branch '2.3.0-SNAPSHOT' into Issue-#2224
jhou-pro Apr 4, 2026
8b8c29d
Merge remote-tracking branch 'origin/2.4.0-SNAPSHOT' into Issue-#2224
jhou-pro Apr 9, 2026
d19463f
Merge branch '2.4.0-SNAPSHOT' into Issue-#2224
jhou-pro Apr 9, 2026
9a4e2fa
#2224 Improve Web UI-capable tests to be able to use UniversalConstan…
jhou-pro Apr 10, 2026
3652039
#2224 Simplify EntityCentreProcessorTest to avoid universal constants…
jhou-pro Apr 10, 2026
46e0f17
#2224 Reuse DataPopulationConfig common logic.
jhou-pro Apr 10, 2026
8e7e168
#2224 Very minor doc improvement.
jhou-pro Apr 10, 2026
5a6259f
Merge branch '2.4.0-SNAPSHOT' into Issue-#2224
jhou-pro Apr 13, 2026
13cad57
#2224 Enhance getResult with IPage result instead of just List of ent…
jhou-pro Apr 15, 2026
bc21bfd
#2224 Cover getResult result page calculations with basic tests.
jhou-pro Apr 15, 2026
763fbd4
#2224 First steps to 'resultCount' API and implementation.
jhou-pro Apr 15, 2026
26503f8
#2224 Correct 'resultCount' API to use all proper conditions for gene…
jhou-pro Apr 17, 2026
f60a3b8
#2224 Cover actual execution of resultExists/Count and getResult with…
jhou-pro Apr 17, 2026
85f88e7
#2224 Add docs to the API method.
jhou-pro Apr 17, 2026
2d1ad66
#2224 Correct / extend docs.
jhou-pro Apr 17, 2026
bddb29a
#2224 Provide docs and minor re-factoring.
jhou-pro Apr 17, 2026
e4e7fec
#2224 Basic tests for resultCount.
jhou-pro Apr 17, 2026
0a3924c
#2224 Additional tests for resultCount to cover createdBy condition f…
jhou-pro Apr 18, 2026
be58b41
#2224 Explicitly exclude transport non-persistent entity-typed proper…
jhou-pro Apr 18, 2026
71a57ca
Revert "#2224 b. Temporal workaround to allow 'EntityCentreConfig / M…
jhou-pro Apr 18, 2026
44b1d4d
#2224 Expose getParentAnd API method to pre/postActions on Entity Cen…
jhou-pro May 4, 2026
7714707
#2224 Enhance 'tg-ui-action' with context customisation API.
jhou-pro May 4, 2026
13f5a29
#2224 Capture centre config entity as part of ConfigSettings for 'Ent…
jhou-pro May 4, 2026
86621ac
#2224 De-duplicate date population config logic.
jhou-pro May 5, 2026
7780a38
#2224 Adjust tests with CentreConfig change.
jhou-pro May 5, 2026
85b850d
Merge branch '2.4.0-SNAPSHOT' into Issue-#2224
jhou-pro May 31, 2026
84547c6
#2224 More clear intent for the parameter preserving all existing inv…
jhou-pro May 5, 2026
37c94e5
Merge branch '2.4.0-SNAPSHOT' into Issue-#2224
jhou-pro Jun 2, 2026
5bc9697
Merge branch '2.4.0-SNAPSHOT' into Issue-#2224
jhou-pro Jun 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
package ua.com.fielden.platform.test_config;

import static org.apache.commons.lang3.StringUtils.isEmpty;

import java.util.Optional;
import java.util.Properties;

import ua.com.fielden.platform.test.DbCreator;
import ua.com.fielden.platform.test.IDomainDrivenTestCaseConfiguration;
import ua.com.fielden.platform.test.db_creators.H2DbCreator;
import ua.com.fielden.platform.test.runners.AbstractDomainDrivenTestCaseRunner;
import ua.com.fielden.platform.test.runners.H2DomainDrivenTestCaseRunner;
import ua.com.fielden.platform.test.runners.PostgresqlDomainDrivenTestCaseRunner;
import ua.com.fielden.platform.test.runners.SqlServerDomainDrivenTestCaseRunner;

/**
* A test runner that selects a test configuration {@link ITestContext} from either {@link H2DomainDrivenTestCaseRunner} or {@link PostgresqlDomainDrivenTestCaseRunner} for running unit test.
* The criteria for selecting the appropriate test runner is based on runtime settings.
*
* @author TG Team
*/
import ua.com.fielden.platform.test.runners.H2DomainDrivenTestCaseRunner.H2TestContext;
import ua.com.fielden.platform.test.runners.PostgresqlDomainDrivenTestCaseRunner.PostgresqlTestContext;
import ua.com.fielden.platform.test.runners.SqlServerDomainDrivenTestCaseRunner.SqlServerTestContext;

import java.util.Optional;
import java.util.Properties;

import static org.apache.commons.lang3.StringUtils.isEmpty;

/// A test runner that selects a test configuration [ITestContext] from [SqlServerTestContext] or [PostgresqlTestContext].
/// The criteria for selecting the appropriate test runner is based on runtime settings.
///
public class H2OrPostgreSqlOrSqlServerContextSelector extends AbstractDomainDrivenTestCaseRunner {

// Note: This assumes PostgreSQL is listening on port 5432 (the default).
// There is not much else in the URI that would uniquely identify that we are connecting to a PostgreSQL database.
private static final boolean POSTGRESQL = !isEmpty(System.getProperty("databaseUri")) && System.getProperty("databaseUri").contains("5432");
private static final boolean SQL_SERVER = !isEmpty(System.getProperty("databaseUri")) && System.getProperty("databaseUri").contains("database");
protected static final boolean POSTGRESQL = !isEmpty(System.getProperty("databaseUri")) && System.getProperty("databaseUri").contains("5432");
protected static final boolean SQL_SERVER = !isEmpty(System.getProperty("databaseUri")) && System.getProperty("databaseUri").contains("database");

public H2OrPostgreSqlOrSqlServerContextSelector(final Class<?> klass) throws Exception {
super(klass, POSTGRESQL ? PostgresqlDbCreator.class : (SQL_SERVER ? SqlServerDbCreator.class : H2DbCreator.class), Optional.empty());
Expand All @@ -45,10 +42,10 @@ public void dbCleanUp() {
selectRunnerConfig().dbCleanUp();
}

private ITestContext selectRunnerConfig() {
protected ITestContext selectRunnerConfig() {
return POSTGRESQL
? new PostgresqlDomainDrivenTestCaseRunner.PostgresqlTestContext()
: (SQL_SERVER ? new SqlServerDomainDrivenTestCaseRunner.SqlServerTestContext() : new H2DomainDrivenTestCaseRunner.H2TestContext(this));
? new PostgresqlTestContext()
: (SQL_SERVER ? new SqlServerTestContext() : new H2TestContext(this));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;

/**
* The entity holder for centre context and criteria entity's modified props.
*
* @author TG Team
*
*/
/// The entity holder for centre context and criteria entity's modified props.
///
@KeyType(String.class)
@KeyTitle(value = "Key", desc = "Some key description")
@CompanionObject(ICentreContextHolder.class)
// GraphQL Web API schema may not find `CentreContextHolder` type in case if it is used as property in allowed for introspection types
// (e.g. those that are persistent / synthetic and have no @DenyIntrospection).
// That's why it is explicitly denied for introspection and such properties become `AbstractDomainTreeRepresentation.isExcluded`.
@DenyIntrospection
public class CentreContextHolder extends AbstractEntity<String> {

@IsProperty(Object.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
package ua.com.fielden.platform.entity.functional.centre;

import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import static ua.com.fielden.platform.entity.NoKey.NO_KEY;
import ua.com.fielden.platform.entity.AbstractEntity;
import ua.com.fielden.platform.entity.IContinuationData;
import ua.com.fielden.platform.entity.NoKey;
import ua.com.fielden.platform.entity.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ua.com.fielden.platform.entity.AbstractEntity;
import ua.com.fielden.platform.entity.IContinuationData;
import ua.com.fielden.platform.entity.NoKey;
import ua.com.fielden.platform.entity.annotation.CompanionObject;
import ua.com.fielden.platform.entity.annotation.IsProperty;
import ua.com.fielden.platform.entity.annotation.KeyType;
import ua.com.fielden.platform.entity.annotation.Observable;
import ua.com.fielden.platform.entity.annotation.Title;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import static ua.com.fielden.platform.entity.NoKey.NO_KEY;

/**
* The entity holder for saving information: entity's modified props + centre context, if any.
*
* @author TG Team
*
*/
/// The entity holder for saving information: entity's modified props + centre context, if any.
///
@KeyType(NoKey.class)
@CompanionObject(ISavingInfoHolder.class)
// GraphQL Web API schema may not find `CentreContextHolder` type in case if it is used as property in allowed for introspection types
// (e.g. those that are persistent / synthetic and have no @DenyIntrospection).
// That's why it is explicitly denied for introspection and such properties become `AbstractDomainTreeRepresentation.isExcluded`.
@DenyIntrospection
public class SavingInfoHolder extends AbstractEntity<NoKey> {

@IsProperty(Object.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,12 @@ private Map<String, Object> enhanceQueryParams(final Map<String, Object> buildPa
return buildParametersMap;
}

/// Executes the configured Entity Centre query to find count of entities.
///
public int runCount() {
return count(generateQueryWithSummaries().getKey());
}

/// Executes the configured entity query.
///
public final IPage<T> run(final int pageSize) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static boolean isPropertyAuthorised(final Class<?> root, final String pro
// Root property (aka "entity itself") is always authorised.
return property.isEmpty()
// Non-root property access is governed by *_CanRead_property_* tokens, where the `property` part is never empty.
|| authorisePropertyReading(root, property, authorisationModel, securityTokenProvider).orElseGet(Result::successful).isSuccessful();
|| authorisePropertyIfGuarded(root, property, authorisationModel).orElseGet(Result::successful).isSuccessful();
}

/// Creates an Entity Centre query for a list of [QueryProperty] and other parameters.
Expand All @@ -91,7 +91,7 @@ public static <T extends AbstractEntity<?>> EntityQueryProgressiveInterfaces.ICo
final IDates dates)
{
authoriseReading(type.getSimpleName(), READ, authorisationModel, securityTokenProvider).ifFailure(Result::throwRuntime);
authoriseCriteria(queryProperties, authorisationModel, securityTokenProvider).ifFailure(Result::throwRuntime);
authoriseCriteria(queryProperties, authorisationModel).ifFailure(Result::throwRuntime);
if (createdByUserConstraint.isPresent()) {
final QueryProperty queryProperty = EntityQueryCriteriaUtils.createNotInitialisedQueryProperty(managedType, "createdBy");
final List<String> createdByCriteria = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,25 @@
import ua.com.fielden.platform.data.generator.WithCreatedByUser;
import ua.com.fielden.platform.entity.AbstractEntity;
import ua.com.fielden.platform.entity.DynamicEntityKey;
import ua.com.fielden.platform.entity.annotation.CompanionObject;
import ua.com.fielden.platform.entity.annotation.CompositeKeyMember;
import ua.com.fielden.platform.entity.annotation.CritOnly;
import ua.com.fielden.platform.entity.annotation.*;
import ua.com.fielden.platform.entity.annotation.CritOnly.Type;
import ua.com.fielden.platform.entity.annotation.DescTitle;
import ua.com.fielden.platform.entity.annotation.IsProperty;
import ua.com.fielden.platform.entity.annotation.KeyType;
import ua.com.fielden.platform.entity.annotation.MapEntityTo;
import ua.com.fielden.platform.entity.annotation.MapTo;
import ua.com.fielden.platform.entity.annotation.Observable;
import ua.com.fielden.platform.entity.annotation.Title;
import ua.com.fielden.platform.reflection.TitlesDescsGetter;
import ua.com.fielden.platform.security.user.User;
import ua.com.fielden.platform.utils.Pair;

/**
* Represents a typical example of an entity to be generated. This particular entity is generated by generator {@link TgGeneratedEntityGenerator}.
*
* @author TG Team
*
*/
import static ua.com.fielden.platform.entity.annotation.CritOnly.Type.SINGLE;

/// Represents a typical example of an entity to be generated. This particular entity is generated by generator `TgGeneratedEntityGenerator`.
///
@KeyType(DynamicEntityKey.class)
@CompanionObject(ITgGeneratedEntity.class)
@MapEntityTo
@DescTitle("Desc")
public class TgGeneratedEntity extends AbstractEntity<DynamicEntityKey> implements WithCreatedByUser<TgGeneratedEntity> {
private static final long serialVersionUID = 1L;

private static final Pair<String, String> entityTitleAndDesc = TitlesDescsGetter.getEntityTitleAndDesc(TgGeneratedEntity.class);
public static final String ENTITY_TITLE = entityTitleAndDesc.getKey();
public static final String ENTITY_DESC = entityTitleAndDesc.getValue();

@IsProperty(assignBeforeSave = true)
@MapTo
Expand All @@ -47,10 +41,25 @@ public class TgGeneratedEntity extends AbstractEntity<DynamicEntityKey> implemen
private User critOnlyMultiProp;

@IsProperty
@CritOnly(Type.SINGLE)
@CritOnly(SINGLE)
@Title(value = "CritOnly Single", desc = "CritOnly single property")
private User critOnlySingleProp;

@IsProperty
@CritOnly(SINGLE)
@Required
private Integer requiredProp;

public Integer getRequiredProp() {
return requiredProp;
}

@Observable
public TgGeneratedEntity setRequiredProp(Integer requiredProp) {
this.requiredProp = requiredProp;
return this;
}

@Observable
public TgGeneratedEntity setEntityKey(final String entityKey) {
this.entityKey = entityKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ public static Result authoriseReading(final String entityTypeSimpleName, final T

/// Validates the criteria values to determine whether they can be applied under the authorisation model.
///
public static Result authoriseCriteria(final List<QueryProperty> queryProperties, final IAuthorisationModel authorisation, final ISecurityTokenProvider securityTokenProvider) {
public static Result authoriseCriteria(final List<QueryProperty> queryProperties, final IAuthorisationModel authorisation) {
return queryProperties.stream()
.map(queryProperty -> {
// Criterion without any conditions is authorised.
// Root property (aka "entity itself") is always authorised.
if (!queryProperty.isEmptyWithoutMnemonics() && !"".equals(queryProperty.getPropertyName())) {
final var originalType = getOriginalType(stripIfNeeded(queryProperty.getEntityClass()));
return authorisePropertyReading(originalType, queryProperty.getPropertyName(), authorisation, securityTokenProvider);
return authorisePropertyIfGuarded(originalType, queryProperty.getPropertyName(), authorisation);
}
return Optional.<Result>empty();
})
Expand All @@ -78,7 +78,9 @@ public static Result authoriseCriteria(final List<QueryProperty> queryProperties
.orElseGet(Result::successful);
}

public static Optional<Result> authorisePropertyReading(final Class<?> entityType, final String propertyName, final IAuthorisationModel authorisation, final ISecurityTokenProvider securityTokenProvider) {
/// Finds authorisation annotation for entity property and performs authorisation, if present.
///
public static Optional<Result> authorisePropertyIfGuarded(final Class<?> entityType, final String propertyName, final IAuthorisationModel authorisation) {
return getPropertyAnnotationOptionally(Authorise.class, entityType, propertyName)
.map(annot -> (Class<? extends ISecurityToken>) annot.value())
.map(authorisation::authorise);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ua.com.fielden.platform.security.tokens.persistent;

import ua.com.fielden.platform.sample.domain.TgGeneratedEntity;
import ua.com.fielden.platform.sample.domain.TgVehicleModel;
import ua.com.fielden.platform.security.ISecurityToken;
import ua.com.fielden.platform.security.tokens.Template;

import static java.lang.String.format;

/// A security token for entity [TgGeneratedEntity] to guard Read.
///
public class TgGeneratedEntity_CanRead_Token implements ISecurityToken {
public final static String TITLE = format(Template.READ.forTitle(), TgGeneratedEntity.ENTITY_TITLE);
public final static String DESC = format(Template.READ.forDesc(), TgGeneratedEntity.ENTITY_TITLE);
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
package ua.com.fielden.platform.ui.config;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import ua.com.fielden.platform.algorithm.search.ITreeNode;
import ua.com.fielden.platform.entity.AbstractEntity;
import ua.com.fielden.platform.entity.annotation.CompanionObject;
import ua.com.fielden.platform.entity.annotation.DenyIntrospection;
import ua.com.fielden.platform.entity.annotation.DescTitle;
import ua.com.fielden.platform.entity.annotation.IsProperty;
import ua.com.fielden.platform.entity.annotation.KeyTitle;
import ua.com.fielden.platform.entity.annotation.KeyType;
import ua.com.fielden.platform.entity.annotation.MapEntityTo;
import ua.com.fielden.platform.entity.annotation.MapTo;
import ua.com.fielden.platform.entity.annotation.Observable;
import ua.com.fielden.platform.error.Result;
import ua.com.fielden.platform.entity.annotation.*;
import ua.com.fielden.platform.reflection.ClassesRetriever;
import ua.com.fielden.platform.reflection.PropertyTypeDeterminator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import static ua.com.fielden.platform.error.Result.failure;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package ua.com.fielden.platform.web.centre;

import static ua.com.fielden.platform.domaintree.ICalculatedProperty.CalculatedPropertyCategory.AGGREGATED_EXPRESSION;
import static ua.com.fielden.platform.domaintree.impl.AbstractDomainTreeRepresentation.isCalculatedAndOfTypes;

import java.util.List;
import java.util.stream.Collectors;

import static ua.com.fielden.platform.domaintree.ICalculatedProperty.CalculatedPropertyCategory.AGGREGATED_EXPRESSION;
import static ua.com.fielden.platform.domaintree.impl.AbstractDomainTreeRepresentation.isCalculatedAndOfTypes;

/**
* Utilities for Web API (centre, master) and its implementation.
*
Expand All @@ -22,6 +22,9 @@ public class WebApiUtils {
* The surrogate title of centre 'link' configuration. This is used when link with centre parameters opens.
*/
public static final String LINK_CONFIG_TITLE = "_______________________link";
public static final String CONFIG_DOES_NOT_EXIST = "Configuration does not exist.";
public static final String SAVE_MSG = "Please save and try again.";
public static final String DUPLICATE_SAVE_MSG = "Please duplicate, save and try again.";

/** Private default constructor to prevent instantiation. */
private WebApiUtils() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ua.com.fielden.platform.web.utils;

/// Distinguishes the two execution modes of `CriteriaResource#executeEntityCentreConfiguration`.
///
/// Sealed deliberately so that any future Entity Centre evolution that introduces a new mode forces
/// reconciliation with the central execution method (the compiler will flag a non-exhaustive switch).
/// This protects programmatic callers (e.g., `DefaultEntityCentreProcessor`) from breaking when the
/// UI flow changes.
///
/// Permitted implementations:
/// - [HeadlessCentreExecution] -- programmatic API; data only, no UI augmentation.
/// - [UiCentreExecution] -- UI-driven; rendering hints, action indices, dynamic-column metadata,
/// and (when running) the criteria-changed indication are produced.
///
public sealed interface CentreExecutionMode permits HeadlessCentreExecution, UiCentreExecution {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ua.com.fielden.platform.web.utils;

import ua.com.fielden.platform.security.user.User;
import ua.com.fielden.platform.ui.config.EntityCentreConfig;
import ua.com.fielden.platform.ui.menu.MiWithConfigurationSupport;
import ua.com.fielden.platform.web.interfaces.DeviceProfile;

import java.util.Optional;

/// Convenient record holding Entity Centre configuration settings.
///
/// @param saveAsName optional "save-as" name for named configuration or empty [Optional] for default one
/// @param owner a [User] that created the configuration (or own it through inheritance process)
/// @param device indicates whether the configuration belongs to [DeviceProfile#DESKTOP] namespace or [DeviceProfile#MOBILE]
/// @param miType menu item type for the configuration
/// @param centreConfig Entity Centre configuration entity instance
///
public record ConfigSettings(
Optional<String> saveAsName,
User owner,
DeviceProfile device,
Class<? extends MiWithConfigurationSupport<?>> miType,
EntityCentreConfig centreConfig
) {}
Loading