Interface JAppExtension

You can create a custom application panel throught the app extension mecanism.

It offers a way to add your own panel, map interactor, redux store data, etc ...

This way you can fully customize your JMap Server NG with your own code, written with your favourite dev tools.

interface JAppExtension {
    destroyFn?: (() => void);
    id: string;
    initFn: ((params) => void);
    injectMapRequestParameters?: RequestTransformFunction;
    interactor?: JMapInteractor;
    isProjectExtension?: boolean;
    jmapCloudExtensionUrn?: string;
    onAppRegistrationDone?: (() => void);
    onPanelCreation: ((panelContainerId) => void);
    onPanelDestroy?: ((panelContainerId) => void);
    onRegistrationDone?: (() => void);
    panelIcon?: string;
    panelTitle?: string | JTranslationItem;
    panelTooltip?: string | JTranslationItem;
    renderMouseOver?: ((layer, feature) => undefined | JExtensionMouseOver);
    serverExtensionId?: string;
    serviceToExpose?: any;
    startBeforeMapIsReady?: boolean;
    storeReducer?: ((currentReducerState, action) => any);
    translationBundle?: JTranslationBundle;
}

Hierarchy (view full)

Properties

destroyFn?: (() => void)

The destroy function.

Only used for "project" scoped extensions (useless for "application" scoped extension).

For "project" scoped extensions, when a project will be deactivated, all project's extensions are unregistered.

Before unregister those extensions, this function is called.

For example, when this function is called you should clean all your event listeners.

Don't mind about cleaning the redux state, because it will be destroyed by the register function.

Then the redux state will be created again when the next project will be loaded, and the extension will be registered again.

Type declaration

    • (): void
    • Returns void

id: string

The unique extension identifier

initFn: ((params) => void)

The init function of your extension.

Here you can start initialize your extension.

By default param is an empty object, but for project server extensions only, a parameter "serverInfo" is passed, fetched from the project configuration that is defined in the admininistration.

Type declaration

injectMapRequestParameters?: RequestTransformFunction

An optional handler that returns a Maplibre RequestParameters object

Provide this handler if your extentions needs to add something special in map requests, like providing credentials, adding headers, etc.

Great care must be taken to not blindly modify every request passed to this handler. You should only modify requests known to your extension. This can usually be determined by looking at the url received by the handler.

See Maplibre documentation for reference:

https://maplibre.org/maplibre-gl-js/docs/API/types/maplibregl.MapOptions

https://maplibre.org/maplibre-gl-js/docs/API/types/maplibregl.RequestParameters

Example

JMap.Extension.register({
id: "MyExtension", // Unique id
initFn: () => {
// here you can start your UI component if needed
console.log("JMap is started and my extension has been successfuly started")
},
injectMapRequestParameters: (url, resourceType) => {
if (resourceType === 'Source' && url.indexOf('http://myHost') > -1) {
return {
url,
headers: {'my-custom-header': true},
credentials: 'include' // Include cookies for cross-origin requests
}
}
return { url }
}
})
interactor?: JMapInteractor

An optional map interactor.

See [[JMap.Service.Map.Interaction]] for more details.

isProjectExtension?: boolean

By default an extension is "application" scoped. But you can set the extension as "project" scoped.

If an extension is application scoped, it will be loaded one time, and never destroyed.

If it's set as project scoped :

  • The extension will be registered each time a project is activated (= initFn will be called).
  • When a project is deactivated, the extension function destroyFn is called (if defined), then the extension is unregistered (redux store, service, etc... will be destroyed).
jmapCloudExtensionUrn?: string

If your extensions is available for JMap Cloud, you have to set this parameter.

This parameter is used to uniquely identify your extension among all other JMap Cloud extensions.

This parameter can be set alongside JCoreExtension.serverExtensionId if your extension is also available for JMap Server.

If set, this parameter must be a v4 string. Each Jmap Cloud extension must have a unique identifier, so you have to make sure that each of your extensions defines a unique jmapCloudExtensionUrn.

JMap Cloud only supports Project extensions

onAppRegistrationDone?: (() => void)

The panel registration method.

This method is called each time the app extension is :

  • Registered, after the panel and interactors have been created

Here you can perform actions after the registering of the extension.

Type declaration

    • (): void
    • Returns void

onPanelCreation: ((panelContainerId) => void)

The panel creation method.

This is where you have to :

  • Create your panel UI
  • Add your listeners (like Redux subscribe)
  • ect ...

This method is called each time the panel is :

  • Created : after a panel change
  • Displayed : after the panel is displayed after been hidden

Type declaration

    • (panelContainerId): void
    • Parameters

      • panelContainerId: string

        The html container id where you can insert your application.

      Returns void

onPanelDestroy?: ((panelContainerId) => void)

The panel destroy method.

This is where you have to :

  • Destroy the panel UI (if not yet done).
  • Remove your listeners (like Redux unsubscribe)
  • etc ...

This method is called each time the panel is :

  • Destroyed : after a panel change (panelContainerId div doesn't exist when called)
  • Hidden : when the panel is hidden (panelContainerId div still exist when called)

Type declaration

    • (panelContainerId): void
    • Parameters

      • panelContainerId: string

        The html container id where you can insert your application.

      Returns void

onRegistrationDone?: (() => void)

The registration function.

Triggered when this extension has been registered.

Type declaration

    • (): void
    • Returns void

panelIcon?: string

The panel icon.

An url (png, jpeg, svg, etc ...), a base 64 string or an svg tag as a string, as you like. For an svg string a viewbox need to be specified for the icon to appear, if no fill attribute is specified, the icon will follow the app theme.

panelTitle?: string | JTranslationItem

The panel title.

If provided, will create a header on top of the panel having the same style of the others panels headers.

panelTooltip?: string | JTranslationItem

The panel icon tooltip.

renderMouseOver?: ((layer, feature) => undefined | JExtensionMouseOver)

You can provide a renderMouseOver function.

If set, this function has to return a JExtensionMouseOver, and it will be displayed at the end of the standard mouseover.

Type declaration

serverExtensionId?: string

If your extensions is depending on a server extension, you have to set this parameter.

This parameter is used to determine if an extension is a backend extension or not, and also used in order to provide the parameter to the extension (initFn params).

It should be the same id as the JS extension id, it but could be different.

serviceToExpose?: any

If you want you can expose a service.

If your extension id is "MyExtension", your service will be accessible like that :

JMap.Extension.MyExtension.doSomething()
startBeforeMapIsReady?: boolean

By default :

  • "application" scoped extensions are initialized (= initFn called) the first time the map is loaded
  • "project" scoped extensions are initialized after a project has changed and the new map is loaded

If you set this parameter to true :

  • "application" scoped extensions will be initialized as soon the extension is registered
  • "project" scoped extensions will be initialized as soon the project has changed
storeReducer?: ((currentReducerState, action) => any)

You can provide your own Redux store reducer : https://redux.js.org/basics/reducers.

Like that you can develop UI component that react to the redux state changes.

You can get the data store using this function : JMap.getDataStore, and then dispatch your own actions.

A redux reducer is a pure JS function that take the current reducer state (can be undefined first time) and an action, and return the new state (the same if no changes has been made for the action).

Type declaration

    • (currentReducerState, action): any
    • Parameters

      • currentReducerState: any
      • action: any

      Returns any

translationBundle?: JTranslationBundle

You can provide a translation bundle for your extesion. All translations will be handled by the JMap Server NG translation engine. See JMap.Language.addBundle for more details on bundles