Hi Creatio Community,

I'm currently working with an editable detail grid, and I need to filter a lookup column (UsrPort) based on the connected user's roles ("Stay SPOC TC", "Stay SPOC Casablanca", "Stay SPOC Jorf Lasfar", "Stay SPOC Laayoune", and "Stay SPOC Safi").

I've tried several approaches including:

  • Defining lookupListConfig with prepareList binding (works fine on regular pages but does not trigger in editable grids).



    Here's the latest implementation I've tested:
     

generateActiveRowControlsConfig: function(id, columnsConfig, rowConfig) {
    this.mixins.ConfigurationGridUtilitiesV2.generateActiveRowControlsConfig.call(this, id, columnsConfig, rowConfig);
 
    var scope = this;
 
    Terrasoft.each(rowConfig, function(columnItem) {
        var columnKey = columnItem.key && columnItem.key[0];
        if (columnKey && columnKey.name === "UsrPort") {
            columnItem.controlConfig = columnItem.controlConfig || {};
            columnItem.controlConfig.lookupListConfig = columnItem.controlConfig.lookupListConfig || {};
            columnItem.controlConfig.lookupListConfig.filter = function() {
                var filters = Terrasoft.createFilterGroup();
 
                // Example of role checks
                var allowedPorts = [];
                if (scope.get("IsStaySpocCasa")) allowedPorts.push("CASABLANCA");
                if (scope.get("IsStaySpocJorf")) allowedPorts.push("JORF LASFAR");
                // Add similar checks for other roles
 
                if (allowedPorts.length > 0) {
                    filters.add("PortFilter", Terrasoft.createColumnInFilterWithParameters("Name", allowedPorts));
                } else {
                    filters.add("EmptyFilter", Terrasoft.createColumnFilterWithParameter(
                        Terrasoft.ComparisonType.EQUAL, "Id", Terrasoft.GUID_EMPTY));
                }
 
                return filters;
            };
        }
    }, this);
},

This configuration currently doesn't work and results in the error mentioned above.

Could someone help clarify the correct way to implement role-based filtering on lookup columns within editable detail grids? If anyone has successfully implemented this or faced a similar issue, your guidance would be greatly appreciated!

Thanks in advance for your help!

Best regards,

Like 0

Like

2 comments

For classic details, rules implemented on the page are also manifested in the list for the detail. I believe you can just implement the filtering for the lookup on the page for the detail, then it will work in the list as well. 

Thank you Ryan  for your answer!
Actually, my detail is an editable grid. I noticed that the page-level lookup filtering doesn't propagate into editable grids automatically. From my tests and observations, the editable grids seem to require explicit filtering logic within the generateActiveRowControlsConfig method instead.
Could you please confirm if this understanding is correct, and perhaps suggest any best practices or examples explicitly for editable grids?

Show all comments

I am trying to create a folder in the Contacts Freedom UI List Page that only contains Contact records that are currently active. I know there is a field in the System Administration Object that is an Active status field (shown in the Users list page). I am trying to access this field; however, it is not showing up in the dropdown list of columns in the filter builder popup page. Any help would be great. I attached an image showing the columns currently visible to me for that System Admin Object. 

Like 0

Like

2 comments
Best reply

It would look like this - I typically also add Type=4 for users (although that’s a little redundant) and also add Connection Type=0 to get employee users (not external/portal users). 

Basically, from your screenshot, click "Quantity". Then set count > 0 (or click count to change to exists), then add the sub-conditions under that.

Ryan

It would look like this - I typically also add Type=4 for users (although that’s a little redundant) and also add Connection Type=0 to get employee users (not external/portal users). 

Basically, from your screenshot, click "Quantity". Then set count > 0 (or click count to change to exists), then add the sub-conditions under that.

Ryan

Ryan Farley,

Thank you Ryan for your time and help! This solution worked for me. 

Show all comments

I need to create a mask for this text field, it is a document, which has 11 digits, and is written as follows: ###.###.###-##.

I also want to limit the quantity and leave only periods and hyphens for typing.

The quantity entered is 11, but with the mask it becomes 14, I don't know if it is possible to block this.

Can anyone help me with this?

{
	"operation": "insert",
	"name": "Input_CPF",
	"values": {
		"type": "crt.Input",
		"multiline": false,
		"label": "$Resources.Strings.PDS_SCCPF_luo5kno",
		"labelPosition": "auto",
		"control": "$PDS_SCCPF_luo5kno"
	},
	"parentName": "FlexContainer_6gej1t9",
	"propertyName": "items",
	"index": 1
}
Like 0

Like

2 comments
Best reply

Hello,

 

In order to create the mask for the text field you can add a handler that will apply formatting to the text field value when user are typing.

 

You can use the following code snippet as an example:

 

{
	request: "crt.HandleViewModelAttributeChangeRequest",
	handler: async (request, next) => {
		if(request.attributeName == "PDS_SCCPF_luo5kno"){
			let value = await request.$context.PDS_SCCPF_luo5kno; 
			value = value.replace(/\D/g, ""); // Remove non-digit characters
			if (value.length > 11){
				value = value.slice(0, 11); // Limit to 11 digits
			}
			let formatted = "";
			if (value.length > 0) {
				formatted += value.slice(0, 3);
			}
			if (value.length >= 4) {
				formatted += "." + value.slice(3, 6);
			}
			if (value.length >= 7) {
				formatted += "." + value.slice(6, 9);
			}
			if (value.length >= 10) {
				formatted += "-" + value.slice(9, 11);
			}
			request.$context.PDS_SCCPF_luo5kno = formatted;
 			request.preventAttributeChangeRequest = true;
		}
		return next?.handle(request);
	}
}

Hello,

 

In order to create the mask for the text field you can add a handler that will apply formatting to the text field value when user are typing.

 

You can use the following code snippet as an example:

 

{
	request: "crt.HandleViewModelAttributeChangeRequest",
	handler: async (request, next) => {
		if(request.attributeName == "PDS_SCCPF_luo5kno"){
			let value = await request.$context.PDS_SCCPF_luo5kno; 
			value = value.replace(/\D/g, ""); // Remove non-digit characters
			if (value.length > 11){
				value = value.slice(0, 11); // Limit to 11 digits
			}
			let formatted = "";
			if (value.length > 0) {
				formatted += value.slice(0, 3);
			}
			if (value.length >= 4) {
				formatted += "." + value.slice(3, 6);
			}
			if (value.length >= 7) {
				formatted += "." + value.slice(6, 9);
			}
			if (value.length >= 10) {
				formatted += "-" + value.slice(9, 11);
			}
			request.$context.PDS_SCCPF_luo5kno = formatted;
 			request.preventAttributeChangeRequest = true;
		}
		return next?.handle(request);
	}
}

Thanks so much.
It worked wonderfully.

Show all comments

Hello;
In my 7.17 version i create a file repository override class and it work correctly
when I try to upgrade to 8,2,1 the FileService core class change and it create fileRepository object based on interface not class (ClassFactory.Get) and it run based method loadFile not override one.
Is it any solution to set the the default class for interface

Like 0

Like

2 comments

Hi,

Yes, starting from version 8.x, Creatio uses dependency injection (DI) more actively, including for services like IFileRepository, which is now resolved via ClassFactory.Get<IFileRepository>().

To override the default implementation, you can register your custom class as the default for the interface in the dependency container.
 

Solution: Register your class for the interface

You have to create your own AppEventListener and bind your class to the appropriate interface there.

 

public class UsrAppEventListener : AppEventListenerBase
{
	public override void OnAppStart(AppEventContext context) 	{
		base.OnAppStart(context);
		ClassFactory.Bind<IFileRepository, CustomFileRepository>(reuseType: ReuseType.Singleton);
    }
}

 

Where:

  • CustomFileRepository is your custom class that implements IFileRepository
  • ReuseType.Singleton (or None) depends on your usage

⚠️ Important: Ensure your class fully implements the IFileRepository interface.

This way, when FileService calls ClassFactory.Get<IFileRepository>(), it will receive your custom implementation.

TU Irina

Show all comments

So i'm making a simple Creatio app where I want to upload an image, encode it in base64 format, and pass it via WebService to my application.

 

I made a simple page with a button that calls business process where WebService is called.

I also added attachment component, uploaded a few images, and can successfully access the last image in my business process via formulas (get it's name, info ect.)

 

I don't have much experience in C#, so I'm kindly asking if someone could give me an example code how to read the image in Script Task named Base64 Encoder, after it's been fetched in "ImageReader" task, and return/forward encoded B64 image to "API CALL" task.

 

Thanks in advance!

Like 0

Like

7 comments

Hello,

 

First you should add Process file element to your business process where you can get the file and keep it for further usage in the process.

Then in Script Task you can retrieve that file and apply encoding. You can use the following code as an example

 

var files = context.Process.FindFlowElementByName("ObjectFileProcessingUserTask1").GetPropertyValue("ObjectFiles") as ICompositeObjectList<ICompositeObject>;
foreach(var file in files)
{
	if(file.TryGetValue<EntityFileLocator>("File", out EntityFileLocator fileLocator))
	{
		IFile fileItem = UserConnection.GetFile(fileLocator);
		using (System.IO.Stream stream = fileItem.Read())
		{
			/* Retrieve the file content and save it to the array. */
			var content = stream.ReadToEnd();
			var encodedContent = Convert.ToBase64String(content);
			Set<string>("EncodedFile", encodedContent);
		}
	}
}

 

Here ObjectFileProcessingUserTask1 is the name of Process file element in the business process.

Also don't forget to include Terrasoft.File and Terrasoft.File.Abstractions namespaces to the business process. In order to do that open the business process designer, go to the Methods tab and add the namespaces to the Usings list.

You can find more information about file processing in the articles:
https://academy.creatio.com/docs/8.x/no-code-customization/bpm-tools/process-elements-reference/system-actions/process-file-element
https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platfor…

Thank you so much for the response.

I have successfully compiled my BusinessProcess, but how do I access 'EncodedFile' in my other tasks?

For example, I want to display it inside Auto-generated page, but I don't see my ScriptTask among my Process Elements in Formula window.

Please have a look at the “Process parameters” tab, as the result of the script execution is written to the “EncodedFile” process parameter

Considering it is a Base64 string, which process parameter type should I choose? Unlimited length text?

 

Also, I would like to get image width and height in the code and save it to parameter as well.

How can I get them in code?

Since Base64 string might be long Unlimited length text type will be a good choice for the parameter that will be used for storing it.

 

In order to get and save image width and height first you have to create 2 process parameters of type Integer (e.g.  ImageWidthParam and ImageHeightParam). Then in Script Task you can get the values using the following code:

 

using (System.IO.Stream stream = fileItem.Read())
{
	using (Image img = Image.FromStream(stream))
	{
		Set<int>("ImageWidthParam", img.Width);
		Set<int>("ImageHeightParam", img.Height);
	}
	/* Retrieve the file content and save it to the array. */
	var content = stream.ReadToEnd();
	var encodedContent = Convert.ToBase64String(content);
	Set<string>("EncodedFile", encodedContent);
} 


Also add System.Drawing namespace to the business process the same way as you added Terrasoft.File and Terrasoft.File.Abstractions namespaces.

 

Thank you so much for the replies!

 

Only thing that doesn't work is that EncodedFile seems to be empty.

When I try to print it inside AutoGeneratedPage as a text field it shows nothing, and when I forward it in a WebService .json body to my API there is no data.

 

Process file element is fetching last 10 records from uploaded files, I tried looking up uploaded files and there are test images there, so there should be valid input to my ScriptTask.

 

Is there something about Process Parameter "EncodedFile" that I should set up differently except setting its type as Unlimited length text? Everything else I left at default values.

The problem that EncodedFile parameter is empty could be that the stream position is at the end, so when you call stream.ReadToEnd(), there's nothing left to read.
You can update a proposed code a bit to make sure that stream position is not at the end before reading from it.

 

/* Retrieve the file content and save it to the array. */
var content = stream.ReadToEnd();
var encodedContent = Convert.ToBase64String(content);
Set<string>("EncodedFile", encodedContent);
using (MemoryStream imageStream = new MemoryStream(content))
using (Image img = Image.FromStream(imageStream))
{
	Set<int>("ImageWidthParam", img.Width);
	Set<int>("ImageHeightParam", img.Height);
}

 

Also I would recommend to debug Script Task code in Visual Studio in case you have some issues to make sure that it's executing as expected.

Show all comments

Hi 
Anyone has experience to integrating  to AzureAPI OAUTH -- 

 

While we can se the client id and client secret code how do we provide  the following ?

Authorization: Bearer {AccessToken}

  • x-ms-date: {Generated RFC 1123 Date}
  •  
Like 0

Like

2 comments

Hello Sarangarajan,

As we understand, you want to specify an additional header besides Bearer in the service request. If so, you can do this by simply adding the header in the web service settings.

You may find more information in the "Set up the REST web service integration" article.

Best regards,

Anhelina!

In the above case 
x-ms-date: {Generated RFC 1123 Date}  -- value need to be current date and time in RFC 1123 format -- that how do we set it up

Show all comments

I’m encountering an issue in Creatio where the tabs on the page expand automatically after I add an object under the DataGrid. This expansion causes the left-side data grid to become invisible, as the tabs take up too much space.

I’d like to have the data grid on the right side of the page with corresponding values displayed on the left side. However, the tabs expanding is affecting the layout, making it difficult to view the grid properly.

Is there any property or setting I can adjust to prevent the tabs from expanding when I add an object to the DataGrid?

I’d appreciate your guidance on resolving this issue.

Thanks in advance for your help!

 

Attachment is screen shot. I was not able to upload MP4 file.

Like 0

Like

1 comments

Hi Samir,

We can see that you submitted a case to our support team. We will continue our communication there.

Have a great day!

Show all comments

Hello community

I am encountering an issue when using the Clio utility to create a custom Angular module. When attempting to configure the workspace, I am facing errors, and I would appreciate your assistance in resolving them.

The errors I receive are as follows:

 

When running the command clio dconf -e dev-env:

[WAR] - Downloading of cor libraries requires cliogate version 2.0.0.0 or higher.

 

When running the command clio restorew -e dev-env:

[ERR] - To use this command, you need to install the cliogate package version 2.0.0.0 or higher.

However, when I run the command clio ver, the output shows:

 

clio:   8.0.1.21

[INF] - gate:   2.0.0.29

dotnet:   8.0.14

 

My connection to dev-env is stable, and I can see the list of packages

It appears that I have the correct version of the cliogate package installed (2.0.0.29), but I am still facing issues. 

Has anyone encountered a similar situation?

What could be causing this behavior in Clio?

Are there perhaps some configuration nuances that I'm missing?

Unfortunately, I haven’t been able to find any solutions or descriptions of similar errors online. Thank you in advance for any ideas or recommendations!

Like 0

Like

9 comments
Best reply

Artem Ivzhenko,

Hello, the issue was resolved in the clio version 8.0.1.27. Thanks for your attention. In this version, we fixed the situation when the config file URL uses a form like 'HTTP(s): my-creatoio.com/' with '/' in the end.

The command "clio ver" shows the version of the Clio command line itself. The error is mentioning the version of cliogate, which is a package installed on the Creatio system. 

To check the version of cliogate, use: 

clio ver --gate -e dev-env

To install or update the cliogate on the system, use: 

clio install-gate -e dev-env

Ryan

Sorry, missed that you mentioned the version of cliogate is up to date already. I've not experienced that issue. 

It seems there might be an issue with the connection between a clio and your dev. Try installing the gate again:

clio install-gate some_application_name

And then restart the dev:
clio restart some_application_name

 

This message only appears when dev-env does not have cliogate package installed,m  you can validate it with  `clio packages -f cliogate`. 

You should see something like this. If nothing comes back, then you need to reinstall cliogate. 

Use `clio gate -e dev-env` to reinstall cliogate

Dmytro Vovchenko,

I got an exception on this:


clio install-gate -e dev-env
Uploading...
   at System.Net.HttpWebRequest.GetResponse()
   at Creatio.Client.CreatioClient.Login(Int32 requestTimeout)
   at Creatio.Client.CreatioClient.InitAuthCookie(Int32 requestTimeout)
   at Creatio.Client.CreatioClient.get_AuthCookie()
   at Creatio.Client.CreatioClient.CreateCreatioRequest(String url, String requestData, Int32 requestTimeout)
   at Creatio.Client.CreatioClient.UploadFile(String url, String filePath, Int32 defaultTimeout)
   at Clio.Common.CreatioClientAdapter.UploadFile(String url, String filePath)
   at Clio.Package.BasePackageInstaller.UploadPackage(String filePath, EnvironmentSettings environmentSettings)
   at Clio.Package.BasePackageInstaller.InstallPackedPackage(String filePath, EnvironmentSettings environmentSettings, PackageInstallOptions packageInstallOptions)
   at Clio.Package.BasePackageInstaller.InstallPackage(String packagePackedFileOrFolderPath, EnvironmentSettings environmentSettings, PackageInstallOptions packageInstallOptions)
   at Clio.Package.BasePackageInstaller.InternalInstall(String packagePath, EnvironmentSettings environmentSettings, PackageInstallOptions packageInstallOptions, String reportPath)
   at Clio.Package.PackageInstaller.Install(String packagePath, EnvironmentSettings environmentSettings, PackageInstallOptions packageInstallOptions, String reportPath)
   at Clio.Command.PushPackageCommand.Execute(PushPkgOptions options)

Artem Ivzhenko,

according to the trace of the error the request to login either timed out or returned an error. This might be also related to the fact that dev apps are shut down automatically in case there is no activity in the dev app for the past 60 minutes. Try the following steps:

  1. Open the login page of the dev app in the UI and make sure it's loaded.
  2. Wait for 1-2 minutes (for the app to completely initialize after starting).
  3. Try executing the cliogate install once again.

Please let us know about the result.

Oleg Drobina,

I followed the steps you outlined above and I still get the same error.
I don't understand why a connection error occurs, especially since the ping command returns:
[INF] - Done ping-app.
At the same time, other developers connected to the same environment are working without any issues.
I am not connected to a VPN or proxy server.

Oleg Drobina,

In my understanding, a timeout error should not occur immediately after running the command, but rather after some time has passed, since a timeout cannot happen within just one second.
In my case, I receive the error right after launching the command, without any delay.

Artem Ivzhenko,

Hello, the issue was resolved in the clio version 8.0.1.27. Thanks for your attention. In this version, we fixed the situation when the config file URL uses a form like 'HTTP(s): my-creatoio.com/' with '/' in the end.

Show all comments

I have two attachment pages, but when I attach a file on the first page, it also appears on the second page. How can I implement a filter so that the attachment only shows on the page where it was uploaded? i'm using FreedomUI.

 

Like 0

Like

2 comments
Best reply

You can use tags. The File objects have a Tag field, you can set up each file list to have a different tag, then the tag will get added to the file based on which list the file was added to, and the lists will also filter by this tag.

To do this, you simply need to enter a tag name for each of the file lists, just type in a value in the File tag property: 

Ryan

You can use tags. The File objects have a Tag field, you can set up each file list to have a different tag, then the tag will get added to the file based on which list the file was added to, and the lists will also filter by this tag.

To do this, you simply need to enter a tag name for each of the file lists, just type in a value in the File tag property: 

Ryan

Ryan Farley,

Thank you Ryan

Show all comments

Building a new set of application and need to create 50 tables -- 
1. 20 of them are going to hold permanent records

2. 30 of them are going to hold just transient data just enough to show in the screen (by API calls data will be retrieved -- Creatio does not have easy way to show API data without storing)

Have the DDLs -- so how we can create these in Creatio one shot  instead of going through one by one 

 

Thanks and Regards

Sarang

Like 0

Like

1 comments

Hello, 

Thank you for your question. Currently, unfortunately, there is no built-in functionality to create multiple tables at once.

However, if you are working with a large number of tables, an alternative approach could be using Development tools or Data Import via scripts/API, depending on your requirements.

Show all comments