added react-display-hierarchy (#673)

This commit is contained in:
Nanddeep Nachan 2018-11-12 14:20:47 +05:30 committed by Vesa Juvonen
parent f1359c18cc
commit e2dd322679
37 changed files with 18947 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,11 @@
{
"@microsoft/generator-sharepoint": {
"isCreatingSolution": true,
"environment": "spo",
"version": "1.6.0",
"libraryName": "spfx-react-hierarchy-view",
"libraryId": "2fd9a018-0cd9-4cca-9e84-4fac64b83333",
"packageManager": "npm",
"componentType": "webpart"
}
}

View File

@ -0,0 +1,85 @@
## Web part displaying hierarchical information from SharePoint list
### Summary
At the time of developing this sample, the Office 365 UI fabric does not have any control for displaying hierarchical information. This web part helps to display the hierarchical information from SharePoint list.
![Web part preview][figure1]
The web part is configured to render the mock data when added to local SharePoint workbench.
![Local SharePoint Workbench Run][figure2]
When added to SharePoint site, the source list containing hierarchical information can be configured from web part properties.
The sample also provisions the list called “Hierarchy” which can be used as an example to start using the web part.
![SharePoint Run][figure3]
### SharePoint Asset
A SharePoint list (named Hierarchy) is provisioned to store the hierarchical data. The schema of the list is as below.
![List Schema][figure4]
The Parent column is a lookup on same lists Title column.
The solution also provisions sample data to the Hierarchy list.
![List Sample Data][figure5]
### NPM Packages Used
Below NPM packages are used to develop this sample.
1. sp-pnp-js (https://www.npmjs.com/package/sp-pnp-js)
2. react-orgchart (https://www.npmjs.com/package/react-orgchart)
3. array-to-tree (https://www.npmjs.com/package/array-to-tree)
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/drop-1.6-green.svg)
## Applies to
* [SharePoint Framework Developer Preview](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
* [Office 365 developer tenant](http://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant)
## Solution
Solution|Author(s)
--------|---------
react-display-hierarchy|[Nanddeep Nachan](https://www.linkedin.com/in/nanddeepnachan/) (SharePoint Consultant, [@NanddeepNachan](https://http://twitter.com/NanddeepNachan) )
 |[Ravi Kulkarni](https://www.linkedin.com/in/ravi-kulkarni-a5381723/) (SharePoint Consultant)
## Version history
Version|Date|Comments
-------|----|--------
1.0.0|October 15, 2018|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.**
---
## Prerequisites
- SharePoint Online tenant
- Site Collection created under the **/sites/** or **/**
## Minimal Path to Awesome
- Clone this repo
- npm i
- gulp serve --nobrowser
- Open workbench on your tennant, ie. https://contoso.sharepoint.com/sites/salestesm/_layouts/15/workbench.aspx
- Search and add web part "Display Hierarchy"
## Features
This sample web part shows how data stored in SharePoint list can be transformed to show hierarchical information
- Rendering hierarchical information
- SharePoint assets provisioning
- Creating extensible services
- Using mock data to test the web part locally
- Using @sp-pnp-js
- Using @react-orgchart
- Using @array-to-tree
[figure1]: ./assets/webpart-preview.png
[figure2]: ./assets/local-sharepoint-workbench-run.png
[figure3]: ./assets/sharepoint-run.gif
[figure4]: ./assets/list-schema.png
[figure5]: ./assets/list-sample-data.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -0,0 +1,18 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
"version": "2.0",
"bundles": {
"react-hierarchy-view-web-part": {
"components": [
{
"entrypoint": "./lib/webparts/reactHierarchyView/ReactHierarchyViewWebPart.js",
"manifest": "./src/webparts/reactHierarchyView/ReactHierarchyViewWebPart.manifest.json"
}
]
}
},
"externals": {},
"localizedResources": {
"ReactHierarchyViewWebPartStrings": "lib/webparts/reactHierarchyView/loc/{locale}.js"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
"deployCdnPath": "temp/deploy"
}

View File

@ -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": "spfx-react-hierarchy-view",
"accessKey": "<!-- ACCESS KEY -->"
}

View File

@ -0,0 +1,29 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "spfx-react-hierarchy-view-client-side-solution",
"id": "2fd9a018-0cd9-4cca-9e84-4fac64b83333",
"version": "1.0.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true,
"features": [
{
"title": "react-display-hierarchy-deployment",
"description": "react-display-hierarchy-deployment",
"id": "c99c6e2c-f45c-41f4-84b4-f05f2031eab3",
"version": "1.0.0.0",
"assets": {
"elementManifests": [
"elements.xml"
],
"elementFiles": [
"schema.xml"
]
}
}
]
},
"paths": {
"zippedPackage": "solution/spfx-react-hierarchy-view.sppkg"
}
}

View File

@ -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/"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
"cdnBasePath": "<!-- PATH TO CDN -->"
}

View File

@ -0,0 +1,7 @@
'use strict';
const gulp = require('gulp');
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(gulp);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
{
"name": "spfx-react-hierarchy-view",
"version": "0.0.1",
"private": true,
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"build": "gulp bundle",
"clean": "gulp clean",
"test": "gulp test"
},
"dependencies": {
"@microsoft/sp-core-library": "1.6.0",
"@microsoft/sp-lodash-subset": "1.6.0",
"@microsoft/sp-office-ui-fabric-core": "1.6.0",
"@microsoft/sp-webpart-base": "1.6.0",
"@pnp/common": "^1.2.3",
"@pnp/graph": "^1.2.3",
"@pnp/logging": "^1.2.3",
"@pnp/odata": "^1.2.3",
"@pnp/sp": "^1.2.3",
"@types/es6-promise": "0.0.33",
"@types/react": "15.6.6",
"@types/react-dom": "15.5.6",
"@types/webpack-env": "1.13.1",
"array-to-tree": "^3.3.0",
"react": "15.6.2",
"react-dom": "15.6.2",
"react-orgchart": "^1.0.5"
},
"devDependencies": {
"@microsoft/sp-build-web": "1.6.0",
"@microsoft/sp-module-interfaces": "1.6.0",
"@microsoft/sp-webpart-workbench": "1.6.0",
"tslint-microsoft-contrib": "~5.0.0",
"gulp": "~3.9.1",
"@types/chai": "3.4.34",
"@types/mocha": "2.2.38",
"ajv": "~5.2.2"
}
}

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListInstance
CustomSchema="schema.xml"
FeatureId="00bfea71-de22-43b2-a848-c05709900100"
Title="Hierarchy"
Description="List with hierarchy information"
TemplateType="100"
Url="Lists/Hierarchy">
<Data>
<Rows>
<Row>
<Field Name="Title">Director of Human Resources</Field>
<Field Name="Parent"></Field>
</Row>
<Row>
<Field Name="Title">Compensation Analysis</Field>
<Field Name="Parent">1;#Director of Human Resources</Field>
</Row>
<Row>
<Field Name="Title">Risk Management</Field>
<Field Name="Parent">1;#Director of Human Resources</Field>
</Row>
<Row>
<Field Name="Title">Employee Relations</Field>
<Field Name="Parent">1;#Director of Human Resources</Field>
</Row>
<Row>
<Field Name="Title">Staffing</Field>
<Field Name="Parent">1;#Director of Human Resources</Field>
</Row>
<Row>
<Field Name="Title">Job Evaluation</Field>
<Field Name="Parent">2;#Compensation Analysis</Field>
</Row>
<Row>
<Field Name="Title">Salary Board</Field>
<Field Name="Parent">2;#Compensation Analysis</Field>
</Row>
<Row>
<Field Name="Title">Merit Admin</Field>
<Field Name="Parent">2;#Compensation Analysis</Field>
</Row>
<Row>
<Field Name="Title">Emergency Procedures</Field>
<Field Name="Parent">3;#Risk Management</Field>
</Row>
<Row>
<Field Name="Title">Safety Program</Field>
<Field Name="Parent">3;#Risk Management</Field>
</Row>
<Row>
<Field Name="Title">Grievance Procedure</Field>
<Field Name="Parent">4;#Employee Relations</Field>
</Row>
<Row>
<Field Name="Title">Client Consultations</Field>
<Field Name="Parent">4;#Employee Relations</Field>
</Row>
<Row>
<Field Name="Title">Job Posting</Field>
<Field Name="Parent">5;#Staffing</Field>
</Row>
<Row>
<Field Name="Title">Application Screening</Field>
<Field Name="Parent">5;#Staffing</Field>
</Row>
</Rows>
</Data>
</ListInstance>
</Elements>

View File

@ -0,0 +1,31 @@
<List xmlns:ows="Microsoft SharePoint" Title="Hierarchy" EnableContentTypes="TRUE" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/Hierarchy" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
<MetaData>
<Fields>
<Field ID="{6C798145-A205-4FC4-8175-837B0F7744CC}" Type="Lookup" DisplayName="Parent" Required="false" List="Lists/Hierarchy" ShowField="Title" UnlimitedLengthInDocumentLibrary="TRUE" StaticName="Parent" Name="Parent" Version="1" />
<Field ID="{c29e077d-f466-4d8e-8bbe-72b66c5f205c}" Name="URL" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="URL" Group="Base Columns" Type="URL" DisplayName="URL" AllowDeletion="TRUE" ColName="nvarchar4" RowOrdinal="0" ColName2="nvarchar5" RowOrdinal2="0" />
</Fields>
<Views>
<View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
<XslLink Default="TRUE">main.xsl</XslLink>
<JSLink>clienttemplates.js</JSLink>
<RowLimit Paged="TRUE">30</RowLimit>
<Toolbar Type="Standard" />
<ViewFields>
<FieldRef Name="LinkTitle"></FieldRef>
<FieldRef Name="Parent"></FieldRef>
<FieldRef Name="URL"></FieldRef>
</ViewFields>
<Query>
<OrderBy>
<FieldRef Name="Title" />
</OrderBy>
</Query>
</View>
</Views>
<Forms>
<Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
<Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
<Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
</Forms>
</MetaData>
</List>

View File

@ -0,0 +1 @@
// A file is required to be in the root of the /src directory by the TypeScript compiler

View File

@ -0,0 +1,31 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "a0696899-5523-4520-9744-acbb0bae821f",
"alias": "ReactHierarchyViewWebPart",
"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,
"preconfiguredEntries": [
{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
"group": {
"default": "Other"
},
"title": {
"default": "Display Hierarchy"
},
"description": {
"default": "Display hierarchical view from SharePoint list"
},
"officeFabricIconFontName": "GitGraph",
"properties": {
"description": "ReactHierarchyView"
}
}
]
}

View File

@ -0,0 +1,77 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
BaseClientSideWebPart,
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import * as strings from 'ReactHierarchyViewWebPartStrings';
import ReactHierarchyView from './components/ReactHierarchyView';
import { IReactHierarchyViewProps } from './components/IReactHierarchyViewProps';
import {
Environment,
EnvironmentType,
ServiceScope
} from '@microsoft/sp-core-library';
// sp-pnp-js for SPFx context configuration
import * as pnp from "@pnp/sp";
export interface IReactHierarchyViewWebPartProps {
listName: string;
}
export default class ReactHierarchyViewWebPart extends BaseClientSideWebPart<IReactHierarchyViewWebPartProps> {
public async onInit(): Promise<void> {
return super.onInit().then(_ => {
pnp.sp.setup({
spfxContext: this.context
});
});
}
public render(): void {
const element: React.ReactElement<IReactHierarchyViewProps> = React.createElement(
ReactHierarchyView,
{
serviceScope: this.context.serviceScope,
listName: this.properties.listName
}
);
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.BasicGroupName,
groupFields: [
PropertyPaneTextField('listName', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}

View File

@ -0,0 +1,6 @@
import { ServiceScope } from '@microsoft/sp-core-library';
export interface IReactHierarchyViewProps {
serviceScope: ServiceScope;
listName: string;
}

View File

@ -0,0 +1,108 @@
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
@import '~react-orgchart/index.css';
:global(#workbenchPageContent) {
max-width: initial;
}
:global(.initechNode) {
border: 1px solid;
border-radius: 3px;
padding: 5px;
margin: 1px;
display: inline-block;
background: #005a9e;
}
:global(#initechOrgChart .orgNodeChildGroup .nodeGroupLineVerticalMiddle) {
border-right: solid 3px #005a9e
}
:global(#initechOrgChart .nodeLineBorderTop) {
border-top: solid 3px #005a9e;
}
:global(.reactOrgChart .nodeLineBorderTop) {
border-top: 2px solid #005a9e;
}
:global(.reactOrgChart .orgNodeChildGroup .nodeGroupLineVerticalMiddle) {
border-right: 2px solid #005a9e;
}
.reactHierarchyView {
.container {
max-width: 700px;
margin: 0px auto;
//box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.row {
@include ms-Grid-row;
@include ms-fontColor-white;
//background-color: $ms-color-themeDark;
//padding: 20px;
}
.column {
@include ms-Grid-col;
@include ms-lg10;
@include ms-xl8;
@include ms-xlPush2;
@include ms-lgPush1;
}
.link {
color: #ffffff;
}
.title {
@include ms-font-xl;
@include ms-fontColor-white;
}
.subTitle {
@include ms-font-l;
@include ms-fontColor-white;
}
.description {
@include ms-font-l;
@include ms-fontColor-white;
}
.button {
// Our button
text-decoration: none;
height: 32px;
// Primary Button
min-width: 80px;
background-color: $ms-color-themePrimary;
border-color: $ms-color-themePrimary;
color: $ms-color-white;
// Basic Button
outline: transparent;
position: relative;
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
-webkit-font-smoothing: antialiased;
font-size: $ms-font-size-m;
font-weight: $ms-font-weight-regular;
border-width: 0;
text-align: center;
cursor: pointer;
display: inline-block;
padding: 0 16px;
.label {
font-weight: $ms-font-weight-semibold;
font-size: $ms-font-size-m;
height: 32px;
line-height: 32px;
margin: 0 4px;
vertical-align: top;
display: inline-block;
}
}
}

View File

@ -0,0 +1,127 @@
import * as React from 'react';
import styles from './ReactHierarchyView.module.scss';
import { IReactHierarchyViewProps } from './IReactHierarchyViewProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { IHierarchyService } from '../interfaces';
import { IHierarchyItem, Item } from '../interfaces/IHierarchyItem';
import OrgChart from 'react-orgchart';
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
import { HierarchyService } from '../services';
import { MockHierarchyService } from '../mocks';
import { ServiceScope, Environment, EnvironmentType } from '@microsoft/sp-core-library';
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
export interface IReactHierarchyState {
hierarchyItems: any;
isLoading: boolean;
showErrorMessage: boolean;
errorMessage: string;
}
export default class ReactHierarchyView extends React.Component<IReactHierarchyViewProps, IReactHierarchyState> {
private HierarchyServiceInstance: IHierarchyService;
private _listName: string;
constructor(props: IReactHierarchyViewProps) {
super(props);
this.state = {
hierarchyItems: null,
isLoading: true,
showErrorMessage: false,
errorMessage: ""
};
let serviceScope: ServiceScope;
serviceScope = this.props.serviceScope;
this._listName = this.props.listName;
// Based on the type of environment, return the correct instance of the IHierarchyServiceInstance interface
if (Environment.type == EnvironmentType.SharePoint || Environment.type == EnvironmentType.ClassicSharePoint) {
// Mapping to be used when webpart runs in SharePoint.
this.HierarchyServiceInstance = serviceScope.consume(HierarchyService.serviceKey);
}
else {
// This means webpart is running in the local workbench or from a unit test.
// So we will need a non default implementation of the IHierarchyServiceInstance i.e. MockHierarchyService
this.HierarchyServiceInstance = serviceScope.consume(MockHierarchyService.serviceKey);
}
this.HierarchyServiceInstance.getHierarchyInfo(this._listName).then((hierarchyItems: any) => {
if (Environment.type == EnvironmentType.SharePoint || Environment.type == EnvironmentType.ClassicSharePoint) {
if (hierarchyItems.length > 0) {
let hierarchyNodes: Array<Item> = [];
var count: number;
for (count = 0; count < hierarchyItems.length; count++) {
hierarchyNodes.push(new Item(hierarchyItems[count].Id, hierarchyItems[count].Title, hierarchyItems[count].Url, hierarchyItems[count].Parent ? hierarchyItems[count].Parent.Id : undefined));
}
var arrayToTree: any = require('array-to-tree');
var orgChartHierarchyNodes: any = arrayToTree(hierarchyNodes);
var output: any = JSON.stringify(orgChartHierarchyNodes[0]);
this.setState({
hierarchyItems: JSON.parse(output),
isLoading: false
});
}
else {
this.setState({
isLoading: false,
showErrorMessage: true,
errorMessage: "No records to be displayed"
});
}
}
else {
this.setState({
hierarchyItems: JSON.parse(hierarchyItems),
isLoading: false
});
}
}).catch((error) =>
this.setState({
errorMessage: "Please verify webpart configuration. Error details: " + error.message,
isLoading: false,
showErrorMessage: true
})
);
}
public render(): React.ReactElement<IReactHierarchyViewProps> {
return (
<div className={styles.reactHierarchyView}>
<div className={styles.container}>
<div className={styles.row}>
<div className={styles.column}>
{this.state.isLoading && <Spinner label="Loading Hierarchy View..." />}
{this.state.hierarchyItems &&
<OrgChart tree={this.state.hierarchyItems} NodeComponent={this.MyNodeComponent} />
}
</div>
{this.state.showErrorMessage &&
<MessageBar messageBarType={MessageBarType.warning} isMultiline={false} dismissButtonAriaLabel="Close">
{this.state.errorMessage}</MessageBar>
}
</div>
</div>
</div>
);
}
private MyNodeComponent = ({ node }) => {
if (node.url) {
return (
<div className="initechNode">
<a href={node.url.Url} className={styles.link} >{node.title}</a>
</div>
);
}
else {
return (
<div className="initechNode">{node.title}</div>
);
}
}
}

View File

@ -0,0 +1,21 @@
export interface IHierarchyItem {
Title: string;
Id: number;
parent_id: number;
Url?: string;
Parent: any;
}
export class Item {
private id: number;
private title: string;
private url: string;
private parent_id?: number;
constructor(id: number, title: string, url: string, parent_id?: number) {
this.id = id;
this.title = title;
this.parent_id = parent_id;
this.url = url;
}
}

View File

@ -0,0 +1,6 @@
export interface IHierarchyService {
getHierarchyInfo: (listName?: string) => Promise<any>;
}

View File

@ -0,0 +1 @@
export { IHierarchyService } from './IHierarchyService';

View File

@ -0,0 +1,7 @@
define([], function () {
return {
"PropertyPaneDescription": "Hierarchy View List Configuration",
"BasicGroupName": "Group Name",
"DescriptionFieldLabel": "List Name"
}
});

View File

@ -0,0 +1,10 @@
declare interface IReactHierarchyViewWebPartStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
DescriptionFieldLabel: string;
}
declare module 'ReactHierarchyViewWebPartStrings' {
const strings: IReactHierarchyViewWebPartStrings;
export = strings;
}

View File

@ -0,0 +1,54 @@
import { IHierarchyService } from '../interfaces';
import { ServiceScope, ServiceKey } from '@microsoft/sp-core-library';
export class MockHierarchyService implements IHierarchyService {
public static readonly serviceKey: ServiceKey<IHierarchyService> = ServiceKey.create<IHierarchyService>('datacenter:MockHierarchyService', MockHierarchyService);
constructor(serviceScope: ServiceScope) {
}
public getHierarchyInfo(listName: string): Promise<any> {
const initechOrg: any =
{
id: 1,
title: "Microsoft",
url: {Description: "Microsoft", Url: "http://www.microsoft.com"},
children:[
{
id: 2,
title: "CMS",
url: null,
parent_id: 1,
children:[
{ id: 3, title: "SharePoint", parent_id: 2, url: null },
{ id: 5, title: "DotNetNuke", parent_id: 2, url: null },
{ id: 6, title: "Sitefinity", parent_id: 2, url: null }
]
},
{
id: 7,
title: "E-Commerce",
url: null,
parent_id: 1,
children:[
{ id: 8, title: "nopCommerce", parent_id: 7, url: null },
{ id: 9, title: "asp.net storetront", parent_id: 7, url: null }
]
},
{
id: 10,
title: "3rd Party",
url: null,
parent_id: 1,
children:[
{ id: 11, title: "Telerik", parent_id: 10, url: null },
{ id: 12, title: "DevExpress", parent_id: 10, url: null }
]
}
]
}
;
return new Promise<any>((resolve, reject) => {
resolve(JSON.stringify(initechOrg));
});
}
}

View File

@ -0,0 +1 @@
export { MockHierarchyService } from './MockHierarchyService';

View File

@ -0,0 +1,29 @@
import { IHierarchyService } from '../interfaces';
import { ServiceKey, ServiceScope } from '@microsoft/sp-core-library';
import { PageContext } from '@microsoft/sp-page-context';
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
import { IHierarchyItem } from '../interfaces/IHierarchyItem';
import * as pnp from "@pnp/sp";
export class HierarchyService implements IHierarchyService {
public static readonly serviceKey: ServiceKey<IHierarchyService> = ServiceKey.create<IHierarchyService>('datacenter:hierarchyService', HierarchyService);
private _spHttpClient: SPHttpClient;
private _pageContext: PageContext;
private _currentWebUrl: string;
constructor(serviceScope: ServiceScope) {
serviceScope.whenFinished(() => {
this._spHttpClient = serviceScope.consume(SPHttpClient.serviceKey);
this._pageContext = serviceScope.consume(PageContext.serviceKey);
this._currentWebUrl = this._pageContext.web.absoluteUrl;
});
}
public getHierarchyInfo(listName: string): Promise<IHierarchyItem[]> {
return pnp.sp.web.lists.getByTitle(listName).items.select('Title,Id,URL,Parent/Id,Parent/Title&$expand=Parent/Id').get().then((items: IHierarchyItem[]) => {
return Promise.resolve(items);
}).catch((error) => Promise.reject(error));
}
}

View File

@ -0,0 +1 @@
export { HierarchyService } from './HierarchyService';

View File

@ -0,0 +1,34 @@
{
"compilerOptions": {
"target": "es5",
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"jsx": "react",
"declaration": true,
"sourceMap": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"outDir": "lib",
"typeRoots": [
"./node_modules/@types",
"./node_modules/@microsoft"
],
"types": [
"es6-promise",
"webpack-env"
],
"lib": [
"es5",
"dom",
"es2015.collection"
]
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules",
"lib"
]
}

View File

@ -0,0 +1,32 @@
{
"rulesDirectory": [
"tslint-microsoft-contrib"
],
"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
}
}