Skip to content

Commit

Permalink
Merge pull request #959 from Esri/add-share-to-map-card
Browse files Browse the repository at this point in the history
add share to map card
  • Loading branch information
jmhauck authored Oct 15, 2024
2 parents b31a763 + 72d57a4 commit ae93dda
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/assets/t9n/map-card/resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"zoom": "Zoom",
"refresh": "Refresh",
"editMultiple": "Edit multiple",
"clearSelection": "Clear selection"
"clearSelection": "Clear selection",
"share": "Share"
}
3 changes: 2 additions & 1 deletion src/assets/t9n/map-card/resources_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"zoom": "Zoom",
"refresh": "Refresh",
"editMultiple": "Edit multiple",
"clearSelection": "Clear selection"
"clearSelection": "Clear selection",
"share": "Share"
}
24 changes: 24 additions & 0 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,10 @@ export namespace Components {
* boolean: when true the search widget will be available
*/
"enableSearch": boolean;
/**
* boolean: when true the share widget will be available
*/
"enableShare": boolean;
/**
* boolean: when true map tools will be displayed within a single expand/collapse widget when false widgets will be loaded individually into expand widgets
*/
Expand Down Expand Up @@ -1003,6 +1007,14 @@ export namespace Components {
* __esri.FeatureLayer: Selected layer
*/
"selectedLayer": __esri.FeatureLayer;
/**
* boolean: When true the share options will include embed option
*/
"shareIncludeEmbed": boolean;
/**
* boolean: When true the share options will include social media sharing
*/
"shareIncludeSocial": boolean;
/**
* boolean: When true the map widget tools will have no margin between them. When false the map widget tools will have a margin between them.
*/
Expand Down Expand Up @@ -3608,6 +3620,10 @@ declare namespace LocalJSX {
* boolean: when true the search widget will be available
*/
"enableSearch"?: boolean;
/**
* boolean: when true the share widget will be available
*/
"enableShare"?: boolean;
/**
* boolean: when true map tools will be displayed within a single expand/collapse widget when false widgets will be loaded individually into expand widgets
*/
Expand Down Expand Up @@ -3688,6 +3704,14 @@ declare namespace LocalJSX {
* __esri.FeatureLayer: Selected layer
*/
"selectedLayer"?: __esri.FeatureLayer;
/**
* boolean: When true the share options will include embed option
*/
"shareIncludeEmbed"?: boolean;
/**
* boolean: When true the share options will include social media sharing
*/
"shareIncludeSocial"?: boolean;
/**
* boolean: When true the map widget tools will have no margin between them. When false the map widget tools will have a margin between them.
*/
Expand Down
3 changes: 3 additions & 0 deletions src/components/crowdsource-manager/crowdsource-manager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@ export class CrowdsourceManager {
enableHome={this.enableHome}
enableLegend={this.enableLegend}
enableSearch={this.enableSearch}
enableShare={this.enableShare}
enableSingleExpand={true}
hidden={!this._isPortraitMobile && isTableLayout}
homeZoomIndex={3}
Expand All @@ -846,6 +847,8 @@ export class CrowdsourceManager {
ref={(el) => this._mapCard = el}
selectedFeaturesIds={this._layerTable?.selectedIds}
selectedLayer={this._layer}
shareIncludeEmbed={this.shareIncludeEmbed}
shareIncludeSocial={this.shareIncludeSocial}
stackTools={true}
theme={this.theme}
toolOrder={["legend", "search", "fullscreen", "basemap", "floorfilter"]}
Expand Down
9 changes: 5 additions & 4 deletions src/components/crowdsource-manager/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ graph TD;
map-card --> calcite-dropdown-group
map-card --> calcite-dropdown-item
map-card --> calcite-loader
map-card --> instant-apps-social-share
map-card --> calcite-tooltip
map-tools --> basemap-gallery
map-tools --> map-search
Expand Down Expand Up @@ -167,6 +168,10 @@ graph TD;
calcite-combobox-item --> calcite-icon
calcite-chip --> calcite-icon
calcite-dropdown-item --> calcite-icon
instant-apps-social-share --> calcite-popover
instant-apps-social-share --> calcite-button
instant-apps-social-share --> calcite-icon
instant-apps-social-share --> calcite-action
card-manager --> calcite-shell
card-manager --> info-card
card-manager --> calcite-flow-item
Expand Down Expand Up @@ -208,10 +213,6 @@ graph TD;
layer-table --> delete-button
layer-table --> calcite-modal
layer-table --> instant-apps-filter-list
instant-apps-social-share --> calcite-popover
instant-apps-social-share --> calcite-button
instant-apps-social-share --> calcite-icon
instant-apps-social-share --> calcite-action
instant-apps-filter-list --> calcite-panel
instant-apps-filter-list --> calcite-loader
instant-apps-filter-list --> calcite-checkbox
Expand Down
110 changes: 109 additions & 1 deletion src/components/map-card/map-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { IBasemapConfig, IMapChange, IMapInfo, ISearchConfiguration, IToolInfo,
import { joinAppProxies } from "templates-common-library-esm/functionality/proxy";
import { getLocaleComponentStrings } from "../../utils/locale";
import { getFeatureLayerView, goToSelection } from "../../utils/mapViewUtils";
import "@esri/instant-apps-components/dist/components/instant-apps-social-share";

// TODO navigation and accessability isn't right for the map list
// tab does not go into the list when it's open
Expand Down Expand Up @@ -84,6 +85,11 @@ export class MapCard {
*/
@Prop() enableFullscreen: boolean;

/**
* boolean: when true the share widget will be available
*/
@Prop() enableShare = false;

/**
* boolean: when true map tools will be displayed within a single expand/collapse widget
* when false widgets will be loaded individually into expand widgets
Expand Down Expand Up @@ -176,6 +182,16 @@ export class MapCard {
*/
@Prop() isMapLayout: boolean;

/**
* boolean: When true the share options will include embed option
*/
@Prop() shareIncludeEmbed: boolean;

/**
* boolean: When true the share options will include social media sharing
*/
@Prop() shareIncludeSocial: boolean;

/**
* number[]: A list of ids that are currently selected
*/
Expand Down Expand Up @@ -329,6 +345,11 @@ export class MapCard {
*/
protected _resizeObserver: ResizeObserver;

/**
* HTMLInstantAppsSocialShareElement: Element to support app sharing to social media
*/
protected _shareNode: HTMLInstantAppsSocialShareElement;

/**
* HTMLCalciteDropdownElement: Dropdown the will support show/hide of table columns
*/
Expand Down Expand Up @@ -373,6 +394,28 @@ export class MapCard {
this._initHome();
}

/**
* Update the toolbar when the share button is enabled/disabled
*/
@Watch("enableShare")
enableShareWatchHandler(): void {
// this should be caught by component did render and is when I test locally
// however have had reported case where it is not somehow on devext so adding explicit check here
if (this._toolbar) {
this._updateToolbar();
}
}

/**
* watch for changes in map view and get the first layer
*/
@Watch("mapView")
async mapViewWatchHandler(): Promise<void> {
if (this.mapView) {
this._updateShareUrl();
}
}

/**
* watch for changes in layer view and verify if it has editing enabled
*/
Expand All @@ -388,6 +431,7 @@ export class MapCard {
*/
@Watch("selectedFeaturesIds")
async selectedFeaturesIdsWatchHandler(): Promise<void> {
this._updateShareUrl();
this._validateEnabledActions();
}

Expand Down Expand Up @@ -421,6 +465,7 @@ export class MapCard {
@Method()
async resetFilter(): Promise<void> {
this._filterActive = false;
this._updateShareUrl();
}

/**
Expand All @@ -429,6 +474,7 @@ export class MapCard {
@Method()
async updateFilterState(): Promise<void> {
this._filterActive = this._definitionExpression !== this.selectedLayer.definitionExpression;
this._updateShareUrl();
}

/**
Expand Down Expand Up @@ -529,6 +575,7 @@ export class MapCard {
{this._getActionBar()}
{/* dropdown actions */}
{!this.isMobile && this.isMapLayout && this._getDropdown("more-table-options")}
{this.enableShare && !this.isMobile ? this._getShare("share") : undefined}
</div>
{/* added calcite progress below header actions to match bottom-border with the split/table view */}
<calcite-progress class={progressClass} value={0} />
Expand Down Expand Up @@ -684,7 +731,7 @@ export class MapCard {
return prev;
}, 0);

const skipControls = ["solutions-more", "solutions-map-layer-picker-container", "map-picker"];
const skipControls = ["solutions-more", "solutions-map-layer-picker-container", "map-picker", "solutions-action-share"];
if (controlsWidth > toolbarWidth) {
if (this._toolbarSizeInfos.length > 0) {
const controlsThatFit = [...this._toolbarSizeInfos].reverse().reduce((prev, cur) => {
Expand Down Expand Up @@ -910,6 +957,67 @@ export class MapCard {
) : undefined;
}

/**
* Get an action and tooltip for share
*
* @param icon string the name of the icon to display, will also be used in its id
*
* @returns VNode The node representing the DOM element that will contain the action
*/
protected _getShare(
icon: string
): VNode {
return (
<div class="share-action" id={this._getId(icon)}>
<instant-apps-social-share
autoUpdateShareUrl={false}
class="instant-app-share"
embed={this.shareIncludeEmbed}
popoverButtonIconScale="s"
ref={el => this._shareNode = el}
scale="m"
shareButtonColor="neutral"
shareButtonType="action"
socialMedia={this.shareIncludeSocial}
view={this.mapView}
/>
{this._getToolTip("bottom", icon, this._translations.share)}
</div>
)
}

/**
* Called each time the values that are used for custom url params change
*/
_updateShareUrl(): void {
const url = this._shareNode?.shareUrl;
if (!url) {
return;
}
const urlObj = new URL(url);

//set the additional search params
if (this._loadedId) {
urlObj.searchParams.set("webmap", this._loadedId);
} else {
urlObj.searchParams.delete("webmap");
}

if (this.selectedLayer?.id) {
urlObj.searchParams.set("layer", this.selectedLayer.id);
} else {
urlObj.searchParams.delete("layer");
}

if (this.selectedFeaturesIds?.length > 0) {
urlObj.searchParams.set("oid", this.selectedFeaturesIds.join(","));
} else {
urlObj.searchParams.delete("oid");
}

this._shareNode.shareUrl = urlObj.href;
}

/**
* Open show/hide dropdown
* @protected
Expand Down
9 changes: 9 additions & 0 deletions src/components/map-card/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
| `enableHome` | `enable-home` | boolean: when true the home widget will be available | `boolean` | `undefined` |
| `enableLegend` | `enable-legend` | boolean: when true the legend widget will be available | `boolean` | `undefined` |
| `enableSearch` | `enable-search` | boolean: when true the search widget will be available | `boolean` | `undefined` |
| `enableShare` | `enable-share` | boolean: when true the share widget will be available | `boolean` | `false` |
| `enableSingleExpand` | `enable-single-expand` | boolean: when true map tools will be displayed within a single expand/collapse widget when false widgets will be loaded individually into expand widgets | `boolean` | `true` |
| `hidden` | `hidden` | boolean: When true the map display will be hidden | `boolean` | `undefined` |
| `homeZoomIndex` | `home-zoom-index` | number: The placement index of the home and zoom components. This index shows where to place the component relative to other components. For example a value of 0 would place it topmost when position is top-*, leftmost for bottom-left and right most for bottom-right. | `number` | `3` |
Expand All @@ -35,6 +36,8 @@
| `onlyShowUpdatableLayers` | `only-show-updatable-layers` | boolean: When true only editable layers that support the update capability will be available | `boolean` | `undefined` |
| `selectedFeaturesIds` | -- | number[]: A list of ids that are currently selected | `number[]` | `undefined` |
| `selectedLayer` | -- | __esri.FeatureLayer: Selected layer | `FeatureLayer` | `undefined` |
| `shareIncludeEmbed` | `share-include-embed` | boolean: When true the share options will include embed option | `boolean` | `undefined` |
| `shareIncludeSocial` | `share-include-social` | boolean: When true the share options will include social media sharing | `boolean` | `undefined` |
| `stackTools` | `stack-tools` | boolean: When true the map widget tools will have no margin between them. When false the map widget tools will have a margin between them. | `boolean` | `true` |
| `theme` | `theme` | theme: "light" \| "dark" theme to be used | `"dark" \| "light"` | `undefined` |
| `toolOrder` | -- | Valid tools: "legend", "search", "fullscreen", "basemap", "floorfilter" | `string[]` | `undefined` |
Expand Down Expand Up @@ -103,6 +106,7 @@ Type: `Promise<void>`
- calcite-dropdown-group
- calcite-dropdown-item
- calcite-loader
- instant-apps-social-share
- calcite-tooltip

### Graph
Expand All @@ -119,6 +123,7 @@ graph TD;
map-card --> calcite-dropdown-group
map-card --> calcite-dropdown-item
map-card --> calcite-loader
map-card --> instant-apps-social-share
map-card --> calcite-tooltip
map-tools --> basemap-gallery
map-tools --> map-search
Expand Down Expand Up @@ -176,6 +181,10 @@ graph TD;
calcite-combobox-item --> calcite-icon
calcite-chip --> calcite-icon
calcite-dropdown-item --> calcite-icon
instant-apps-social-share --> calcite-popover
instant-apps-social-share --> calcite-button
instant-apps-social-share --> calcite-icon
instant-apps-social-share --> calcite-action
crowdsource-manager --> map-card
style map-card fill:#f9f,stroke:#333,stroke-width:4px
```
Expand Down

0 comments on commit ae93dda

Please sign in to comment.