Added Tile V2 webpart
This solution creates a customisable Tiles Webpart, it uses a stored collection from the PnP PropertyFieldCollectionData control and allows the user to choose the colour scheme (theme or custom) and to set the size of the tiles. By default the tiles use a fluid flex layout to use the available screen area.
This commit is contained in:
parent
b821678949
commit
19bd386580
|
@ -0,0 +1,25 @@
|
|||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
|
||||
# change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# we recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[{package,bower}.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -0,0 +1,32 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
|
||||
# Build generated files
|
||||
dist
|
||||
lib
|
||||
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
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"isCreatingSolution": true,
|
||||
"environment": "spo",
|
||||
"version": "1.11.0",
|
||||
"libraryName": "tiles",
|
||||
"libraryId": "d56958d6-9eaf-4500-934b-b421c22a7d1f",
|
||||
"packageManager": "npm",
|
||||
"isDomainIsolated": false,
|
||||
"componentType": "webpart"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
# Tiles-V2
|
||||
|
||||
## Summary
|
||||
|
||||
This solution creates a customisable Tiles Webpart, it uses a stored collection from the PnP PropertyFieldCollectionData control and allows the user to choose the colour scheme (theme or custom) and to set the size of the tiles. By default the tiles use a fluid flex layout to use the available screen area.
|
||||
|
||||
This is a rebuild of the awesome project created by @hugoabernier [https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-tiles] so the credit goes to him!
|
||||
|
||||
[https://github.com/omarelanis/sp-dev-fx-webparts/blob/master/samples/hero-webpart/Sample/Hero-Webpart.gif]
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
|
||||
![version](https://img.shields.io/npm/v/@microsoft/sp-component-base/latest?color=green)
|
||||
|
||||
## 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)
|
||||
|
||||
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)
|
||||
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
tiles-v2 | Omar El-Anis @ SP Bytes www.spbytes.com
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|July 14, 2021|Initial release
|
||||
|
||||
## 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.**
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
Description of the extension that expands upon high-level summary above.
|
||||
|
||||
This extension illustrates the following concepts:
|
||||
|
||||
- Store data (including icons) in a collection from property panel
|
||||
- Allow usage of site theme or custom colours
|
||||
- Set size of tile content based on slider bar
|
||||
- Load the data onto the page to display a tile webpart
|
||||
|
||||
## References
|
||||
|
||||
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||
- [Building for Microsoft teams](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/build-for-teams-overview)
|
||||
- [Use Microsoft Graph in your solution](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-microsoft-graph-apis)
|
||||
- [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
|
Binary file not shown.
After Width: | Height: | Size: 2.0 MiB |
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"tiles-web-part": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/Tiles/TilesWebPart.js",
|
||||
"manifest": "./src/webparts/Tiles/TilesWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"TilesWebPartStrings": "lib/webparts/Tiles/loc/{locale}.js",
|
||||
"PropertyControlStrings": "node_modules/@pnp/spfx-property-controls/lib/loc/{locale}.js",
|
||||
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||
"deployCdnPath": "temp/deploy"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||
"workingDir": "./temp/deploy/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "tiles",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "Tiles V2 Webpart - Modern",
|
||||
"id": "d56958d6-9eaf-4500-934b-b421c22a7d1f",
|
||||
"version": "1.0.0.0",
|
||||
"skipFeatureDeployment": true,
|
||||
"includeClientSideAssets": true,
|
||||
"isDomainIsolated": false,
|
||||
"developer": {
|
||||
"name": "Omar El-Anis",
|
||||
"websiteUrl": "",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"mpnId": ""
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/Tiles_V2_Modern.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||
"port": 4321,
|
||||
"https": true,
|
||||
"initialPage": "https://localhost:5432/workbench",
|
||||
"api": {
|
||||
"port": 5432,
|
||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
'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.`);
|
||||
|
||||
build.initialize(require('gulp'));
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "tiles",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "lib/index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-core-library": "1.11.0",
|
||||
"@microsoft/sp-lodash-subset": "1.11.0",
|
||||
"@microsoft/sp-office-ui-fabric-core": "1.11.0",
|
||||
"@microsoft/sp-property-pane": "1.11.0",
|
||||
"@microsoft/sp-webpart-base": "1.11.0",
|
||||
"@pnp/graph": "^2.2.0",
|
||||
"@pnp/sp": "^2.2.0",
|
||||
"@pnp/spfx-controls-react": "2.5.0",
|
||||
"@pnp/spfx-property-controls": "2.4.0",
|
||||
"office-ui-fabric-react": "^7.164.2",
|
||||
"typestyle": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "1.11.0",
|
||||
"@microsoft/sp-tslint-rules": "1.11.0",
|
||||
"@microsoft/sp-module-interfaces": "1.11.0",
|
||||
"@microsoft/sp-webpart-workbench": "1.11.0",
|
||||
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
||||
"gulp": "~3.9.1",
|
||||
"@types/chai": "3.4.34",
|
||||
"@types/mocha": "2.2.38",
|
||||
"ajv": "~5.2.2",
|
||||
"@types/webpack-env": "1.13.1",
|
||||
"@types/es6-promise": "0.0.33"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "26cb4af3-7f48-4737-b82a-4e24167c2d07",
|
||||
"alias": "Tiles-V2",
|
||||
"componentType": "WebPart",
|
||||
"version": "*",
|
||||
"manifestVersion": 2,
|
||||
"requiresCustomScript": false,
|
||||
"loadLegacyFabricCss": true,
|
||||
"supportedHosts": ["SharePointWebPart","TeamsTab"],
|
||||
"supportsThemeVariants": true,
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70",
|
||||
"group": { "default": "Other" },
|
||||
"title": { "default": "Tiles V2" },
|
||||
"description": { "default": "Tiles V2 Webpart for Modern sites" },
|
||||
"officeFabricIconFontName": "Tiles",
|
||||
"properties": {
|
||||
"title": "Tiles V2"
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,238 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDom from 'react-dom';
|
||||
import * as strings from 'TilesWebPartStrings';
|
||||
import { BaseClientSideWebPart} from '@microsoft/sp-webpart-base';
|
||||
import { ThemeProvider, ThemeChangedEventArgs, IReadonlyTheme} from '@microsoft/sp-component-base';
|
||||
import { IPropertyPaneConfiguration} from "@microsoft/sp-property-pane";
|
||||
import { PropertyPaneToggle,PropertyPaneSlider } from '@microsoft/sp-property-pane';
|
||||
import { Tiles, ITilesProps, ITileInfo, LinkTarget } from './components';
|
||||
import { IconPicker } from '@pnp/spfx-controls-react/lib/IconPicker';
|
||||
import { initializeIcons } from 'office-ui-fabric-react/lib';
|
||||
|
||||
const ThemeColorsFromWindow: any = (window as any).__themeState__.theme;
|
||||
|
||||
export interface ITilesWebPartProps {
|
||||
collectionData: ITileInfo[];
|
||||
tileHeight: number;
|
||||
tileColour: string;
|
||||
tileFont: string;
|
||||
title: string;
|
||||
customColour: boolean;
|
||||
themeVariant: IReadonlyTheme | undefined;
|
||||
ThemeColorsFromWindow: IReadonlyTheme | undefined;
|
||||
}
|
||||
|
||||
export default class TilesWebPart extends BaseClientSideWebPart<ITilesWebPartProps> {
|
||||
private propertyFieldNumber;
|
||||
private propertyFieldCollectionData;
|
||||
private customCollectionFieldType;
|
||||
private propertyFieldColorPicker;
|
||||
private propertyFieldColorPickerStyle;
|
||||
private _themeProvider: ThemeProvider;
|
||||
private _themeVariant: IReadonlyTheme | undefined;
|
||||
|
||||
protected onInit(): Promise<void> {
|
||||
// Consume the new ThemeProvider service
|
||||
this._themeProvider = this.context.serviceScope.consume(ThemeProvider.serviceKey);
|
||||
|
||||
// If it exists, get the theme variant
|
||||
this._themeVariant = this._themeProvider.tryGetTheme();
|
||||
|
||||
// Register a handler to be notified if the theme variant changes
|
||||
this._themeProvider.themeChangedEvent.add(this, this._handleThemeChangedEvent);
|
||||
|
||||
if (this.context.sdks.microsoftTeams)
|
||||
initializeIcons();
|
||||
|
||||
return super.onInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current theme variant reference and re-render.
|
||||
*
|
||||
* @param args The new theme
|
||||
*/
|
||||
private _handleThemeChangedEvent(args: ThemeChangedEventArgs): void {
|
||||
this._themeVariant = args.theme;
|
||||
this.render();
|
||||
}
|
||||
|
||||
|
||||
public render(): void {
|
||||
const element: React.ReactElement<ITilesProps> = React.createElement(
|
||||
Tiles,
|
||||
{
|
||||
title: this.properties.title,
|
||||
tileHeight: this.properties.tileHeight,
|
||||
tileColour: this.properties.tileColour,
|
||||
tileFont: this.properties.tileFont,
|
||||
customColour: this.properties.customColour,
|
||||
collectionData: this.properties.collectionData,
|
||||
displayMode: this.displayMode,
|
||||
themeVariant: this._themeVariant,
|
||||
ThemeColorsFromWindow: ThemeColorsFromWindow,
|
||||
fUpdateProperty: (value: string) => {
|
||||
this.properties.title = value;
|
||||
},
|
||||
fPropertyPaneOpen: this.context.propertyPane.open
|
||||
}
|
||||
);
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
||||
//executes only before property pane is loaded.
|
||||
protected async loadPropertyPaneResources(): Promise<void> {
|
||||
// import additional controls/components
|
||||
const { PropertyFieldColorPicker, PropertyFieldColorPickerStyle } = await import (
|
||||
/* webpackChunkName: 'pnp-propcontrols-number' */
|
||||
'@pnp/spfx-property-controls/lib/PropertyFieldColorPicker'
|
||||
);
|
||||
|
||||
const { PropertyFieldNumber } = await import (
|
||||
/* webpackChunkName: 'pnp-propcontrols-number' */
|
||||
'@pnp/spfx-property-controls/lib/propertyFields/number'
|
||||
);
|
||||
const { PropertyFieldCollectionData, CustomCollectionFieldType } = await import (
|
||||
/* webpackChunkName: 'pnp-propcontrols-colldata' */
|
||||
'@pnp/spfx-property-controls/lib/PropertyFieldCollectionData'
|
||||
);
|
||||
|
||||
this.propertyFieldNumber = PropertyFieldNumber;
|
||||
this.propertyFieldCollectionData = PropertyFieldCollectionData;
|
||||
this.customCollectionFieldType = CustomCollectionFieldType;
|
||||
this.propertyFieldColorPicker = PropertyFieldColorPicker;
|
||||
this.propertyFieldColorPickerStyle = PropertyFieldColorPickerStyle;
|
||||
}
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
let tileColourplaceholder: any = [];
|
||||
let tileFontplaceholder: any = [];
|
||||
if (this.properties.customColour) {
|
||||
tileColourplaceholder = this.propertyFieldColorPicker('tileColour', {
|
||||
key: "tileColour",
|
||||
label: strings.tileColour,
|
||||
selectedColor: this.properties.tileColour,
|
||||
onPropertyChange: this.onPropertyPaneFieldChanged,
|
||||
properties: this.properties,
|
||||
disabled: false,
|
||||
isHidden: false,
|
||||
alphaSliderHidden: false,
|
||||
style: this.propertyFieldColorPickerStyle.Full,
|
||||
iconName: 'Precipitation'
|
||||
});
|
||||
tileFontplaceholder=this.propertyFieldColorPicker('tileFont', {
|
||||
key: "tileFont",
|
||||
label: strings.tileFont,
|
||||
selectedColor: this.properties.tileFont,
|
||||
onPropertyChange: this.onPropertyPaneFieldChanged,
|
||||
properties: this.properties,
|
||||
disabled: false,
|
||||
isHidden: false,
|
||||
alphaSliderHidden: false,
|
||||
style: this.propertyFieldColorPickerStyle.Full,
|
||||
iconName: 'Precipitation'
|
||||
});
|
||||
}
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: strings.PropertyPaneDescription
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupName: "Tile Content",
|
||||
groupFields: [
|
||||
this.propertyFieldCollectionData("collectionData", {
|
||||
key: "collectionData",
|
||||
label: strings.tilesDataLabel,
|
||||
panelHeader: strings.tilesPanelHeader,
|
||||
panelDescription: ``,
|
||||
manageBtnLabel: strings.tilesManageBtn,
|
||||
value: this.properties.collectionData,
|
||||
fields: [
|
||||
{
|
||||
id: "title",
|
||||
title: strings.titleField,
|
||||
type: this.customCollectionFieldType.string,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
id: "description",
|
||||
title: strings.descriptionField,
|
||||
type: this.customCollectionFieldType.string,
|
||||
required: false
|
||||
},
|
||||
{
|
||||
id: "url",
|
||||
title: strings.urlField,
|
||||
type: this.customCollectionFieldType.string,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
id: "icon",
|
||||
title: "Select Icon",
|
||||
type: this.customCollectionFieldType.custom,
|
||||
onCustomRender: (field, value, onUpdate, item, itemId, onError) => {
|
||||
return (
|
||||
React.createElement(IconPicker , {
|
||||
key: itemId,
|
||||
buttonLabel:"Select File",
|
||||
onChange: (iconName: string) => {
|
||||
onUpdate(field.id, iconName);
|
||||
return Event;
|
||||
},
|
||||
onSave: (iconName: string) => {
|
||||
onUpdate(field.id, iconName);
|
||||
return Event;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "target",
|
||||
title: strings.targetField,
|
||||
type: this.customCollectionFieldType.dropdown,
|
||||
options: [
|
||||
{
|
||||
key: LinkTarget.parent,
|
||||
text: strings.targetCurrent
|
||||
},
|
||||
{
|
||||
key: LinkTarget.blank,
|
||||
text: strings.targetNew
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
]},
|
||||
{
|
||||
groupName: "Tile Settings",
|
||||
groupFields: [
|
||||
PropertyPaneSlider('tileHeight', {
|
||||
label: 'Tile Height',
|
||||
max: 300,
|
||||
min: 120,
|
||||
step: 1,
|
||||
showValue: true,
|
||||
value: this.properties.tileHeight
|
||||
}),
|
||||
PropertyPaneToggle('customColour', {
|
||||
key: 'customColourID',
|
||||
label: 'Theme or Custom colours',
|
||||
onText: 'Custom Colours',
|
||||
offText: 'Theme Colours',
|
||||
checked: this.properties.customColour
|
||||
}),
|
||||
tileColourplaceholder,
|
||||
tileFontplaceholder
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
export interface ITileInfo {
|
||||
title: string;
|
||||
description: string;
|
||||
url: string;
|
||||
icon: string;
|
||||
target: LinkTarget;
|
||||
}
|
||||
|
||||
export enum LinkTarget {
|
||||
parent = "",
|
||||
blank = "_blank"
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { ITilesWebPartProps } from './../TilesWebPart';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
|
||||
export interface ITilesProps extends ITilesWebPartProps {
|
||||
displayMode: DisplayMode;
|
||||
|
||||
fUpdateProperty: (value: string) => void;
|
||||
fPropertyPaneOpen: () => void;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import {stylesheet} from 'typestyle';
|
||||
import {IReadonlyTheme} from '@microsoft/sp-component-base';
|
||||
export const createstyles = (theme: IReadonlyTheme) => {
|
||||
return stylesheet({
|
||||
root: {
|
||||
backgroundColor: theme.semanticColors.bodyBackground,
|
||||
},
|
||||
title: {
|
||||
color: theme.palette.themePrimary,
|
||||
fontSize: theme.fonts.large.fontSize
|
||||
}
|
||||
});
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||
$ms-themePrimary: "[theme:themePrimary, default:#0078d7]";
|
||||
$ms-themeSecondary: "[theme:themeSecondary, default:#2488d8]";
|
||||
|
||||
.tiles {
|
||||
.message {
|
||||
@include ms-font-m;
|
||||
}
|
||||
|
||||
.error {
|
||||
@include ms-font-m;
|
||||
color: $ms-color-alert;
|
||||
}
|
||||
|
||||
.tilesList {
|
||||
@include ms-Grid-row;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tileBG{
|
||||
color: $ms-themePrimary;
|
||||
}
|
||||
|
||||
.tileFont{
|
||||
color: $ms-themeSecondary;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import * as React from 'react';
|
||||
import * as strings from 'TilesWebPartStrings';
|
||||
import styles from './Tiles.module.scss';
|
||||
import { ITilesProps } from '.';
|
||||
import { Tile } from './tile';
|
||||
import { WebPartTitle } from '@pnp/spfx-controls-react/lib/WebPartTitle';
|
||||
import { Placeholder } from '@pnp/spfx-controls-react/lib/Placeholder';
|
||||
import {createstyles } from './ThemeVariantTypeStyle.styles';
|
||||
import { css } from "@uifabric/utilities/lib/css";
|
||||
|
||||
export class Tiles extends React.Component<ITilesProps, {}> {
|
||||
|
||||
/**
|
||||
* Default React remder method
|
||||
*/
|
||||
public render(): React.ReactElement<ITilesProps> {
|
||||
const CustomStyles = createstyles(this.props.themeVariant);
|
||||
return (
|
||||
<div className={css(styles.tiles, CustomStyles.root)}>
|
||||
<WebPartTitle displayMode={this.props.displayMode}
|
||||
title={this.props.title}
|
||||
updateProperty={this.props.fUpdateProperty} />
|
||||
|
||||
{
|
||||
this.props.collectionData && this.props.collectionData.length > 0 ? (
|
||||
<div className={styles.tilesList}>
|
||||
{
|
||||
this.props.collectionData.map((tile, idx) =>
|
||||
<Tile key={idx}
|
||||
item={tile}
|
||||
tileHeight={this.props.tileHeight}
|
||||
tileColour={this.props.tileColour}
|
||||
tileFont={this.props.tileFont}
|
||||
customColour={this.props.customColour}
|
||||
themeVariant={this.props.themeVariant}
|
||||
ThemeColorsFromWindow={this.props.ThemeColorsFromWindow}/>)
|
||||
}
|
||||
</div>
|
||||
) : (
|
||||
<Placeholder
|
||||
iconName='Edit'
|
||||
iconText={strings.noTilesIconText}
|
||||
description={strings.noTilesConfigured}
|
||||
buttonLabel={strings.noTilesBtn}
|
||||
onConfigure={this.props.fPropertyPaneOpen} />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './ITilesProps';
|
||||
export * from './ITileInfo';
|
||||
export * from './Tiles';
|
|
@ -0,0 +1,12 @@
|
|||
import { ITileInfo } from '..';
|
||||
import { IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||
|
||||
export interface ITileProps {
|
||||
item: ITileInfo;
|
||||
tileHeight: number;
|
||||
tileColour: string;
|
||||
tileFont: string;
|
||||
customColour:boolean;
|
||||
themeVariant: IReadonlyTheme | undefined;
|
||||
ThemeColorsFromWindow: IReadonlyTheme | undefined;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||
|
||||
.tile {
|
||||
@include ms-Grid-col;
|
||||
// @include ms-sm6;
|
||||
// @include ms-md3;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
margin-bottom: 16px;
|
||||
flex-basis: 120px;
|
||||
min-width: 120px;
|
||||
|
||||
a {
|
||||
background-color: $ms-color-themePrimary;
|
||||
box-sizing: border-box;
|
||||
color: $ms-color-white;
|
||||
display: block;
|
||||
min-height: 123px;
|
||||
overflow: hidden;
|
||||
padding: 15px;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
|
||||
&:hover, &:visited {
|
||||
color: $ms-color-white;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
a * {
|
||||
color: $ms-color-white;
|
||||
}
|
||||
|
||||
.tileIcon {
|
||||
@include ms-fontSize-su;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tileTitle {
|
||||
@include ms-fontSize-m;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 15px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.overflow {
|
||||
background-color: rgba(180, 180, 180, 0.6);
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
padding: 15px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 100%;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.overflow {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import * as React from 'react';
|
||||
import styles from './Tile.module.scss';
|
||||
import { ITileProps } from '.';
|
||||
import { Icon } from 'office-ui-fabric-react/lib/components/Icon';
|
||||
import { IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||
|
||||
|
||||
|
||||
export class Tile extends React.Component<ITileProps, {}> {
|
||||
public render(): React.ReactElement<ITileProps> {
|
||||
|
||||
//const { semanticColors }: IReadonlyTheme = this.props.themeVariant;
|
||||
const { palette }: IReadonlyTheme = this.props.themeVariant;
|
||||
const tileStyle: React.CSSProperties = {};
|
||||
const icoStyle: React.CSSProperties = {};
|
||||
const tileFontSize: React.CSSProperties = {};
|
||||
const tileInnerStyle: React.CSSProperties = {};
|
||||
const fontInnerStyle: React.CSSProperties = {};
|
||||
if (this.props.tileHeight) {
|
||||
tileStyle.height = `${this.props.tileHeight}px`;
|
||||
icoStyle.fontSize = `${Math.round(this.props.tileHeight / 2 - 18)}px`;
|
||||
tileFontSize.fontSize = `${Math.round(this.props.tileHeight / 6 - 6)}px`;
|
||||
}
|
||||
if (this.props.customColour){
|
||||
if (this.props.tileColour) {
|
||||
tileInnerStyle.backgroundColor = `${this.props.tileColour}`;
|
||||
fontInnerStyle.color = `${this.props.tileFont}`;
|
||||
}
|
||||
}else{
|
||||
tileInnerStyle.backgroundColor = palette.themePrimary;
|
||||
fontInnerStyle.color = palette.white;
|
||||
}
|
||||
return (
|
||||
<div className={styles.tile} style={tileStyle}>
|
||||
<a href={this.props.item.url}
|
||||
target={this.props.item.target}
|
||||
title={this.props.item.title} style={tileInnerStyle}>
|
||||
<div className={styles.tileIcon}>
|
||||
<Icon iconName={this.props.item.icon} style={{...fontInnerStyle,...icoStyle}}/>
|
||||
</div>
|
||||
<div className={styles.tileTitle} style={{...fontInnerStyle,...tileFontSize}}>
|
||||
{this.props.item.title}
|
||||
</div>
|
||||
<div className={styles.overflow}>
|
||||
{this.props.item.description}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './ITileProps';
|
||||
export * from './Tile';
|
|
@ -0,0 +1,25 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Kachel Web Part Konfiguration",
|
||||
"TilesListDescription": "Die Liste zum konfigurieren der Kacheln kann unter folgendem Link gefunden werden:",
|
||||
"TileHeight": "Geben Sie die Höhe der Kacheln an",
|
||||
"iconInformation": "Die Namen zum angeben des Icon Feldes können unter der folgenden URL gefunden werden:",
|
||||
|
||||
"tilesDataLabel": "Kacheldaten",
|
||||
"tilesPanelHeader": "Konfigurieren Sie Ihre Kachel",
|
||||
"tilesManageBtn": "Kacheln konfigurieren",
|
||||
|
||||
"titleField": "Title",
|
||||
"descriptionField": "Description",
|
||||
"urlField": "URL",
|
||||
"iconField": "UI Fabric icon name",
|
||||
"targetField": "Target",
|
||||
|
||||
"targetCurrent": "Aktuelles Fenster",
|
||||
"targetNew": "Neuer Tab",
|
||||
|
||||
"noTilesIconText": "Konfigurieren Sie Ihre Kachel",
|
||||
"noTilesConfigured": "Konfigurieren Sie den Webpart damit Kacheln angezeigt werden können",
|
||||
"noTilesBtn": "Konfigurieren",
|
||||
}
|
||||
});
|
|
@ -0,0 +1,27 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "This webpart displayes a group of tiles which can be set to navigate to different URLs",
|
||||
"TilesListDescription": "The list for configuring the tiles can be found on the following link:",
|
||||
"TileHeight": "Specify the height of the tiles",
|
||||
"tileColour": "Set the tile background colour",
|
||||
"tileFont": "Set the tile font colour",
|
||||
"iconInformation": "Enter the details for each icon one row at a time",
|
||||
|
||||
"tilesDataLabel": "Set the items to be displayed in the tiles",
|
||||
"tilesPanelHeader": "Configure your tiles",
|
||||
"tilesManageBtn": "Configure the tiles",
|
||||
|
||||
"titleField": "Title",
|
||||
"descriptionField": "Description",
|
||||
"urlField": "URL (add https:// for external links)",
|
||||
"iconField": "UI Fabric icon name",
|
||||
"targetField": "Target URL",
|
||||
|
||||
"targetCurrent": "Current window",
|
||||
"targetNew": "New tab",
|
||||
|
||||
"noTilesIconText": "Configure your tiles",
|
||||
"noTilesConfigured": "Please configure the web part in order to show tiles",
|
||||
"noTilesBtn": "Configure",
|
||||
}
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Configuraación del elemento web de Recuadros",
|
||||
"TilesListDescription": "La lista para configurar los recuadros se puede encontar en el siguiente enlace:",
|
||||
"TileHeight": "Especifique el alto de los recuadros",
|
||||
"iconInformation": "Los nombres a especificar para el campo icono poueden encontrarse en la siguiente direccion URL:",
|
||||
|
||||
"tilesDataLabel": "Datos del recuadro",
|
||||
"tilesPanelHeader": "Configure sus recuadros",
|
||||
"tilesManageBtn": "Configure los recuadros",
|
||||
|
||||
"titleField": "Título",
|
||||
"descriptionField": "Descripción",
|
||||
"urlField": "URL",
|
||||
"iconField": "Nombre de icono de UI Fabric",
|
||||
"targetField": "Destino",
|
||||
|
||||
"targetCurrent": "Ventana actual",
|
||||
"targetNew": "Nueva ventana",
|
||||
|
||||
"noTilesIconText": "Configure sus recuadros",
|
||||
"noTilesConfigured": "Favor de configurar el elemento web en el orden a mostrar los recuadros",
|
||||
"noTilesBtn": "Configure",
|
||||
}
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Configuration des tuiles de la partie Web",
|
||||
"TilesListDescription": "La liste de configuration des tuiles est disponible sur le lien suivant:",
|
||||
"TileHeight": "Spécifiez la hauteur des tuiles",
|
||||
"iconInformation": "Les noms à spécifier pour le champ d'icône se trouvent à l'URL suivante:",
|
||||
|
||||
"tilesDataLabel": "Données de tuiles",
|
||||
"tilesPanelHeader": "Configurez vos tuiles",
|
||||
"tilesManageBtn": "Configurer les tuiles",
|
||||
|
||||
"titleField": "Titre",
|
||||
"descriptionField": "Description",
|
||||
"urlField": "URL",
|
||||
"iconField": "Nom de l'icône d'UI Fabric",
|
||||
"targetField": "Cible",
|
||||
|
||||
"targetCurrent": "Page fenêtre",
|
||||
"targetNew": "Nouvel onglet",
|
||||
|
||||
"noTilesIconText": "Configurez vos tuiles",
|
||||
"noTilesConfigured": "Veuillez configurer la partie Web pour afficher les tuiles.",
|
||||
"noTilesBtn": "Configurer",
|
||||
}
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
declare interface ITilesWebPartStrings {
|
||||
PropertyPaneDescription: string;
|
||||
TilesListDescription: string;
|
||||
TileHeight: string;
|
||||
tileColour: string;
|
||||
tileFont: string;
|
||||
iconInformation: string;
|
||||
|
||||
// Properties
|
||||
tilesDataLabel: string;
|
||||
tilesPanelHeader: string;
|
||||
tilesManageBtn: string;
|
||||
|
||||
// Tile fields
|
||||
titleField: string;
|
||||
descriptionField: string;
|
||||
urlField: string;
|
||||
iconField: string;
|
||||
targetField: string;
|
||||
|
||||
targetCurrent: string;
|
||||
targetNew: string;
|
||||
|
||||
// Component
|
||||
noTilesIconText: string;
|
||||
noTilesConfigured: string;
|
||||
noTilesBtn: string;
|
||||
}
|
||||
|
||||
declare module 'TilesWebPartStrings' {
|
||||
const strings: ITilesWebPartStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Flis webdel konfigurasjon",
|
||||
"TilesListDescription": "Listen med fliskonfigurasjoner finnes på følgende lenke:",
|
||||
"TileHeight": "Angi høyden på flisene",
|
||||
"iconInformation": "Navnene som skal angis i ikonfeltet finnes på følgende URL:",
|
||||
|
||||
"tilesDataLabel": "Flisdata",
|
||||
"tilesPanelHeader": "Konfigurer dine fliser",
|
||||
"tilesManageBtn": "Konfigurer flisene",
|
||||
|
||||
"titleField": "Tittel",
|
||||
"descriptionField": "Beskrivelse",
|
||||
"urlField": "URL",
|
||||
"iconField": "UI Fabric ikonnavn",
|
||||
"targetField": "Mål",
|
||||
|
||||
"targetCurrent": "Gjeldende vindu",
|
||||
"targetNew": "Nytt vindu",
|
||||
|
||||
"noTilesIconText": "Konfigurer dine fliser",
|
||||
"noTilesConfigured": "Vennligst konfigurer webdelen for å vise dine fliser",
|
||||
"noTilesBtn": "Konfigurer",
|
||||
}
|
||||
});
|
|
@ -0,0 +1,26 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Tegel webpart configuratie",
|
||||
"TilesListDescription": "De lijst voor het configureren van de tegels kan gevonden worden via de volgende link:",
|
||||
"TileHeight": "Specificeer de hoogte van de tegels",
|
||||
"iconInformation": "De icoonnamen kan je vinden via de volgende URL:",
|
||||
|
||||
"tilesDataLabel": "Tegel data",
|
||||
"tilesPanelHeader": "Configureer je tegels",
|
||||
"tilesManageBtn": "Configureer je tegels",
|
||||
|
||||
"titleField": "Titel",
|
||||
"descriptionField": "Omschrijving",
|
||||
"urlField": "URL",
|
||||
"iconField": "UI Fabric icoonnaam",
|
||||
"targetField": "Doel",
|
||||
|
||||
"targetCurrent": "Huidig venster",
|
||||
"targetNew": "Nieuw tabblad",
|
||||
|
||||
"noTilesIconText": "Configureer je tegels",
|
||||
"noTilesConfigured": "Configureer de webpart om tegels te tonen",
|
||||
"noTilesBtn": "Configureer",
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Tiles webbdelskonfiguration",
|
||||
"TilesListDescription": "Listan för att konfigurera tiles finns på följande länk",
|
||||
"TileHeight": "Ange höjden på tilesen",
|
||||
"iconInformation": "Namnen som ska anges i ikonfältet finns på följande webbadress:",
|
||||
|
||||
"tilesDataLabel": "Tiledata",
|
||||
"tilesPanelHeader": "Konfigurera dina tiles",
|
||||
"tilesManageBtn": "Konfigurera tilesen",
|
||||
|
||||
"titleField": "Titel",
|
||||
"descriptionField": "Beskrivning",
|
||||
"urlField": "URL",
|
||||
"iconField": "UI Fabric ikonnamn",
|
||||
"targetField": "Mål",
|
||||
|
||||
"targetCurrent": "Aktuellt fönster",
|
||||
"targetNew": "Ny flik",
|
||||
|
||||
"noTilesIconText": "Konfigurera dina tiles",
|
||||
"noTilesConfigured": "Var god konfigurera webbdelen för att tilesen skall kunna visas",
|
||||
"noTilesBtn": "Konfigurera",
|
||||
}
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Döşeme web parçası yapılandırması",
|
||||
"TilesListDescription": "Döşemeleri yapılandırma listesi aşağıdaki linkte bulunabilir.:",
|
||||
"TileHeight": "Döşemenin yüksekliğini belirtin",
|
||||
"iconInformation": "İkon alanı için belirtilecek isimler aşağıdaki URL’de bulunabilir:",
|
||||
|
||||
"tilesDataLabel": "Döşeme Verisi",
|
||||
"tilesPanelHeader": "Döşemelerini yapılandır",
|
||||
"tilesManageBtn": "Döşemeleri yapılandırın",
|
||||
|
||||
"titleField": "Başlık",
|
||||
"descriptionField": "Açıklama",
|
||||
"urlField": "URL",
|
||||
"iconField": "UI Fabric ikon adı",
|
||||
"targetField": "Hedef",
|
||||
|
||||
"targetCurrent": "Geçerli pencere ",
|
||||
"targetNew": "Yeni sekme",
|
||||
|
||||
"noTilesIconText": "Döşemelerini yapılandır",
|
||||
"noTilesConfigured": "Döşemeleri göstermek için lütfen web bölümünü yapılandırın",
|
||||
"noTilesBtn": "Yapılandır",
|
||||
}
|
||||
});
|
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 383 B |
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.5/MicrosoftTeams.schema.json",
|
||||
"manifestVersion": "1.5",
|
||||
"packageName": "Tiles V2 App",
|
||||
"id": "3f170f95-26da-4621-9f3e-6e10078c8fa3",
|
||||
"version": "0.1",
|
||||
"developer": {
|
||||
"name": "Omar El-Anis",
|
||||
"websiteUrl": "https://spdeveloper.co.uk",
|
||||
"privacyUrl": "https://spdeveloper.co.uk",
|
||||
"termsOfUseUrl": "https://spdeveloper.co.uk"
|
||||
},
|
||||
"name": {
|
||||
"short": "Tiles V2 App"
|
||||
},
|
||||
"description": {
|
||||
"short": "Displayes a group of links as tiles",
|
||||
"full": "This app displayes a group of tiles which can be set to navigate to different URLs"
|
||||
},
|
||||
"icons": {
|
||||
"outline": "3f170f95-26da-4621-9f3e-6e10078c8fa3_outline.png",
|
||||
"color": "3f170f95-26da-4621-9f3e-6e10078c8fa3_color.png"
|
||||
},
|
||||
"accentColor": "#004578",
|
||||
"configurableTabs": [
|
||||
{
|
||||
"configurationUrl": "https://{teamSiteDomain}{teamSitePath}/_layouts/15/TeamsLogon.aspx?SPFX=true&dest={teamSitePath}/_layouts/15/teamshostedapp.aspx%3FopenPropertyPane=true%26teams%26componentId=26cb4af3-7f48-4737-b82a-4e24167c2d07%26forceLocale={locale}",
|
||||
"canUpdateConfiguration": true,
|
||||
"scopes": [
|
||||
"team"
|
||||
]
|
||||
}
|
||||
],
|
||||
"validDomains": [
|
||||
"*.login.microsoftonline.com",
|
||||
"*.sharepoint.com",
|
||||
"spoprod-a.akamaihd.net",
|
||||
"resourceseng.blob.core.windows.net"
|
||||
],
|
||||
"webApplicationInfo": {
|
||||
"resource": "https://{teamSiteDomain}",
|
||||
"id": "00000003-0000-0ff1-ce00-000000000000"
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/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": [
|
||||
"es6-promise",
|
||||
"webpack-env"
|
||||
],
|
||||
"lib": [
|
||||
"es5",
|
||||
"dom",
|
||||
"es2015.collection"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"lib"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"extends": "@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-use-before-declare": true,
|
||||
"no-with-statement": true,
|
||||
"semicolon": true,
|
||||
"trailing-comma": false,
|
||||
"typedef": false,
|
||||
"typedef-whitespace": false,
|
||||
"use-named-parameter": true,
|
||||
"variable-name": false,
|
||||
"whitespace": false
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue