Hi everyone,

I have encountered a small usability issue and I am hoping someone might have a suggestion.

When opening a record directly from an email (via a URL link), the page loads fine, but the “Close” button in the top right corner and the back arrow don’t work as expected. It appears that since the record is opened directly via a URL and not through standard navigation, there is no previous page for the app to return to.

While we understand the technical reason behind this, it’s not ideal from a user experience perspective. Users expect to be able to go back to the list or close the record.

Has anyone found a good way to improve or work around this?

Thanks!

Csilla

Like 0

Like

1 comments

I believe this is fixed somewhat in 8.3 as a beta feature that can be enabled (out of the box disabled)

Changed behavior of the Button component whose Action parameter in the Freedom UI Designer setup area is set to "Close page" when the action is executed immediately after the user logs into Creatio. Previously, the redirect behavior was inconsistent and could lead to navigating outside the instance or to an unintended blank state. Now, the user is redirected to the Creatio desktop page if the previous browser page is not a Creatio page. The functionality is managed by the EnableNavigationToDesktopBeforeQuit additional feature. Out of the box, disabled.

Ryan

Show all comments

How to capture client side validation errors on Creatio formpages and move them to a table or if there is an existing table to read. For example, a user forgets to select the 'House type' and an error comes up. We want these errors logged somewhere.

Like 0

Like

1 comments

Hello,

In Creatio you can set up logging:

The Change Log records changes to business data.

Audit Log records system settings, events, and data. It logs events related to changes in the user role structure, the distribution of access permissions, changes in the system setting values, user authorization in Creatio, etc.

Please refer to these articles:
How to set up Change Log
How to set up Audit Log

Application logs can be setup via Nlog.

Have a great day!

Show all comments

Just like the title says is it possible to extract data from xlsx or csv file to Creatio through a service class? I know you can do it through freedom UI, but I am wondering if it's possible to do it through code. Do terrasoft libraries provide that support?

Like 1

Like

1 comments

Hi Michal,

we use NPOI library

Kind regards,
Vladimir

Show all comments

Is there an out of the box web service in Creatio that could be used to find all the roles that a user belongs to? Or to check if the user belongs to a particular role?  Where can I find the documentation on all the inbuilt webservices provided by Creatio?

Like 0

Like

14 comments
Best reply

Just verified, this is working for me. This is a sample for the account page to disable the account Type if it is "Customer". 

Add an attribute to the viewModelConfigDiff:

viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[
    {
        "operation": "merge",
        "path": [
            "attributes"
        ],
        "values": {
            "IsTypeEnabled": {
            	value: true
            }
        }
    }
]/**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/,

Then, I added a change request handler to listen for values in the Type attribute (which also triggers when the page is initially populated, which is when request.silent==true):

handlers: /**SCHEMA_HANDLERS*/[
	{
		request: "crt.HandleViewModelAttributeChangeRequest",
		handler: async (request, next) => {
 
			if (request.attributeName === "Type") {
				request.$context.IsTypeEnabled = (!request.value || request.value.displayValue !== "Customer");
				if (!request.silent) {
					console.log("Type changed", request.oldValue, request.value);
				}
			}
 
			return next?.handle(request);
		}
	}
]/**SCHEMA_HANDLERS*/,

Now, I wire up my attribute to the Type in the viewConfigDiff: 

{
	"operation": "merge",
	"name": "Type",
	"values": {
		"readonly": "$IsTypeEnabled | crt.InvertBooleanValue"
	}
}

Note, i am using a converter to invert the value since my attribute indicates it's enabled, but the property expects the inverse.

With this in place, if I open an Account with Type=Customer, or change the Type to Customer it is disabled/readonly.

One thing to note, many controls have both a readonly and a disabled property, not sure what the difference is, both seem to work for me, but the readonly seems to be the one that gives the control the visual lock icon. The disabled property also disables the control, but you don't get the lock icon for the control.

Ryan

Basically, you'll query SysUserInRole where the current user = the SysUser value. The SysRole lookup column will provide you the roles linked to this user. 

See here: https://customerfx.com/article/determining-if-a-user-has-a-specific-role-in-bpmonline/

For a Freedom UI approach, see https://customerfx.com/article/showing-or-hiding-a-field-if-the-current-user-is-a-member-of-a-role-in-a-creatio-freedom-ui-page/

Ryan

Thanks Ryan.  Is there a way to use a webservice for this requirement? Are there any out-of-the-box Webservices that can be called to check if the current user belongs a particular Role using Freedom UI approach ?

If this will be consumed from within Creatio on a Freedom UI page, it's just as easy to do a model query from the Freedom UI page (as shown in the article) as it is to call a web service. Maybe I am missing what you're trying to do? Calling a web service wouldn't really be any different than doing what is suggested in the article using a model query. You could wrap that up as a server-side C# code and expose as a web service, but ultimately, the Freedom UI page is going to request something, whether the web service or the model query, so you could just skip the web service IMO and use the model query.

Thanks Ryan.  Yes I agree. Its just that I wanted to explore using webservices in Creatio and also resuse this webservice across projects and am in the process of creating a C# webservice to achieve this.

Ryan Farley,

On a related note, this approach works fine for hiding or showing the fields based on a condition. But is there a way to make it readonly (disabled) based on a condition?  I noticed that the "visible" property can be set using a boolean variable like $flag, but this doesnt seem to have any effect with the "readonly" properties of the Text box and Combo box.  Is this a known issue and is there a workaround?

Ajay Varghese,

I believe I've been able to bind the readonly property to an attribute and set it programmatically with success (but don't have a system at the moment to verify)

Ajay Varghese,

I'm not sure of an OOTB service for that (roles and user roles). There might be, but it would be a simple service to create. The service would perform the ESQ similar to what is in the articles.

Ajay Varghese,

Additionally, I often wrap that sort of reusable stuff in a client schema class or module so it's easily reusable. Then, whether the class performs a model query or calls a service is irrelevant since it's still abstracted from what is calling it on pages. 

Ryan

Ryan Farley,

Yes, thanks for that direction. I have managed to create the webservices using that approach and it works fine. I am a bit surprised that setting that webservice output flag to the readonly property of a textbox and combobox doesnt have any impact while if I use it on the "visible" property then it works fine.  

Will wait for your response once you get access to your machine.

Just verified, this is working for me. This is a sample for the account page to disable the account Type if it is "Customer". 

Add an attribute to the viewModelConfigDiff:

viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[
    {
        "operation": "merge",
        "path": [
            "attributes"
        ],
        "values": {
            "IsTypeEnabled": {
            	value: true
            }
        }
    }
]/**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/,

Then, I added a change request handler to listen for values in the Type attribute (which also triggers when the page is initially populated, which is when request.silent==true):

handlers: /**SCHEMA_HANDLERS*/[
	{
		request: "crt.HandleViewModelAttributeChangeRequest",
		handler: async (request, next) => {
 
			if (request.attributeName === "Type") {
				request.$context.IsTypeEnabled = (!request.value || request.value.displayValue !== "Customer");
				if (!request.silent) {
					console.log("Type changed", request.oldValue, request.value);
				}
			}
 
			return next?.handle(request);
		}
	}
]/**SCHEMA_HANDLERS*/,

Now, I wire up my attribute to the Type in the viewConfigDiff: 

{
	"operation": "merge",
	"name": "Type",
	"values": {
		"readonly": "$IsTypeEnabled | crt.InvertBooleanValue"
	}
}

Note, i am using a converter to invert the value since my attribute indicates it's enabled, but the property expects the inverse.

With this in place, if I open an Account with Type=Customer, or change the Type to Customer it is disabled/readonly.

One thing to note, many controls have both a readonly and a disabled property, not sure what the difference is, both seem to work for me, but the readonly seems to be the one that gives the control the visual lock icon. The disabled property also disables the control, but you don't get the lock icon for the control.

Ryan

Ryan Farley,

Thanks Ryan, this worked fine for me. I guess I defined the flag outside of the ViewModelConfigDiff section and hence for some reason whike it worked with the visible property but it consistently failed with the readonly property.  

Ryan Farley,

Just a clarification, does HandleViewModelAttributeChangeRequest trigger on both inital page load as well, in addition to any changes to the page?

Ajay Varghese,

Yes it does. When the page initially loads the data for the record, the change event is triggered at that time for each attribute loaded. Meaning, when the data is loaded and bound it will trigger this change (since it is changing the attributes from empty/nothing to a value). It also triggers this request when the user changes values on the page. The request has a silent property. When true (meaning it was a silent change), that means the change was triggered by the system loading the value and NOT by some action performed by the user. If silent=false, that means the user caused the change. If you only want to trigger on a change made by the user, include !request.silent, for example: 

if (request.attributeName === "Type" && !request.silent) {
    // Type was changed by the user
}

Ryan

Got it.  Thank you.

Show all comments

Hi everyone,

 

I´m currently working on a project using documents in Freedom UI, and i was wondering if anyone has successfully implemented PDF generation directly from Creatio using a library in source code without relying on paid marketplace add-ons.

I came across this POST wich outlines an approach that seemed this method may no longer be applicable in the most recent versions of Creatio.

Any insights or shared experiences would be appreciated.

 

Regards,

Like 2

Like

6 comments
Best reply

Can't really do it without a 3rd party DLL or service. Some of the newer marketplace addons use the Free Spire.Doc .NET library, which is pretty easy to work with and would be easy to implement. There is a paid version of Spire.Doc, but the free version would likely suffice for most purposes (and can be used for commercial purposes)

Can't really do it without a 3rd party DLL or service. Some of the newer marketplace addons use the Free Spire.Doc .NET library, which is pretty easy to work with and would be easy to implement. There is a paid version of Spire.Doc, but the free version would likely suffice for most purposes (and can be used for commercial purposes)

Ryan Farley,

thank you for your response and for the recommendation,

I actually downloaded the free version of Spire.Doc and started exploring it — it does look quite promising. However, since I’m working entirely within Creatio Cloud, I believe there might be a limitation when it comes to using third-party DLLs directly, though I’m not completely sure.

Do you think it would be viable to integrate Spire.Doc by hosting the functionality externally (for example, as a microservice or an Azure Function) and calling it from Creatio via a REST API? I’d love to hear your thoughts on whether that approach makes sense or if you’ve seen it work in similar cases.

Thanks again for your help and insights.

Paulo Chacoff Leiton,

As Ryan said, we use the paid version of Spire.Doc in our marketplace app: https://marketplace.creatio.com/app/experceo-word-pdf-converter-creatio

It allows you to generate an unlimited number of PDF documents with unlimited pages (the Free version is limited to 3 pages).

Thank you
Mohamed
 

Still amazes me how conversion to pdf is not an Out of the Box feature of Creatio

(actually was and disappeared a couple of years ago)

We have used aspose connector in the past but there are a lot of errors in communication and quality is not acceptable.
we are also considering using the Spire.Doc library for future developments

Ryan Farley,

Do you happen to have a reference of how to invoke functionality from external libraries or assembly reference? i´ve trying to use Spire.doc in a source code file and script task but i always get a "missing assembly reference"

Just to illustrate the attempt, here´s a basic example a tried to convert word document to PDF with source code file:

 

Any guidance on how to properly reference and use third party libraries like this in Creatio would be appreciated.

 

using Spire.Doc;
using Spire.Doc.Documents;
using System.IO;
 
namespace JJ
{
    public class DocService
    {
        public byte[] GenerateDocx() {
            var doc = new Document();
            doc.AddSection().AddParagraph().AppendText("Hola desde Creatio!");
            using (var ms = new MemoryStream()) {
                doc.SaveToStream(ms, FileFormat.Docx);
                return ms.ToArray();
            }
        }
        public byte[] ConvertToPdf(byte[] docxBytes) {
            var document = new Document();
            using (var ms = new MemoryStream(docxBytes)) {
                 document.LoadFromStream(ms, FileFormat.Docx);
            }
            using (var outMs = new MemoryStream()) {
                 document.SaveToStream(outMs, FileFormat.PDF);
                 return outMs.ToArray();
            }
        }
    }
}
Show all comments

Hello,

I am developing a custom UI component using the angular remote module provided by Creatio.

The front-end part will be in the angular project. Now, If I want to call a server action(for ex: from my custom component a button click -> pass the record id to server action -> get the record retrieved and perform more server actions) where should I put that logic and how to call that logic from remote module?

Also, how do I run/debug the remote module during the development?

TIA.

Like 0

Like

6 comments
Best reply

You would implement the C# code and expose as a configuration service, see https://customerfx.com/article/creating-a-web-service-and-consuming-it-from-client-side-javascript-in-bpmonline/

Then to consume the service from the remote module, you'd use the devkit sdk as shown here: https://customerfx.com/article/calling-configuration-web-services-from-client-side-code-in-a-creatio-freedom-ui-page/

Ryan

You would implement the C# code and expose as a configuration service, see https://customerfx.com/article/creating-a-web-service-and-consuming-it-from-client-side-javascript-in-bpmonline/

Then to consume the service from the remote module, you'd use the devkit sdk as shown here: https://customerfx.com/article/calling-configuration-web-services-from-client-side-code-in-a-creatio-freedom-ui-page/

Ryan

Ryan Farley,

Thank you.. If I want to ship this source code along with my package.. I have to put it under Resources as shown in the below image?

Can you also tell me if it is possible to run/debug the remote module during the development?

If I run the remote module using ng serve I am getting below error.
 


core.mjs:6531 ERROR Error: Remote entry with name 'angproject' does not exist
   at AppModule.ngDoBootstrap (app.module.ts:28:23)

bootstrap.ts:7 Error: Remote entry with name 'angproject' does not exist
   at AppModule.ngDoBootstrap (app.module.ts:28:23)

Sagar Rodda writes:

Ryan Farley,

If I want to ship this source code along with my package

You could sync your workspace to Creatio, add it in the package there and then download the workspace back and you'll see it under the Schemas folder. Or you could add it under Files\cs

Got it.. thank you so much.. I'll try it and let you know here how it goes..

Ryan Farley,

Can you add your comments on this please - https://community.creatio.com/questions/get-object-context-custom-butto…

Show all comments

Hi creatio community,

I am developing a custom campaign element (sms element) as described in this link: https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/platform-customization/classic-ui/marketing-campaigns-basics/examples/implement-a-campaign-element  

I have implemented it and it works fine. The thing that I'm missing here which is very important in my case, is that I want the "SmsText" parameter to have dynamic values inside it. For example in the "SmsText" message value i want to have "Hi " + Contact.Name. This solution provides only static text which in most scenarios the sms message text should be dynamic. 

Could you give any idea/solution on how i can implement in my case?

Thanks

Like 0

Like

2 comments

Any information about this question?

Hi, not quite understand what you mean by "static". You can pass additional parameters to your element and set the value of "SmsText" whatever you please inside the schema UsrTestSmsElementPropertiesPage

Show all comments

I am developing a custom button with the remote module. I created and deployed the component using the clio tool.
When I click on the button, I want to get the object context where this button is placed. 

For example:
if the button is used in the Contact form page then I want to access contact record details(Ex: email, name, type, record id etc..) in the click handler.

If the button is used in the Account form page then I want to access account record details(Ex: name, owner, primary contact, record id etc..) in the click handler.

Can you help me to achieve that?
I have searched in the academy but didn't find an example. Also, I have not found documentation about the apis in @creatio-devkit/common module.

Like 0

Like

6 comments

Hi Sagar,

The ability to pass input values to a remote module component via @creatio-devkit/common is available starting from Creatio 8.1. This library is not present in version 8.0.

You can definitely implement this in 8.1+ to access the current record context (like ID, Name, etc.) inside your custom button component.

Helpful links:
- Implement a remote module - Creatio Academy
- @creatio-devkit/common

What to do:
- Add @CrtInput() to the input properties in your Angular component to receive values from the page context.
- In your Freedom UI schema (viewConfigDiff), pass record fields using $ bindings like $Id, $Name, etc.

Example implementation:
button.component.ts:

@Component({...})
@CrtViewElement({ selector: 'usr-button', type: 'usr.Button' })
export class ButtonComponent {
 @Input() 
 @CrtInput() 
 recordId!: string;
 
 @Input() 
 @CrtInput() 
 name?: string;

 handleClick(): void {
   alert(`Record ID: ${this.recordId}\nName: ${this.name}`);
 }
}

In Freedom UI JSON schema:

{
 "operation": "insert",
 "name": "UsrCustomButton",
 "values": {
   "type": "usr.Button",
   "recordId": "$Id",
   "name": "$Name"
 },
 "parentName": "SideContainer",
 "propertyName": "items",
 "index": 0
}
 

Daiana Gavrylenko,

Thanks for the reply.. I want to clarify that the app I am developing using remote module is for marketplace. So, If I'll be not having access to the Freedom UI json(correct me if I am wrong).

All I want is, the app(button) can be placed in any page(Account, Contact, custom app). Upong clicking the button I want access to the details.

Sagar Rodda,

What Daiana mentioned in the approach you need to take. The component is independent of the page. You receive values in the page via binding. The properties with @Input() are bindable and can be bound to properties of the page. The idea is that you'd add your button to a page, then bind properties for pass values from the record to the component.

Ryan Farley,

Okay.. I'll try to implement this..

may I know where I am supposed to put this in my remote module?

In Freedom UI JSON schema:

{
 "operation": "insert",
 "name": "UsrCustomButton",
 "values": {
   "type": "usr.Button",
   "recordId": "$Id",
   "name": "$Name"
 },
 "parentName": "SideContainer",
 "propertyName": "items",
 "index": 0
}

That is the part that adds the component (your button) to the page. That would exist on the page you add the button to in the viewConfigDiff. When you drag your button to the page, that gets added to the page code, but it also shows it was modified to add the binding properties "recordId" and "name" (which are bound to the current record's "Id" and "Name columns). That part has to get modified manually by the user of your button component since there's currently no designer support for custom components. 

Ryan Farley,

Unfortunately I can't take this approach as we have plans to push our app to marketplace. We can't expect the developers to update their form page everytime they use our app. 

Show all comments

Hi,

i have a use case where i have to load thousand of records in a object and process them as fast as possible. I've built a trial app with an object "staging" where i load the records and one process "elaborate_record" triggered by signal "record inserted in staging". This process has a wait so i can keep track of starting time and and ending time. 

What i've noticed is that 10 "elaborate_record" are started concurrently at the same time, when they finish another 10 processes are started and so on. I can then infer that there is a cap of 10 maximum concurrent processes (at least on the trial instance). 

My question is if it is possible to increase this cap. And if so how? I understand that it might be closely related to the sizing of the environment but i wasn't able to find any documentation about this aspect. I'm working on creatio cloud, not on premise.

Thank you!

Like 1

Like

1 comments

Hello,

We have checked this question and there should be no limitation of this kind on the number of processes run at a time. We have also tested this behavior on a demo and could not reproduce it, therefore we suggest you to register a case for our support team at support@creatio.com so we could check this issue on your environment directly.

Show all comments

Hi Community,

We’re encountering an issue reported by our customer where the application takes an unusually long time to load when login, and sometimes gets stuck on the loading screen.

After investigation, here are some of our findings:

  • Infrastructure doesn't seem to be the issue—server resources are normal, and the application is deployed on-site based on the Creatio deployment calculator.
  • It's not related to internet connectivity—once the login is successful, all subsequent loading behaves normally and runs smoothly.
  • We noticed an interesting behavior:
    When the user opens the login page again in a new tab (without a return URL) or in an incognito window and logs in, the login is successful and the home page loads instantly.
    However, if the user tries to access a full URL such as [Base URL]/0/shell/... or the login page with a return URL in a new tab, the application remains stuck on the loading screen.

While opening a new tab or incognito as a temporary workaround, it's not a viable solution for business users.

Has anyone experienced a similar issue or found a reliable fix for this behavior? Any suggestions or insights would be appreciated.

Best regards,
Khaerul Anwar

Like 0

Like

2 comments

Greetings,

We have not encountered this specific issue before. It is possible that what you described is related to browser caching, although we cannot confirm this with certainty.

For a thorough investigation, we will need the site logs and the exact time the issue occurred so we can analyze the problem in detail.

Please create a support request by emailing us at support@creatio.com.

Regards, 
Orkhan

Hi Orkhan,

We initially suspected that the issue might be related to browser caching, but strangely, it occurs for all users.

We previously attempted to submit a support request, but because our customer support package ("Business support") does not include "Performance diagnostics," the Creatio support team was unable to provide a solution. That’s why I’m now reaching out to the community for help.

Show all comments