IManuallyTriggeredHandler
The IManuallyTriggeredHandler interface allows you to add custom handlers to models, which can be manually triggered/activated by users within the Document system admin. If there are manually triggered handlers registered, Veva will show a new menu in the document system admin where there will be a menu item for each handler.
The ActionType can be "Action" or "OpenUrl". For handlers which have a action type of "OpenUrl", the Run() method needs to return that URL as a string. Once activated, the URL returned from the Run() method will simply be opened in a new window. Handlers which have a action type of "Action" will be executed async, i.e Veva will call the Run() method asynchronously, so those handlers are meant to perform some server side-processing.
If you want the user to confirm the action before it's executed, then make sure to let ShowConfirmation return true. If your handler is of the type "Action", it can have public properties marked with the [EditorBrowsable] attribute and then Veva will present those properties to the user for filling out. That way you can add settings to your handler which the user can configure before running it.
Interface declaration
public interface IManuallyTriggeredHandler { string ActionName { get; } string ActionDescription { get; } ActionTypeEnum ActionType { get; } bool ShowConfirmation { get; } string Run(DocumentModel model); }
Example
The following example defines a Gatsby build trigger which the user can manually trigger. It has a type of "Action" which means that Veva will trigger the Run() method asynchronously in the backround, and it has ShowConfirmation = true, so the user will be asked to confirm the action.
Once confirmed, it will perform a server-side POST request to the configured Gatsby preview webhook URL to trigger a preview build in Gatsby. The use case for this handler is a Headless web app built with Gatsby which reads content from a model in the Veva documents system. Once the user has updated the content in the model, he can simply click the "Preview" menu item in Veva to have a preview built in Gatsby which should then reflect the updated content.
[DisplayName("Gatsby build trigger")] [Description("Triggers a preview build in Gatsby")] public class TriggerPreviewHandler : IDocumentHandler, IManuallyTriggeredHandler { private readonly ISettingsService _settingsService; private readonly IModelFoldersRepository _folderRepository; public string ActionName => "Preview"; public string ActionDescription => "Trigger a preview build in Gatsby"; public ActionTypeEnum ActionType => ActionTypeEnum.Action; public bool ShowConfirmation => true; public TriggerPreviewHandler(ISettingsService settingsService, IModelFoldersRepository folderRepository) { _settingsService = settingsService; _folderRepository = folderRepository; } public string Run(DocumentModel model) { var folder = _folderRepository.FindById(model.FolderId); if (folder != null) { var settings = _settingsService.GetSettings<GatsbyWebsiteSettings>(folder.WebsiteId, null); if (string.IsNullOrEmpty(settings.PreviewWebhookUrl)) { throw new Exception("Gatsby Preview WebHook URL not set! Go to the website settings and find the Gatsby tab. Enter the WebHook URL to use."); } HttpClient client = new HttpClient(); var httpResponse = AsyncHelper.RunSync(() => client.PostAsync(settings.PreviewWebhookUrl, null)); if (!httpResponse.IsSuccessStatusCode) { throw new Exception(string.Format("The POST request to the WebHook did not return a success status code. The returned status code was: {0}", httpResponse.StatusCode.ToString())); } } else { throw new Exception("This model is not in a folder - cannot determine websiteId!"); } return string.Empty; } }
Registration
This is how the implementation is registered into the DI container in Veva, this should be done in your module config file (The class which implements IModule).
public void ConfigureServices(IServiceCollection services, IConfiguration configuration) { services.AddNamed<IDocumentHandler, TriggerPreviewHandler>(ServiceLifetime.Transient); }