Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Add `token` to `ArcGisMapServerCatalogItem`, `ArcGisMapServerCatalogGroup`, `ArcGisFeatureServerCatalogItem`, `ArcGisFeatureServerCatalogGroup`, `ArcGisImageServerCatalogItem`, `I3SCatalogItem` and `ArcGisCatalogGroup` - if defined, it will be added to the `token` parameter for all ArcGIS Rest API requests.
- Added `tokenUrl` to `ArcGisImageServerCatalogItem`, and tweaked behaviour in `ArcGisMapServerCatalogItem` and `ArcGisImageServerCatalogItem` so that if both `token` and `tokenUrl` are defined, then `tokenUrl` will be used. This allows the token to be refreshed if needed.
- WMTS read URL from operations metadata #7371
- Add `workbenchControlFlags` trait to all catalog members for enabling or disabling workbench controls.
- Add `<settingspanel>` custom component to open Map settings panel from template code (like short report, feature info etc).
- Add UI to show toast messages.
- [The next improvement]
Expand Down
2 changes: 1 addition & 1 deletion lib/ReactViews/Map/MapNavigation/Items/MyLocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class MyLocation extends MapNavigationItemController {
coordinates: [longitude, latitude]
},
properties: {
title: t("location.location"),
title: t<string>("location.location"),
longitude: longitude,
latitude: latitude
}
Expand Down
39 changes: 27 additions & 12 deletions lib/ReactViews/Workbench/Controls/ViewingControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import { observer } from "mobx-react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
import Rectangle from "terriajs-cesium/Source/Core/Rectangle";
import createGuid from "terriajs-cesium/Source/Core/createGuid";
import defined from "terriajs-cesium/Source/Core/defined";
import Rectangle from "terriajs-cesium/Source/Core/Rectangle";
import SplitDirection from "terriajs-cesium/Source/Scene/SplitDirection";
import {
Category,
DataSourceAction
} from "../../../Core/AnalyticEvents/analyticEvents";
import TerriaError from "../../../Core/TerriaError";
import filterOutUndefined from "../../../Core/filterOutUndefined";
import getDereferencedIfExists from "../../../Core/getDereferencedIfExists";
import getPath from "../../../Core/getPath";
import isDefined from "../../../Core/isDefined";
import TerriaError from "../../../Core/TerriaError";
import CatalogMemberMixin, {
getName
} from "../../../ModelMixins/CatalogMemberMixin";
Expand All @@ -26,13 +26,13 @@ import MappableMixin from "../../../ModelMixins/MappableMixin";
import SearchableItemMixin from "../../../ModelMixins/SearchableItemMixin";
import TimeVarying from "../../../ModelMixins/TimeVarying";
import CameraView from "../../../Models/CameraView";
import addUserCatalogMember from "../../../Models/Catalog/addUserCatalogMember";
import SplitItemReference from "../../../Models/Catalog/CatalogReferences/SplitItemReference";
import addUserCatalogMember from "../../../Models/Catalog/addUserCatalogMember";
import CommonStrata from "../../../Models/Definition/CommonStrata";
import hasTraits from "../../../Models/Definition/hasTraits";
import Model, { BaseModel } from "../../../Models/Definition/Model";
import getAncestors from "../../../Models/getAncestors";
import hasTraits from "../../../Models/Definition/hasTraits";
import { ViewingControl } from "../../../Models/ViewingControls";
import getAncestors from "../../../Models/getAncestors";
import ViewState from "../../../ReactViewModels/ViewState";
import AnimatedSpinnerIcon from "../../../Styled/AnimatedSpinnerIcon";
import Box from "../../../Styled/Box";
Expand All @@ -44,6 +44,11 @@ import SplitterTraits from "../../../Traits/TraitsClasses/SplitterTraits";
import { exportData } from "../../Preview/ExportData";
import LazyItemSearchTool from "../../Tools/ItemSearchTool/LazyItemSearchTool";
import WorkbenchButton from "../WorkbenchButton";
import {
WorkbenchControls,
enableAllControls,
isControlEnabled
} from "./WorkbenchControls";

const BoxViewingControl = styled(Box).attrs({
centered: true,
Expand Down Expand Up @@ -91,10 +96,11 @@ const ViewingControlMenuButton = styled(RawButton).attrs({
interface PropsType {
viewState: ViewState;
item: BaseModel;
controls?: WorkbenchControls;
}

const ViewingControls: React.FC<PropsType> = observer((props) => {
const { viewState, item } = props;
const { viewState, item, controls = enableAllControls } = props;
const { t } = useTranslation();
const [isMenuOpen, setIsOpen] = useState(false);
const [isMapZoomingToCatalogItem, setIsMapZoomingToCatalogItem] =
Expand Down Expand Up @@ -328,11 +334,15 @@ const ViewingControls: React.FC<PropsType> = observer((props) => {
return sortBy(
uniqBy([...itemViewingControls, ...globalViewingControls], "id"),
"name"
);
}, [item, viewState.globalViewingControlOptions]);
).filter(({ id }) => {
// Exclude disabled controls
return isControlEnabled(controls, id);
});
}, [item, controls, viewState.globalViewingControlOptions]);

const renderViewingControlsMenu = () => {
const canSplit =
controls.compare &&
!item.terria.configParameters.disableSplitter &&
hasTraits(item, SplitterTraits, "splitDirection") &&
hasTraits(item, SplitterTraits, "disableSplitter") &&
Expand Down Expand Up @@ -376,7 +386,8 @@ const ViewingControls: React.FC<PropsType> = observer((props) => {
</ViewingControlMenuButton>
</li>
) : null}
{viewState.useSmallScreenInterface === false &&
{controls.difference &&
viewState.useSmallScreenInterface === false &&
DiffableMixin.isMixedInto(item) &&
!item.isShowingDiff &&
item.canDiffImages ? (
Expand All @@ -392,7 +403,8 @@ const ViewingControls: React.FC<PropsType> = observer((props) => {
</ViewingControlMenuButton>
</li>
) : null}
{viewState.useSmallScreenInterface === false &&
{controls.exportData &&
viewState.useSmallScreenInterface === false &&
ExportableMixin.isMixedInto(item) &&
item.canExportData ? (
<li key={"workbench.exportData"}>
Expand All @@ -407,7 +419,8 @@ const ViewingControls: React.FC<PropsType> = observer((props) => {
</ViewingControlMenuButton>
</li>
) : null}
{viewState.useSmallScreenInterface === false &&
{controls.search &&
viewState.useSmallScreenInterface === false &&
SearchableItemMixin.isMixedInto(item) &&
item.canSearch ? (
<li key={"workbench.searchItem"}>
Expand Down Expand Up @@ -464,6 +477,7 @@ const ViewingControls: React.FC<PropsType> = observer((props) => {
onClick={zoomTo}
title={t("workbench.zoomToTitle")}
disabled={
!controls.idealZoom ||
// disabled if the item cannot be zoomed to or if a zoom is already in progress
(MappableMixin.isMixedInto(item) && item.disableZoomTo) ||
isMapZoomingToCatalogItem === true
Expand All @@ -483,7 +497,8 @@ const ViewingControls: React.FC<PropsType> = observer((props) => {
title={t("workbench.previewItemTitle")}
iconElement={() => <Icon glyph={Icon.GLYPHS.about} />}
disabled={
CatalogMemberMixin.isMixedInto(item) && item.disableAboutData
!controls.aboutData ||
(CatalogMemberMixin.isMixedInto(item) && item.disableAboutData)
}
>
{t("workbench.previewItem")}
Expand Down
87 changes: 87 additions & 0 deletions lib/ReactViews/Workbench/Controls/WorkbenchControls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Static and dynamic flags for enabling/disabling controls in the Workbench
*/
export type WorkbenchControls = {
// When true, disable all controls by default. You can then selectively
// enable/disable flags individually to override the default.
disableAll: boolean;

compare: boolean; // Flag for compare tool also known as splitter
difference: boolean; // Flag for difference tool
idealZoom: boolean;
aboutData: boolean;
exportData: boolean;
search: boolean; // Flag for item search tool
opacity: boolean;
scaleWorkbench: boolean;
timer: boolean;
chartItems: boolean;
filter: boolean;
dateTime: boolean;
timeFilter: boolean;
selectableDimensions: boolean;
colorScaleRange: boolean;
shortReport: boolean;
legend: boolean;

[dynamicControl: string]: boolean | undefined;
};

export const enableAllControls: WorkbenchControls = {
disableAll: false,

compare: true, // Flag for compare tool also known as splitter
difference: true, // Flag for difference tool
idealZoom: true,
aboutData: true,
exportData: true,
search: true, // Flag for item search tool
opacity: true,
scaleWorkbench: true,
timer: true,
chartItems: true,
filter: true,
dateTime: true,
timeFilter: true,
selectableDimensions: true,
colorScaleRange: true,
shortReport: true,
legend: true
};

export const disableAllControls: WorkbenchControls = {
disableAll: true,

compare: false, // Flag for compare tool also known as splitter
difference: false, // Flag for difference tool
idealZoom: false,
aboutData: false,
exportData: false,
search: false, // Flag for item search tool
opacity: false,
scaleWorkbench: false,
timer: false,
chartItems: false,
filter: false,
dateTime: false,
timeFilter: false,
selectableDimensions: false,
colorScaleRange: false,
shortReport: false,
legend: false
};

/**
* Check if a control is enabled in the given controls object
*
* @param controls WorkbenchControls object
* @param controlName Either one of the static keys defined by @type {WorkbenchControls} or the id of a dynamic control, eg: "table-styling"
*/
export function isControlEnabled(
controls: WorkbenchControls,
controlName: string
): boolean {
return controlName in controls
? !!controls[controlName]
: !controls.disableAll;
}
Loading
Loading