"use strict";
define([
"backbone",
"models/maps/Map",
"collections/maps/MapAssets",
"common/IconUtilities",
"common/SearchParams",
], (Backbone, MapModel, MapAssets, IconUtilities, SearchParams) => {
/**
* @classdesc A AssetCategory Model contains metadata about the category, like a label and an icon.
* @classcategory Models/Maps
* @class AssetCategory
* @name AssetCategory
* @augments Backbone.Model
* @since 2.28.0
* @constructor
*/
const AssetCategory = Backbone.Model.extend(
/** @lends AssetCategory.prototype */ {
/**
* The name of this type of model
* @type {string}
*/
type: "AssetCategory",
/**
* Default attributes for AssetCategory models
* @name AssetCategory#defaults
* @type {object}
* @property {string} label A user friendly name for this category, to be displayed
* in a map.
* @property {string} icon
* A PID for an SVG saved as a dataObject, or an SVG string. The SVG will be used
* as an icon that will be displayed next to the category label. It should be an
* SVG file that has no fills, borders, or styles set on it (since the icon will
* be shaded dynamically by the maps CSS using a fill attribute). It must use a
* viewbox property rather than a height and width.
* @property {boolean} [expanded = false] Set to true when this category has been
* expanded by the user.
* @property {MapAssets} mapAssets The data to render in the map.
*/
defaults() {
return {
label: "",
icon: '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="m3.2 7.3 8.6 4.6a.5.5 0 0 0 .4 0l8.6-4.6a.4.4 0 0 0 0-.8L12.1 3a.5.5 0 0 0-.4 0L3.3 6.5a.4.4 0 0 0 0 .8Z"/><path d="M20.7 10.7 19 9.9l-6.7 3.6a.5.5 0 0 1-.4 0L5 9.9l-1.8.8a.5.5 0 0 0 0 .8l8.5 5a.5.5 0 0 0 .5 0l8.5-5a.5.5 0 0 0 0-.8Z"/><path d="m20.7 15.1-1.5-.7-7 3.8a.5.5 0 0 1-.4 0l-7-3.8-1.5.7a.5.5 0 0 0 0 .9l8.5 5a.5.5 0 0 0 .5 0l8.5-5a.5.5 0 0 0 0-.9Z"/></svg>',
expanded: false,
};
},
/**
* The source of a specific category to show in the ToolBarView, as well as
* display properties of the asset.
* @typedef {object} AssetCategoryConfig
* @name MapConfig#AssetCategoryConfig
* @property {string} label - A user friendly name for this category, to be
* displayed in a map.
* @property {string} icon - A PID for an SVG saved as a dataObject, or an SVG
* string. The SVG will be used as an icon that will be displayed next to the
* category label. It should be an SVG file that has no fills, borders, or styles
* set on it (since the icon will be shaded dynamically by the maps CSS using a
* fill attribute). It must use a viewbox property rather than a height and width.
* @property {MapAssets} layers - The data to render in the map.
*/
/**
* Executed when a new AssetCategory model is created.
* @param {MapConfig#AssetCategoryConfig} categoryConfig The initial values of the
* attributes, which will be set on the model.
*/
initialize(categoryConfig) {
if (!categoryConfig?.layers) {
throw new Error(`Category ${categoryConfig.label} has empty layers.`);
}
const searchParamLayerIds = SearchParams.getEnabledLayers();
const layers = categoryConfig.layers.map((layer) => {
// Consider portal configuration and URL search params.
const visible = searchParamLayerIds.length
? Boolean(layer.layerId) &&
searchParamLayerIds.includes(layer.layerId)
: layer.visible;
return {
...layer,
configuredVisibility: layer.visible,
originalVisibility: visible,
visible,
};
});
this.set("mapAssets", new MapAssets(layers));
this.set("label", categoryConfig.label);
// Fetch the icon, if there is one
if (categoryConfig.icon) {
try {
if (IconUtilities.isSVG(categoryConfig.icon)) {
this.updateIcon(categoryConfig.icon);
} else {
IconUtilities.fetchIcon(categoryConfig.icon).then((icon) =>
this.updateIcon(icon),
);
}
} catch (error) {
// Do nothing. Use the default icon instead.
}
}
},
/**
* Sanitizes an SVG string and updates the model's 'icon' attribute the sanitized
* string.
* @param {string} icon An SVG string to use for the AssetCategory icon
*/
updateIcon(icon) {
if (!icon) return;
this.set("icon", IconUtilities.sanitizeIcon(icon));
},
/**
* Set the parent map model on each of the MapAsset models in this
* collection. This must be the Map model that contains this asset
* collection.
* @param {MapModel} mapModel The map model to set on each of the AssetCategory
* models
*/
setMapModel(mapModel) {
this.get("mapAssets").setMapModel(mapModel);
},
},
);
return AssetCategory;
});