Domain Bundles

Motivation

The previous sections show how different aspects of individual apps — such as the background maps, thematic layers, or search — can be configured.

However, there might be situations where many apps share the same configuration options, for example the same services for basemaps or thematical maps. Multiple apps can share parts of dedicated configuration options but not all of them.

With the help of domain bundles it is possible to ship these configurations in a custom bundle. This bundle can be reused in multiple apps. In addition, multiple configuration options for various functionalities of an app can be combined into a single domain bundle. By this means all domain relevant configuration aspects can be delivered by one bundle.

The deployment as bundle helps to combine the configuration options contained in numerous apps in a various ways. Bundles also offer the option of being versioned. In this way, updates to the configuration of one or more apps can be distributed among multiple apps.

Creating Domain-Bundles

The configuration in a domain bundle is structured in the same way as in the app configuration (app.json).

Structure and options

In general, a domain bundle contains at least one JSON file (manifest.json), which stores one or more configuration fragments. All configuration fragments are described in JSON within the keyword domain-config. It is possible to configure one or more of these fragments in parallel in a domain bundle. The following snippet shows an example of an empty configuration containing all possible fragments:

{
    "name": "domain-yourCustomDomainBundleName",
    "version": "1.0.0",
    "dependencies": {
        "domains-system": "^4.4.0"
    },
    "main": "",
    "layer": "",
    "i18n": [],
    "domain-config": {
        "map-basemaps": [],
        "map-layers": [],
        "ags-stores": [],
        "report-mappings": []
    }
}

Each fragment is addressed by its own keyword. The configuration is similar to the corresponding part of the app configuration file (app.json). The following table lists the possible fragments of the domain bundle configuration:

Fragment Keyword in domain-config Equivalent in app.json

Basemaps

"map-basemaps"

"map-init": {
    "Config": {
        "basemaps": []
    }
}

Operational Layers

map-layers

"map-init": {
    "Config": {
        "map": {
            "layers": []
        }
    }
}

Sources for search and selection

ags-stores

"agssearch": {
  "AGSStore": []
}

Reports

report-mappings

"reporttool": {
  "ReportTask": {
    "mappings": []
  }
}

Complete Sample

The following example shows a full domain bundle configuration using all available configuration fragments:

{
    "name": "domain-yourCustomDomainBundleName",
    "version": "1.0.0",
    "dependencies": {
        "domains-system": "^4.4.0"
    },
    "main": "",
    "layer": "",
    "i18n": [],
    "domain-config": {
        "map-basemaps": [
            {
                "id": "esri_street",
                "title": "Streets",
                "thumbnailUrl": "resource('images/thumbnailImage.png')",
                "basemap": "gray-vector"
            }
        ],
        "map-layers": [
            {
                "id": "koeln3",
                "title": "Koeln",
                "url": "https://services.conterra.de/arcgis/rest/services/common/koeln/MapServer",
                "coverImage": "resource('images/coverImage.png')",
                "type": "AGS_DYNAMIC",
                "visible": true
            }
        ],
        "ags-stores": [
            {
                "id": "store01",
                "title": "Adressen",
                "url": "https://services.conterra.de/arcgis/rest/services/common/koeln_adressen/MapServer/0",
                "omniSearchSearchAttr": "ADRESSE",
                "omniSearchDefaultLabel": "Adressen"
            }
        ],
        "report-mappings": [
            {
                "storeId": "store01",
                "reportId": "report01",
                "fileName": "Report.pdf"
            }
        ]
    }
}

Using Domain-Bundles

Domain bundles are installed and used the same way as other bundles (see Managing bundles).

Domain bundles can be used in one or more apps. The configuration fragments of the domain bundles are added to the existing app configuration. Depending on the configuration fragment, the following general conditions apply.

Consequences for the app

Every fragment configured with a domain bundle (for example map or search) affects the app and its configuration. The following section describes how domain bundles affect app configurations:

Basemaps

Background maps are configured within the keyword map-basemaps in the same way as in app.json. The active basemap is defined with the property "selected":true. For example:

{
    "map-basemaps": [
        {
            "id": "esri_street",
            "title": "Streets",
            "thumbnailUrl": "resource('images/thumbnailImage.png')",
            "basemap": "gray-vector",
            "selected": true
        }
    ]
}

The following table shows how background maps provided by domain bundles affect the app and it’s configuration:

Behavior when …​ Description Sample

…​ applying the configuration

Background maps from domain bundles are added to the app and are available for selection after loading the bundle.

Background maps with unique IDs are added to the map. Because only one background map can be selected, the background map is only selected from a domain bundle if there is no selected background map in the app and no other domain bundle has previously selected a background map.

…​ order is fixed

Background maps are added in the order of the loaded domain bundles.

In the map, only one background map is active at a time. However, the order has an effect on the display in the Basemap toggler, for example.

…​ a duplicate is found

Background maps that have already been loaded are not overwritten. App configuration takes priority over domain bundle configuration.

The background map to be loaded is not applied if a background map that has already been configured in the app or a background map that was previously loaded by another domain bundle has the same ID.

Operational Layer

The configuration of operational layers with the map-layers keyword in domain bundles corresponds to the configuration of the map.layers property in the map-init bundle configuration. For example:

{
    "map-layers": [
        {
            "id": "koeln3",
            "title": "Koeln",
            "url": "https://services.conterra.de/arcgis/rest/services/common/koeln/MapServer",
            "coverImage": "resource('images/coverImage.png')",
            "type": "AGS_DYNAMIC",
            "visible": true
        }
    ]
}

Operational layers from domain bundles are applied to the map in a similar way as if they were configured directly in the app. The following table presents situation-specific features:

Behavior when …​ Description Sample

…​ applying the configuration

Operational layers, sub-layers, popup templates and other configurations are added to the map as soon as the domain bundle is loaded.

…​ order is fixed

Operational layers are added to the map in a fixed order. The layers of first-loaded domain bundles are added to the map in the same order from bottom to top.

The order influences not only the arrangement of the topic tiles in Map Flow, but also the display order - and overlapping - of layers in the map.

…​ a duplicate is found

Operational layers from a domain bundle with IDs that have already been added to the map won’t be overvwritten.

No configuration options of a layer whose ID already exists in the map are adopted - according to that, settings are not merged.

Stores for search and selection

Stores for search and spatial selection are configured with the keyword ags-stores - analogoue to the configuration of AGSStore for the agssearch bundle in app.json.

To use this function the domain-bundle needs to define a dependency to bundle agssearch. Alternatively, this bundle might be loaded in the app itself.

{
    "ags-stores": [
        {
            "id": "store01",
            "title": "Adressen",
            "url": "https://services.conterra.de/arcgis/rest/services/common/koeln_adressen/MapServer/0",
            "omniSearchSearchAttr": "ADRESSE",
            "omniSearchDefaultLabel": "Adressen"
        }
    ]
}
Behavior when …​ Description Sample

…​ applying the configuration

Stores from domain bundles are registered in the system and are available for various functions as defined in their useIn property.

A domain bundle can be used to expand the spatial selection and search by stores.

…​ order is fixed

The sequence has no effect on the functionality.

However, the loading order has implications on the source list of spatial selection.

…​ a duplicate is found

There is no check for duplicates or existing store.

Stores from a domain bundle with ID or URL that already exist are added to the app.

Report mappings

Report mappings are defined by keyword report-mapping - analogue to the ReportTask mappings of bundle reporttool in app.json.

To use this function the domain-bundle needs to define a dependency to bundle reporttool. Alternatively, this bundle might be loaded in the app itself.

{
    "report-mappings": [
        {
            "storeId": "store01",
            "reportId": "report01",
            "fileName": "Report.pdf"
        }
    ]
}
Behavior when …​ Description Sample

…​ applying the configuration

Mappings from domain bundles are added in addition to existing mappings.

A domain-bundle can be used to provide custom mappings for its content.

…​ order is fixed

The sequence has no effect on the functionality.

In case of a duplicated definition of a mapping the mapping loaded first is used.

…​ a duplicate is found

The check is performed by property "storeId". If a mapping for a certain store is already defined the one that is loaded latest is ignored.

A mapping defined by a domain-bundle with a storeId that is already used by another mapping is not added to the app.

Evaluation order

As the preceding descriptions of the effects of domain bundles on app behavior show, the order in which domain bundles are loaded is crucial in many cases. It is therefore possible to adjust this order. Thus, for example, the display order of operational layers can be influenced. This also ensures that in case of ambiguous IDs, the particularly important domain bundles are loaded first.

The following excerpt from an app.json configuration shows how to change the order in which domain bundles are loaded and applied. Specify the bundle names in the order in which they should be loaded. It is sufficient to specify only the bundle names for which a sequence is important. Bundles that are not listed are loaded and applied randomly after the performances.

Fragment from
"domains-system": {
    "Config": {
        "domainBundleOrder": ["domain-domainBundleForBasmaps", "domain-domainBundleForMapLayers"]
    }
}
The order in which domain bundles are loaded is only evaluated when the app is starting. When dynamically starting or stopping a domain bundle during app runtime the order is ignored.