Studio Developer Manual / Version 2406.0
Table Of ContentsThe 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: studioAppsContext._.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: studioAppsContext._.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 studioAppsContext._.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); }}>