First Release
This commit is contained in:
parent
ace849b28e
commit
4c9a148dbf
|
@ -19,3 +19,4 @@ npm i react-leaflet-markercluster
|
|||
npm run serve
|
||||
npm install @pnp/spfx-property-controls --save --save-exact
|
||||
npm run serve
|
||||
gulp clean; gulp build; gulp bundle --ship; gulp package-solution --ship;
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "SPFx app dev Map Webpart",
|
||||
"name": "SPFx app dev - interactive map webpart",
|
||||
"id": "cc048abe-6531-4295-ab7a-12a1c95de606",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false,
|
||||
"developer": {
|
||||
"name": "",
|
||||
"websiteUrl": "",
|
||||
"name": "Sergej Schwabauer",
|
||||
"websiteUrl": "https://spfx-app.dev/",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"mpnId": "Undefined-1.14.0"
|
||||
},
|
||||
"metadata": {
|
||||
"shortDescription": {
|
||||
"default": "spfxappdev.webparts.map description"
|
||||
"default": "Includes an interactive map module with which you can create markers"
|
||||
},
|
||||
"longDescription": {
|
||||
"default": "spfxappdev.webparts.map description"
|
||||
"default": "Includes an interactive map module with which you can create markers"
|
||||
},
|
||||
"screenshotPaths": [],
|
||||
"videoUrl": "",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
const build = require('@microsoft/sp-build-web');
|
||||
|
||||
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||
build.addSuppression(/Warning - \[sass\] The local CSS class/gi);
|
||||
|
||||
var getTasks = build.rig.getTasks;
|
||||
build.rig.getTasks = function () {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "spfxappdev-webparts-map",
|
||||
"version": "0.0.1",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -21,7 +21,7 @@ export class InlineColorPicker extends React.Component<IInlineColorPickerProps,
|
|||
public static defaultProps: IInlineColorPickerProps = {
|
||||
color: '#000000',
|
||||
isDisbaled: false
|
||||
}
|
||||
};
|
||||
|
||||
private targetElement: HTMLDivElement = null;
|
||||
|
||||
|
|
|
@ -24,11 +24,12 @@
|
|||
"de-de": "Interaktive Karte"
|
||||
},
|
||||
"description": {
|
||||
"default": "Map description"
|
||||
"default": "An interactive map with which you can create markers",
|
||||
"de-de": "Eine interactive Karte mit der man Markierungen erstellen kann"
|
||||
},
|
||||
"officeFabricIconFontName": "MapPin",
|
||||
"properties": {
|
||||
"title": "Map",
|
||||
"title": "",
|
||||
"markerItems": [],
|
||||
"markerCategories": [],
|
||||
"center": [51.505, -0.09],
|
||||
|
|
|
@ -215,8 +215,13 @@ export default class MapWebPart extends BaseClientSideWebPart<IMapWebPartProps>
|
|||
groupName: strings.WebPartPropertyGroupAbout,
|
||||
groupFields: [
|
||||
PropertyPaneWebPartInformation({
|
||||
description: `This is a <strong>demo webpart</strong>, used to demonstrate all the <a href="https://aka.ms/sppnp">PnP</a> property controls`,
|
||||
moreInfoLink: `https://pnp.github.io/sp-dev-fx-property-controls/`,
|
||||
description: `<h3>Author</h3>
|
||||
<a href='https://spfx-app.dev/'>SPFx-App.dev</a>
|
||||
<h3>Version</h3>
|
||||
${this.context.manifest.version}
|
||||
<h3>Web Part Instance id</h3>
|
||||
${this.context.instanceId}`,
|
||||
moreInfoLink: `https://spfx-app.dev/`,
|
||||
key: '3f860b48-1dc3-496d-bd28-b145672289cc'
|
||||
})
|
||||
]
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import * as React from 'react';
|
||||
import { IMarker, IMarkerCategory, MarkerType } from './IMapProps';
|
||||
import './Map.module.scss';
|
||||
import { clone } from '@microsoft/sp-lodash-subset';
|
||||
import { cloneDeep } from '@microsoft/sp-lodash-subset';
|
||||
import { Icon, Panel, TextField, IPanelProps, PrimaryButton, DefaultButton, IChoiceGroupOption, ChoiceGroup, IDropdownOption, Dropdown, getColorFromString, IColor, PanelType, Label, TooltipHost } from 'office-ui-fabric-react';
|
||||
import { Guid } from '@microsoft/sp-core-library';
|
||||
import { isNullOrEmpty, isFunction } from '@spfxappdev/utility';
|
||||
|
@ -35,9 +35,9 @@ interface IAddOrEditPanelState {
|
|||
export default class AddOrEditPanel extends React.Component<IAddOrEditPanelProps, IAddOrEditPanelState> {
|
||||
|
||||
public state: IAddOrEditPanelState = {
|
||||
markerItem: clone(this.props.markerItem),
|
||||
markerCategories: clone(this.props.markerCategories),
|
||||
isSaveButtonDisabled: true,
|
||||
markerItem: cloneDeep(this.props.markerItem),
|
||||
markerCategories: cloneDeep(this.props.markerCategories),
|
||||
isSaveButtonDisabled: false,
|
||||
isManageCategoriesDialogVisible: false
|
||||
};
|
||||
|
||||
|
@ -63,7 +63,18 @@ export default class AddOrEditPanel extends React.Component<IAddOrEditPanelProps
|
|||
|
||||
this.isNewMarker = this.props.markerItem.id.Equals(Guid.empty.toString());
|
||||
this.headerText = this.isNewMarker ? strings.PanelHeaderNewLabel : strings.PanelHeaderEditLabel;
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: Readonly<IAddOrEditPanelProps>, prevState: Readonly<IAddOrEditPanelState>, snapshot?: any): void {
|
||||
|
||||
if(!JSON.stringify(prevProps.markerCategories).Equals(JSON.stringify(this.props.markerCategories)) ||
|
||||
!JSON.stringify(prevProps.markerItem).Equals(JSON.stringify(this.props.markerItem))) {
|
||||
this.setState({
|
||||
markerCategories: cloneDeep(this.props.markerCategories),
|
||||
markerItem: cloneDeep(this.props.markerItem),
|
||||
isSaveButtonDisabled: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public render(): React.ReactElement<IAddOrEditPanelProps> {
|
||||
|
@ -74,7 +85,7 @@ export default class AddOrEditPanel extends React.Component<IAddOrEditPanelProps
|
|||
<Panel
|
||||
type={PanelType.medium}
|
||||
isOpen={true}
|
||||
onDismiss={() => { this.onConfigPanelDismiss() }}
|
||||
onDismiss={() => { this.onConfigPanelDismiss(); }}
|
||||
headerText={this.headerText}
|
||||
closeButtonAriaLabel={strings.CloseLabel}
|
||||
onRenderFooterContent={(props: IPanelProps) => {
|
||||
|
@ -233,7 +244,7 @@ export default class AddOrEditPanel extends React.Component<IAddOrEditPanelProps
|
|||
return (<></>);
|
||||
}
|
||||
|
||||
const headerLabel: string = this.state.markerItem.type == "Dialog" ? strings.LabelDialogHeader : strings.LabelPanelHeader
|
||||
const headerLabel: string = this.state.markerItem.type == "Dialog" ? strings.LabelDialogHeader : strings.LabelPanelHeader;
|
||||
|
||||
return (<>
|
||||
<TextField label={headerLabel} defaultValue={this.state.markerItem.markerClickProps.content.headerText} onChange={(ev: any, headerText: string) => {
|
||||
|
@ -255,7 +266,7 @@ export default class AddOrEditPanel extends React.Component<IAddOrEditPanelProps
|
|||
return content;
|
||||
}} />
|
||||
|
||||
</>)
|
||||
</>);
|
||||
}
|
||||
|
||||
private renderUrlSettings(): JSX.Element {
|
||||
|
|
|
@ -6,18 +6,18 @@ export type MarkerType = "Panel"|"Dialog"|"Url"|"None";
|
|||
|
||||
export interface IMarkerClickProps {
|
||||
url: IMarkerUrlProperties;
|
||||
content: IMarkerContentProperties
|
||||
content: IMarkerContentProperties;
|
||||
}
|
||||
|
||||
export interface IMarkerUrlProperties {
|
||||
href: string;
|
||||
target: '_self'|'_blank'|'embedded';
|
||||
};
|
||||
}
|
||||
|
||||
export interface IMarkerContentProperties {
|
||||
headerText: string;
|
||||
html: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IMarkerIcon {
|
||||
markerColor: string;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as React from 'react';
|
||||
import { IMarkerCategory } from './IMapProps';
|
||||
import './Map.module.scss';
|
||||
import { clone } from '@microsoft/sp-lodash-subset';
|
||||
import { cloneDeep } from '@microsoft/sp-lodash-subset';
|
||||
import { Icon, Dialog, TextField, PrimaryButton, DefaultButton, getColorFromString, IColor, DialogFooter, DialogContent, DialogType, MessageBar, TooltipHost } from 'office-ui-fabric-react';
|
||||
import { Guid } from '@microsoft/sp-core-library';
|
||||
import { isNullOrEmpty, isFunction } from '@spfxappdev/utility';
|
||||
|
@ -28,7 +28,7 @@ interface IManageMarkerCategoriesDialogState {
|
|||
export default class ManageMarkerCategoriesDialog extends React.Component<IManageMarkerCategoriesDialogProps, IManageMarkerCategoriesDialogState> {
|
||||
|
||||
public state: IManageMarkerCategoriesDialogState = {
|
||||
markerCategories: clone(this.props.markerCategories),
|
||||
markerCategories: cloneDeep(this.props.markerCategories),
|
||||
isSaveButtonDisabled: false,
|
||||
isNewFormVisible: false,
|
||||
isDialogVisible: true
|
||||
|
@ -39,7 +39,7 @@ export default class ManageMarkerCategoriesDialog extends React.Component<IManag
|
|||
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
public componentDidMount(): void {
|
||||
this.validateForm();
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ export default class ManageMarkerCategoriesDialog extends React.Component<IManag
|
|||
{this.state.markerCategories.map((cat: IMarkerCategory, index: number): JSX.Element => {
|
||||
return (<div key={cat.id} className='spfxappdev-grid-row categories-grid' data-catid={cat.id}>
|
||||
{this.renderForm(cat, index)}
|
||||
</div>)
|
||||
</div>);
|
||||
})}
|
||||
</>
|
||||
}
|
||||
|
|
|
@ -252,4 +252,8 @@
|
|||
.category-messagebar {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.CanvasControlToolbar {
|
||||
z-index: 2000 !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import * as React from 'react';
|
|||
import * as ReactDom from 'react-dom';
|
||||
import styles from './Map.module.scss';
|
||||
import { IMapProps, IMarker, IMarkerCategory, IMarkerIcon, emptyMarkerItem } from './IMapProps';
|
||||
import { clone } from '@microsoft/sp-lodash-subset';
|
||||
import { cloneDeep } from '@microsoft/sp-lodash-subset';
|
||||
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
|
||||
import "leaflet/dist/leaflet.css";
|
||||
import "react-leaflet-markercluster/dist/styles.min.css";
|
||||
|
@ -33,8 +33,8 @@ interface IMapState {
|
|||
export default class Map extends React.Component<IMapProps, IMapState> {
|
||||
|
||||
public state: IMapState = {
|
||||
markerItems: clone(this.props.markerItems),
|
||||
markerCategories: clone(this.props.markerCategories),
|
||||
markerItems: cloneDeep(this.props.markerItems),
|
||||
markerCategories: cloneDeep(this.props.markerCategories),
|
||||
showAddOrEditMarkerPanel: false,
|
||||
showClickContent: false,
|
||||
changePositionMarkerId: '-1'
|
||||
|
@ -71,14 +71,14 @@ export default class Map extends React.Component<IMapProps, IMapState> {
|
|||
this.setAllCatagoriesDictionary();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Readonly<IMapProps>, prevState: Readonly<IMapState>, snapshot?: any): void {
|
||||
public componentDidUpdate(prevProps: Readonly<IMapProps>, prevState: Readonly<IMapState>, snapshot?: any): void {
|
||||
|
||||
if(!JSON.stringify(prevProps.markerCategories).Equals(JSON.stringify(this.props.markerCategories))) {
|
||||
this.setState({
|
||||
markerCategories: this.props.markerCategories
|
||||
markerCategories: cloneDeep(this.props.markerCategories)
|
||||
}, () => {
|
||||
this.setAllCatagoriesDictionary();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -105,6 +105,7 @@ export default class Map extends React.Component<IMapProps, IMapState> {
|
|||
maxZoom={this.props.maxZoom}
|
||||
scrollWheelZoom={isScrollWheelZoomEnabled}
|
||||
touchZoom={isScrollWheelZoomEnabled}
|
||||
doubleClickZoom={isScrollWheelZoomEnabled}
|
||||
dragging={isDraggingEnabled}
|
||||
|
||||
whenCreated={(map: L.Map) => {
|
||||
|
@ -329,7 +330,7 @@ export default class Map extends React.Component<IMapProps, IMapState> {
|
|||
</div>
|
||||
</div>
|
||||
<Label style={{}}>{cat.name}</Label>
|
||||
</div>)
|
||||
</div>);
|
||||
})}
|
||||
</div>);
|
||||
}
|
||||
|
@ -352,7 +353,7 @@ export default class Map extends React.Component<IMapProps, IMapState> {
|
|||
return (<Panel
|
||||
type={PanelType.medium}
|
||||
isOpen={true}
|
||||
onDismiss={() => { this.onContentPanelOrDialogDismiss() }}
|
||||
onDismiss={() => { this.onContentPanelOrDialogDismiss(); }}
|
||||
headerText={this.state.currentMarker.markerClickProps.content.headerText}
|
||||
closeButtonAriaLabel="Close"
|
||||
onRenderFooterContent={(props: IPanelProps) => {
|
||||
|
@ -521,12 +522,12 @@ export default class Map extends React.Component<IMapProps, IMapState> {
|
|||
}
|
||||
|
||||
private onCreateNewMarkerContextMenuItemClick(): void {
|
||||
this.state.currentMarker = clone(emptyMarkerItem);
|
||||
this.state.currentMarker = cloneDeep(emptyMarkerItem);
|
||||
this.state.currentMarker.latitude = this.lastLatLngRightClickPosition.lat;
|
||||
this.state.currentMarker.longitude = this.lastLatLngRightClickPosition.lng;
|
||||
this.state.showAddOrEditMarkerPanel = true;
|
||||
|
||||
this.setState({...this.state})
|
||||
this.setState({...this.state});
|
||||
}
|
||||
|
||||
private onSetStartView(): void {
|
||||
|
|
|
@ -18,4 +18,4 @@ export const MarkerIcon: React.FunctionComponent<IMarkerIcon> = (iconProperties)
|
|||
<span className="map-icon" style={iconColor}><Icon iconName={iconProperties.iconName} /></span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue