close

Filter

loading table of contents...

Studio Developer Manual / Version 2404

Table Of Contents

9.36.5.3 Adding Custom Services

The previous sections cover the built-in services and utilities that are available for custom apps. This section covers how to add custom services to the Studio Apps framework.

Services of Custom App

Adding services that a custom app offers is straightforward and a typical pattern for ReactJs apps is as follows, taken from the My-Edited-Contents App.

const [sortModel, setSortModel] = React.useState<GridSortItem>({
  field: "displayName",
  sort: undefined,
});

...

useEffect(() => {
  const myEditedContentsServiceDesc = createMyEditedContentsServiceDescriptor({
    providingApp: studioApps._.getMyAppDescriptor().cmKey
  });

  const myEditedContentsService = new MyEditedContentsServiceImpl(setSortModel);
  getServiceAgent().registerService(myEditedContentsService, myEditedContentsServiceDesc);

  return () => myEditedContentsServiceDesc
                 && getServiceAgent().unregisterServices(myEditedContentsServiceDesc);
}, [])

The service is registered in the context of a useEffect() hook. The service gets passed a state setter function of a ReactJs component, so that it can have effect on the app. Finally, the service is unregistered when the component is un-mounted.

In this particular case, the MyEditedContentsService is one that is also listed in the cmServices list of the app manifest. So it its MyEditedContentsServiceProps are required to extend WithProvidingApp and the providing app must be specified.

Adding Services to The Content and Workflow App

Another use case is when a custom app requires a service from a built-in CoreMedia app that does not exist out of the box. However, in this case, such a service can be added via a classical StudioPlugin or StudioStartupPlugin, cf. Section 9.3, “Studio Plugins”. For example, the My-Edited-Contents App has a button to show a StartWorkflowWindow in the Content App. The service for this is not built-in. But part of the My-Edited-Contents App workspace is the MyEditedContentsAppStartupPlugin for the Content App with the following service registration code.

override async init(): Promise<void> {
  super.init();

  const availablePublicationProcesses = await this.waitForPublicationWorkflowAccess();
  const publicationWindowService =
    new ShowStartPublicationWindowServiceImpl(availablePublicationProcesses);
  const serviceDesc = createShowStartPublicationWindowServiceDescriptor({
    providingApp: studioApps._.getMyAppDescriptor().cmKey,
  });
  getServiceAgent().registerService(publicationWindowService, serviceDesc);
}

The service implementation ShowStartPublicationWindowServiceImpl looks like this.

class ShowStartPublicationWindowServiceImpl implements ShowStartPublicationWindowService {

  #availableProcessDefinitions: String[];

  constructor(availableProcessDefinitions) {
    this.#availableProcessDefinitions = availableProcessDefinitions;
  }

  async showStartPublicationWindow(contentUris: Array<string>): Promise<void> {
    const config = Config(StartWorkflowWindow);
    config.title = ControlRoom_properties.StartWorkflowWindow_publication_title;
    config.defaultWorkflowName = "Publish Edited Contents";
    config.availableProcessDefinitionNames = this.#availableProcessDefinitions;
    config.initialContents = contentUris.map(beanFactory._.getRemoteBean);
    config.getWorkflowIssuesWindowFunction = WorkflowUtils.getWorkflowIssuesWindow;
    const window = new StartWorkflowWindow(config);
    window.show();

    await studioApps._.focusMe();
  }
}

Both service implementation and the registration code take place in the traditional ExtJs CoreMedia Studio context. It is even possible to add this new service as a cmService entry to the Content App's manifest by adding this fragment to the jangaroo.config.js of the plugin module.

appManifests: {
  en: {
    cmServices: [
      { name: "showStartPublicationWindowService" },
    ],
  },
}

Now the service can be used in the My-Edited-Contents App.

<IconButton color={"primary"} onClick={async () => {
  const contentUris = contentDetails.map((contentDetail) => contentDetail.id);
  getServiceAgent().executeServiceMethod({
    serviceDescriptor: createShowStartPublicationWindowServiceDescriptor(),
    method: "showStartPublicationWindow",
  }, contentUris);
}}>

Search Results

Table Of Contents
warning

Your Internet Explorer is no longer supported.

Please use Mozilla Firefox, Google Chrome, or Microsoft Edge.