ohif-viewer/docs/latest/managers/commands.md
Alireza 5643f8f6d2
feat: Added documentation for OHIF-v3 (#2450)
* Added docs with new screenshots

* Added doc to architecture

* Added documentations to various extension modules

* Added more documentation to modes

* Added docs to managers

* Added docs for services

* Fixed deployment docs

* Added white labelling documentation

* Added i18n docs and measurement export
2021-06-15 11:15:29 -04:00

180 lines
5.0 KiB
Markdown

# Commands Manager
## Overview
The `CommandsManager` is a class defined in the `@ohif/core` project. The Commands Manager tracks named commands (or functions) that are scoped to
a context. When we attempt to run a command with a given name, we look for it
in our active contexts. If found, we run the command, passing in any application
or call specific data specified in the command's definition.
> Note: A single instance of `CommandsManager` should be defined in the consuming application, and it is used when constructing the `ExtensionManager`.
A `simplified skeleton` of the `CommandsManager` is shown below:
```js
export class CommandsManager {
constructor({ getActiveContexts } = {}) {
this.contexts = {};
this._getActiveContexts = getActiveContexts;
}
getContext(contextName) {
const context = this.contexts[contextName];
return context;
}
/**...**/
createContext(contextName) {
/** ... **/
this.contexts[contextName] = {};
}
registerCommand(contextName, commandName, definition) {
/**...**/
const context = this.getContext(contextName);
/**...**/
context[commandName] = definition;
}
runCommand(commandName, options = {}, contextName) {
const definition = this.getCommand(commandName, contextName);
/**...**/
const { commandFn } = definition;
const commandParams = Object.assign(
{},
definition.options, // "Command configuration"
options // "Time of call" info
);
/**...**/
return commandFn(commandParams);
}
/**...**/
}
```
### Instantiating
When we instantiate the `CommandsManager`, we are passing two methods:
- `getAppState` - Should return the application's state when called (Not implemented in `v3`)
- `getActiveContexts` - Should return the application's active contexts when
called
These methods are used internally to help determine which commands are currently
valid, and how to provide them with any state they may need at the time they are
called.
```js
// platform/viewer/src/appInit.js
const commandsManagerConfig = {
getAppState: () => {},
/** Used by commands to determine active context */
getActiveContexts: () => [
'VIEWER',
'DEFAULT',
'ACTIVE_VIEWPORT::CORNERSTONE',
],
};
const commandsManager = new CommandsManager(commandsManagerConfig);
```
## Commands/Context Registration
The `ExtensionManager` handles registering commands and creating contexts, so you don't need to register all your commands manually. Simply, create a `commandsModule` in your extension, and it will get automatically registered in the `context` provided.
A *simplified version* of this registration is shown below to give an idea about the process.
```js
export default class ExtensionManager {
constructor({ commandsManager }) {
this._commandsManager = commandsManager
}
/** ... **/
registerExtension = (extension, configuration = {}, dataSources = []) => {
let extensionId = extension.id
/** ... **/
// Register Modules provided by the extension
moduleTypeNames.forEach((moduleType) => {
const extensionModule = this._getExtensionModule(
moduleType,
extension,
extensionId,
configuration
)
if (moduleType === 'commandsModule') {
this._initCommandsModule(extensionModule)
}
/** registering other modules **/
})
}
_initCommandsModule = (extensionModule) => {
let { definitions, defaultContext } = extensionModule
defaultContext = defaultContext || 'VIEWER'
if (!this._commandsManager.getContext(defaultContext)) {
this._commandsManager.createContext(defaultContext)
}
Object.keys(definitions).forEach((commandName) => {
const commandDefinition = definitions[commandName]
const commandHasContextThatDoesNotExist =
commandDefinition.context &&
!this._commandsManager.getContext(commandDefinition.context)
if (commandHasContextThatDoesNotExist) {
this._commandsManager.createContext(commandDefinition.context)
}
this._commandsManager.registerCommand(
commandDefinition.context || defaultContext,
commandName,
commandDefinition
)
})
}
}
```
If you find yourself in a situation where you want to register a command/context manually, ask
yourself "why can't I register these commands via an extension?", but if you insist, you can use the `CommandsManager` API to do so:
```js
// Command Registration
commandsManager.registerCommand('context', 'name', commandDefinition);
// Context Creation
commandsManager.createContext('string');
```
## `CommandsManager` Public API
If you would like to run a command in the consuming app or an extension, you can
use `runCommand(commandName, options = {}, contextName)`.
```js
// Run a command, it will run all the `speak` commands in all contexts
commandsManager.runCommand('speak', { command: 'hello' });
// Run command, from Default context
commandsManager.runCommand('speak', { command: 'hello' }, ['DEFAULT']);
// Returns all commands for a given context
commandsManager.getContext('string');
```