diff --git a/CHANGES.md b/CHANGES.md index 40e3d36c10d..345758a0b6c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ #### next release (8.7.5) +- TSify some `js` and `jsx` files and provide `.d.ts` ambient type files for a few others. This is so that running `tsc` on an external project that imports Terria code will typecheck successfully. - [The next improvement] #### 8.7.4 - 2024-06-07 @@ -23,6 +24,7 @@ #### 8.7.2 - 2024-05-14 +- Add NumberParameterEditor to enable WPS AllowedValues Ranges to be set and use DefaultValue - Feature info template has access to activeStyle of item having TableTraits. - Updated a few dependencies to fix security warnings: `underscore`, `visx`, `shpjs`, `resolve-uri-loader`, `svg-sprite-loader` - Allow related maps UI strings to be translated. Translation support for related maps content is not included. diff --git a/buildprocess/configureWebpack.js b/buildprocess/configureWebpack.js index 964deee41f0..57978564483 100644 --- a/buildprocess/configureWebpack.js +++ b/buildprocess/configureWebpack.js @@ -32,6 +32,7 @@ function configureWebpack( ".webpack.js", ".web.js", ".js", + ".mjs", ".ts", ".tsx" ]; @@ -111,6 +112,14 @@ function configureWebpack( }) }); + // Some packages exports an .mjs file for ESM imports. + // This rule instructs webpack to import mjs modules correctly. + config.module.rules.push({ + test: /\.mjs$/, + include: /node_modules/, + type: "javascript/auto" + }); + const zipJsDir = path.dirname(require.resolve("@zip.js/zip.js/package.json")); config.module.rules.push({ diff --git a/lib/Core/ConsoleAnalytics.d.ts b/lib/Core/ConsoleAnalytics.d.ts new file mode 100644 index 00000000000..d59edf93e53 --- /dev/null +++ b/lib/Core/ConsoleAnalytics.d.ts @@ -0,0 +1,17 @@ +declare class ConsoleAnalytics { + start: ( + configParameters: Partial<{ + enableConsoleAnalytics: boolean; + googleAnalyticsKey: any; + googleAnalyticsOptions: any; + }> + ) => void; + logEvent: ( + category: string, + action: string, + label?: string, + value?: number + ) => void; +} + +export default ConsoleAnalytics; diff --git a/lib/Core/ConsoleAnalytics.js b/lib/Core/ConsoleAnalytics.js index 2a6dc4e662a..ba57a641e37 100644 --- a/lib/Core/ConsoleAnalytics.js +++ b/lib/Core/ConsoleAnalytics.js @@ -1,5 +1,3 @@ -"use strict"; - var defined = require("terriajs-cesium/Source/Core/defined").default; const i18next = require("i18next").default; @@ -49,4 +47,4 @@ ConsoleAnalytics.prototype.logEvent = function ( } }; -module.exports = ConsoleAnalytics; +export default ConsoleAnalytics; diff --git a/lib/Core/DataUri.js b/lib/Core/DataUri.ts similarity index 85% rename from lib/Core/DataUri.js rename to lib/Core/DataUri.ts index 0518ed093e8..8b8097284d0 100644 --- a/lib/Core/DataUri.js +++ b/lib/Core/DataUri.ts @@ -1,18 +1,14 @@ -"use strict"; - -var DataUri = { +export default { /** * Turn a file with the supplied type and stringified data into a data uri that can be set as the href of an anchor tag. * @param {String} type Data type, eg. 'json' or 'csv'. * @param {String} dataString The data. * @return {String} A string that can be used to in an anchor tag's 'href' attribute to represent downloadable data. */ - make: function (type, dataString) { + make: function (type: string, dataString: string): string | undefined { if (dataString) { // Using attachment/* mime type makes safari download as attachment. text/* works on Chrome (as does attachment). return "data:attachment/" + type + "," + encodeURIComponent(dataString); } } }; - -module.exports = DataUri; diff --git a/lib/Core/ServerConfig.d.ts b/lib/Core/ServerConfig.d.ts new file mode 100644 index 00000000000..7195274ec41 --- /dev/null +++ b/lib/Core/ServerConfig.d.ts @@ -0,0 +1,6 @@ +declare class ServerConfig { + config: unknown; + init(serverConfigUrl: string): Promise; +} + +export default ServerConfig; diff --git a/lib/Core/ServerConfig.js b/lib/Core/ServerConfig.js index 766d0bb136e..0d9a3b45725 100644 --- a/lib/Core/ServerConfig.js +++ b/lib/Core/ServerConfig.js @@ -1,5 +1,3 @@ -"use strict"; - const i18next = require("i18next").default; var defaultValue = require("terriajs-cesium/Source/Core/defaultValue").default; var loadJson = require("./loadJson").default; @@ -49,4 +47,4 @@ ServerConfig.prototype.init = function (serverConfigUrl) { }); }; -module.exports = ServerConfig; +export default ServerConfig; diff --git a/lib/Core/arrayContains.js b/lib/Core/arrayContains.js deleted file mode 100644 index 8930b8214ad..00000000000 --- a/lib/Core/arrayContains.js +++ /dev/null @@ -1,12 +0,0 @@ -"use strict"; - -function arrayContains(array, value) { - for (var i = 0; i < array.length; ++i) { - if (array[i] === value) { - return true; - } - } - - return false; -} -module.exports = arrayContains; diff --git a/lib/Core/containsAny.js b/lib/Core/containsAny.js deleted file mode 100644 index dac94168d30..00000000000 --- a/lib/Core/containsAny.js +++ /dev/null @@ -1,25 +0,0 @@ -"use strict"; - -var defined = require("terriajs-cesium/Source/Core/defined").default; - -/** - * Determins is a given string contains any of a number of possible strings. - * - * @param {String} s The string to test. - * @param {String[]} possibleStrings The possible strings to test `s` for. - * @return {Boolean} true if `s` contains any of the strings in `possibleStrings`; otherwise, false. - */ -var containsAny = function (s, possibleStrings) { - if (!defined(s)) { - return false; - } - - for (var i = 0; i < possibleStrings.length; ++i) { - if (s.indexOf(possibleStrings[i]) >= 0) { - return true; - } - } - return false; -}; - -module.exports = containsAny; diff --git a/lib/Core/containsAny.ts b/lib/Core/containsAny.ts new file mode 100644 index 00000000000..9c16a415932 --- /dev/null +++ b/lib/Core/containsAny.ts @@ -0,0 +1,23 @@ +import defined from "terriajs-cesium/Source/Core/defined"; + +/** + * Determins is a given string contains any of a number of possible strings. + * + * @param s The string to test. + * @param possibleStrings The possible strings to test `s` for. + * @return true if `s` contains any of the strings in `possibleStrings`; otherwise, false. + */ +const containsAny = function (s: string, possibleStrings: string[]) { + if (!defined(s)) { + return false; + } + + for (let i = 0; i < possibleStrings.length; ++i) { + if (s.indexOf(possibleStrings[i]) >= 0) { + return true; + } + } + return false; +}; + +export default containsAny; diff --git a/lib/Core/formatPropertyValue.js b/lib/Core/formatPropertyValue.ts similarity index 84% rename from lib/Core/formatPropertyValue.js rename to lib/Core/formatPropertyValue.ts index ba83320aec4..31da5c7ebe1 100644 --- a/lib/Core/formatPropertyValue.js +++ b/lib/Core/formatPropertyValue.ts @@ -1,6 +1,4 @@ -"use strict"; - -var linkifyContent = require("./linkifyContent"); +import linkifyContent from "./linkifyContent"; /** * Format the value for the description, used by the Feature Info Panel. @@ -9,7 +7,7 @@ var linkifyContent = require("./linkifyContent"); * @param {} value The value to format. * @param {Object} [options] Number formatting options, passed to Number.toLocaleString(). */ -function formatPropertyValue(value, options) { +function formatPropertyValue(value: any, options?: Intl.NumberFormatOptions) { if (typeof value === "number") { // Note we default useGrouping to false (not true) and maximumFractionDigits to 20 (not 3). return value.toLocaleString(undefined, { @@ -27,4 +25,4 @@ function formatPropertyValue(value, options) { return value; } -module.exports = formatPropertyValue; +export default formatPropertyValue; diff --git a/lib/Core/linkifyContent.js b/lib/Core/linkifyContent.ts similarity index 72% rename from lib/Core/linkifyContent.js rename to lib/Core/linkifyContent.ts index c8063ae9b8e..af31b3cccd0 100644 --- a/lib/Core/linkifyContent.js +++ b/lib/Core/linkifyContent.ts @@ -1,11 +1,11 @@ -"use strict"; +import linkifyIt from "linkify-it"; -var linkify = require("linkify-it")(); +const linkify = linkifyIt(); -function linkifyContent(content) { - var matches = linkify.match(content), - result = [], - last; +function linkifyContent(content: string) { + const matches = linkify.match(content), + result = []; + let last: number; if (matches) { last = 0; @@ -29,4 +29,4 @@ function linkifyContent(content) { return content; } -module.exports = linkifyContent; +export default linkifyContent; diff --git a/lib/Core/loadArrayBuffer.ts b/lib/Core/loadArrayBuffer.ts index 575ef970e8f..b1ca292fffa 100644 --- a/lib/Core/loadArrayBuffer.ts +++ b/lib/Core/loadArrayBuffer.ts @@ -6,5 +6,3 @@ export default function loadArrayBuffer( ): Promise { return Resource.fetchArrayBuffer({ url: urlOrResource, headers: headers })!; } - -module.exports = loadArrayBuffer; diff --git a/lib/Core/loadText.js b/lib/Core/loadText.js deleted file mode 100644 index 2c05abe1128..00000000000 --- a/lib/Core/loadText.js +++ /dev/null @@ -1,10 +0,0 @@ -const Resource = require("terriajs-cesium/Source/Core/Resource").default; - -function loadText(urlOrResource, headers) { - var resource = Resource.createIfNeeded(urlOrResource); - return resource.fetchText({ - headers: headers - }); -} - -module.exports = loadText; diff --git a/lib/Core/loadText.ts b/lib/Core/loadText.ts new file mode 100644 index 00000000000..dcf4af63aac --- /dev/null +++ b/lib/Core/loadText.ts @@ -0,0 +1,12 @@ +import Resource from "terriajs-cesium/Source/Core/Resource"; + +async function loadText(urlOrResource: string | Resource): Promise { + const resource = (Resource as any).createIfNeeded(urlOrResource) as Resource; + const response = resource.fetchText(); + if (response === undefined) { + throw new Error("Request throttled"); + } + return response; +} + +export default loadText; diff --git a/lib/Core/loadWithXhr.d.ts b/lib/Core/loadWithXhr.d.ts new file mode 100644 index 00000000000..70f42f9119c --- /dev/null +++ b/lib/Core/loadWithXhr.d.ts @@ -0,0 +1,13 @@ +import Resource from "terriajs-cesium/Source/Core/Resource"; + +interface Options extends Resource.ConstructorOptions { + responseType?: string; + headers?: any; + overrideMimeType?: string; + method?: "GET" | "POST" | "PUT"; + data?: any; +} + +declare function loadWithXhr(options: Options): Promise; + +export default loadWithXhr; diff --git a/lib/Core/loadWithXhr.js b/lib/Core/loadWithXhr.js index 668a6bab9b4..d656fe46f32 100644 --- a/lib/Core/loadWithXhr.js +++ b/lib/Core/loadWithXhr.js @@ -31,4 +31,4 @@ Object.defineProperties(loadWithXhr, { } }); -module.exports = loadWithXhr; +export default loadWithXhr; diff --git a/lib/Core/loadXML.js b/lib/Core/loadXML.ts similarity index 51% rename from lib/Core/loadXML.js rename to lib/Core/loadXML.ts index 6987ba8f0d5..863f2ab3dd0 100644 --- a/lib/Core/loadXML.js +++ b/lib/Core/loadXML.ts @@ -1,8 +1,10 @@ -const Resource = require("terriajs-cesium/Source/Core/Resource").default; +import Resource from "terriajs-cesium/Source/Core/Resource"; -async function loadXML(urlOrResource) { - var resource = Resource.createIfNeeded(urlOrResource); - const respone = await resource.fetchXML(); +async function loadXML( + urlOrResource: string | Resource +): Promise { + const resource = (Resource as any).createIfNeeded(urlOrResource) as Resource; + const response = await resource.fetchXML(); /** * Sometimes Cesium's Resource.fetchXML will return an Array Buffer (usually in Node.js env) @@ -13,17 +15,17 @@ async function loadXML(urlOrResource) { * See full license here https://github.com/fengyuanchen/is-array-buffer/blob/main/LICENSE */ if ( - respone instanceof ArrayBuffer || - toString.call(respone) === "[object ArrayBuffer]" + response instanceof ArrayBuffer || + toString.call(response) === "[object ArrayBuffer]" ) { const enc = new TextDecoder("utf-8"); - const xmlString = enc.decode(respone); + const xmlString = enc.decode(response as any); const parser = new DOMParser(); return parser.parseFromString(xmlString, "text/xml"); } - return respone; + return response; } -module.exports = loadXML; +export default loadXML; diff --git a/lib/Core/markdownToHtml.ts b/lib/Core/markdownToHtml.ts index 63e5231c452..fafb1df3a20 100644 --- a/lib/Core/markdownToHtml.ts +++ b/lib/Core/markdownToHtml.ts @@ -1,10 +1,8 @@ -"use strict"; - -const defined = require("terriajs-cesium/Source/Core/defined").default; -const MarkdownIt = require("markdown-it"); -const DOMPurify = require("dompurify/dist/purify"); -import injectTerms from "./injectTerms"; +import DOMPurify from "dompurify"; +import MarkdownIt from "markdown-it"; +import defined from "terriajs-cesium/Source/Core/defined"; import { Term } from "../ReactViewModels/defaultTerms"; +import injectTerms from "./injectTerms"; const md = new MarkdownIt({ html: true, diff --git a/lib/Core/pollToPromise.js b/lib/Core/pollToPromise.js deleted file mode 100644 index d66d1a41558..00000000000 --- a/lib/Core/pollToPromise.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; - -var defaultValue = require("terriajs-cesium/Source/Core/defaultValue").default; -var getTimestamp = require("terriajs-cesium/Source/Core/getTimestamp").default; - -var pollToPromise = function (f, options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var pollInterval = defaultValue(options.pollInterval, 1); - var timeout = defaultValue(options.timeout, 5000); - - return new Promise((resolve, reject) => { - var startTimestamp = getTimestamp(); - var endTimestamp = startTimestamp + timeout; - - function poller() { - if (f()) { - resolve(); - } else { - if (getTimestamp() > endTimestamp) { - reject(); - } else { - setTimeout(poller, pollInterval); - } - } - } - - poller(); - }); -}; - -module.exports = pollToPromise; diff --git a/lib/Core/pollToPromise.ts b/lib/Core/pollToPromise.ts new file mode 100644 index 00000000000..57efa3c01c6 --- /dev/null +++ b/lib/Core/pollToPromise.ts @@ -0,0 +1,35 @@ +import defaultValue from "terriajs-cesium/Source/Core/defaultValue"; +import getTimestamp from "terriajs-cesium/Source/Core/getTimestamp"; + +interface Options { + pollInterval?: number; + timeout?: number; +} + +const pollToPromise = function (f: () => boolean, options: Options) { + options = defaultValue(options, (defaultValue as any).EMPTY_OBJECT); + + const pollInterval = defaultValue(options.pollInterval, 1); + const timeout = defaultValue(options.timeout, 5000); + + return new Promise((resolve, reject) => { + const startTimestamp = getTimestamp(); + const endTimestamp = startTimestamp + timeout; + + function poller() { + if (f()) { + resolve(); + } else { + if (getTimestamp() > endTimestamp) { + reject(); + } else { + setTimeout(poller, pollInterval); + } + } + } + + poller(); + }); +}; + +export default pollToPromise; diff --git a/lib/Core/readJson.js b/lib/Core/readJson.ts similarity index 58% rename from lib/Core/readJson.js rename to lib/Core/readJson.ts index da1a98c7d10..672d804f268 100644 --- a/lib/Core/readJson.js +++ b/lib/Core/readJson.ts @@ -1,20 +1,19 @@ -"use strict"; - -const json5 = require("json5"); -const readText = require("./readText"); +import json5 from "json5"; +import { JsonObject } from "./Json"; +import readText from "./readText"; /** * Try to read the file as JSON. If that fails, try JSON5. * @param {File} file The file. * @return {Promise} The JSON or json5 object described by the file. */ -function readJson(file) { +function readJson(file: Blob): Promise { return readText(file).then((s) => { try { - return JSON.parse(s); + return JSON.parse(s!); } catch (e) { if (e instanceof SyntaxError) { - return json5.parse(s); + return json5.parse(s!); } else { throw e; } @@ -22,4 +21,4 @@ function readJson(file) { }); } -module.exports = readJson; +export default readJson; diff --git a/lib/Core/readText.js b/lib/Core/readText.ts similarity index 53% rename from lib/Core/readText.js rename to lib/Core/readText.ts index fc85b495436..622362de8f0 100644 --- a/lib/Core/readText.js +++ b/lib/Core/readText.ts @@ -1,10 +1,7 @@ -"use strict"; -const i18next = require("i18next").default; +import i18next from "i18next"; +import DeveloperError from "terriajs-cesium/Source/Core/DeveloperError"; -const DeveloperError = - require("terriajs-cesium/Source/Core/DeveloperError").default; - -function readText(file) { +function readText(file: Blob): Promise { return new Promise((resolve, reject) => { if (typeof file === "undefined") { throw new DeveloperError(i18next.t("core.readText.fileRequired")); @@ -14,8 +11,8 @@ function readText(file) { reader.readAsText(file); reader.onload = function (event) { - const allText = event.target.result; - resolve(allText); + const allText = event.target?.result; + resolve((allText ?? undefined) as string | undefined); }; reader.onerror = function (e) { reject(e); @@ -23,4 +20,4 @@ function readText(file) { }); } -module.exports = readText; +export default readText; diff --git a/lib/Core/readXml.js b/lib/Core/readXml.js deleted file mode 100644 index c21fb7264be..00000000000 --- a/lib/Core/readXml.js +++ /dev/null @@ -1,28 +0,0 @@ -"use strict"; - -const i18next = require("i18next").default; -var readText = require("./readText"); - -var RuntimeError = require("terriajs-cesium/Source/Core/RuntimeError").default; - -var parser; - -function readXml(file) { - return readText(file).then(function (result) { - if (!parser) { - parser = new DOMParser(); - } - - var xml = parser.parseFromString(result, "application/xml"); - if ( - !xml || - !xml.documentElement || - xml.getElementsByTagName("parsererror").length > 0 - ) { - throw new RuntimeError(i18next.t("core.readXml.xmlError")); - } - return xml; - }); -} - -module.exports = readXml; diff --git a/lib/Core/readXml.ts b/lib/Core/readXml.ts new file mode 100644 index 00000000000..c2816aeeaa2 --- /dev/null +++ b/lib/Core/readXml.ts @@ -0,0 +1,28 @@ +import i18next from "i18next"; +import readText from "./readText"; +import RuntimeError from "terriajs-cesium/Source/Core/RuntimeError"; + +let parser: DOMParser; + +function readXml(file: Blob) { + return readText(file).then(function (result) { + if (!parser) { + parser = new DOMParser(); + } + + if (!result) { + return undefined; + } + const xml = parser.parseFromString(result, "application/xml"); + if ( + !xml || + !xml.documentElement || + xml.getElementsByTagName("parsererror").length > 0 + ) { + throw new RuntimeError(i18next.t("core.readXml.xmlError")); + } + return xml; + }); +} + +export default readXml; diff --git a/lib/Core/replaceUnderscores.js b/lib/Core/replaceUnderscores.js deleted file mode 100644 index e6e500ff6fd..00000000000 --- a/lib/Core/replaceUnderscores.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -/** - * Replace all underscores in the string with spaces. If the argument is not a string, return it unchanged. - * @param {} string The string to replace. If the argument is not a string, does nothing. - * @return {} The argument with all underscores replaced with spaces. If the argument is not a string, returns the argument unchanged. - */ -function replaceUnderscores(string) { - if (typeof string === "string" || string instanceof String) { - return string.replace(/_/g, " "); - } - return string; -} - -module.exports = replaceUnderscores; diff --git a/lib/Core/replaceUnderscores.ts b/lib/Core/replaceUnderscores.ts new file mode 100644 index 00000000000..c8772e389fa --- /dev/null +++ b/lib/Core/replaceUnderscores.ts @@ -0,0 +1,12 @@ +/** + * Replace all underscores in the string with spaces. If the argument is not a string, return it unchanged. + * @param string The string to replace. If the argument is not a string, does nothing. + * @return The argument with all underscores replaced with spaces. If the argument is not a string, returns the argument unchanged. + */ +function replaceUnderscores(str: any): typeof str { + return typeof str === "string" || str instanceof String + ? str.replace(/_/g, " ") + : str; +} + +export default replaceUnderscores; diff --git a/lib/Core/triggerResize.js b/lib/Core/triggerResize.ts similarity index 61% rename from lib/Core/triggerResize.js rename to lib/Core/triggerResize.ts index 664226ddf15..017b57f0399 100644 --- a/lib/Core/triggerResize.js +++ b/lib/Core/triggerResize.ts @@ -1,16 +1,12 @@ -"use strict"; - /** * Trigger a window resize event. */ -function triggerResize() { +export default function triggerResize() { try { window.dispatchEvent(new Event("resize")); } catch (e) { - var evt = window.document.createEvent("UIEvents"); + const evt = window.document.createEvent("UIEvents"); evt.initUIEvent("resize", true, false, window, 0); window.dispatchEvent(evt); } } - -module.exports = triggerResize; diff --git a/lib/Map/DragPoints/DragPoints.d.ts b/lib/Map/DragPoints/DragPoints.d.ts new file mode 100644 index 00000000000..a450bdb86c1 --- /dev/null +++ b/lib/Map/DragPoints/DragPoints.d.ts @@ -0,0 +1,17 @@ +import CustomDataSource from "terriajs-cesium/Source/DataSources/CustomDataSource"; +import Terria from "../../Models/Terria"; + +declare class DragPoints { + constructor( + terria: Terria, + pointMovedCallback: (draggableObjects: CustomDataSource) => void + ); + + setUp(): void; + updateDraggableObjects(draggableObjects: CustomDataSource): void; + getDragCount(): number; + resetDragCount(): void; + destroy(): void; +} + +export default DragPoints; diff --git a/lib/Map/DragPoints/DragPoints.js b/lib/Map/DragPoints/DragPoints.js index fc50c39646b..0062d4b6c97 100644 --- a/lib/Map/DragPoints/DragPoints.js +++ b/lib/Map/DragPoints/DragPoints.js @@ -1,5 +1,3 @@ -"use strict"; - var defined = require("terriajs-cesium/Source/Core/defined").default; var CesiumDragPoints = require("./CesiumDragPoints"); var LeafletDragPoints = require("./LeafletDragPoints"); @@ -99,4 +97,4 @@ DragPoints.prototype._createDragPointsHelper = function (pointMovedCallback) { } }; -module.exports = DragPoints; +export default DragPoints; diff --git a/lib/Map/LeafletPatched.js b/lib/Map/LeafletPatched.ts similarity index 90% rename from lib/Map/LeafletPatched.js rename to lib/Map/LeafletPatched.ts index 4583f16674e..55062c0e9d0 100644 --- a/lib/Map/LeafletPatched.js +++ b/lib/Map/LeafletPatched.ts @@ -3,7 +3,8 @@ import L from "leaflet"; // Function taken from Leaflet 1.0.1 (https://github.com/Leaflet/Leaflet/blob/v1.0.1/src/layer/vector/Canvas.js#L254-L267) // Leaflet 1.0.2 and later don't trigger click events for every Path, so feature selection only gives 1 result. // Updated to incorporate function changes up to v1.7.1 -L.Canvas.prototype._onClick = function (e) { +const Canvas = L.Canvas as any; +Canvas.prototype._onClick = function (e: any) { const point = this._map.mouseEventToLayerPoint(e); const layers = []; for (let order = this._drawFirst; order; order = order.next) { diff --git a/lib/Map/Vector/EarthGravityModel1996.d.ts b/lib/Map/Vector/EarthGravityModel1996.d.ts new file mode 100644 index 00000000000..d894292d80c --- /dev/null +++ b/lib/Map/Vector/EarthGravityModel1996.d.ts @@ -0,0 +1,10 @@ +declare class EarthGravityModel1996 { + readonly minimumHeight: number; + readonly maximumHeight: number; + + constructor(gridFileUrl: string); + + getHeight(longitude: number, latitude: number): Promise; +} + +export default EarthGravityModel1996; diff --git a/lib/Map/Vector/EarthGravityModel1996.js b/lib/Map/Vector/EarthGravityModel1996.js index 01d75defd56..cd301cff88b 100644 --- a/lib/Map/Vector/EarthGravityModel1996.js +++ b/lib/Map/Vector/EarthGravityModel1996.js @@ -2,7 +2,7 @@ var CesiumMath = require("terriajs-cesium/Source/Core/Math").default; var defined = require("terriajs-cesium/Source/Core/defined").default; -var loadArrayBuffer = require("../../Core/loadArrayBuffer"); +var loadArrayBuffer = require("../../Core/loadArrayBuffer").default; /** * The Earth Gravity Model 1996 (EGM96) geoid. diff --git a/lib/Map/Vector/Reproject.ts b/lib/Map/Vector/Reproject.ts index b883042f591..51e505fd528 100644 --- a/lib/Map/Vector/Reproject.ts +++ b/lib/Map/Vector/Reproject.ts @@ -1,9 +1,8 @@ +import proj4 from "proj4"; import defined from "terriajs-cesium/Source/Core/defined"; -import Proj4Definitions from "./Proj4Definitions"; import urijs from "urijs"; - -const proj4 = require("proj4").default; -const loadText = require("../../Core/loadText"); +import loadText from "../../Core/loadText"; +import Proj4Definitions from "./Proj4Definitions"; export default { TERRIA_CRS: "EPSG:4326", @@ -60,16 +59,21 @@ export default { ): [number, number] | undefined { const source = sourceCode in Proj4Definitions - ? new proj4.Proj(Proj4Definitions[sourceCode]) + ? proj4.Proj(Proj4Definitions[sourceCode]) : undefined; const dest = destCode in Proj4Definitions - ? new proj4.Proj(Proj4Definitions[destCode]) + ? proj4.Proj(Proj4Definitions[destCode]) : undefined; - if (!sourceCode || !destCode) { + if (!source || !dest) { return; } - return proj4(source, dest, coordinates); + const result = proj4.transform(source, dest, coordinates) ?? {}; + if (result) { + const { x, y } = result; + return [x, y]; + } + return undefined; }, /** diff --git a/lib/ModelMixins/XmlRequestMixin.ts b/lib/ModelMixins/XmlRequestMixin.ts index 6bd29d3c32a..5f64e01a919 100644 --- a/lib/ModelMixins/XmlRequestMixin.ts +++ b/lib/ModelMixins/XmlRequestMixin.ts @@ -1,9 +1,8 @@ import URI from "urijs"; import AbstractConstructor from "../Core/AbstractConstructor"; import isDefined from "../Core/isDefined"; - -const loadXML = require("../Core/loadXML"); -const loadWithXhr = require("../Core/loadWithXhr"); +import loadWithXhr from "../Core/loadWithXhr"; +import loadXML from "../Core/loadXML"; export default function XmlRequestMixin>( Base: T diff --git a/lib/Models/Catalog/CatalogItems/KmlCatalogItem.ts b/lib/Models/Catalog/CatalogItems/KmlCatalogItem.ts index 8d7cc0e0e30..170bf30c9fe 100644 --- a/lib/Models/Catalog/CatalogItems/KmlCatalogItem.ts +++ b/lib/Models/Catalog/CatalogItems/KmlCatalogItem.ts @@ -63,28 +63,30 @@ class KmlCatalogItem } protected forceLoadMapItems(): Promise { - return new Promise((resolve) => { - if (isDefined(this.kmlString)) { - const parser = new DOMParser(); - resolve(parser.parseFromString(this.kmlString, "text/xml")); - } else if (isDefined(this._kmlFile)) { - if (this._kmlFile.name && this._kmlFile.name.match(kmzRegex)) { - resolve(this._kmlFile); + return new Promise( + (resolve) => { + if (isDefined(this.kmlString)) { + const parser = new DOMParser(); + resolve(parser.parseFromString(this.kmlString, "text/xml")); + } else if (isDefined(this._kmlFile)) { + if (this._kmlFile.name && this._kmlFile.name.match(kmzRegex)) { + resolve(this._kmlFile); + } else { + resolve(readXml(this._kmlFile)); + } + } else if (isDefined(this.url)) { + resolve(proxyCatalogItemUrl(this, this.url)); } else { - resolve(readXml(this._kmlFile)); + throw networkRequestError({ + sender: this, + title: i18next.t("models.kml.unableToLoadItemTitle"), + message: i18next.t("models.kml.unableToLoadItemMessage") + }); } - } else if (isDefined(this.url)) { - resolve(proxyCatalogItemUrl(this, this.url)); - } else { - throw networkRequestError({ - sender: this, - title: i18next.t("models.kml.unableToLoadItemTitle"), - message: i18next.t("models.kml.unableToLoadItemMessage") - }); } - }) + ) .then((kmlLoadInput) => { - return KmlDataSource.load(kmlLoadInput); + return KmlDataSource.load(kmlLoadInput!); }) .then((dataSource) => { this._dataSource = dataSource; diff --git a/lib/Models/Catalog/Esri/ArcGisMapServerCatalogItem.ts b/lib/Models/Catalog/Esri/ArcGisMapServerCatalogItem.ts index b91a6c9003f..ff0e1880a8b 100644 --- a/lib/Models/Catalog/Esri/ArcGisMapServerCatalogItem.ts +++ b/lib/Models/Catalog/Esri/ArcGisMapServerCatalogItem.ts @@ -88,7 +88,7 @@ class MapServerStratum extends LoadableStratum( } static async load(item: ArcGisMapServerCatalogItem) { - if (!isDefined(item.uri)) { + if (!isDefined(item.uri) || !isDefined(item.url)) { throw new TerriaError({ title: i18next.t("models.arcGisMapServerCatalogItem.invalidUrlTitle"), message: i18next.t( diff --git a/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts b/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts index 1c567135c27..8b4e10ada75 100644 --- a/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts +++ b/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts @@ -163,7 +163,7 @@ export default class WebMapServiceCapabilities { createTransformer((url: string) => { return Promise.resolve(loadXML(url)).then(function (capabilitiesXml) { const json = xml2json(capabilitiesXml); - if (!defined(json.Capability)) { + if (!capabilitiesXml || !defined(json.Capability)) { throw networkRequestError({ title: "Invalid GetCapabilities", message: diff --git a/lib/Models/Catalog/Ows/WebMapTileServiceCapabilities.ts b/lib/Models/Catalog/Ows/WebMapTileServiceCapabilities.ts index 4c494292f84..18cb04ff5aa 100644 --- a/lib/Models/Catalog/Ows/WebMapTileServiceCapabilities.ts +++ b/lib/Models/Catalog/Ows/WebMapTileServiceCapabilities.ts @@ -131,7 +131,7 @@ export default class WebMapTileServiceCapabilities { createTransformer((url: string) => { return Promise.resolve(loadXML(url)).then(function (capabilitiesXml) { const json = xml2json(capabilitiesXml); - if (!defined(json.ServiceIdentification)) { + if (!capabilitiesXml || !defined(json.ServiceIdentification)) { throw networkRequestError({ title: i18next.t( "models.webMapTileServiceCatalogGroup.invalidCapabilitiesTitle" diff --git a/lib/Models/Catalog/Ows/WebProcessingServiceCapabilities.ts b/lib/Models/Catalog/Ows/WebProcessingServiceCapabilities.ts index 0f30e1e2bda..16a9e7f7933 100644 --- a/lib/Models/Catalog/Ows/WebProcessingServiceCapabilities.ts +++ b/lib/Models/Catalog/Ows/WebProcessingServiceCapabilities.ts @@ -54,7 +54,7 @@ export interface ServiceProvider { export default class WebProcessingServiceCapabilities { constructor( - readonly capabilitiesXml: string, + readonly capabilitiesXml: XMLDocument, readonly capabilities: Capabilities ) {} @@ -62,7 +62,7 @@ export default class WebProcessingServiceCapabilities { return Promise.resolve(loadXML(url)).then(function (capabilitiesXml) { const capabilities = parseCapabilities(xml2json(capabilitiesXml)); - if (capabilities === undefined) { + if (capabilitiesXml === undefined || capabilities === undefined) { throw networkRequestError({ title: i18next.t( "models.webProcessingServiceCatalogGroup.invalidCapabilitiesTitle" diff --git a/lib/Models/Catalog/Ows/WebProcessingServiceCatalogFunctionJob.ts b/lib/Models/Catalog/Ows/WebProcessingServiceCatalogFunctionJob.ts index c3eafa7feca..ed9ae07b63e 100644 --- a/lib/Models/Catalog/Ows/WebProcessingServiceCatalogFunctionJob.ts +++ b/lib/Models/Catalog/Ows/WebProcessingServiceCatalogFunctionJob.ts @@ -3,17 +3,17 @@ import { action, computed, isObservableArray, + makeObservable, observable, + override, runInAction, - toJS, - makeObservable, - override + toJS } from "mobx"; import Mustache from "mustache"; import URI from "urijs"; -import isDefined from "../../../Core/isDefined"; import { JsonObject } from "../../../Core/Json"; import TerriaError from "../../../Core/TerriaError"; +import isDefined from "../../../Core/isDefined"; import CatalogFunctionJobMixin from "../../../ModelMixins/CatalogFunctionJobMixin"; import CatalogMemberMixin from "../../../ModelMixins/CatalogMemberMixin"; import XmlRequestMixin from "../../../ModelMixins/XmlRequestMixin"; @@ -23,16 +23,15 @@ import { FeatureInfoTemplateTraits } from "../../../Traits/TraitsClasses/Feature import WebProcessingServiceCatalogFunctionJobTraits from "../../../Traits/TraitsClasses/WebProcessingServiceCatalogFunctionJobTraits"; import CommonStrata from "../../Definition/CommonStrata"; import CreateModel from "../../Definition/CreateModel"; -import createStratumInstance from "../../Definition/createStratumInstance"; import LoadableStratum from "../../Definition/LoadableStratum"; -import { BaseModel } from "../../Definition/Model"; +import { BaseModel, ModelConstructorParameters } from "../../Definition/Model"; import StratumFromTraits from "../../Definition/StratumFromTraits"; import StratumOrder from "../../Definition/StratumOrder"; +import createStratumInstance from "../../Definition/createStratumInstance"; import updateModelFromJson from "../../Definition/updateModelFromJson"; import upsertModelFromJson from "../../Definition/upsertModelFromJson"; import GeoJsonCatalogItem from "../CatalogItems/GeoJsonCatalogItem"; import CatalogMemberFactory from "../CatalogMemberFactory"; -import { ModelConstructorParameters } from "../../Definition/Model"; import proxyCatalogItemUrl from "../proxyCatalogItemUrl"; const executeWpsTemplate = require("./ExecuteWpsTemplate.xml"); diff --git a/lib/Models/Feature/Feature.ts b/lib/Models/Feature/Feature.ts index a149bf0c1ff..fceaf85c047 100644 --- a/lib/Models/Feature/Feature.ts +++ b/lib/Models/Feature/Feature.ts @@ -108,5 +108,3 @@ function addCustomFeatureProperties(entity: Entity) { } } } - -module.exports = TerriaFeature; diff --git a/lib/Models/Feature/ImageryLayerFeatureInfo.js b/lib/Models/Feature/ImageryLayerFeatureInfo.ts similarity index 65% rename from lib/Models/Feature/ImageryLayerFeatureInfo.js rename to lib/Models/Feature/ImageryLayerFeatureInfo.ts index e9a9b84d4fe..eb42f051eff 100644 --- a/lib/Models/Feature/ImageryLayerFeatureInfo.js +++ b/lib/Models/Feature/ImageryLayerFeatureInfo.ts @@ -1,10 +1,6 @@ -"use strict"; - -var ImageryLayerFeatureInfo = - require("terriajs-cesium/Source/Scene/ImageryLayerFeatureInfo").default; -var defined = require("terriajs-cesium/Source/Core/defined").default; - -var formatPropertyValue = require("../../Core/formatPropertyValue"); +import defined from "terriajs-cesium/Source/Core/defined"; +import ImageryLayerFeatureInfo from "terriajs-cesium/Source/Scene/ImageryLayerFeatureInfo"; +import formatPropertyValue from "../../Core/formatPropertyValue"; /** * Configures the description of this feature by creating an HTML table of properties and their values. @@ -12,12 +8,12 @@ var formatPropertyValue = require("../../Core/formatPropertyValue"); * @param {Object} properties An object literal containing the properties of the feature. */ ImageryLayerFeatureInfo.prototype.configureDescriptionFromProperties = - function (properties) { - function describe(properties) { - var html = ''; - for (var key in properties) { + function (properties: any) { + function describe(properties: any) { + let html = '
'; + for (const key in properties) { if (Object.prototype.hasOwnProperty.call(properties, key)) { - var value = properties[key]; + const value = properties[key]; if (defined(value)) { if (typeof value === "object") { html += diff --git a/lib/Models/GlobeOrMap.ts b/lib/Models/GlobeOrMap.ts index a50b43e2874..0cf40450d13 100644 --- a/lib/Models/GlobeOrMap.ts +++ b/lib/Models/GlobeOrMap.ts @@ -33,7 +33,7 @@ import createStratumInstance from "./Definition/createStratumInstance"; import TerriaFeature from "./Feature/Feature"; import Terria from "./Terria"; -require("./Feature/ImageryLayerFeatureInfo"); // overrides Cesium's prototype.configureDescriptionFromProperties +import "./Feature/ImageryLayerFeatureInfo"; // overrides Cesium's prototype.configureDescriptionFromProperties export default abstract class GlobeOrMap { abstract readonly type: string; diff --git a/lib/Models/ItemSearchProviders/TextIndex.ts b/lib/Models/ItemSearchProviders/TextIndex.ts index 39dead55b13..88895e3c317 100644 --- a/lib/Models/ItemSearchProviders/TextIndex.ts +++ b/lib/Models/ItemSearchProviders/TextIndex.ts @@ -1,8 +1,7 @@ import MiniSearch, { Options as MiniSearchOptions } from "minisearch"; -import joinUrl from "./joinUrl"; +import loadText from "../../Core/loadText"; import { IndexBase, IndexType } from "./Types"; - -const loadText = require("../../Core/loadText"); +import joinUrl from "./joinUrl"; // Text search query type TextSearchQuery = string; diff --git a/lib/Models/LocationMarkerUtils.ts b/lib/Models/LocationMarkerUtils.ts index d6c93ba9df4..d7eee1871ca 100644 --- a/lib/Models/LocationMarkerUtils.ts +++ b/lib/Models/LocationMarkerUtils.ts @@ -1,5 +1,4 @@ import i18next from "i18next"; -import markerIcon from "./markerIcon"; import prettifyCoordinates from "../Map/Vector/prettifyCoordinates"; import CommonStrata from "./Definition/CommonStrata"; import CzmlCatalogItem from "./Catalog/CatalogItems/CzmlCatalogItem"; @@ -7,6 +6,9 @@ import Terria from "./Terria"; import LatLonHeight from "../Core/LatLonHeight"; import { toJS } from "mobx"; +// @ts-expect-error +import markerIcon from "../../wwwroot/images/map-pin.png"; + export const LOCATION_MARKER_DATA_SOURCE_NAME = "TerriaJS Location Marker Points"; export const MARKER_UNIQUE_ID = "__TERRRIAJS-LOCATIONMARKER__"; diff --git a/lib/Models/ShareDataService.ts b/lib/Models/ShareDataService.ts index 6162148eb40..eae9fb1e3fc 100644 --- a/lib/Models/ShareDataService.ts +++ b/lib/Models/ShareDataService.ts @@ -58,7 +58,7 @@ export default class ShareDataService { try { const result = await loadWithXhr({ - url: this.url, + url: this.url!, method: "POST", data: JSON.stringify(shareData), headers: { "Content-Type": "application/json" }, diff --git a/lib/Models/getToken.js b/lib/Models/getToken.ts similarity index 75% rename from lib/Models/getToken.js rename to lib/Models/getToken.ts index 41c0539cf55..7f792bb51a7 100644 --- a/lib/Models/getToken.js +++ b/lib/Models/getToken.ts @@ -1,12 +1,13 @@ -const defined = require("terriajs-cesium/Source/Core/defined").default; -const loadWithXhr = require("../Core/loadWithXhr"); -const TerriaError = require("../Core/TerriaError").default; -var i18next = require("i18next").default; +import defined from "terriajs-cesium/Source/Core/defined"; +import loadWithXhr from "../Core/loadWithXhr"; +import TerriaError from "../Core/TerriaError"; +import i18next from "i18next"; +import Terria from "./Terria"; -function getToken(terria, tokenUrl, url) { +function getToken(terria: Terria, tokenUrl: string, url: string) { const options = { url: tokenUrl, - method: "POST", + method: "POST" as const, headers: { "Content-Type": "application/json" }, data: JSON.stringify({ url: url @@ -48,4 +49,4 @@ function getToken(terria, tokenUrl, url) { }); } -module.exports = getToken; +export default getToken; diff --git a/lib/Models/markerIcon.js b/lib/Models/markerIcon.js deleted file mode 100644 index 34a51c1c210..00000000000 --- a/lib/Models/markerIcon.js +++ /dev/null @@ -1,2 +0,0 @@ -import markerIcon from "../../wwwroot/images/map-pin.png"; -export default markerIcon; diff --git a/lib/Models/sendFeedback.ts b/lib/Models/sendFeedback.ts index 60bbf6016f7..3338a5522b3 100644 --- a/lib/Models/sendFeedback.ts +++ b/lib/Models/sendFeedback.ts @@ -28,6 +28,7 @@ export default function sendFeedback(options: { raiseError(terria, "`terria.configParameters.feedbackUrl` is not defined"); return; } + const feedbackUrl = terria.configParameters.feedbackUrl; const shareLinkPromise = options.sendShareURL ? canShorten(terria) @@ -56,7 +57,7 @@ export default function sendFeedback(options: { ); } return loadWithXhr({ - url: terria.configParameters.feedbackUrl, + url: feedbackUrl, responseType: "json", method: "POST", data: JSON.stringify(feedbackData), diff --git a/lib/ReactViewModels/DisclaimerHandler.js b/lib/ReactViewModels/DisclaimerHandler.js deleted file mode 100644 index 1ce8eec8111..00000000000 --- a/lib/ReactViewModels/DisclaimerHandler.js +++ /dev/null @@ -1,135 +0,0 @@ -"use strict"; - -import defined from "terriajs-cesium/Source/Core/defined"; -import combine from "terriajs-cesium/Source/Core/combine"; - -/** - * Shows disclaimers for {@link CatalogItem}s that are dispatched through {@link Terria#disclaimerEvent} - ensures that - * disclaimers that share the same key (as specified in {@link CatalogItem#initialMessage#key}) are only ever displayed - * once per key - if a single disclaimer is triggered 3 different times, for instance, one disclaimer popup will be - * displayed, and then once that disclaimer is accepted, the callbacks for all three {@Terria#disclaimerEvent} will be - * executed. This response will be persisted in localStorage so that subsequent calls to {@Terria#disclaimerEvent} do - * not display any disclaimer and have their successCallback executed immediately. - * - * Also accepts disclaimers with no key, which will always be displayed, and disclaimers with no need for confirmation - * (as specified by {@link CatalogItem#initialMessage#confirmation}), which will have their successCallback executed - * immediately as the message is shown. - * - * Note that this is not for displaying a general disclaimer on startup. - * - * @param terria The {@link Terria} instance to use. - * @param viewState the viewstate to manipulate in order to display notifications. - * @constructor - */ -export default class DisclaimerHandler { - constructor(terria, viewState) { - this.terria = terria; - this.viewState = viewState; - this._pending = {}; - - this.terria.disclaimerListener = this._handleInitialMessage.bind(this); - } - - dispose() { - this.terria.disclaimerListener = undefined; - } - - /** - * Handles the {@Terria#disclaimerEvent} being raised. Only one disclaimer will be shown for each catalogItem with the - * same {@link CatalogItem#initialMessage#key}, but all calls will have their successCallback executed when it's - * accepted. - * - * @param catalogItem The catalog item to display a disclaimer for. - * @param successCallback A callback to execute once the disclaimer is accepted. - * @private - */ - _handleInitialMessage(catalogItem, successCallback) { - var keySpecified = defined(catalogItem.initialMessage.key); - if ( - keySpecified && - this.terria.getLocalProperty(catalogItem.initialMessage.key) - ) { - successCallback(); - return; - } - - if (catalogItem.initialMessage.confirmation) { - if (keySpecified) { - var key = catalogItem.initialMessage.key; - - if (defined(this._pending[key])) { - this._pending[key].push(successCallback); - } else { - this._pending[key] = [successCallback]; - this._openConfirmationModal( - catalogItem, - this._executeCallbacksForKey.bind(this, key) - ); - } - } else { - this._openConfirmationModal(catalogItem, successCallback); - } - } else { - if (keySpecified) { - this.terria.setLocalProperty(catalogItem.initialMessage.key, true); - } - this._openNotificationModel(catalogItem); - successCallback(); - } - } - - /** - * Opens a confirmation modal for the specified {@link CatalogItem}. - * - * @param catalogItem The catalog item to get disclaimer details from. - * @param callback The callback to execute when the modal is dismissed. - * @private - */ - _openConfirmationModal(catalogItem, callback) { - this.viewState.terria.notificationState.addNotificationToQueue( - combine( - { - confirmAction: callback - }, - DisclaimerHandler._generateOptions(catalogItem) - ) - ); - } - - _openNotificationModel(catalogItem) { - this.viewState.terria.notificationState.addNotificationToQueue( - DisclaimerHandler._generateOptions(catalogItem) - ); - } - - /** - * Executes all the callbacks stored in {@link DisclaimerHandler#pending} for the specified key, and clears that key - * in pending. - * - * @param key The key to get callbacks from. - * @private - */ - _executeCallbacksForKey(key) { - (this._pending[key] || []).forEach(function (cb) { - cb(); - }); - this._pending[key] = undefined; - this.terria.setLocalProperty(key, true); - } - - /** - * Generates options for {@link PopupMessageConfirmationViewModel} and {@link PopupMessageViewModel} for a - * {@link CatalogItem} - * @returns {{title: string, message: string, width: number, height: number, confirmText: string}} - * @private - */ - static _generateOptions(catalogItem) { - return { - title: catalogItem.initialMessage.title, - message: catalogItem.initialMessage.content, - confirmText: catalogItem.initialMessage.confirmText, - width: catalogItem.initialMessage.width, - height: catalogItem.initialMessage.height - }; - } -} diff --git a/lib/ReactViewModels/MouseCoords.ts b/lib/ReactViewModels/MouseCoords.ts index 86e2fcf52ca..3142d87e713 100644 --- a/lib/ReactViewModels/MouseCoords.ts +++ b/lib/ReactViewModels/MouseCoords.ts @@ -9,21 +9,14 @@ import Intersections2D from "terriajs-cesium/Source/Core/Intersections2D"; import CesiumMath from "terriajs-cesium/Source/Core/Math"; import Ray from "terriajs-cesium/Source/Core/Ray"; import TerrainProvider from "terriajs-cesium/Source/Core/TerrainProvider"; +import sampleTerrainMostDetailed from "terriajs-cesium/Source/Core/sampleTerrainMostDetailed"; import isDefined from "../Core/isDefined"; -import JSEarthGravityModel1996 from "../Map/Vector/EarthGravityModel1996"; import pickTriangle, { PickTriangleResult } from "../Map/Cesium/pickTriangle"; +import EarthGravityModel1996 from "../Map/Vector/EarthGravityModel1996"; import prettifyCoordinates from "../Map/Vector/prettifyCoordinates"; import prettifyProjection from "../Map/Vector/prettifyProjection"; import Terria from "../Models/Terria"; -// TypeScript 3.6.3 can't tell JSEarthGravityModel1996 is a class and reports -// Cannot use namespace 'JSEarthGravityModel1996' as a type.ts(2709) -// This is a dodgy workaround. -class EarthGravityModel1996 extends JSEarthGravityModel1996 {} - -const sampleTerrainMostDetailed = - require("terriajs-cesium/Source/Core/sampleTerrainMostDetailed").default; - interface Cancelable { cancel: () => void; } diff --git a/lib/ReactViewModels/ViewState.ts b/lib/ReactViewModels/ViewState.ts index 77a1975d62c..eb36fd265a0 100644 --- a/lib/ReactViewModels/ViewState.ts +++ b/lib/ReactViewModels/ViewState.ts @@ -36,7 +36,6 @@ import { RelativePosition, TourPoint } from "./defaultTourPoints"; -import DisclaimerHandler from "./DisclaimerHandler"; import SearchState from "./SearchState"; import CatalogSearchProviderMixin from "../ModelMixins/SearchProviders/CatalogSearchProviderMixin"; import { getMarkerCatalogItem } from "../Models/LocationMarkerUtils"; @@ -373,7 +372,6 @@ export default class ViewState { private _locationMarkerSubscription: IReactionDisposer; private _workbenchHasTimeWMSSubscription: IReactionDisposer; private _storyBeforeUnloadSubscription: IReactionDisposer; - private _disclaimerHandler: DisclaimerHandler; constructor(options: ViewStateOptions) { makeObservable(this); @@ -449,8 +447,6 @@ export default class ViewState { } ); - this._disclaimerHandler = new DisclaimerHandler(terria, this); - this._workbenchHasTimeWMSSubscription = reaction( () => this.terria.workbench.hasTimeWMS, (hasTimeWMS: boolean) => { @@ -540,7 +536,6 @@ export default class ViewState { this._previewedItemIdSubscription(); this._workbenchHasTimeWMSSubscription(); this._locationMarkerSubscription(); - this._disclaimerHandler.dispose(); this.searchState.dispose(); } diff --git a/lib/ReactViews/BottomDock/Timeline/DateFormats.js b/lib/ReactViews/BottomDock/Timeline/DateFormats.ts similarity index 53% rename from lib/ReactViews/BottomDock/Timeline/DateFormats.js rename to lib/ReactViews/BottomDock/Timeline/DateFormats.ts index a8558cf95d4..0026ddc799d 100644 --- a/lib/ReactViews/BottomDock/Timeline/DateFormats.js +++ b/lib/ReactViews/BottomDock/Timeline/DateFormats.ts @@ -1,15 +1,13 @@ -"use strict"; - import defined from "terriajs-cesium/Source/Core/defined"; /** * Formats a date according to the locale if provided, otherwise in a dd/mm/yyyy format. * - * @param {Date} d the date to format - * @param {Locale} [locale] the locale to use for formatting - * @returns {string} A formatted date. + * @param d the date to format + * @param locale the locale to use for formatting + * @returns A formatted date. */ -export function formatDate(d, locale) { +export function formatDate(d: Date, locale?: string): string { if (defined(locale)) { return d.toLocaleDateString(locale); } @@ -19,11 +17,11 @@ export function formatDate(d, locale) { /** * Formats the time according to the locale if provided, otherwise in a hh:mm:ss format. * - * @param {Date} d the date to format - * @param {Locale} [locale] the locale to use for formatting - * @returns {string} A formatted time. + * @param d the date to format + * @param locale the locale to use for formatting + * @returns A formatted time. */ -export function formatTime(d, locale) { +export function formatTime(d: Date, locale?: string): string { if (defined(locale)) { return d.toLocaleTimeString(locale); } @@ -35,20 +33,20 @@ export function formatTime(d, locale) { /** * Combines {@link #formatDate} and {@link #formatTime}. * - * @param {Date} d the date to format - * @param {Locale} [locale] the locale to use for formatting - * @returns {string} A formatted date and time with a comma separating them. + * @param d the date to format + * @param locale the locale to use for formatting + * @returns A formatted date and time with a comma separating them. */ -export function formatDateTime(d, locale) { +export function formatDateTime(d: Date, locale?: string): string { return formatDate(d, locale) + ", " + formatTime(d, locale); } /** * Puts a leading 0 in front of a number of it's less than 10. * - * @param {number} s A number to pad - * @returns {string} A string representing a two-digit number. + * @param s A number to pad + * @returns A string representing a two-digit number. */ -function pad(s) { +function pad(s: number): string { return s < 10 ? "0" + s : `${s}`; } diff --git a/lib/ReactViews/BottomDock/Timeline/Timeline.d.ts b/lib/ReactViews/BottomDock/Timeline/Timeline.d.ts new file mode 100644 index 00000000000..8cd8b6c80c0 --- /dev/null +++ b/lib/ReactViews/BottomDock/Timeline/Timeline.d.ts @@ -0,0 +1,13 @@ +import React from "react"; +import IElementConfig from "../../../Models/IElementConfig"; +import Terria from "../../../Models/Terria"; + +interface PropsType { + terria: Terria; + locale?: unknown; + elementConfig?: IElementConfig; +} + +declare class Timeline extends React.Component {} + +export default Timeline; diff --git a/lib/ReactViews/Custom/Chart/ChartPanel.d.ts b/lib/ReactViews/Custom/Chart/ChartPanel.d.ts new file mode 100644 index 00000000000..0a109cc8c95 --- /dev/null +++ b/lib/ReactViews/Custom/Chart/ChartPanel.d.ts @@ -0,0 +1,12 @@ +import React from "react"; +import Terria from "../../../Models/Terria"; +import ViewState from "../../../ReactViewModels/ViewState"; + +interface PropsType { + viewState: ViewState; + terria: Terria; +} + +declare class ChartPanel extends React.Component {} + +export default ChartPanel; diff --git a/lib/ReactViews/Custom/parseCustomHtmlToReact.ts b/lib/ReactViews/Custom/parseCustomHtmlToReact.ts index 5522d57854f..7d83108bca0 100644 --- a/lib/ReactViews/Custom/parseCustomHtmlToReact.ts +++ b/lib/ReactViews/Custom/parseCustomHtmlToReact.ts @@ -1,21 +1,19 @@ -"use strict"; - +import DOMPurify from "dompurify"; import React, { AnchorHTMLAttributes, createElement, DetailedReactHTMLElement, ReactElement } from "react"; +import combine from "terriajs-cesium/Source/Core/combine"; +import defined from "terriajs-cesium/Source/Core/defined"; import CustomComponent, { DomElement, ProcessNodeContext } from "./CustomComponent"; -import { ExternalLinkWithWarning, ExternalLinkIcon } from "./ExternalLink"; +import { ExternalLinkIcon, ExternalLinkWithWarning } from "./ExternalLink"; -const DOMPurify = require("dompurify/dist/purify"); const HtmlToReact = require("html-to-react"); -const combine = require("terriajs-cesium/Source/Core/combine").default; -const defined = require("terriajs-cesium/Source/Core/defined").default; const utils = require("html-to-react/lib/utils"); const htmlToReactParser = new HtmlToReact.Parser({ diff --git a/lib/ReactViews/Disclaimer.d.ts b/lib/ReactViews/Disclaimer.d.ts new file mode 100644 index 00000000000..7c6ae10693c --- /dev/null +++ b/lib/ReactViews/Disclaimer.d.ts @@ -0,0 +1,5 @@ +import React from "react"; + +declare class Disclaimer extends React.Component<{}> {} + +export default Disclaimer; diff --git a/lib/ReactViews/DragDropNotification.d.ts b/lib/ReactViews/DragDropNotification.d.ts new file mode 100644 index 00000000000..33b2a353455 --- /dev/null +++ b/lib/ReactViews/DragDropNotification.d.ts @@ -0,0 +1,5 @@ +import React from "react"; + +declare class DragDropNotification extends React.Component<{}> {} + +export default DragDropNotification; diff --git a/lib/ReactViews/DragDropNotification.jsx b/lib/ReactViews/DragDropNotification.jsx index 63bf30c8c7d..5edcf1a9cfb 100644 --- a/lib/ReactViews/DragDropNotification.jsx +++ b/lib/ReactViews/DragDropNotification.jsx @@ -1,4 +1,3 @@ -"use strict"; import classNames from "classnames"; import { reaction } from "mobx"; import { observer } from "mobx-react"; diff --git a/lib/ReactViews/ExplorerWindow/Tabs.d.ts b/lib/ReactViews/ExplorerWindow/Tabs.d.ts new file mode 100644 index 00000000000..8714b383e1c --- /dev/null +++ b/lib/ReactViews/ExplorerWindow/Tabs.d.ts @@ -0,0 +1,13 @@ +import React from "react"; +import Terria from "../../Models/Terria"; +import ViewState from "../../ReactViewModels/ViewState"; + +interface PropsType { + terria: Terria; + viewState: ViewState; + tabs?: unknown[]; +} + +declare class Tabs extends React.Component {} + +export default Tabs; diff --git a/lib/ReactViews/Generic/CloseButton.tsx b/lib/ReactViews/Generic/CloseButton.tsx new file mode 100644 index 00000000000..f38f209e7bf --- /dev/null +++ b/lib/ReactViews/Generic/CloseButton.tsx @@ -0,0 +1,34 @@ +// for all the panels and modals we will eventually normalise +import React from "react"; +import styled from "styled-components"; +// import Box from "../../Styled/Box"; +import Icon from "../../Styled/Icon"; +import { ButtonProps, RawButton } from "../../Styled/Button"; + +const StyledCloseButton = styled(RawButton)` + ${(p: any) => !p.noAbsolute && `position: absolute;`} + // width: 20px; + // height: 20px; + width: 14px; + height: 14px; + ${(p: any) => + p.topRight && + ` + top: 15px; + right:15px; + `} + svg { + // fill: ${(p) => p.color || p.theme.darkWithOverlay}; + fill: ${(p) => p.color}; + } +`; + +const CloseButton = (props: ButtonProps) => { + return ( + + + + ); +}; + +export default CloseButton; diff --git a/lib/ReactViews/Generic/Prompt.d.ts b/lib/ReactViews/Generic/Prompt.d.ts new file mode 100644 index 00000000000..29a61a8cca6 --- /dev/null +++ b/lib/ReactViews/Generic/Prompt.d.ts @@ -0,0 +1,20 @@ +import React from "react"; + +interface PropsType { + content: React.ReactNode; + isVisible: boolean; + displayDelay: number; + dismissText: string; + dismissAction: () => void; + centered?: boolean; + caretTopOffset?: number; + caretLeftOffset?: number; + caretSize?: number; + promptWidth?: number; + promptTopOffset?: number; + promptLeftOffset?: number; +} + +declare class Prompt extends React.PureComponent {} + +export default Prompt; diff --git a/lib/ReactViews/HelpScreens/SatelliteHelpPrompt.jsx b/lib/ReactViews/HelpScreens/SatelliteHelpPrompt.tsx similarity index 100% rename from lib/ReactViews/HelpScreens/SatelliteHelpPrompt.jsx rename to lib/ReactViews/HelpScreens/SatelliteHelpPrompt.tsx diff --git a/lib/ReactViews/Map/MapColumn.tsx b/lib/ReactViews/Map/MapColumn.tsx index 0135fb2a5da..2701e89cc85 100644 --- a/lib/ReactViews/Map/MapColumn.tsx +++ b/lib/ReactViews/Map/MapColumn.tsx @@ -60,7 +60,6 @@ export const MapColumn: FC = observer( `} > void; + onClose: () => void; +} + +export declare const GyroscopeGuidance: React.FC; diff --git a/lib/ReactViews/Map/MenuBar/MenuBar.d.ts b/lib/ReactViews/Map/MenuBar/MenuBar.d.ts new file mode 100644 index 00000000000..a1d8f37a149 --- /dev/null +++ b/lib/ReactViews/Map/MenuBar/MenuBar.d.ts @@ -0,0 +1,11 @@ +import IElementConfig from "../../../Models/IElementConfig"; + +interface PropsType { + animationDuration?: number; + menuItems: React.ReactElement[]; + menuLeftItems: React.ReactElement[]; + elementConfig?: IElementConfig; +} + +declare const MenuBar: React.FC; +export default MenuBar; diff --git a/lib/ReactViews/Map/Panels/HelpPanel/HelpPanel.d.ts b/lib/ReactViews/Map/Panels/HelpPanel/HelpPanel.d.ts new file mode 100644 index 00000000000..807fe6c1d6c --- /dev/null +++ b/lib/ReactViews/Map/Panels/HelpPanel/HelpPanel.d.ts @@ -0,0 +1,4 @@ +import React from "react"; + +declare class HelpPanel extends React.Component<{}> {} +export default HelpPanel; diff --git a/lib/ReactViews/Map/Panels/HelpPanel/VideoGuide.d.ts b/lib/ReactViews/Map/Panels/HelpPanel/VideoGuide.d.ts new file mode 100644 index 00000000000..de29f4976d5 --- /dev/null +++ b/lib/ReactViews/Map/Panels/HelpPanel/VideoGuide.d.ts @@ -0,0 +1,14 @@ +import React from "react"; +import ViewState from "../../../../ReactViewModels/ViewState"; + +interface PropsType { + viewState: ViewState; + videoName: string; + videoLink: string; + background: string; + // A number between 0 and 1.0 + backgroundOpacity?: number; +} + +declare class VideoGuide extends React.Component {} +export default VideoGuide; diff --git a/lib/ReactViews/Mobile/MobileHeader.d.ts b/lib/ReactViews/Mobile/MobileHeader.d.ts new file mode 100644 index 00000000000..68eb64b1f86 --- /dev/null +++ b/lib/ReactViews/Mobile/MobileHeader.d.ts @@ -0,0 +1,12 @@ +import { i18n } from "i18next"; +import React from "react"; + +interface PropsType { + version?: string; + menuLeftItems: React.ReactNode[]; + menuItems: React.ReactNode[]; + i18n?: i18n; +} + +declare class MobileHeader extends React.Component {} +export default MobileHeader; diff --git a/lib/ReactViews/Preview/Description.d.ts b/lib/ReactViews/Preview/Description.d.ts new file mode 100644 index 00000000000..0ada6130fcb --- /dev/null +++ b/lib/ReactViews/Preview/Description.d.ts @@ -0,0 +1,11 @@ +import React from "react"; +import { BaseModel } from "../../Models/Definition/Model"; + +interface PropsType { + item: BaseModel; + printView?: boolean; +} + +declare class Description extends React.Component {} + +export default Description; diff --git a/lib/ReactViews/PrivateIndicator/PrivateIndicator.jsx b/lib/ReactViews/PrivateIndicator/PrivateIndicator.tsx similarity index 73% rename from lib/ReactViews/PrivateIndicator/PrivateIndicator.jsx rename to lib/ReactViews/PrivateIndicator/PrivateIndicator.tsx index 06c2cce9781..bb5295f34b2 100644 --- a/lib/ReactViews/PrivateIndicator/PrivateIndicator.jsx +++ b/lib/ReactViews/PrivateIndicator/PrivateIndicator.tsx @@ -1,28 +1,24 @@ import React from "react"; -import PropTypes from "prop-types"; import { useTranslation } from "react-i18next"; - import Icon from "../../Styled/Icon"; import IconWrapper from "../../Styled/IconWrapper"; -PrivateIndicator.propTypes = { - inWorkbench: PropTypes.bool -}; +interface PropsType { + inWorkbench?: boolean; +} -export default function PrivateIndicator(props) { +export default function PrivateIndicator(props: PropsType) { const { t } = useTranslation(); - return ( + fill: ${(p: any) => p.inWorkbench ? p.theme.textLight : p.theme.charcoalGrey}; } `} diff --git a/lib/ReactViews/Search/SearchBoxAndResults.d.ts b/lib/ReactViews/Search/SearchBoxAndResults.d.ts new file mode 100644 index 00000000000..361eb03867c --- /dev/null +++ b/lib/ReactViews/Search/SearchBoxAndResults.d.ts @@ -0,0 +1,22 @@ +import { TFunction } from "i18next"; +import React from "react"; +import Terria from "../../Models/Terria"; +import ViewState from "../../ReactViewModels/ViewState"; + +interface SearchInDataCatalogPropsType { + viewState: ViewState; + handleClick: () => void; +} + +export declare const SearchInDataCatalog: React.FC; + +interface PropsType { + viewState: ViewState; + terria: Terria; + t?: TFunction; + placeholder?: string; +} + +declare class SearchBoxAndResults extends React.Component {} + +export default SearchBoxAndResults; diff --git a/lib/ReactViews/SidePanel/FullScreenButton.d.ts b/lib/ReactViews/SidePanel/FullScreenButton.d.ts new file mode 100644 index 00000000000..0498ca74692 --- /dev/null +++ b/lib/ReactViews/SidePanel/FullScreenButton.d.ts @@ -0,0 +1,13 @@ +import React from "react"; +import IElementConfig from "../../Models/IElementConfig"; + +interface PropsType { + btnText: string; + minified: boolean; + animationDuration?: number; + elementConfig?: IElementConfig; +} + +declare class FullScreenButton extends React.Component {} + +export default FullScreenButton; diff --git a/lib/ReactViews/StandardUserInterface/StandardTheme.jsx b/lib/ReactViews/StandardUserInterface/StandardTheme.tsx similarity index 78% rename from lib/ReactViews/StandardUserInterface/StandardTheme.jsx rename to lib/ReactViews/StandardUserInterface/StandardTheme.tsx index dca182dfab1..a065688d20e 100644 --- a/lib/ReactViews/StandardUserInterface/StandardTheme.jsx +++ b/lib/ReactViews/StandardUserInterface/StandardTheme.tsx @@ -1,8 +1,9 @@ import Variables from "../../Sass/exports/_variables-export.scss"; - import Mixins from "../../Styled/mixins"; export const terriaTheme = { ...Variables, ...Mixins }; + +export type TerriaTheme = typeof terriaTheme; diff --git a/lib/ReactViews/StandardUserInterface/StandardUserInterface.tsx b/lib/ReactViews/StandardUserInterface/StandardUserInterface.tsx index 495587487f5..5fcececb343 100644 --- a/lib/ReactViews/StandardUserInterface/StandardUserInterface.tsx +++ b/lib/ReactViews/StandardUserInterface/StandardUserInterface.tsx @@ -6,7 +6,6 @@ import React, { ReactNode, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { DefaultTheme } from "styled-components"; import combine from "terriajs-cesium/Source/Core/combine"; -import arrayContains from "../../Core/arrayContains"; import ViewState from "../../ReactViewModels/ViewState"; import Disclaimer from "../Disclaimer"; import DragDropFile from "../DragDropFile"; @@ -68,10 +67,7 @@ const StandardUserInterfaceBase: React.FC = }); const handleDragOver = (e: React.DragEvent) => { - if ( - !e.dataTransfer.types || - !arrayContains(e.dataTransfer.types, "Files") - ) { + if (!e.dataTransfer.types || !e.dataTransfer.types.includes("Files")) { return; } e.preventDefault(); diff --git a/lib/ReactViews/StandardUserInterface/processCustomElements.d.ts b/lib/ReactViews/StandardUserInterface/processCustomElements.d.ts new file mode 100644 index 00000000000..24f4b3d9edb --- /dev/null +++ b/lib/ReactViews/StandardUserInterface/processCustomElements.d.ts @@ -0,0 +1,15 @@ +import React from "react"; + +type GroupElementKeys = + | "menu" + | "menuLeft" + | "nav" + | "experimentalMenu" + | "feedback"; + +declare function processCustomElements( + isSmallScreen: boolean, + customUI: React.ReactNode +): Record; + +export default processCustomElements; diff --git a/lib/ReactViews/Story/StoryBuilder.tsx b/lib/ReactViews/Story/StoryBuilder.tsx index 4907ceb1b69..eb864c5c891 100644 --- a/lib/ReactViews/Story/StoryBuilder.tsx +++ b/lib/ReactViews/Story/StoryBuilder.tsx @@ -30,12 +30,12 @@ import SharePanel from "../Map/Panels/SharePanel/SharePanel"; import { WithViewState, withViewState } from "../Context"; import Story from "./Story"; import Styles from "./story-builder.scss"; -import StoryEditor from "./StoryEditor.jsx"; +import StoryEditor from "./StoryEditor"; const dataStoriesImg = require("../../../wwwroot/images/data-stories-getting-started.jpg"); const STORY_VIDEO = "storyVideo"; -type StoryData = ViewState["terria"]["stories"][number]; +export type StoryData = ViewState["terria"]["stories"][number]; interface IProps { isVisible?: boolean; @@ -85,7 +85,7 @@ class StoryBuilder extends React.Component< storyWithOpenMenuId: undefined }; } - removeStory = (index: number, story: StoryData) => { + removeStory = (index: number, story?: StoryData) => { this.setState({ isSharing: false, isRemoving: true, diff --git a/lib/ReactViews/Story/StoryEditor.d.ts b/lib/ReactViews/Story/StoryEditor.d.ts new file mode 100644 index 00000000000..3bf04fdcc2a --- /dev/null +++ b/lib/ReactViews/Story/StoryEditor.d.ts @@ -0,0 +1,15 @@ +import React from "react"; +import Terria from "../../Models/Terria"; +import { StoryData } from "./StoryBuilder"; + +interface PropsType { + story?: StoryData; + removeStory: (id: number) => void; + saveStory: (story: StoryData) => void; + exitEditingMode: () => void; + terria: Terria; +} + +declare class StoryEditor extends React.Component {} + +export default StoryEditor; diff --git a/lib/ReactViews/Tour/TourPortal.d.ts b/lib/ReactViews/Tour/TourPortal.d.ts new file mode 100644 index 00000000000..d7392d851bc --- /dev/null +++ b/lib/ReactViews/Tour/TourPortal.d.ts @@ -0,0 +1,6 @@ +export declare const TourExplanation: React.FC; +export declare const TourPreface: React.FC; + +declare const TourPortal: React.FC<{}>; + +export default TourPortal; diff --git a/lib/ReactViews/Transitions/FadeIn/FadeIn.d.ts b/lib/ReactViews/Transitions/FadeIn/FadeIn.d.ts new file mode 100644 index 00000000000..17057b1b305 --- /dev/null +++ b/lib/ReactViews/Transitions/FadeIn/FadeIn.d.ts @@ -0,0 +1,9 @@ +interface PropsType { + isVisible: boolean; + onEnter?: () => void; + onExited?: () => void; + transitionProps?: any; +} + +declare const FadeIn: React.FC; +export default FadeIn; diff --git a/lib/ReactViews/Transitions/SlideUpFadeIn/SlideUpFadeIn.d.ts b/lib/ReactViews/Transitions/SlideUpFadeIn/SlideUpFadeIn.d.ts new file mode 100644 index 00000000000..60f9e2e91c1 --- /dev/null +++ b/lib/ReactViews/Transitions/SlideUpFadeIn/SlideUpFadeIn.d.ts @@ -0,0 +1,9 @@ +interface PropsType { + isVisible: boolean; + onEnter?: () => void; + onExited?: () => void; + transitionProps?: any; +} + +declare const SlideUpFadeIn: React.FC; +export default SlideUpFadeIn; diff --git a/lib/ReactViews/WelcomeMessage/WelcomeMessage.d.ts b/lib/ReactViews/WelcomeMessage/WelcomeMessage.d.ts new file mode 100644 index 00000000000..858b3816356 --- /dev/null +++ b/lib/ReactViews/WelcomeMessage/WelcomeMessage.d.ts @@ -0,0 +1,12 @@ +import React from "react"; + +interface WelcomeMessagePurePropsType { + showWelcomeMessage: boolean; + setShowWelcomeMessage: (show: boolean) => void; + isTopElement: boolean; +} + +export declare const WelcomeMessagePure: React.FC; + +declare class WelcomeMessage extends React.Component<{}> {} +export default WelcomeMessage; diff --git a/lib/ReactViews/Workbench/Controls/ColorScaleRangeSection.d.ts b/lib/ReactViews/Workbench/Controls/ColorScaleRangeSection.d.ts new file mode 100644 index 00000000000..e9192db03ab --- /dev/null +++ b/lib/ReactViews/Workbench/Controls/ColorScaleRangeSection.d.ts @@ -0,0 +1,11 @@ +import React from "react"; +import { BaseModel } from "../../../Models/Definition/Model"; + +interface PropsType { + item: BaseModel; + minValue: number; + maxValue: number; +} + +declare class ColorScaleRangeSection extends React.Component {} +export default ColorScaleRangeSection; diff --git a/lib/ReactViews/Workbench/Controls/FilterSection.d.ts b/lib/ReactViews/Workbench/Controls/FilterSection.d.ts new file mode 100644 index 00000000000..b599403cb16 --- /dev/null +++ b/lib/ReactViews/Workbench/Controls/FilterSection.d.ts @@ -0,0 +1,9 @@ +import React from "react"; +import { BaseModel } from "../../../Models/Definition/Model"; + +interface PropsType { + item: BaseModel; +} + +declare class FilterSection extends React.Component {} +export default FilterSection; diff --git a/lib/ReactViews/Workbench/Controls/SatelliteImageryTimeFilterSection.d.ts b/lib/ReactViews/Workbench/Controls/SatelliteImageryTimeFilterSection.d.ts new file mode 100644 index 00000000000..35be383dbda --- /dev/null +++ b/lib/ReactViews/Workbench/Controls/SatelliteImageryTimeFilterSection.d.ts @@ -0,0 +1,9 @@ +import React from "react"; +import { BaseModel } from "../../../Models/Definition/Model"; + +interface PropsType { + item: BaseModel; +} + +declare class SatelliteImageryTimeFilterSection extends React.Component {} +export default SatelliteImageryTimeFilterSection; diff --git a/lib/ReactViews/Workbench/Controls/ShortReport.tsx b/lib/ReactViews/Workbench/Controls/ShortReport.tsx index 7143a9eac89..de5dac79e52 100644 --- a/lib/ReactViews/Workbench/Controls/ShortReport.tsx +++ b/lib/ReactViews/Workbench/Controls/ShortReport.tsx @@ -1,5 +1,3 @@ -"use strict"; - import { runInAction } from "mobx"; import { observer } from "mobx-react"; import React from "react"; @@ -103,5 +101,3 @@ export default class ShortReport extends React.Component<{ ); } } - -module.exports = ShortReport; diff --git a/lib/ReactViews/Workbench/Controls/TimerSection.d.ts b/lib/ReactViews/Workbench/Controls/TimerSection.d.ts new file mode 100644 index 00000000000..1ae97eb7525 --- /dev/null +++ b/lib/ReactViews/Workbench/Controls/TimerSection.d.ts @@ -0,0 +1,5 @@ +import React from "react"; +import { BaseModel } from "../../../Models/Definition/Model"; + +declare class TimerSection extends React.Component<{ item: BaseModel }> {} +export default TimerSection; diff --git a/lib/Styled/mixins.js b/lib/Styled/mixins.ts similarity index 81% rename from lib/Styled/mixins.js rename to lib/Styled/mixins.ts index ec3e61403f9..359691550c6 100644 --- a/lib/Styled/mixins.js +++ b/lib/Styled/mixins.ts @@ -1,5 +1,11 @@ // Doesn't result in composed classes that reuse these, but to save some typing +import cssExports from "../Sass/exports/_variables-export.scss"; + +interface MixinProps { + theme: typeof cssExports; +} + export const scrollBars = () => ` -webkit-overflow-scrolling: touch; @@ -41,16 +47,16 @@ export const removeListStyles = () => ` margin: 0; `; -export const borderRadiusTop = (radius) => ` +export const borderRadiusTop = (radius: number | string) => ` border-radius: ${radius}px ${radius}px 0 0; `; -export const borderRadiusRight = (radius) => ` +export const borderRadiusRight = (radius: number | string) => ` border-radius: 0 ${radius}px ${radius}px 0; `; -export const borderRadiusBottom = (radius) => ` +export const borderRadiusBottom = (radius: number | string) => ` border-radius: 0 0 ${radius}px ${radius}px; `; -export const borderRadiusLeft = (radius) => ` +export const borderRadiusLeft = (radius: number | string) => ` border-radius: ${radius}px 0 0 ${radius}px; `; @@ -65,7 +71,7 @@ export const addBasicHoverStyles = () => ` * unfortunately this means more classnames outputted, but gives us consistency * in the meantime. * */ -export const addTerriaPrimaryBtnStyles = (props) => ` +export const addTerriaPrimaryBtnStyles = (props: MixinProps) => ` background: ${props.theme.colorPrimary}; color: ${props.theme.textLight}; svg { @@ -79,7 +85,7 @@ export const addTerriaPrimaryBtnStyles = (props) => ` } `; -export const addTerriaSecondaryBtnStyles = (props) => ` +export const addTerriaSecondaryBtnStyles = (props: MixinProps) => ` color: ${props.theme.colorPrimary}; // Don't override border here on secondary, as it's set specifically on certain buttons e.g. story cancel button @@ -91,7 +97,7 @@ export const addTerriaSecondaryBtnStyles = (props) => ` ${addBasicHoverStyles()} `; -export const addTerriaTertiaryBtnStyles = (props) => ` +export const addTerriaTertiaryBtnStyles = (props: MixinProps) => ` color: ${props.theme.modalText}; background: ${props.theme.modalBg}; border: 2px solid ${props.theme.modalText}; @@ -103,7 +109,7 @@ export const addTerriaTertiaryBtnStyles = (props) => ` } `; -export const addTerriaMapBtnStyles = (props) => ` +export const addTerriaMapBtnStyles = (props: MixinProps) => ` color: ${props.theme.textLight}; background-color: ${props.theme.dark}; &:hover, @@ -123,7 +129,7 @@ export const addTerriaMapBtnStyles = (props) => ` } `; -export const addTerriaLightBtnStyles = (props) => ` +export const addTerriaLightBtnStyles = (props: MixinProps) => ` color: ${props.theme.textLight}; svg { fill: ${props.theme.textLight}; @@ -135,7 +141,7 @@ export const addTerriaLightBtnStyles = (props) => ` } `; -export const addTerriaScrollbarStyles = (props) => ` +export const addTerriaScrollbarStyles = () => ` -webkit-overflow-scrolling: touch; &::-webkit-scrollbar { diff --git a/lib/ThirdParty/xml2json.d.ts b/lib/ThirdParty/xml2json.d.ts new file mode 100644 index 00000000000..7e663dfa272 --- /dev/null +++ b/lib/ThirdParty/xml2json.d.ts @@ -0,0 +1,4 @@ +export default function xml2json( + xml: XMLDocument | string | undefined, + extended?: boolean +): any; diff --git a/lib/ThirdParty/xml2json.js b/lib/ThirdParty/xml2json.js index fcd396f09c4..61ae6d160cd 100644 --- a/lib/ThirdParty/xml2json.js +++ b/lib/ThirdParty/xml2json.js @@ -180,4 +180,4 @@ function text2xml(str) { return parser.parseFromString(str, "text/xml"); } -module.exports = xml2json; +export default xml2json; diff --git a/package.json b/package.json index 013c37ac6e4..3670120de86 100644 --- a/package.json +++ b/package.json @@ -57,13 +57,16 @@ "@types/jasmine-ajax": "^3.3.0", "@types/json5": "^0.0.30", "@types/leaflet": "^1.7.10", + "@types/linkify-it": "^3.0.5", "@types/lodash-es": "^4.17.3", + "@types/markdown-it": "^14.0.1", "@types/math-expression-evaluator": "^1.2.0", "@types/ms": "^0.7.31", "@types/mustache": "^0.8.32", "@types/node-fetch": "^2.6.2", "@types/papaparse": "^4.5.9", "@types/pbf": "^3.0.1", + "@types/proj4": "^2.5.5", "@types/rbush": "^3.0.0", "@types/rc-slider": "^8.6.6", "@types/react": "^17.0.3", @@ -133,9 +136,9 @@ "javascript-natural-sort": "^0.7.1", "json5": "^2.1.0", "leaflet": "^1.8.0", - "linkify-it": "^2.0.0", + "linkify-it": "^5.0.0", "lodash-es": "^4.17.11", - "markdown-it": "^11.0.0", + "markdown-it": "^14.1.0", "math-expression-evaluator": "^1.3.7", "mini-css-extract-plugin": "^0.5.0", "minisearch": "^3.0.2",