aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2020-04-13 11:16:03 -0400
committerBob Zeleznik <zzzman@gmail.com>2020-04-13 11:16:03 -0400
commited02920bd50e284e188376b142f494df4e330ac5 (patch)
treea18681a123dc50956c461023957224ce797b53e6 /src
parentb235c94614141752c98d24a395682a02297d9e6a (diff)
parentbf622aa5b5cd9d3256ee8e4f26245b9858cccfba (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
Diffstat (limited to 'src')
-rw-r--r--src/Utils.ts5
-rw-r--r--src/client/cognitive_services/CognitiveServices.ts3
-rw-r--r--src/client/documents/Documents.ts9
-rw-r--r--src/client/views/Main.tsx1
-rw-r--r--src/client/views/collections/CollectionMapView.scss4
-rw-r--r--src/client/views/collections/CollectionMapView.tsx71
-rw-r--r--src/client/views/collections/CollectionView.tsx10
-rw-r--r--src/new_fields/Types.ts1
-rw-r--r--src/server/ApiManagers/UtilManager.ts13
-rw-r--r--src/server/server_Initialization.ts1
10 files changed, 92 insertions, 26 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index e3ec10dcd..a8cde0624 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -63,11 +63,6 @@ export namespace Utils {
return prepend("/corsProxy/") + encodeURIComponent(url);
}
- export async function getApiKey(target: string): Promise<string> {
- const response = await fetch(prepend(`/environment/${target.toUpperCase()}`));
- return response.text();
- }
-
export function CopyText(text: string) {
const textArea = document.createElement("textarea");
textArea.value = text;
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index 5d83de233..8c63ae906 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -8,7 +8,6 @@ import { UndoManager } from "../util/UndoManager";
import requestPromise = require("request-promise");
import { List } from "../../new_fields/List";
import { ClientRecommender } from "../ClientRecommender";
-import { ImageBox } from "../views/nodes/ImageBox";
type APIManager<D> = { converter: BodyConverter<D>, requester: RequestExecutor };
type RequestExecutor = (apiKey: string, body: string, service: Service) => Promise<string>;
@@ -46,7 +45,7 @@ export enum Confidence {
export namespace CognitiveServices {
const ExecuteQuery = async <D>(service: Service, manager: APIManager<D>, data: D): Promise<any> => {
- const apiKey = await Utils.getApiKey(service);
+ const apiKey = process.env[service.toUpperCase()];
if (!apiKey) {
console.log(`No API key found for ${service}: ensure index.ts has access to a .env file in your root directory.`);
return undefined;
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 703c049cd..43e379125 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -49,6 +49,8 @@ import { ContextMenuProps } from "../views/ContextMenuItem";
import { ContextMenu } from "../views/ContextMenu";
import { LinkBox } from "../views/nodes/LinkBox";
import { ScreenshotBox } from "../views/nodes/ScreenshotBox";
+import CollectionMapView from "../views/collections/CollectionMapView";
+import LocationField, { LocationData } from "../../new_fields/LocationField";
const requestImageSize = require('../util/request-image-size');
const path = require('path');
@@ -277,8 +279,7 @@ export namespace Docs {
}],
[DocumentType.SCREENSHOT, {
layout: { view: ScreenshotBox, dataField: data },
- options: {}
- }]
+ }],
]);
// All document prototypes are initialized with at least these values
@@ -624,6 +625,10 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", backgroundColor: "black", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Linear }, id);
}
+ export function MapDocument(documents: Array<Doc>, options: DocumentOptions = {}) {
+ return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), options);
+ }
+
export function CarouselDocument(documents: Array<Doc>, options: DocumentOptions) {
return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Carousel });
}
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 6d705aa44..b21eb9c8f 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -5,7 +5,6 @@ import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { DocServer } from "../DocServer";
import { AssignAllExtensions } from "../../extensions/General/Extensions";
-process.env.HANDWRITING = "61088486d76c4b12ba578775a5f55422";
AssignAllExtensions();
diff --git a/src/client/views/collections/CollectionMapView.scss b/src/client/views/collections/CollectionMapView.scss
new file mode 100644
index 000000000..c74433902
--- /dev/null
+++ b/src/client/views/collections/CollectionMapView.scss
@@ -0,0 +1,4 @@
+.collectionMapView-contents {
+ width: 100%;
+ height: 100%;
+} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx
new file mode 100644
index 000000000..b67daeb53
--- /dev/null
+++ b/src/client/views/collections/CollectionMapView.tsx
@@ -0,0 +1,71 @@
+import { observer } from "mobx-react";
+import { makeInterface } from "../../../new_fields/Schema";
+import { documentSchema } from "../../../new_fields/documentSchemas";
+import React = require("react");
+import { Map, Marker, MapProps, GoogleApiWrapper } from "google-maps-react";
+import { NumCast, StrCast } from "../../../new_fields/Types";
+import { CollectionSubView } from "./CollectionSubView";
+import { Utils } from "../../../Utils";
+import { Opt } from "../../../new_fields/Doc";
+
+type MapDocument = makeInterface<[typeof documentSchema]>;
+const MapDocument = makeInterface(documentSchema);
+
+export type LocationData = google.maps.LatLngLiteral & { address?: string };
+
+@observer
+class CollectionMapView extends CollectionSubView<MapDocument, Partial<MapProps> & { google: any }>(MapDocument) {
+
+ render() {
+ const { childLayoutPairs, props } = this;
+ const { Document } = props;
+ const center: LocationData = { lat: NumCast(Document.mapCenterLat), lng: NumCast(Document.mapCenterLng) };
+ if (!center.lat) {
+ center.lat = childLayoutPairs.length ? NumCast(childLayoutPairs[0].layout.locationLat, 0) : 0;
+ center.lng = childLayoutPairs.length ? NumCast(childLayoutPairs[0].layout.locationLng, 0) : 0;
+ }
+ return (
+ <div
+ className={"collectionMapView-contents"}
+ >
+ <Map
+ {...props}
+ zoom={NumCast(Document.zoom, 10)}
+ center={center}
+ initialCenter={center}
+ >
+ {childLayoutPairs.map(({ layout }) => {
+ const location: LocationData = {
+ lat: NumCast(childLayoutPairs[0].layout.locationLat, 0),
+ lng: NumCast(childLayoutPairs[0].layout.locationLng, 0)
+ };
+ let icon: Opt<google.maps.Icon>, iconUrl: Opt<string>;
+ if ((iconUrl = StrCast(Document.mapIconUrl, null))) {
+ const iconSize = new google.maps.Size(NumCast(layout.mapIconWidth, 45), NumCast(layout.mapIconHeight, 45));
+ icon = {
+ size: iconSize,
+ scaledSize: iconSize,
+ url: iconUrl
+ };
+ }
+ return (
+ <Marker
+ key={Utils.GenerateGuid()}
+ label={StrCast(layout.title)}
+ position={location}
+ onClick={() => {
+ Document.mapCenterLat = location.lat;
+ Document.mapCenterLng = location.lng;
+ }}
+ icon={icon}
+ />
+ );
+ })}
+ </Map>
+ </div>
+ );
+ }
+
+}
+
+export default GoogleApiWrapper({ apiKey: process.env.GOOGLE_MAPS! })(CollectionMapView) as any; \ No newline at end of file
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 86df9c080..4d04f2050 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -1,7 +1,7 @@
import { library } from '@fortawesome/fontawesome-svg-core';
import { faEye, faEdit } from '@fortawesome/free-regular-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faColumns, faCopy, faEllipsisV, faFingerprint, faImage, faProjectDiagram, faSignature, faSquare, faTh, faThList, faTree } from '@fortawesome/free-solid-svg-icons';
+import { faColumns, faCopy, faEllipsisV, faFingerprint, faImage, faProjectDiagram, faSignature, faSquare, faTh, faThList, faTree, faGlobeAmericas } from '@fortawesome/free-solid-svg-icons';
import { action, observable, computed } from 'mobx';
import { observer } from "mobx-react";
import * as React from 'react';
@@ -44,12 +44,15 @@ import { Docs } from '../../documents/Documents';
import { ScriptField, ComputedField } from '../../../new_fields/ScriptField';
import { InteractionUtils } from '../../util/InteractionUtils';
import { ObjectField } from '../../../new_fields/ObjectField';
+import CollectionMapView from './CollectionMapView';
+import { ClientUtils } from '../../util/ClientUtils';
+import { GoogleApiWrapper } from 'google-maps-react';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
export const COLLECTION_BORDER_WIDTH = 2;
const path = require('path');
-library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy);
+library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faGlobeAmericas, faEllipsisV, faImage, faEye as any, faCopy);
export enum CollectionViewType {
Invalid = "invalid",
@@ -65,6 +68,7 @@ export enum CollectionViewType {
Carousel = "carousel",
Linear = "linear",
Staff = "staff",
+ Map = "map"
}
export interface CollectionRenderProps {
@@ -170,6 +174,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (<CollectionStackingView key="collview" {...props} />); }
case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView key="collview" {...props} />); }
case CollectionViewType.Time: { return (<CollectionTimeView key="collview" {...props} />); }
+ case CollectionViewType.Map: return (<CollectionMapView key="collview" {...props} />);
case CollectionViewType.Freeform:
default: { this.props.Document._freeformLayoutEngine = undefined; return (<CollectionFreeFormView key="collview" {...props} />); }
}
@@ -211,6 +216,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
subItems.push({ description: "Masonry", event: () => this.props.Document._viewType = CollectionViewType.Masonry, icon: "columns" });
subItems.push({ description: "Carousel", event: () => this.props.Document._viewType = CollectionViewType.Carousel, icon: "columns" });
subItems.push({ description: "Pivot/Time", event: () => this.props.Document._viewType = CollectionViewType.Time, icon: "columns" });
+ subItems.push({ description: "Map", event: () => this.props.Document._viewType = CollectionViewType.Map, icon: "globe-americas" });
switch (this.props.Document._viewType) {
case CollectionViewType.Freeform: {
subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) });
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 0ca35fab2..aa44cefa0 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -87,6 +87,7 @@ export function BoolCast(field: FieldResult, defaultVal: boolean | null = false)
export function DateCast(field: FieldResult) {
return Cast(field, DateField, null);
}
+
export function ScriptCast(field: FieldResult) {
return Cast(field, ScriptField, null);
}
diff --git a/src/server/ApiManagers/UtilManager.ts b/src/server/ApiManagers/UtilManager.ts
index ad8119bf4..aec523cd0 100644
--- a/src/server/ApiManagers/UtilManager.ts
+++ b/src/server/ApiManagers/UtilManager.ts
@@ -14,19 +14,6 @@ export default class UtilManager extends ApiManager {
protected initialize(register: Registration): void {
- register({
- method: Method.GET,
- subscription: new RouteSubscriber("environment").add("key"),
- secureHandler: ({ req, res }) => {
- const { key } = req.params;
- const value = process.env[key];
- if (!value) {
- console.log(red(`process.env.${key} is not defined.`));
- }
- return res.send(value);
- }
- });
-
// register({
// method: Method.POST,
// subscription: "/IBMAnalysis",
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index 1150118f7..add607761 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -20,7 +20,6 @@ import * as request from 'request';
import RouteSubscriber from './RouteSubscriber';
import { publicDirectory } from '.';
import { logPort, } from './ActionUtilities';
-import { Utils } from '../Utils';
import { blue, yellow } from 'colors';
import * as cors from "cors";