Merge pull request #2101 from Adam-it/react-find-parker-webpart
new react webpart for Halloween 🎃🎃🎃 (react-find-parker)
33
samples/react-find-parker/.gitignore
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Build generated files
|
||||||
|
dist
|
||||||
|
lib
|
||||||
|
release
|
||||||
|
solution
|
||||||
|
temp
|
||||||
|
*.sppkg
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# OSX
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Visual Studio files
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
.vs
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
|
||||||
|
# Resx Generated Code
|
||||||
|
*.resx.ts
|
||||||
|
|
||||||
|
# Styles Generated Code
|
||||||
|
*.scss.ts
|
16
samples/react-find-parker/.npmignore
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
!dist
|
||||||
|
config
|
||||||
|
|
||||||
|
gulpfile.js
|
||||||
|
|
||||||
|
release
|
||||||
|
src
|
||||||
|
temp
|
||||||
|
|
||||||
|
tsconfig.json
|
||||||
|
tslint.json
|
||||||
|
|
||||||
|
*.log
|
||||||
|
|
||||||
|
.yo-rc.json
|
||||||
|
.vscode
|
13
samples/react-find-parker/.yo-rc.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"plusBeta": false,
|
||||||
|
"isCreatingSolution": true,
|
||||||
|
"environment": "spo",
|
||||||
|
"version": "1.13.0",
|
||||||
|
"libraryName": "react-find-parker",
|
||||||
|
"libraryId": "5659e702-453b-4b73-9ead-fa1859234a18",
|
||||||
|
"packageManager": "npm",
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"componentType": "webpart"
|
||||||
|
}
|
||||||
|
}
|
87
samples/react-find-parker/README.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# Find Parker
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Work is not about work 🤨, sometimes a bit of fun is in order 🕹️.
|
||||||
|
This webpart is a simple find object game.
|
||||||
|

|
||||||
|
|
||||||
|
User may set up how many elements will she or he be looking for in the property pane
|
||||||
|

|
||||||
|
|
||||||
|
By changing the icon svg image we may create a find easter egg 🥚 game or find pumpkins for Halloween 🎃🎃🎃
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
or good old where's Wally game 😉
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
## Applies to
|
||||||
|
|
||||||
|
- [SharePoint Framework](https://aka.ms/spfx)
|
||||||
|
- [Microsoft 365 tenant](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||||
|
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
Solution|Author(s)
|
||||||
|
--------|---------
|
||||||
|
react-find-parker | [Adam Wojcik](https://github.com/Adam-it)
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Version|Date|Comments
|
||||||
|
-------|----|--------
|
||||||
|
1.0|october 31, 2021|Halloween 🎃🎃🎃 & Initial release
|
||||||
|
|
||||||
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
|
- Clone this repository
|
||||||
|
- Ensure that you are at the solution folder
|
||||||
|
- in the command-line run:
|
||||||
|
- `npm install`
|
||||||
|
- `gulp serve`
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
This project contains sample client-side web parts built on the SharePoint Framework using React
|
||||||
|
- using React for building SharePoint Framework client-side web parts
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||||
|
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
|
||||||
|
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you're having issues building the solution, please run [spfx doctor](https://pnp.github.io/cli-microsoft365/cmd/spfx/spfx-doctor/) from within the solution folder to diagnose incompatibility issues with your environment.
|
||||||
|
|
||||||
|
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/issues?q=label%3Areact-find-parker) to see if anybody else is having the same issues.
|
||||||
|
|
||||||
|
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=label%3Areact-find-parker) and see what the community is saying.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-find-parker&authors=@Adam-it&title=react-find-parker%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-find-parker&authors=@Adam-it&title=react-find-parker%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-find-parker&authors=@Adam-it&title=react-find-parker%20-%20).
|
||||||
|
|
||||||
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-find-parker" />
|
BIN
samples/react-find-parker/assets/config.png
Normal file
After Width: | Height: | Size: 194 KiB |
BIN
samples/react-find-parker/assets/findParker.png
Normal file
After Width: | Height: | Size: 504 KiB |
BIN
samples/react-find-parker/assets/findWally.png
Normal file
After Width: | Height: | Size: 100 KiB |
BIN
samples/react-find-parker/assets/findpumpkin.png
Normal file
After Width: | Height: | Size: 92 KiB |
BIN
samples/react-find-parker/assets/halloween.gif
Normal file
After Width: | Height: | Size: 2.1 MiB |
BIN
samples/react-find-parker/assets/parker.gif
Normal file
After Width: | Height: | Size: 2.0 MiB |
51
samples/react-find-parker/assets/sample.json
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "pnp-sp-dev-spfx-web-parts-react-find-parker",
|
||||||
|
"source": "pnp",
|
||||||
|
"title": "Find Parker",
|
||||||
|
"shortDescription": "This webpart is a simple find object game.",
|
||||||
|
"url": "https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-find-parker",
|
||||||
|
"longDescription": [
|
||||||
|
"Work is not about work 🤨, sometimes a bit of fun is in order 🕹️",
|
||||||
|
"This webpart is a simple find object game."
|
||||||
|
],
|
||||||
|
"creationDateTime": "2021-10-31",
|
||||||
|
"updateDateTime": "2021-10-31",
|
||||||
|
"products": [
|
||||||
|
"SharePoint",
|
||||||
|
"Office"
|
||||||
|
],
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"key": "CLIENT-SIDE-DEV",
|
||||||
|
"value": "React"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SPFX-VERSION",
|
||||||
|
"value": "1.13.0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thumbnails": [
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"order": 100,
|
||||||
|
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-find-parker/assets/parker.gif",
|
||||||
|
"alt": "Find Parker"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"gitHubAccount": "Adam-it",
|
||||||
|
"pictureUrl": "https://github.com/Adam-it.png",
|
||||||
|
"name": "Adam Wojcik"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Build your first SharePoint client-side web part",
|
||||||
|
"description": "Client-side web parts are client-side components that run in the context of a SharePoint page. Client-side web parts can be deployed to SharePoint environments that support the SharePoint Framework. You can also use modern JavaScript web frameworks, tools, and libraries to build them.",
|
||||||
|
"url": "https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
18
samples/react-find-parker/config/config.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||||
|
"version": "2.0",
|
||||||
|
"bundles": {
|
||||||
|
"find-parker-web-part": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"entrypoint": "./lib/webparts/findParker/FindParkerWebPart.js",
|
||||||
|
"manifest": "./src/webparts/findParker/FindParkerWebPart.manifest.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"externals": {},
|
||||||
|
"localizedResources": {
|
||||||
|
"FindParkerWebPartStrings": "lib/webparts/findParker/loc/{locale}.js"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||||
|
"workingDir": "./release/assets/",
|
||||||
|
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||||
|
"container": "react-find-parker",
|
||||||
|
"accessKey": "<!-- ACCESS KEY -->"
|
||||||
|
}
|
21
samples/react-find-parker/config/package-solution.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||||
|
"solution": {
|
||||||
|
"name": "react-find-parker-client-side-solution",
|
||||||
|
"id": "5659e702-453b-4b73-9ead-fa1859234a18",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"includeClientSideAssets": true,
|
||||||
|
"skipFeatureDeployment": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"developer": {
|
||||||
|
"name": "",
|
||||||
|
"websiteUrl": "",
|
||||||
|
"privacyUrl": "",
|
||||||
|
"termsOfUseUrl": "",
|
||||||
|
"mpnId": "Undefined-1.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"zippedPackage": "solution/react-find-parker.sppkg"
|
||||||
|
}
|
||||||
|
}
|
6
samples/react-find-parker/config/serve.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||||
|
"port": 4321,
|
||||||
|
"https": true,
|
||||||
|
"initialPage": "https://tenanttocheck.sharepoint.com/_layouts/workbench.aspx"
|
||||||
|
}
|
4
samples/react-find-parker/config/write-manifests.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||||
|
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||||
|
}
|
16
samples/react-find-parker/gulpfile.js
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
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.`);
|
||||||
|
|
||||||
|
var getTasks = build.rig.getTasks;
|
||||||
|
build.rig.getTasks = function () {
|
||||||
|
var result = getTasks.call(build.rig);
|
||||||
|
|
||||||
|
result.set('serve', result.get('serve-deprecated'));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
build.initialize(require('gulp'));
|
21373
samples/react-find-parker/package-lock.json
generated
Normal file
32
samples/react-find-parker/package.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "react-find-parker",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "gulp bundle",
|
||||||
|
"clean": "gulp clean",
|
||||||
|
"test": "gulp test"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": "16.13.1",
|
||||||
|
"react-dom": "16.13.1",
|
||||||
|
"office-ui-fabric-react": "7.174.1",
|
||||||
|
"@microsoft/sp-core-library": "1.13.0",
|
||||||
|
"@microsoft/sp-property-pane": "1.13.0",
|
||||||
|
"@microsoft/sp-webpart-base": "1.13.0",
|
||||||
|
"@microsoft/sp-lodash-subset": "1.13.0",
|
||||||
|
"@microsoft/sp-office-ui-fabric-core": "1.13.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "16.9.51",
|
||||||
|
"@types/react-dom": "16.9.8",
|
||||||
|
"@microsoft/sp-build-web": "1.13.0",
|
||||||
|
"@microsoft/sp-tslint-rules": "1.13.0",
|
||||||
|
"@microsoft/sp-module-interfaces": "1.13.0",
|
||||||
|
"@microsoft/rush-stack-compiler-3.9": "0.4.47",
|
||||||
|
"gulp": "~4.0.2",
|
||||||
|
"ajv": "~5.2.2",
|
||||||
|
"@types/webpack-env": "1.13.1"
|
||||||
|
}
|
||||||
|
}
|
1
samples/react-find-parker/src/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
|
"id": "5a233f7d-d5aa-4af4-97b3-ada5befdf3cf",
|
||||||
|
"alias": "FindParkerWebPart",
|
||||||
|
"componentType": "WebPart",
|
||||||
|
|
||||||
|
// The "*" signifies that the version should be taken from the package.json
|
||||||
|
"version": "*",
|
||||||
|
"manifestVersion": 2,
|
||||||
|
|
||||||
|
// If true, the component can only be installed on sites where Custom Script is allowed.
|
||||||
|
// Components that allow authors to embed arbitrary script code should set this to true.
|
||||||
|
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||||
|
"requiresCustomScript": false,
|
||||||
|
"supportedHosts": ["SharePointWebPart", "TeamsPersonalApp", "TeamsTab", "SharePointFullPage"],
|
||||||
|
"supportsThemeVariants": true,
|
||||||
|
|
||||||
|
"preconfiguredEntries": [{
|
||||||
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||||
|
"group": { "default": "Other" },
|
||||||
|
"title": { "default": "FindParker" },
|
||||||
|
"description": { "default": "FindParker description" },
|
||||||
|
"officeFabricIconFontName": "Page",
|
||||||
|
"properties": {
|
||||||
|
"numberOfElements": 3
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactDom from 'react-dom';
|
||||||
|
import * as strings from 'FindParkerWebPartStrings';
|
||||||
|
import { Version } from '@microsoft/sp-core-library';
|
||||||
|
import { IPropertyPaneConfiguration, PropertyPaneSlider } from '@microsoft/sp-property-pane';
|
||||||
|
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||||
|
import FindParker from './components/FindParker/FindParker';
|
||||||
|
import { IFindParkerProps } from './components//FindParker/IFindParkerProps';
|
||||||
|
import { IFindParkerWebPartProps } from './IFindParkerWebPartProps';
|
||||||
|
|
||||||
|
export default class FindParkerWebPart extends BaseClientSideWebPart<IFindParkerWebPartProps> {
|
||||||
|
|
||||||
|
public render(): void {
|
||||||
|
const element: React.ReactElement<IFindParkerProps> = React.createElement(
|
||||||
|
FindParker,
|
||||||
|
{
|
||||||
|
numberOfElements: this.properties.numberOfElements
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ReactDom.render(element, this.domElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onDispose(): void {
|
||||||
|
ReactDom.unmountComponentAtNode(this.domElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get dataVersion(): Version {
|
||||||
|
return Version.parse('1.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||||
|
return {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
header: {
|
||||||
|
description: strings.PropertyPaneDescription
|
||||||
|
},
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
groupName: strings.PropertyPaneBasicGroupName,
|
||||||
|
groupFields: [
|
||||||
|
PropertyPaneSlider('numberOfElements', {
|
||||||
|
label: strings.PropertyPaneNumberOfElementsFieldLabel,
|
||||||
|
min: 1,
|
||||||
|
max: 20,
|
||||||
|
value: 5,
|
||||||
|
showValue: true,
|
||||||
|
step: 1
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export interface IFindParkerWebPartProps {
|
||||||
|
numberOfElements: number;
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
@import "~office-ui-fabric-react/dist/sass/References.scss";
|
||||||
|
@import "../../../styles/Common.module.scss";
|
||||||
|
|
||||||
|
.findParker {
|
||||||
|
.container {
|
||||||
|
background-color: $neutralLight;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
|
||||||
|
.row {
|
||||||
|
@include ms-Grid-row;
|
||||||
|
|
||||||
|
.column {
|
||||||
|
@include ms-Grid-col;
|
||||||
|
@include ms-lg10;
|
||||||
|
@include ms-xl8;
|
||||||
|
@include ms-xlPush2;
|
||||||
|
@include ms-lgPush1;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
@include ms-font-xxl;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
@include ms-font-m;
|
||||||
|
text-align: justify;
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.parkersContener {
|
||||||
|
.parker {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,163 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import * as strings from 'FindParkerWebPartStrings';
|
||||||
|
import styles from './FindParker.module.scss';
|
||||||
|
import { IFindParkerProps } from './IFindParkerProps';
|
||||||
|
import { IFindParkerState } from './IFindParkerState';
|
||||||
|
import { DefaultButton } from '@microsoft/office-ui-fabric-react-bundle/node_modules/office-ui-fabric-react/lib/Button';
|
||||||
|
import Constants from '../../model/Constants';
|
||||||
|
import Icon from '../../model/Icon';
|
||||||
|
import IParker from '../../model/IParker';
|
||||||
|
|
||||||
|
export default class FindParker extends React.Component<IFindParkerProps, IFindParkerState> {
|
||||||
|
|
||||||
|
constructor(props: IFindParkerProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
numberOfFoundElements: 0,
|
||||||
|
gameStarted: false,
|
||||||
|
gameFinsihed: false,
|
||||||
|
foundPlaceForParkers: false,
|
||||||
|
listOfParkers: [],
|
||||||
|
elements: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public componentDidMount(): void {
|
||||||
|
const { numberOfElements } = this.props;
|
||||||
|
|
||||||
|
if(document.querySelector(Constants.mainPageContent) === null){
|
||||||
|
this.setState({ foundPlaceForParkers: false });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const listOfParkers = this.createListOfParkers(numberOfElements);
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
listOfParkers: listOfParkers,
|
||||||
|
foundPlaceForParkers: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): React.ReactElement<IFindParkerProps> {
|
||||||
|
|
||||||
|
const {
|
||||||
|
gameStarted,
|
||||||
|
gameFinsihed,
|
||||||
|
foundPlaceForParkers,
|
||||||
|
numberOfFoundElements,
|
||||||
|
elements } = this.state;
|
||||||
|
const { numberOfElements } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div id='findParkerId' className={styles.findParker}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.row}>
|
||||||
|
<div className={styles.column}>
|
||||||
|
<p className={styles.title}>{strings.GameTitle}</p>
|
||||||
|
{foundPlaceForParkers ?
|
||||||
|
<p className={styles.label}>{strings.GameDescription}</p>
|
||||||
|
:
|
||||||
|
<p className={styles.label}>{strings.CouldNotFindPlaceForParkersDescription}</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{!gameStarted ?
|
||||||
|
<div className={styles.row}>
|
||||||
|
<div className={styles.column}>
|
||||||
|
{foundPlaceForParkers ?
|
||||||
|
<DefaultButton onClick={() => this.startGame()}>{strings.StartGameButton}</DefaultButton>
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div className={styles.row}>
|
||||||
|
{!gameFinsihed ?
|
||||||
|
<div className={styles.column}>
|
||||||
|
<p className={styles.label}>{strings.GameProgressELementsLabel} <strong>{numberOfElements}</strong></p>
|
||||||
|
<p className={styles.label}>{strings.GameProgressLabel} <strong>{numberOfFoundElements}</strong></p>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div className={styles.column}>
|
||||||
|
<p className={styles.label}>{strings.EndGameMessage}</p>
|
||||||
|
<DefaultButton onClick={() => this.restartGame()}>{strings.RestartGameButton}</DefaultButton>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div className={styles.parkersContener}>
|
||||||
|
{elements}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderParkers(listOfParkers: Array<IParker>): void {
|
||||||
|
let items = [];
|
||||||
|
listOfParkers.forEach(parker => {
|
||||||
|
const style = {
|
||||||
|
top: parker.top,
|
||||||
|
left: parker.left,
|
||||||
|
transform: parker.transform
|
||||||
|
};
|
||||||
|
items.push(<img alt='pnpParker' src={Icon.svg} width='65' className={styles.parker} style={style} onClick={() => this.parkerFound(parker.id)} />);
|
||||||
|
});
|
||||||
|
this.setState({ elements: items });
|
||||||
|
}
|
||||||
|
|
||||||
|
private parkerFound(id: number): void {
|
||||||
|
let numberOfFoundElements = this.state.numberOfFoundElements + 1;
|
||||||
|
this.setState({ numberOfFoundElements: numberOfFoundElements });
|
||||||
|
let parkers = this.state.listOfParkers;
|
||||||
|
parkers = parkers.filter(parker => parker.id !== id);
|
||||||
|
this.setState({ listOfParkers: parkers });
|
||||||
|
this.renderParkers(parkers);
|
||||||
|
|
||||||
|
if (numberOfFoundElements === this.props.numberOfElements) {
|
||||||
|
this.setState({ gameFinsihed: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private startGame(): void {
|
||||||
|
this.setState({ gameStarted: true });
|
||||||
|
this.renderParkers(this.state.listOfParkers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private restartGame(): void {
|
||||||
|
const { numberOfElements } = this.props;
|
||||||
|
this.setState({ gameFinsihed: false });
|
||||||
|
const listOfParkers = this.createListOfParkers(numberOfElements);
|
||||||
|
this.setState({
|
||||||
|
listOfParkers: listOfParkers,
|
||||||
|
numberOfFoundElements: 0
|
||||||
|
});
|
||||||
|
this.renderParkers(listOfParkers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private createListOfParkers(numberOfElements: number): Array<IParker> {
|
||||||
|
const pageHeight: number = document.querySelector(Constants.mainPageContent).scrollHeight;
|
||||||
|
const pageWidth: number = document.querySelector(Constants.mainPageContent).scrollWidth;
|
||||||
|
const findParkerWebPart = document.getElementById('findParkerId').getBoundingClientRect();
|
||||||
|
let listOfParkers = [];
|
||||||
|
for (let index = 0; index < numberOfElements; index++) {
|
||||||
|
const y: number = this.randomNumber((0 - findParkerWebPart.y + 185), (pageHeight - findParkerWebPart.y - 300));
|
||||||
|
const x: number = this.randomNumber((0 - findParkerWebPart.x + 100), (pageWidth - findParkerWebPart.x - 300));
|
||||||
|
const rotate: number = this.randomNumber(0, 180);
|
||||||
|
const parker: IParker = {
|
||||||
|
id: index,
|
||||||
|
left: x,
|
||||||
|
top: y,
|
||||||
|
transform: `rotate(${rotate}deg)`
|
||||||
|
};
|
||||||
|
listOfParkers.push(parker);
|
||||||
|
}
|
||||||
|
|
||||||
|
return listOfParkers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private randomNumber(min: number, max: number): number {
|
||||||
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export interface IFindParkerProps {
|
||||||
|
numberOfElements: number;
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
import IParker from "../../model/IParker";
|
||||||
|
|
||||||
|
export interface IFindParkerState {
|
||||||
|
numberOfFoundElements: number;
|
||||||
|
listOfParkers: Array<IParker>;
|
||||||
|
elements: Array<React.ReactElement>;
|
||||||
|
gameStarted: boolean;
|
||||||
|
gameFinsihed: boolean;
|
||||||
|
foundPlaceForParkers: boolean;
|
||||||
|
}
|
15
samples/react-find-parker/src/webparts/findParker/loc/en-us.js
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
define([], function() {
|
||||||
|
return {
|
||||||
|
"PropertyPaneDescription": "Settings",
|
||||||
|
"PropertyPaneBasicGroupName": "Elements settings",
|
||||||
|
"PropertyPaneNumberOfElementsFieldLabel": "number of elements to find",
|
||||||
|
"GameTitle": "Find Parker",
|
||||||
|
"GameDescription": "🎯 The goal of the game is to find all elements on the page.",
|
||||||
|
"CouldNotFindPlaceForParkersDescription": "🙄 Your page seems strange, I don't see any playground to play here 😉",
|
||||||
|
"StartGameButton": "🎮 Start the game !",
|
||||||
|
"RestartGameButton": "🎮 It was fun, lets try again",
|
||||||
|
"EndGameMessage": "Congrats! You are awesome 👍👍👍",
|
||||||
|
"GameProgressELementsLabel": "🔍 Elements to find: ",
|
||||||
|
"GameProgressLabel": "👉 You found: "
|
||||||
|
}
|
||||||
|
});
|
18
samples/react-find-parker/src/webparts/findParker/loc/mystrings.d.ts
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
declare interface IFindParkerWebPartStrings {
|
||||||
|
PropertyPaneDescription: string;
|
||||||
|
PropertyPaneBasicGroupName: string;
|
||||||
|
PropertyPaneNumberOfElementsFieldLabel: string;
|
||||||
|
GameTitle: string;
|
||||||
|
GameDescription: string;
|
||||||
|
CouldNotFindPlaceForParkersDescription: string;
|
||||||
|
StartGameButton: string;
|
||||||
|
RestartGameButton: string;
|
||||||
|
EndGameMessage: string;
|
||||||
|
GameProgressELementsLabel: string;
|
||||||
|
GameProgressLabel: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'FindParkerWebPartStrings' {
|
||||||
|
const strings: IFindParkerWebPartStrings;
|
||||||
|
export = strings;
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export default class Constants {
|
||||||
|
public static mainPageContent: string = 'div[data-automation-id=\'contentScrollRegion\'][role=\'main\']';
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
export default class IParker {
|
||||||
|
public id: number;
|
||||||
|
public top: number;
|
||||||
|
public left: number;
|
||||||
|
public transform: string;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
@import "~office-ui-fabric-react/dist/sass/References.scss";
|
||||||
|
|
||||||
|
// colors
|
||||||
|
$themePrimary: "[theme: themePrimary, default: #0078d7]";
|
||||||
|
$themeLighterAlt: "[theme: themeLighterAlt, default: #eff6fc]";
|
||||||
|
$themeLighter: "[theme: themeLighter, default: #deecf9]";
|
||||||
|
$themeLight: "[theme: themeLight, default: #c7e0f4]";
|
||||||
|
$themeTertiary: "[theme: themeTertiary, default: #71afe5]";
|
||||||
|
$themeSecondary: "[theme: themeSecondary, default: #2b88d8]";
|
||||||
|
$themeDarkAlt: "[theme: themeDarkAlt, default: #106ebe]";
|
||||||
|
$themeDark: "[theme: themeDark, default: #005a9e]";
|
||||||
|
$themeDarker: "[theme: themeDarker, default: #004578]";
|
||||||
|
$neutralLighterAlt: "[theme: neutralLighterAlt, default: #f8f8f8]";
|
||||||
|
$neutralLighter: "[theme: neutralLighter, default: #f4f4f4]";
|
||||||
|
$neutralLight: "[theme: neutralLight, default: #eaeaea]";
|
||||||
|
$neutralQuaternaryAlt: "[theme: neutralQuaternaryAlt, default: #dadada]";
|
||||||
|
$neutralQuaternary: "[theme: neutralQuaternary, default: #d0d0d0]";
|
||||||
|
$neutralTertiaryAlt: "[theme: neutralTertiaryAlt, default: #c8c8c8]";
|
||||||
|
$neutralTertiary: "[theme: neutralTertiary, default: #a6a6a6]";
|
||||||
|
$neutralSecondaryAlt: "[theme: neutralSecondaryAlt, default: #767676]";
|
||||||
|
$neutralSecondary: "[theme: neutralSecondary, default: #666666]";
|
||||||
|
$neutralPrimaryAlt: "[theme: neutralPrimaryAlt, default: #3c3c3c]";
|
||||||
|
$neutralPrimary: "[theme: neutralPrimary, default: #333]";
|
||||||
|
$neutralDark: "[theme: neutralDark, default: #212121]";
|
||||||
|
$black: "[theme: black, default: #000000]";
|
||||||
|
$white: "[theme: white, default: #fff]";
|
||||||
|
$primaryBackground: "[theme: primaryBackground, default: #fff]";
|
||||||
|
$primaryText: "[theme: primaryText, default: #333]";
|
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 542 B |
35
samples/react-find-parker/tsconfig.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.9/includes/tsconfig-web.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"jsx": "react",
|
||||||
|
"declaration": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"outDir": "lib",
|
||||||
|
"inlineSources": false,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"typeRoots": [
|
||||||
|
"./node_modules/@types",
|
||||||
|
"./node_modules/@microsoft"
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
"webpack-env"
|
||||||
|
],
|
||||||
|
"lib": [
|
||||||
|
"es5",
|
||||||
|
"dom",
|
||||||
|
"es2015.collection",
|
||||||
|
"es2015.promise"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx"
|
||||||
|
]
|
||||||
|
}
|
29
samples/react-find-parker/tslint.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
|
||||||
|
"rules": {
|
||||||
|
"class-name": false,
|
||||||
|
"export-name": false,
|
||||||
|
"forin": false,
|
||||||
|
"label-position": false,
|
||||||
|
"member-access": true,
|
||||||
|
"no-arg": false,
|
||||||
|
"no-console": false,
|
||||||
|
"no-construct": false,
|
||||||
|
"no-duplicate-variable": true,
|
||||||
|
"no-eval": false,
|
||||||
|
"no-function-expression": true,
|
||||||
|
"no-internal-module": true,
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
"no-switch-case-fall-through": true,
|
||||||
|
"no-unnecessary-semicolons": true,
|
||||||
|
"no-unused-expression": true,
|
||||||
|
"no-with-statement": true,
|
||||||
|
"semicolon": true,
|
||||||
|
"trailing-comma": false,
|
||||||
|
"typedef": false,
|
||||||
|
"typedef-whitespace": false,
|
||||||
|
"use-named-parameter": true,
|
||||||
|
"variable-name": false,
|
||||||
|
"whitespace": false
|
||||||
|
}
|
||||||
|
}
|