From c05937f48f4c26b44cec8260ea4abb7297ab0df7 Mon Sep 17 00:00:00 2001 From: Chad Burt Date: Tue, 2 Jan 2024 09:22:51 -0800 Subject: [PATCH] WIP --- package-lock.json | 38 ++- packages/api/generated-schema.gql | 4 + packages/api/migrations/current.sql | 3 + .../src/admin/data/InteractivitySettings.tsx | 192 ++++++----- packages/client/src/components/MapboxMap.tsx | 57 ++-- .../dataLayers/LayerInteractivityManager.ts | 94 +++++- .../src/dataLayers/MapContextManager.ts | 9 +- .../client/src/dataLayers/SidebarPopup.tsx | 26 ++ .../client/src/dataLayers/sidebar-popup.css | 27 ++ packages/client/src/generated/graphql.ts | 28 +- packages/client/src/generated/queries.ts | 27 +- packages/client/src/projects/ProjectApp.tsx | 318 +++++++++--------- .../client/src/projects/ProjectAppSidebar.tsx | 10 +- .../client/src/queries/BasemapAdmin.graphql | 1 + .../src/queries/DraftTableOfContents.graphql | 6 + .../queries/PublishedTableOfContents.graphql | 1 + .../mapbox-gl-esri-sources/package-lock.json | 1 - 17 files changed, 538 insertions(+), 304 deletions(-) create mode 100644 packages/client/src/dataLayers/SidebarPopup.tsx create mode 100644 packages/client/src/dataLayers/sidebar-popup.css diff --git a/package-lock.json b/package-lock.json index 40d382fed..1f4f5d5c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,8 @@ "license": "BSD-3-Clause", "dependencies": { "form-data": "^4.0.0", - "node-fetch": "^2.6.7" + "node-fetch": "^2.6.7", + "typescript": "^5.2" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^4.17.0", @@ -6951,6 +6952,19 @@ "node": ">=10" } }, + "node_modules/lerna/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -11340,16 +11354,15 @@ "dev": true }, "node_modules/typescript": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", - "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", - "dev": true, + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/uglify-js": { @@ -17093,6 +17106,12 @@ "requires": { "lru-cache": "^6.0.0" } + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true } } }, @@ -20460,10 +20479,9 @@ "dev": true }, "typescript": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", - "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", - "dev": true + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==" }, "uglify-js": { "version": "3.17.4", diff --git a/packages/api/generated-schema.gql b/packages/api/generated-schema.gql index 8eb646dc6..122c16628 100644 --- a/packages/api/generated-schema.gql +++ b/packages/api/generated-schema.gql @@ -6535,6 +6535,7 @@ type InteractivitySetting implements Node { """ nodeId: ID! shortTemplate: String + title: String! type: InteractivityType! } @@ -6550,6 +6551,7 @@ input InteractivitySettingInput { layers: [String] longTemplate: String shortTemplate: String + title: String type: InteractivityType } @@ -6567,6 +6569,7 @@ input InteractivitySettingPatch { layers: [String] longTemplate: String shortTemplate: String + title: String type: InteractivityType } @@ -6576,6 +6579,7 @@ enum InteractivityType { FIXED_BLOCK NONE POPUP + SIDEBAR_OVERLAY TOOLTIP } diff --git a/packages/api/migrations/current.sql b/packages/api/migrations/current.sql index 8da533983..da67cc2f1 100644 --- a/packages/api/migrations/current.sql +++ b/packages/api/migrations/current.sql @@ -1 +1,4 @@ -- Enter migration here +ALTER TYPE interactivity_type ADD VALUE IF NOT EXISTS 'SIDEBAR_OVERLAY'; + +alter table interactivity_settings add column if not exists title text not null default ''; \ No newline at end of file diff --git a/packages/client/src/admin/data/InteractivitySettings.tsx b/packages/client/src/admin/data/InteractivitySettings.tsx index e1216c403..58ccd2e40 100644 --- a/packages/client/src/admin/data/InteractivitySettings.tsx +++ b/packages/client/src/admin/data/InteractivitySettings.tsx @@ -50,6 +50,7 @@ export default function InteractivitySettings({ const attributeNames = useSourcePropertyNames(dataSourceId || 0, sublayer); const [shortTemplate, setShortTemplate] = useState(settings?.shortTemplate); const [longTemplate, setLongTemplate] = useState(settings?.longTemplate); + const [title, setTitle] = useState(settings?.title); const [pickLayersOpen, setPickLayersOpen] = useState(false); useEffect(() => { @@ -59,6 +60,9 @@ export default function InteractivitySettings({ if (settings && settings.longTemplate && longTemplate === undefined) { setLongTemplate(settings.longTemplate); } + if (settings && settings.title && title === undefined) { + setTitle(settings.title); + } if (settings && type === undefined) { setType(settings.type); } @@ -72,6 +76,7 @@ export default function InteractivitySettings({ type, longTemplate, shortTemplate, + title }, }); } @@ -90,7 +95,11 @@ export default function InteractivitySettings({ return input; } - const sanitizeTemplate = (propName: "longTemplate" | "shortTemplate") => { + const sanitizeTemplate = (propName: "longTemplate" | "shortTemplate" | "title") => { + console.log('sanitize', propName); + if (propName === "title") { + setTitle(title || ""); + } if (propName === "longTemplate") { setLongTemplate(sanitizeInput(longTemplate || "")); } else { @@ -134,82 +143,82 @@ export default function InteractivitySettings({ }, ...(!sublayer ? [ - { - label: t("Banner"), - description: basemap - ? t( - "Short text can be displayed towards the top of the map when the user hovers over features in the selected basemap layers." - ) - : t( - "Short text can be displayed towards the top of the map when the user hovers over features." - ), - value: InteractivityType.Banner, - children: ( - <> - setShortTemplate(value)} - attributeNames={attributeNames} - basemap={basemap} - layers={data.interactivitySetting?.layers as string[]} - onSelectLayers={() => setPickLayersOpen(true)} - /> - - ), - }, - { - label: t("Tooltip"), - description: - "Short text is displayed next to the mouse cursor.", - value: InteractivityType.Tooltip, - children: ( - <> - setShortTemplate(value)} - attributeNames={attributeNames} - basemap={basemap} - layers={data.interactivitySetting?.layers as string[]} - onSelectLayers={() => setPickLayersOpen(true)} - /> - + { + label: t("Banner"), + description: basemap + ? t( + "Short text can be displayed towards the top of the map when the user hovers over features in the selected basemap layers." + ) + : t( + "Short text can be displayed towards the top of the map when the user hovers over features." ), - }, - ] + value: InteractivityType.Banner, + children: ( + <> + setShortTemplate(value)} + attributeNames={attributeNames} + basemap={basemap} + layers={data.interactivitySetting?.layers as string[]} + onSelectLayers={() => setPickLayersOpen(true)} + /> + + ), + }, + { + label: t("Tooltip"), + description: + "Short text is displayed next to the mouse cursor.", + value: InteractivityType.Tooltip, + children: ( + <> + setShortTemplate(value)} + attributeNames={attributeNames} + basemap={basemap} + layers={data.interactivitySetting?.layers as string[]} + onSelectLayers={() => setPickLayersOpen(true)} + /> + + ), + }, + ] : []), ...(!sublayer ? [ - { - label: "Custom Popup", - description: - "Popup windows can be opened and closed to show detailed information.", - value: InteractivityType.Popup, - children: ( - <> - setLongTemplate(value)} - attributeNames={attributeNames} - basemap={basemap} - layers={data.interactivitySetting?.layers as string[]} - onSelectLayers={() => setPickLayersOpen(true)} - /> - - ), - }, - ] + { + label: "Custom Popup", + description: + "Popup windows can be opened and closed to show detailed information.", + value: InteractivityType.Popup, + children: ( + <> + setLongTemplate(value)} + attributeNames={attributeNames} + basemap={basemap} + layers={data.interactivitySetting?.layers as string[]} + onSelectLayers={() => setPickLayersOpen(true)} + /> + + ), + }, + ] : []), { label: "Popup with all columns", @@ -233,6 +242,37 @@ export default function InteractivitySettings({ // /> // ), // }, + { + label: "Sidebar", + description: + "Similar to a popup, but the content is displayed in a sidebar.", + value: InteractivityType.SidebarOverlay, + children:
+

{t("Sidebar title")}

{t("You may reference feature properties in the title but html tags will not be rendered")}

+ setTitle(value)} + attributeNames={attributeNames} + basemap={basemap} + layers={data.interactivitySetting?.layers as string[]} + onSelectLayers={() => setPickLayersOpen(true)} + /> +

{t("Sidebar content")}

{t("Content can reference feature properties and include html content.")}

+ setLongTemplate(value)} + attributeNames={attributeNames} + /> +
, + }, ]} value={selectedType} onChange={(type) => { @@ -247,9 +287,9 @@ export default function InteractivitySettings({ function TemplateEditor(props: { type: InteractivityType; selectedType: InteractivityType; - propName: "shortTemplate" | "longTemplate"; + propName: "shortTemplate" | "longTemplate" | "title"; templateValue: string | undefined; - onSave: (propName: "shortTemplate" | "longTemplate") => void; + onSave: (propName: "shortTemplate" | "longTemplate" | "title") => void; onChange: (value: string) => void; attributeNames: string[]; layers?: string[]; @@ -274,7 +314,7 @@ function TemplateEditor(props: { onBeforeChange={(editor, data, value) => { props.onChange(value); }} - onChange={(editor, data, value) => {}} + onChange={(editor, data, value) => { }} /> )}
@@ -208,8 +211,8 @@ export default React.memo(function MapboxMap(props: OverlayMapProps) { style={ sidebar.open ? { - paddingLeft: sidebar.width + "px", - } + paddingLeft: sidebar.width + "px", + } : {} } > @@ -232,8 +235,8 @@ export default React.memo(function MapboxMap(props: OverlayMapProps) { }} > {mapContext.displayedMapBookmark.errors.missingBasemap || - mapContext.displayedMapBookmark.errors.missingLayers.length > 0 || - mapContext.displayedMapBookmark.errors.missingSketches.length > + mapContext.displayedMapBookmark.errors.missingLayers.length > 0 || + mapContext.displayedMapBookmark.errors.missingSketches.length > 0 ? ( {state.children} , diff --git a/packages/client/src/dataLayers/LayerInteractivityManager.ts b/packages/client/src/dataLayers/LayerInteractivityManager.ts index 69e6b13ba..34d4ccc92 100644 --- a/packages/client/src/dataLayers/LayerInteractivityManager.ts +++ b/packages/client/src/dataLayers/LayerInteractivityManager.ts @@ -263,7 +263,9 @@ export default class LayerInteractivityManager extends EventEmitter { return ( prev.bannerMessages.join("") !== next.bannerMessages.join("") || prev.fixedBlocks.join("") !== next.fixedBlocks.join("") || - prev.tooltip !== next.tooltip + prev.tooltip !== next.tooltip || + prev.sidebarPopupContent !== next.sidebarPopupContent || + prev.sidebarPopupTitle !== next.sidebarPopupTitle ); } @@ -340,23 +342,66 @@ export default class LayerInteractivityManager extends EventEmitter { layers: this.interactiveVectorLayerIds, }); const top = features[0]; + console.log({ top }, e.point, e.lngLat); let vectorPopupOpened = false; if (top) { const interactivitySetting = this.getInteractivitySettingForFeature(top); if ( interactivitySetting && - interactivitySetting.type === InteractivityType.Popup + (interactivitySetting.type === InteractivityType.Popup || + interactivitySetting.type === InteractivityType.SidebarOverlay) ) { - new Popup({ closeOnClick: true, closeButton: true }) - .setLngLat([e.lngLat.lng, e.lngLat.lat]) - .setHTML( - Mustache.render(interactivitySetting.longTemplate || "", { - ...mustacheHelpers, - ...top.properties, - }) - ) - .addTo(this.map!); vectorPopupOpened = true; + const content = Mustache.render( + interactivitySetting.longTemplate || "", + { + ...mustacheHelpers, + ...top.properties, + } + ); + if (interactivitySetting.type === InteractivityType.Popup) { + new Popup({ closeOnClick: true, closeButton: true }) + .setLngLat([e.lngLat.lng, e.lngLat.lat]) + .setHTML(content) + .addTo(this.map!); + } else { + if (this.map) { + if (this.map.getLayer("sidebar-popup-click-location")) { + this.map.removeLayer("sidebar-popup-click-location"); + this.map.removeSource("sidebar-popup-click-location"); + } + this.map.addSource("sidebar-popup-click-location", { + type: "geojson", + data: { + type: "Feature", + properties: {}, + geometry: { + type: "Point", + coordinates: [e.lngLat.lng, e.lngLat.lat], + }, + }, + }); + this.map.addLayer({ + id: "sidebar-popup-click-location", + type: "circle", + source: "sidebar-popup-click-location", + paint: { + "circle-radius": 4, + "circle-color": "rgba(255, 255, 255, 0.5)", + "circle-stroke-color": "rgba(0,0,0,0.2)", + "circle-stroke-width": 1, + }, + layout: { + visibility: "visible", + }, + }); + } + this.setState((prev) => ({ + ...prev, + sidebarPopupContent: content, + sidebarPopupTitle: interactivitySetting.title, + })); + } } else if ( interactivitySetting && interactivitySetting.type === InteractivityType.AllPropertiesPopup @@ -405,6 +450,16 @@ export default class LayerInteractivityManager extends EventEmitter { .addTo(this.map!); vectorPopupOpened = true; } + } else { + if (this.map?.getLayer("sidebar-popup-click-location")) { + this.map.removeLayer("sidebar-popup-click-location"); + this.map.removeSource("sidebar-popup-click-location"); + } + this.setState((prev) => ({ + ...prev, + sidebarPopupContent: undefined, + sidebarPopupTitle: undefined, + })); } if (!vectorPopupOpened) { // Are any image layers active that support identify tools? @@ -422,6 +477,18 @@ export default class LayerInteractivityManager extends EventEmitter { } }; + clearSidebarPopup = () => { + this.setState((prev) => ({ + ...prev, + sidebarPopupContent: undefined, + sidebarPopupTitle: undefined, + })); + if (this.map?.getLayer("sidebar-popup-click-location")) { + this.map.removeLayer("sidebar-popup-click-location"); + this.map.removeSource("sidebar-popup-click-location"); + } + }; + // Note, this will only work with ArcGIS Server // TODO: refactor this at some point to support CustomGLSources // more generally @@ -648,6 +715,7 @@ export default class LayerInteractivityManager extends EventEmitter { break; case InteractivityType.Popup: case InteractivityType.AllPropertiesPopup: + case InteractivityType.SidebarOverlay: cursor = "pointer"; break; case InteractivityType.FixedBlock: @@ -672,7 +740,9 @@ export default class LayerInteractivityManager extends EventEmitter { (interactivitySetting.type === InteractivityType.Banner || interactivitySetting.type === InteractivityType.FixedBlock || interactivitySetting.type === InteractivityType.Popup || - interactivitySetting.type === InteractivityType.AllPropertiesPopup) + interactivitySetting.type === + InteractivityType.AllPropertiesPopup || + interactivitySetting.type === InteractivityType.SidebarOverlay) ) { // Don't waste cycles on a state update } else { diff --git a/packages/client/src/dataLayers/MapContextManager.ts b/packages/client/src/dataLayers/MapContextManager.ts index b6a7d69de..984178592 100644 --- a/packages/client/src/dataLayers/MapContextManager.ts +++ b/packages/client/src/dataLayers/MapContextManager.ts @@ -1081,7 +1081,12 @@ class MapContextManager extends EventEmitter { // at new Ut (mapbox-gl.js:36:1) let glDrawLayers: AnyLayer[] = []; let glDrawSources: { [id: string]: GeoJSONSource } = {}; - const existingStyle = this.map?.getStyle(); + let existingStyle: mapboxgl.Style | undefined; + try { + existingStyle = this.map?.getStyle(); + } catch (e) { + // do nothing + } if (existingStyle) { glDrawLayers = existingStyle.layers?.filter((l) => l.id.indexOf("gl-draw") === 0) || @@ -2852,6 +2857,8 @@ export interface MapContextInterface { bannerMessages: string[]; tooltip?: Tooltip; fixedBlocks: string[]; + sidebarPopupContent?: string; + sidebarPopupTitle?: string; selectedBasemap?: string; cameraOptions?: CameraOptions; /* Indicates the map state is ready to render a map */ diff --git a/packages/client/src/dataLayers/SidebarPopup.tsx b/packages/client/src/dataLayers/SidebarPopup.tsx new file mode 100644 index 000000000..d25da3926 --- /dev/null +++ b/packages/client/src/dataLayers/SidebarPopup.tsx @@ -0,0 +1,26 @@ +require("./sidebar-popup.css"); + +export default function SidebarPopup(props: { content?: string, title?: string; onClose: () => void }) { + // const fullSidebarContext = useContext(FullSidebarContext); + + // useEffect(() => { + // if (props.content && fullSidebarContext.open) { + // fullSidebarContext.setOpen(false); + // } + // }, [props.content, fullSidebarContext]); + if (!props.content) { + return null; + } + return ( +
+
+
+

{props.title}

+ +
+ +
+
+
+ ) +} \ No newline at end of file diff --git a/packages/client/src/dataLayers/sidebar-popup.css b/packages/client/src/dataLayers/sidebar-popup.css new file mode 100644 index 000000000..3b789d44b --- /dev/null +++ b/packages/client/src/dataLayers/sidebar-popup.css @@ -0,0 +1,27 @@ +.sidebar-popup h1 { + @apply text-lg; +} + +.sidebar-popup h2 { + @apply text-base; +} + +.sidebar-popup dl { + @apply divide-y divide-gray-100 mt-2 border border-gray-100 rounded; +} + +.sidebar-popup dt { + @apply text-sm font-medium leading-6 text-gray-900; +} + +.sidebar-popup dd { + @apply mt-1 text-sm leading-6 text-gray-700; +} + +.sidebar-popup dl div { + @apply px-2; +} + +.sidebar-popup dl div:nth-child(even) { + @apply bg-gray-50; +} diff --git a/packages/client/src/generated/graphql.ts b/packages/client/src/generated/graphql.ts index b301d997b..093dd05a6 100644 --- a/packages/client/src/generated/graphql.ts +++ b/packages/client/src/generated/graphql.ts @@ -5588,6 +5588,7 @@ export type InteractivitySetting = Node & { /** A globally unique identifier. Can be used in various places throughout the system to identify this single value. */ nodeId: Scalars['ID']; shortTemplate?: Maybe; + title: Scalars['String']; type: InteractivityType; }; @@ -5621,6 +5622,7 @@ export type InteractivitySettingInput = { layers?: Maybe>>; longTemplate?: Maybe; shortTemplate?: Maybe; + title?: Maybe; type?: Maybe; }; @@ -5632,6 +5634,7 @@ export type InteractivitySettingPatch = { layers?: Maybe>>; longTemplate?: Maybe; shortTemplate?: Maybe; + title?: Maybe; type?: Maybe; }; @@ -5641,6 +5644,7 @@ export enum InteractivityType { FixedBlock = 'FIXED_BLOCK', None = 'NONE', Popup = 'POPUP', + SidebarOverlay = 'SIDEBAR_OVERLAY', Tooltip = 'TOOLTIP' } @@ -14897,7 +14901,7 @@ export type BasemapDetailsFragment = ( & Pick & { interactivitySettings?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )>, optionalBasemapLayers: Array<( { __typename?: 'OptionalBasemapLayer' } & Pick @@ -15605,7 +15609,7 @@ export type LayersAndSourcesForItemsQuery = ( & Pick & { interactivitySettings?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )>, sprites?: Maybe @@ -15837,7 +15841,7 @@ export type InteractivitySettingsForLayerQuery = ( & Pick & { interactivitySettings?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )> } )> } ); @@ -15848,6 +15852,7 @@ export type UpdateInteractivitySettingsMutationVariables = Exact<{ cursor?: Maybe; longTemplate?: Maybe; shortTemplate?: Maybe; + title?: Maybe; }>; @@ -15857,7 +15862,7 @@ export type UpdateInteractivitySettingsMutation = ( { __typename?: 'UpdateInteractivitySettingPayload' } & { interactivitySetting?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )> } )> } ); @@ -16011,7 +16016,7 @@ export type InteractivitySettingsByIdQuery = ( { __typename?: 'Query' } & { interactivitySetting?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )> } ); @@ -17148,7 +17153,7 @@ export type DataLayerDetailsFragment = ( & ClientSpriteFragment )>>, interactivitySettings?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )> } ); @@ -19629,6 +19634,7 @@ export const BasemapDetailsFragmentDoc = gql` longTemplate shortTemplate type + title } labelsLayerId name @@ -20143,6 +20149,7 @@ export const DataLayerDetailsFragmentDoc = gql` longTemplate shortTemplate type + title } } ${ClientSpriteFragmentDoc}`; @@ -23101,6 +23108,7 @@ export const LayersAndSourcesForItemsDocument = gql` longTemplate shortTemplate type + title } staticId sprites { @@ -23700,6 +23708,7 @@ export const InteractivitySettingsForLayerDocument = gql` longTemplate shortTemplate type + title } } } @@ -23733,9 +23742,9 @@ export type InteractivitySettingsForLayerQueryHookResult = ReturnType; export type InteractivitySettingsForLayerQueryResult = Apollo.QueryResult; export const UpdateInteractivitySettingsDocument = gql` - mutation UpdateInteractivitySettings($id: Int!, $type: InteractivityType, $cursor: CursorType, $longTemplate: String, $shortTemplate: String) { + mutation UpdateInteractivitySettings($id: Int!, $type: InteractivityType, $cursor: CursorType, $longTemplate: String, $shortTemplate: String, $title: String) { updateInteractivitySetting( - input: {id: $id, patch: {type: $type, cursor: $cursor, longTemplate: $longTemplate, shortTemplate: $shortTemplate}} + input: {id: $id, patch: {type: $type, cursor: $cursor, longTemplate: $longTemplate, shortTemplate: $shortTemplate, title: $title}} ) { interactivitySetting { id @@ -23743,6 +23752,7 @@ export const UpdateInteractivitySettingsDocument = gql` cursor longTemplate shortTemplate + title } } } @@ -23767,6 +23777,7 @@ export type UpdateInteractivitySettingsMutationFn = Apollo.MutationFunction; + title: Scalars['String']; type: InteractivityType; }; @@ -5619,6 +5620,7 @@ export type InteractivitySettingInput = { layers?: Maybe>>; longTemplate?: Maybe; shortTemplate?: Maybe; + title?: Maybe; type?: Maybe; }; @@ -5630,6 +5632,7 @@ export type InteractivitySettingPatch = { layers?: Maybe>>; longTemplate?: Maybe; shortTemplate?: Maybe; + title?: Maybe; type?: Maybe; }; @@ -5639,6 +5642,7 @@ export enum InteractivityType { FixedBlock = 'FIXED_BLOCK', None = 'NONE', Popup = 'POPUP', + SidebarOverlay = 'SIDEBAR_OVERLAY', Tooltip = 'TOOLTIP' } @@ -14895,7 +14899,7 @@ export type BasemapDetailsFragment = ( & Pick & { interactivitySettings?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )>, optionalBasemapLayers: Array<( { __typename?: 'OptionalBasemapLayer' } & Pick @@ -15603,7 +15607,7 @@ export type LayersAndSourcesForItemsQuery = ( & Pick & { interactivitySettings?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )>, sprites?: Maybe @@ -15835,7 +15839,7 @@ export type InteractivitySettingsForLayerQuery = ( & Pick & { interactivitySettings?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )> } )> } ); @@ -15846,6 +15850,7 @@ export type UpdateInteractivitySettingsMutationVariables = Exact<{ cursor?: Maybe; longTemplate?: Maybe; shortTemplate?: Maybe; + title?: Maybe; }>; @@ -15855,7 +15860,7 @@ export type UpdateInteractivitySettingsMutation = ( { __typename?: 'UpdateInteractivitySettingPayload' } & { interactivitySetting?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )> } )> } ); @@ -16009,7 +16014,7 @@ export type InteractivitySettingsByIdQuery = ( { __typename?: 'Query' } & { interactivitySetting?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )> } ); @@ -17146,7 +17151,7 @@ export type DataLayerDetailsFragment = ( & ClientSpriteFragment )>>, interactivitySettings?: Maybe<( { __typename?: 'InteractivitySetting' } - & Pick + & Pick )> } ); @@ -19627,6 +19632,7 @@ export const BasemapDetailsFragmentDoc = /*#__PURE__*/ gql` longTemplate shortTemplate type + title } labelsLayerId name @@ -20141,6 +20147,7 @@ export const DataLayerDetailsFragmentDoc = /*#__PURE__*/ gql` longTemplate shortTemplate type + title } } ${ClientSpriteFragmentDoc}`; @@ -21429,6 +21436,7 @@ export const LayersAndSourcesForItemsDocument = /*#__PURE__*/ gql` longTemplate shortTemplate type + title } staticId sprites { @@ -21713,14 +21721,15 @@ export const InteractivitySettingsForLayerDocument = /*#__PURE__*/ gql` longTemplate shortTemplate type + title } } } `; export const UpdateInteractivitySettingsDocument = /*#__PURE__*/ gql` - mutation UpdateInteractivitySettings($id: Int!, $type: InteractivityType, $cursor: CursorType, $longTemplate: String, $shortTemplate: String) { + mutation UpdateInteractivitySettings($id: Int!, $type: InteractivityType, $cursor: CursorType, $longTemplate: String, $shortTemplate: String, $title: String) { updateInteractivitySetting( - input: {id: $id, patch: {type: $type, cursor: $cursor, longTemplate: $longTemplate, shortTemplate: $shortTemplate}} + input: {id: $id, patch: {type: $type, cursor: $cursor, longTemplate: $longTemplate, shortTemplate: $shortTemplate, title: $title}} ) { interactivitySetting { id @@ -21728,6 +21737,7 @@ export const UpdateInteractivitySettingsDocument = /*#__PURE__*/ gql` cursor longTemplate shortTemplate + title } } } @@ -21839,6 +21849,7 @@ export const InteractivitySettingsByIdDocument = /*#__PURE__*/ gql` longTemplate shortTemplate type + title } } `; diff --git a/packages/client/src/projects/ProjectApp.tsx b/packages/client/src/projects/ProjectApp.tsx index 152fd6b42..4c3775c0d 100644 --- a/packages/client/src/projects/ProjectApp.tsx +++ b/packages/client/src/projects/ProjectApp.tsx @@ -1,7 +1,7 @@ import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import bytes from "bytes"; -import React, { Suspense, useState, useMemo } from "react"; +import React, { Suspense, useState, useMemo, createContext } from "react"; import { Route, useHistory, useParams, useRouteMatch } from "react-router-dom"; import MapboxMap from "../components/MapboxMap"; import { @@ -46,6 +46,12 @@ const LazyCacheSettingsPage = React.lazy( ) ); + +export const FullSidebarContext = createContext({ + open: false, + setOpen: (open: boolean) => { }, +}); + export default function ProjectApp() { const [mapContainerPortal, setMapContainerPortal] = useState(null); @@ -70,6 +76,7 @@ export default function ProjectApp() { // eslint-disable-next-line `/${slug}/app/:sidebar` ); + const [expandSidebar, setExpandSidebar] = useState(!showSidebar); const { t, i18n } = useTranslation("sidebar"); const sidebarTitles: { [key: string]: string } = { @@ -89,169 +96,170 @@ export default function ProjectApp() {
- - {/* */} - - - - {/* */} -
- - setExpandSidebar(false)} - mapSettingsPopupActions={ - <> - - - { - // if ( - // mapContext.digitizingLockState === - // DigitizingLockState.Free - // ) { - // mapContext.manager?.measure(); - // } else if ( - // mapContext.digitizingLockedBy === "MeasureControl" - // ) { - // mapContext.manager?.cancelMeasurement(); - // } else { - // // do nothing. Don't interfere with sketching - // } - // }} - /> - - } + + + {/* */} + + + + {/* */} +
+ + setExpandSidebar(false)} + mapSettingsPopupActions={ + <> + + + { + // if ( + // mapContext.digitizingLockState === + // DigitizingLockState.Free + // ) { + // mapContext.manager?.measure(); + // } else if ( + // mapContext.digitizingLockedBy === "MeasureControl" + // ) { + // mapContext.manager?.cancelMeasurement(); + // } else { + // // do nothing. Don't interfere with sketching + // } + // }} + /> + + } + /> +
+
+ { + setExpandSidebar((prev) => !prev); + history.replace(`/${slug}/app`); + }} /> -
-
- { - setExpandSidebar((prev) => !prev); - history.replace(`/${slug}/app`); - }} - /> - - history.push(`/${slug}/app`)} - /> - - - history.replace(`/${slug}/app`)} - dark={dark} - hidden={Boolean(!showSidebar)} - noPadding={ - /sketches/.test(history.location.pathname) || - /forums/.test(history.location.pathname) - } - > - - -
+ + history.push(`/${slug}/app`)} + /> + + + history.replace(`/${slug}/app`)} + dark={dark} + hidden={Boolean(!showSidebar)} + noPadding={ + /sketches/.test(history.location.pathname) || + /forums/.test(history.location.pathname) } > - + +
+ } + > + - - - - - - - { - return ( - - - - - { - setExpandSidebar((prev) => false); - }} - /> - - - - - - + /> + ( +
); } diff --git a/packages/client/src/projects/ProjectAppSidebar.tsx b/packages/client/src/projects/ProjectAppSidebar.tsx index db36f11cc..ea628a3d0 100644 --- a/packages/client/src/projects/ProjectAppSidebar.tsx +++ b/packages/client/src/projects/ProjectAppSidebar.tsx @@ -49,9 +49,8 @@ const ProjectAppSidebar: React.FunctionComponent<{ // bounce: false, // }, // }} - className={`flex-col flex absolute left-16 top-0 h-full overflow-hidden z-10 ${ - props.dark ? "bg-gray-50" : "bg-gray-50" - } w-72 md:w-96 2xl:w-128`} + className={`flex-col flex absolute left-16 top-0 h-full overflow-hidden z-10 ${props.dark ? "bg-gray-50" : "bg-gray-50" + } w-72 md:w-96 2xl:w-128`} style={{ boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 2px 0 rgba(0, 0, 0, 0.06)", @@ -82,9 +81,8 @@ const ProjectAppSidebar: React.FunctionComponent<{
{props.children}
diff --git a/packages/client/src/queries/BasemapAdmin.graphql b/packages/client/src/queries/BasemapAdmin.graphql index 8c110f31a..f1fe5c37a 100644 --- a/packages/client/src/queries/BasemapAdmin.graphql +++ b/packages/client/src/queries/BasemapAdmin.graphql @@ -8,6 +8,7 @@ fragment BasemapDetails on Basemap { longTemplate shortTemplate type + title } labelsLayerId name diff --git a/packages/client/src/queries/DraftTableOfContents.graphql b/packages/client/src/queries/DraftTableOfContents.graphql index e355f773c..d98c6b8ac 100644 --- a/packages/client/src/queries/DraftTableOfContents.graphql +++ b/packages/client/src/queries/DraftTableOfContents.graphql @@ -59,6 +59,7 @@ query layersAndSourcesForItems( longTemplate shortTemplate type + title } staticId sprites { @@ -397,6 +398,7 @@ query InteractivitySettingsForLayer($layerId: Int!) { longTemplate shortTemplate type + title } } } @@ -407,6 +409,7 @@ mutation UpdateInteractivitySettings( $cursor: CursorType $longTemplate: String $shortTemplate: String + $title: String ) { updateInteractivitySetting( input: { @@ -416,6 +419,7 @@ mutation UpdateInteractivitySettings( cursor: $cursor longTemplate: $longTemplate shortTemplate: $shortTemplate + title: $title } } ) { @@ -425,6 +429,7 @@ mutation UpdateInteractivitySettings( cursor longTemplate shortTemplate + title } } } @@ -539,6 +544,7 @@ query InteractivitySettingsById($id: Int!) { longTemplate shortTemplate type + title } } diff --git a/packages/client/src/queries/PublishedTableOfContents.graphql b/packages/client/src/queries/PublishedTableOfContents.graphql index 796976e29..f9dab1f40 100644 --- a/packages/client/src/queries/PublishedTableOfContents.graphql +++ b/packages/client/src/queries/PublishedTableOfContents.graphql @@ -91,5 +91,6 @@ fragment DataLayerDetails on DataLayer { longTemplate shortTemplate type + title } } diff --git a/packages/mapbox-gl-esri-sources/package-lock.json b/packages/mapbox-gl-esri-sources/package-lock.json index 718d81348..d076b1f29 100644 --- a/packages/mapbox-gl-esri-sources/package-lock.json +++ b/packages/mapbox-gl-esri-sources/package-lock.json @@ -7,7 +7,6 @@ "": { "name": "@seasketch/mapbox-gl-esri-sources", "version": "0.9.0", - "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { "@mapbox/tilebelt": "^1.0.2",