add react-pnpjs-project-online sample (#1080)

This commit is contained in:
Joel Rodrigues 2019-12-09 09:09:49 +00:00 committed by Vesa Juvonen
parent fc7fbd981a
commit e204ea6e44
44 changed files with 19249 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,12 @@
{
"@microsoft/generator-sharepoint": {
"isCreatingSolution": true,
"environment": "spo",
"version": "1.8.2",
"libraryName": "pnpjs-project-online",
"libraryId": "ef683471-0607-4681-a03f-725a67b08014",
"packageManager": "npm",
"isDomainIsolated": false,
"componentType": "webpart"
}
}

View File

@ -0,0 +1,59 @@
# React PnPjs Project Online
## Summary
This sample shows how to use SPFx to consume data from the Project Online REST API using a custom module for PnPjs.
The web part is currently logging the data returned from the API to the browser console as a simple proof of concept.
Custom PnPjs module: [pnpjs-project-online-package](https://www.npmjs.com/package/pnpjs-project-online-package)
![Demo](./assets/Preview.gif)
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/version-1.8.2-green.svg)
## Applies to
- [SharePoint Framework](https:/dev.office.com/sharepoint)
- [Office 365 tenant](https://dev.office.com/sharepoint/docs/spfx/set-up-your-development-environment)
- [Project Online](<https://docs.microsoft.com/en-us/previous-versions/office/project-javascript-api/jj712612(v%3Doffice.15)>)
## Prerequisites
- Office 365 subscription with SharePoint Online and Project Online licence
- SharePoint Framework [development environment](https://dev.office.com/sharepoint/docs/spfx/set-up-your-development-environment) already set up.
- Project site with sample data available.
## Solution
| Solution | Author(s) |
| -------------------------- | -------------- |
| react-pnpjs-project-online | Joel Rodrigues |
## Version history
| Version | Date | Comments |
| ------- | ---------------- | --------------- |
| 1.0 | December 4, 2019 | 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
- in the command line run:
- `npm install`
- `gulp serve`
## Features
This Web Part illustrates the following concepts on top of the SharePoint Framework:
-Using PnPjs with a custom package to interact with Project Online REST API
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-pnpjs-project-online" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 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": {
"project-online-web-part": {
"components": [
{
"entrypoint": "./lib/webparts/projectOnline/ProjectOnlineWebPart.js",
"manifest": "./src/webparts/projectOnline/ProjectOnlineWebPart.manifest.json"
}
]
}
},
"externals": {},
"localizedResources": {
"ProjectOnlineWebPartStrings": "lib/webparts/projectOnline/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": "pnpjs-project-online",
"accessKey": "<!-- ACCESS KEY -->"
}

View File

@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "pnpjs-project-online-client-side-solution",
"id": "ef683471-0607-4681-a03f-725a67b08014",
"version": "1.0.0.0",
"includeClientSideAssets": true,
"isDomainIsolated": false
},
"paths": {
"zippedPackage": "solution/pnpjs-project-online.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,45 @@
{
"name": "pnpjs-project-online",
"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.8.2",
"@microsoft/sp-lodash-subset": "1.8.2",
"@microsoft/sp-office-ui-fabric-core": "1.8.2",
"@microsoft/sp-property-pane": "1.8.2",
"@microsoft/sp-webpart-base": "1.8.2",
"@pnp/common": "1.3.7",
"@pnp/logging": "1.3.7",
"@pnp/odata": "1.3.7",
"@types/es6-promise": "0.0.33",
"@types/react": "16.7.22",
"@types/react-dom": "16.8.0",
"@types/webpack-env": "1.13.1",
"office-ui-fabric-react": "6.143.0",
"pnpjs-project-online-package": "0.0.2",
"react": "16.7.0",
"react-dom": "16.7.0"
},
"resolutions": {
"@types/react": "16.7.22"
},
"devDependencies": {
"@microsoft/sp-build-web": "1.8.2",
"@microsoft/sp-tslint-rules": "1.8.2",
"@microsoft/sp-module-interfaces": "1.8.2",
"@microsoft/sp-webpart-workbench": "1.8.2",
"@microsoft/rush-stack-compiler-2.9": "0.7.7",
"gulp": "~3.9.1",
"@types/chai": "3.4.34",
"@types/mocha": "2.2.38",
"ajv": "~5.2.2"
}
}

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,27 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "0880bb0a-db38-4f66-97ca-1a15459d2967",
"alias": "ProjectOnlineWebPart",
"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"],
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
"group": { "default": "Other" },
"title": { "default": "ProjectOnline" },
"description": { "default": "ProjectOnline description" },
"officeFabricIconFontName": "Page",
"properties": {
"description": "ProjectOnline"
}
}]
}

View File

@ -0,0 +1,75 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { setup as pnpSetup } from "@pnp/common";
import { project } from "pnpjs-project-online-package";
import * as strings from 'ProjectOnlineWebPartStrings';
import { ProjectOnline } from './components/ProjectOnline';
import { IProjectOnlineProps } from './components/ProjectOnline';
export interface IProjectOnlineWebPartProps {
description: string;
}
export default class ProjectOnlineWebPart extends BaseClientSideWebPart<IProjectOnlineWebPartProps> {
public onInit(): Promise<void> {
return super.onInit().then(_ => {
// other init code may be present
project.setup({
spfxContext: this.context
});
});
}
public render(): void {
const element: React.ReactElement<IProjectOnlineProps> = React.createElement(
ProjectOnline,
{
description: this.properties.description
}
);
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('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}

View File

@ -0,0 +1,9 @@
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
.calendars {
button {
margin: 5px;
}
}

View File

@ -0,0 +1,76 @@
import * as React from 'react';
import styles from './Calendars.module.scss';
import { ICalendarsProps } from './ICalendarsProps';
import { project, Calendar, CommandResult, CalendarCollection, CalendarExceptionCollection, CalendarException } from "pnpjs-project-online-package";
import { Button } from "office-ui-fabric-react/lib/Button";
import { dateAdd } from '@pnp/common';
export class Calendars extends React.Component<ICalendarsProps, {}> {
private _calendars: CalendarCollection[];
public render(): React.ReactElement<ICalendarsProps> {
return (
<div className={styles.calendars}>
<Button text='Get all calendars' onClick={this._getAllCalendars}></Button>
<Button text='Get calendar by Id' onClick={this._getCalendarById}></Button>
{/* <Button text='Add calendar' onClick={this._addCalendar}></Button> */}
{/* <Button text='Add calendar exception' onClick={this._addCalendarException}></Button> */}
<Button text='Copy calendar' onClick={this._copyCalendar}></Button>
<Button text='Delete calendar' onClick={this._deleteCalendar}></Button>
</div>
);
}
private _getAllCalendars = async () => {
this._calendars = await project.calendars.get();
console.log('Calendars', this._calendars);
}
// private _addCalendar = async () => {
// const calendar: CommandResult<Calendar> = await project.calendars.add({
// Name: 'Test Calendar ' + Date.now()
// });
// console.log(calendar);
// }
private _getCalendarById = async () => {
const calendar: Calendar = await project.calendars.getById('c421980e-457e-e911-b07c-00155d088c05').get();
console.log('Calendar', calendar);
const calendarExceptions: CalendarExceptionCollection[] = await project.calendars.getById('c421980e-457e-e911-b07c-00155d088c05').baseCalendarExceptions.get();
console.log('Calendar exceptions', calendarExceptions);
}
private _copyCalendar = async () => {
const newCalendarName = 'Test Calendar ' + Date.now();
const calendar: CommandResult<Calendar> = await project.calendars.getById('b6635b2e-e747-4771-a78b-24f7509629d0').copyTo(newCalendarName);
console.log('Calendar', calendar);
}
private _deleteCalendar = async () => {
await project.calendars.getById('1cdc823e-417e-e911-b08a-00155d10891f').delete();
console.log('Calendar deleted');
}
// private _addCalendarException = async () => {
// const calendarException: CommandResult<CalendarException> = await project.calendars.getById('c421980e-457e-e911-b07c-00155d088c05').baseCalendarExceptions.add({
// Name: 'Test Calendar exception ' + Date.now(),
// Start: new Date(2019,1,15),
// Finish: new Date(2019,12,15),
// Shift1Start: 1,
// Shift1Finish: 60,
// Shift2Start: 1,
// Shift2Finish: 60,
// Shift3Start: 1,
// Shift3Finish: 60,
// Shift4Start: 1,
// Shift4Finish: 60,
// Shift5Start: 1,
// Shift5Finish: 60,
// });
// console.log('Calendar exception', calendarException);
// }
}

View File

@ -0,0 +1,2 @@
export interface ICalendarsProps {
}

View File

@ -0,0 +1,2 @@
export * from './ICalendarsProps';
export * from './Calendars';

View File

@ -0,0 +1,3 @@
export interface IProjectAssignmentsProps {
projectId: string;
}

View File

@ -0,0 +1,9 @@
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
.buttons {
button {
margin: 5px;
}
}

View File

@ -0,0 +1,52 @@
import * as React from 'react';
import styles from './ProjectAssignments.module.scss';
import { IProjectAssignmentsProps } from './IProjectAssignmentsProps';
import { project, User, CustomFieldCollection, PublishedAssignmentCollection, Calendar, PublishedTaskLinkCollection, PublishedTask, PublishedAssignment, PublishedProjectResource } from "pnpjs-project-online-package";
import { Button } from "office-ui-fabric-react/lib/Button";
export class ProjectAssignments extends React.Component<IProjectAssignmentsProps, {}> {
public render(): React.ReactElement<IProjectAssignmentsProps> {
return (
<div className={styles.buttons}>
<Button text='Get all project assignments' onClick={this._getAllProjectAssignments}></Button>
<Button text='Get project assignment by Id' onClick={this._getProjectAssignmentById}></Button>
</div>
);
}
private _getAllProjectAssignments = async () => {
const projectAssignments: PublishedAssignmentCollection[] = await project.projects.getById(this.props.projectId).assignments.get();
console.log('Project assignments', projectAssignments);
}
private _getProjectAssignmentById = async () => {
const id = '56701829-2d77-e911-8166-000d3a6dc32c';
const publishedAssignment: PublishedAssignment = await project.projects.getById(this.props.projectId).assignments.getById(id).get();
console.log('Assignment', publishedAssignment);
const assignmentTask: PublishedTask = await project.projects.getById(this.props.projectId).assignments.getById(id).task.get();
console.log('Assignment Task', assignmentTask);
const assignmentResource: PublishedProjectResource = await project.projects.getById(this.props.projectId).assignments.getById(id).resource.get();
console.log('Assignment Resource', assignmentResource);
const assignmentOwner: PublishedTask = await project.projects.getById(this.props.projectId).assignments.getById(id).owner.get();
console.log('Assignment Owner', assignmentOwner);
const customFields: CustomFieldCollection[] = await project.projects.getById(this.props.projectId).assignments.getById(id).customFields.get();
console.log('Custom Fields', customFields);
const parentAssignment: PublishedAssignment = await project.projects.getById(this.props.projectId).assignments.getById(id).parent.get();
console.log('Parent Assignment', parentAssignment);
}
}

View File

@ -0,0 +1,2 @@
export * from './IProjectAssignmentsProps';
export * from './ProjectAssignments';

View File

@ -0,0 +1,3 @@
export interface IProjectOnlineProps {
description: string;
}

View File

@ -0,0 +1,3 @@
export interface IProjectOnlineState {
projectId: string;
}

View File

@ -0,0 +1,22 @@
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
.projectOnline {
.container {
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);
@include ms-fontColor-white;
background-color: $ms-color-themeDark;
padding: 20px;
}
.title {
@include ms-font-xl;
@include ms-fontColor-white;
}
.subTitle {
@include ms-font-l;
@include ms-fontColor-white;
}
}

View File

@ -0,0 +1,55 @@
import * as React from 'react';
import styles from './ProjectOnline.module.scss';
import { IProjectOnlineProps, IProjectOnlineState } from '.';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { Projects } from "../Projects";
import { ProjectTasks } from "../ProjectTasks";
import { ProjectAssignments } from "../ProjectAssignments/index";
import { Calendars } from '../Calendars';
export class ProjectOnline extends React.Component<IProjectOnlineProps, IProjectOnlineState> {
constructor(props: IProjectOnlineProps) {
super(props);
this.state = {
projectId: ''
};
}
public render(): React.ReactElement<IProjectOnlineProps> {
return (
<div className={styles.projectOnline}>
<div className={styles.container}>
<span className={styles.title}>Welcome to Project Online!</span>
<p className={styles.subTitle}>Customize Project Online experiences using SPFx Web Parts.</p>
<TextField label="Project Id" value={this.state.projectId} onChange={this._onChange} />
<h3>Projects</h3>
<Projects projectId={this.state.projectId}></Projects>
<h3>Project Tasks</h3>
<ProjectTasks projectId={this.state.projectId}></ProjectTasks>
<h3>Project Assignments</h3>
<ProjectAssignments projectId={this.state.projectId}></ProjectAssignments>
<h3>Calendars</h3>
<Calendars></Calendars>
</div>
</div>
);
}
private _onChange = (ev: React.FormEvent<HTMLInputElement>, newValue?: string) => {
this.setState({ projectId: newValue || '' });
}
}

View File

@ -0,0 +1,3 @@
export * from './IProjectOnlineProps';
export * from './IProjectOnlineState';
export * from './ProjectOnline';

View File

@ -0,0 +1,3 @@
export interface IProjectTasksProps {
projectId: string;
}

View File

@ -0,0 +1,9 @@
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
.buttons {
button {
margin: 5px;
}
}

View File

@ -0,0 +1,57 @@
import * as React from 'react';
import styles from './ProjectTasks.module.scss';
import { IProjectTasksProps } from './IProjectTasksProps';
import { project, User, CustomFieldCollection, PublishedAssignmentCollection, Calendar, PublishedTaskLinkCollection, PublishedTaskCollection, PublishedTask } from "pnpjs-project-online-package";
import { Button } from "office-ui-fabric-react/lib/Button";
export class ProjectTasks extends React.Component<IProjectTasksProps, {}> {
public render(): React.ReactElement<IProjectTasksProps> {
return (
<div className={styles.buttons}>
<Button text='Get all project tasks' onClick={this._getAllProjectTasks}></Button>
<Button text='Get project task by Id' onClick={this._getProjectTaskById}></Button>
</div>
);
}
private _getAllProjectTasks = async () => {
const projectTasks: PublishedTaskCollection[] = await project.projects.getById(this.props.projectId).tasks.get();
console.log('Project tasks', projectTasks);
}
private _getProjectTaskById = async () => {
const id = '3a701829-2d77-e911-8166-000d3a6dc32c';
const publishedTask: PublishedTask = await project.projects.getById(this.props.projectId).tasks.getById(id).get();
console.log('Published task', publishedTask);
const publishedAssignmentCollection: PublishedAssignmentCollection[] = await project.projects.getById(this.props.projectId).tasks.getById(id).assignments.get();
console.log('Published Assignment Collection', publishedAssignmentCollection);
const calendar: Calendar = await project.projects.getById(this.props.projectId).tasks.getById(id).calendar.get();
console.log('Calendar', calendar);
const customFieldCollection: CustomFieldCollection[] = await project.projects.getById(this.props.projectId).tasks.getById(id).customFields.get();
console.log('Custom Field Collection', customFieldCollection);
const parentTaskLink: PublishedTask = await project.projects.getById(this.props.projectId).tasks.getById(id).parent.get();
console.log('Parent Task Link', parentTaskLink);
const predecessorTasks: PublishedTaskLinkCollection[] = await project.projects.getById(this.props.projectId).tasks.getById(id).predecessors.get();
console.log('Predecessor Tasks', predecessorTasks);
const successorTasks: PublishedTaskLinkCollection[] = await project.projects.getById(this.props.projectId).tasks.getById(id).successors.get();
console.log('Successor Tasks', successorTasks);
const statusManager: User = await project.projects.getById(this.props.projectId).tasks.getById(id).statusManager.get();
console.log('Status Manager', statusManager);
}
}

View File

@ -0,0 +1,2 @@
export * from './IProjectTasksProps';
export * from './ProjectTasks';

View File

@ -0,0 +1,3 @@
export interface IProjectsProps {
projectId: string;
}

View File

@ -0,0 +1,9 @@
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
.buttons {
button {
margin: 5px;
}
}

View File

@ -0,0 +1,117 @@
import * as React from 'react';
import styles from './Projects.module.scss';
import { IProjectsProps } from './IProjectsProps';
import { project, PublishedProject, ProjectCollection, User, CustomFieldCollection, Phase, ProjectSummaryTask, QueueJobCollection, Stage, PublishedAssignmentCollection, Calendar, DraftProject, PublishedProjectResourceCollection, PublishedTaskLinkCollection, PublishedTaskCollection, CommandResult, QueueJob } from "pnpjs-project-online-package";
import { Button } from "office-ui-fabric-react/lib/Button";
import { TypedHash } from '@pnp/common';
export class Projects extends React.Component<IProjectsProps, {}> {
public render(): React.ReactElement<IProjectsProps> {
return (
<div className={styles.buttons}>
<Button text='Get all projects' onClick={this._getAllProjects}></Button>
<Button text='Get project by Id' onClick={this._getProjectById}></Button>
<Button text='Add project' onClick={this._addProject}></Button>
<Button text='Update project' onClick={this._updateProject}></Button>
<Button text='Submit Workflow' onClick={this._updateProjectWorkflow}></Button>
<Button text='Delete project' onClick={this._deleteProject}></Button>
</div>
);
}
private _getAllProjects = async () => {
const projects: ProjectCollection[] = await project.projects.get();
console.log('Projects', projects);
}
private _addProject = async () => {
const proj: CommandResult<PublishedProject> = await project.projects.add({
Name: 'JR test ' + Date.now(),
Description: 'Test project',
EnterpriseProjectTypeId: '7ca316cc-b347-e711-80d1-00155d3c701a'
});
console.log(proj);
}
private _getProjectById = async () => {
const publishedProject: PublishedProject = await project.projects.getById(this.props.projectId).get();
console.log('Project', publishedProject);
const user: User = await project.projects.getById(this.props.projectId).checkedOutBy.get();
console.log('Checked out by', user);
const customFields: CustomFieldCollection[] = await project.projects.getById(this.props.projectId).customFields.get();
console.log('Custom Fields', customFields);
const enterpriseProjectType: CustomFieldCollection = await project.projects.getById(this.props.projectId).enterpriseProjectType.get();
console.log('Enterprise Project Type', enterpriseProjectType);
const phase: Phase = await project.projects.getById(this.props.projectId).phase.get();
console.log('Phase', phase);
const projectSummaryTask: ProjectSummaryTask = await project.projects.getById(this.props.projectId).projectSummaryTask.get();
console.log('Project Summary Task', projectSummaryTask);
const queueJobs: QueueJobCollection[] = await project.projects.getById(this.props.projectId).queueJobs.get();
console.log('Queue Jobs', queueJobs);
const stage: Stage = await project.projects.getById(this.props.projectId).stage.get();
console.log('Stage', stage);
const assignments: PublishedAssignmentCollection[] = await project.projects.getById(this.props.projectId).assignments.get();
console.log('Assignments', assignments);
const calendar: Calendar = await project.projects.getById(this.props.projectId).calendar.get();
console.log('Calendar', calendar);
const draft: DraftProject = await project.projects.getById(this.props.projectId).draft.get();
console.log('Draft', draft);
const includeCustomFields: PublishedProject = await project.projects.getById(this.props.projectId).includeCustomFields.get();
console.log('Include Custom Fields', includeCustomFields);
const owner: User = await project.projects.getById(this.props.projectId).owner.get();
console.log('Owner', owner);
const projectResources: PublishedProjectResourceCollection[] = await project.projects.getById(this.props.projectId).projectResources.get();
console.log('Project Resources', projectResources);
const taskLinks: PublishedTaskLinkCollection[] = await project.projects.getById(this.props.projectId).taskLinks.get();
console.log('Task Links', taskLinks);
const tasks: PublishedTaskCollection[] = await project.projects.getById(this.props.projectId).tasks.get();
console.log('Tasks', tasks);
}
private _updateProject = async () => {
const checkedOutProject: CommandResult<DraftProject> = await project.projects.getById(this.props.projectId).checkOut();
console.log('CheckOut', checkedOutProject);
const updateValue: TypedHash<string> = {
'Description': 'Updated project ' + Date.now()
};
const update: CommandResult<QueueJob> = await checkedOutProject.instance.update(
updateValue
);
console.log('Update', update);
const publish: CommandResult<QueueJob> = await checkedOutProject.instance.publish(false);
console.log('Publish', publish);
const checkIn: CommandResult<QueueJob> = await checkedOutProject.instance.checkIn(true);
console.log('Check In', checkIn);
}
private _updateProjectWorkflow = async () => {
const submitToWorkflow: void = await project.projects.getById(this.props.projectId).submitToWorkflow();
console.log('Submit To Workflow', submitToWorkflow);
}
private _deleteProject = async () => {
const deleteJob: CommandResult<QueueJob> = await project.projects.getById(this.props.projectId).delete();
console.log('Delete', deleteJob);
}
}

View File

@ -0,0 +1,2 @@
export * from './IProjectsProps';
export * from './Projects';

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,38 @@
{
"extends": "./node_modules/@microsoft/rush-stack-compiler-2.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": [
"es6-promise",
"webpack-env"
],
"lib": [
"es5",
"dom",
"es2015.collection"
]
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules",
"lib"
]
}

View File

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