Adde Data Connections

This commit is contained in:
petkir 2020-06-22 22:30:37 +02:00
parent e073836425
commit 4b089918d8
5 changed files with 260 additions and 214 deletions

View File

@ -67,11 +67,14 @@ Unexpected call to method or property access.
# Webpart Steps # Webpart Steps
* DataConnection
** Task missing
* BucketEdit Does not refresh Component
# Webpart Steps Done
* PNP Placeholder Control for Config * PNP Placeholder Control for Config
* PNP WebpartTitle Control * PNP WebpartTitle Control
* DataConnection
* Usage of BucketEdit in pane * Usage of BucketEdit in pane
* PNP Order pane Control * PNP Order pane Control

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import * as ReactDom from 'react-dom'; import * as ReactDom from 'react-dom';
import { Version, Guid } from '@microsoft/sp-core-library'; import { Version, Guid, Environment, EnvironmentType } from '@microsoft/sp-core-library';
import { BaseClientSideWebPart, PropertyPaneDropdown } from '@microsoft/sp-webpart-base'; import { BaseClientSideWebPart, PropertyPaneDropdown } from '@microsoft/sp-webpart-base';
import { import {
IPropertyPaneConfiguration, IPropertyPaneConfiguration,
@ -36,6 +36,7 @@ export interface IKanbanBoardWebPartProps {
export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoardWebPartProps> { export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoardWebPartProps> {
private kanbanComponent = null; private kanbanComponent = null;
private statekey: string = Date.now().toString();
public onInit(): Promise<void> { public onInit(): Promise<void> {
return super.onInit().then(_ => { return super.onInit().then(_ => {
@ -48,8 +49,6 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
} }
public render(): void { public render(): void {
/* /*
const element: React.ReactElement<IKanbanBoardProps > = React.createElement( const element: React.ReactElement<IKanbanBoardProps > = React.createElement(
KanbanBoard, KanbanBoard,
@ -61,12 +60,10 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
*/ */
/* /*
const element: React.ReactElement<IMockKanbanProps > = React.createElement( const element: React.ReactElement<IMockKanbanProps > = React.createElement(
MockKanban, MockKanban,{});
{
}
);
*/ */
console.log('bucket render webpart');
console.log(this.properties.buckets);
const element: React.ReactElement<IKanbanBoardV2Props> = React.createElement( const element: React.ReactElement<IKanbanBoardV2Props> = React.createElement(
KanbanBoardV2, KanbanBoardV2,
{ {
@ -76,6 +73,7 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
updateProperty: (value: string) => { updateProperty: (value: string) => {
this.properties.title = value; this.properties.title = value;
}, },
statekey: this.statekey,
context: this.context, context: this.context,
listId: this.properties.listId, listId: this.properties.listId,
configuredBuckets: this.properties.buckets configuredBuckets: this.properties.buckets
@ -122,12 +120,17 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
onListsRetrieved: (lists) => { onListsRetrieved: (lists) => {
//TODO Check from TS Definition it should be a string but i get a number //TODO Check from TS Definition it should be a string but i get a number
// with Typesafe equal it fails // with Typesafe equal it fails
if (Environment.type == EnvironmentType.Local || Environment.type == EnvironmentType.Test) {
return lists;
} else {
const alists = lists.filter((l: any) => { const alists = lists.filter((l: any) => {
return (l.BaseTemplate === 171 || l.BaseTemplate === 107); return (l.BaseTemplate === 171 || l.BaseTemplate === 107);
} });
);
return alists; return alists;
} }
}
}) })
] ]
}); });
@ -137,7 +140,7 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
{ {
groupName: "Order Buckets", groupName: "Order Buckets",
groupFields: [ groupFields: [
PropertyFieldOrder("orderedItems", { PropertyFieldOrder("buckets", {
key: "orderedItems", key: "orderedItems",
label: "Ordered Items", label: "Ordered Items",
items: this.properties.buckets, items: this.properties.buckets,
@ -193,22 +196,17 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
private bucketConfigurationChanged(propertyPath: string, oldValue: any, newValue: any) { private bucketConfigurationChanged(propertyPath: string, oldValue: any, newValue: any) {
//its an array part !!!!! //its an array part !!!!!
if (propertyPath.indexOf('bucket_') !== -1) { if (propertyPath.indexOf('bucket_') !== -1) {
const oribuckets: IKanbanBucket[] = cloneDeep(this.properties.buckets);
const newbuckets: IKanbanBucket[] = cloneDeep(this.properties.buckets); const newbuckets: IKanbanBucket[] = cloneDeep(this.properties.buckets);
const bucketindex: number = +propertyPath.split('_')[1]; const bucketindex: number = +propertyPath.split('_')[1];
newbuckets[bucketindex] = newValue; newbuckets[bucketindex] = newValue;
//merge and every else is good //maybe better to make a array control (Update)
//
console.log('buckes updated old saved'); this.onPropertyPaneFieldChanged("buckets", oribuckets, newbuckets);
console.log(oldValue); this.properties.buckets = newbuckets;
// this.onPropertyPaneFieldChanged('buckets', this.properties.buckets, newbuckets); this.context.propertyPane.refresh();
this.properties.buckets = cloneDeep(newbuckets); this.render();
// array child Properties change dows not trigger rerender
// i think this is better as an Property With da DateTimeValue to force Rerender
console.log('old');
console.log(this.properties.buckets);
console.log('new');
console.log(newbuckets);
this.kanbanComponent.forceUpdate();
} else { } else {
throw "propertypath is not a bucket"; throw "propertypath is not a bucket";

View File

@ -1,14 +1,15 @@
import * as React from 'react'; import * as React from 'react';
import styles from './KanbanBoardV2.module.scss'; import styles from './KanbanBoardV2.module.scss';
import * as strings from 'KanbanBoardWebPartStrings';
import { DisplayMode, Guid } from '@microsoft/sp-core-library'; import { DisplayMode, Guid } from '@microsoft/sp-core-library';
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle"; import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder"; import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
import { WebPartContext } from '@microsoft/sp-webpart-base'; import { WebPartContext } from '@microsoft/sp-webpart-base';
import { Spinner } from 'office-ui-fabric-react/lib/Spinner'; import { Spinner } from 'office-ui-fabric-react/lib/Spinner';
import { IKanbanBucket } from '../../../kanban/IKanbanBucket'; import { IKanbanBucket } from '../../../kanban/IKanbanBucket';
import { IKanbanTask } from '../../../kanban/IKanbanTask'; import { IKanbanTask, KanbanTaskMamagedPropertyType } from '../../../kanban/IKanbanTask';
import KanbanComponent from '../../../kanban/KanbanComponent'; import KanbanComponent from '../../../kanban/KanbanComponent';
import { findIndex, clone, isEqual } from '@microsoft/sp-lodash-subset'; import { findIndex, clone, isEqual, cloneDeep } from '@microsoft/sp-lodash-subset';
import { sp } from '@pnp/sp'; import { sp } from '@pnp/sp';
import { mergeBucketsWithChoices } from './helper'; import { mergeBucketsWithChoices } from './helper';
@ -20,6 +21,7 @@ export interface IKanbanBoardV2Props {
context: WebPartContext; context: WebPartContext;
listId: string; listId: string;
configuredBuckets: IKanbanBucket[]; // need mearge with current readed configuredBuckets: IKanbanBucket[]; // need mearge with current readed
statekey: string; // force refresh ;)
} }
export interface IKanbanBoardV2State { export interface IKanbanBoardV2State {
@ -47,11 +49,12 @@ export default class KanbanBoardV2 extends React.Component<IKanbanBoardV2Props,
this._getData(); this._getData();
} }
public shouldComponentUpdate(nextProps: IKanbanBoardV2Props, nextState: IKanbanBoardV2State): boolean { public shouldComponentUpdate(nextProps: IKanbanBoardV2Props, nextState: IKanbanBoardV2State): boolean {
if (!isEqual(this.state, nextState)) { return true; } if (!isEqual(this.state, nextState)) { return true; }
if (!isEqual(this.props, nextProps)) { if (!isEqual(this.props, nextProps)) {
console.log('change in Props found') //stateKey
return true; } return true;
}
return false; return false;
} }
public componentDidUpdate(prevProps: IKanbanBoardV2Props) { public componentDidUpdate(prevProps: IKanbanBoardV2Props) {
@ -59,7 +62,11 @@ export default class KanbanBoardV2 extends React.Component<IKanbanBoardV2Props,
if (this.props.listId !== prevProps.listId) { if (this.props.listId !== prevProps.listId) {
this._getData(); this._getData();
} }
const currentPropBuckets: IKanbanBucket[] = mergeBucketsWithChoices(this.props.configuredBuckets, this.choices);
if (!isEqual(this.state.buckets, currentPropBuckets)) {
this.setState({ buckets: cloneDeep(currentPropBuckets) });
}
/*
const currentbuckets: IKanbanBucket[] = mergeBucketsWithChoices(this.props.configuredBuckets, this.choices); const currentbuckets: IKanbanBucket[] = mergeBucketsWithChoices(this.props.configuredBuckets, this.choices);
console.log(this.props.configuredBuckets); console.log(this.props.configuredBuckets);
console.log(currentbuckets); console.log(currentbuckets);
@ -68,7 +75,7 @@ export default class KanbanBoardV2 extends React.Component<IKanbanBoardV2Props,
this.setState({ buckets: currentbuckets }); this.setState({ buckets: currentbuckets });
} }*/
} }
public render(): React.ReactElement<IKanbanBoardV2Props> { public render(): React.ReactElement<IKanbanBoardV2Props> {
@ -123,7 +130,15 @@ export default class KanbanBoardV2 extends React.Component<IKanbanBoardV2Props,
const elementsIndex = findIndex(this.state.tasks, element => element.taskId == taskId); const elementsIndex = findIndex(this.state.tasks, element => element.taskId == taskId);
let newArray = [...this.state.tasks]; // same as Clone let newArray = [...this.state.tasks]; // same as Clone
newArray[elementsIndex].bucket = targetBucket.bucket; newArray[elementsIndex].bucket = targetBucket.bucket;
sp.web.lists.getById(this.props.listId).items.getById(+taskId).update({
Status: targetBucket.bucket
}).then(res => {
console.log("Task updated");
this.setState({ tasks: newArray }); this.setState({ tasks: newArray });
}).catch(error=> {
this.setState({ errorMessage: 'Error Update Task Item' });
});
} }
@ -146,14 +161,42 @@ export default class KanbanBoardV2 extends React.Component<IKanbanBoardV2Props,
this.setState({ isConfigured: false, loading: false, errorMessage: 'No Buckets found' }); this.setState({ isConfigured: false, loading: false, errorMessage: 'No Buckets found' });
return; return;
} }
sp.web.lists.getById(listId).items.getAll().then(res => { const odatafiels: string[] = ['AssignedTo/Id', 'AssignedTo/Title', 'AssignedTo/Name', 'AssignedTo/EMail',
//Map Items to task 'ID', 'Title', 'Status', 'Priority', 'PercentComplete', 'Body'
];
sp.web.lists.getById(listId).items
.select(odatafiels.join(','))
.expand('AssignedTo').getAll().then(res => {
const tasks: IKanbanTask[] = res.map((x) => {
return {
taskId: '' + x.ID,
title: x.Title,
htmlDescription: x.Body,
assignedTo: (x.AssignedTo && (x.AssignedTo).length === 1) ?
{
text: x.AssignedTo[0].Title
}
: undefined,
priority: x.Priority,
bucket: x.Status,
mamagedProperties: [
{
name: 'PercentComplete',
displayName: strings.PercentComplete,
type: KanbanTaskMamagedPropertyType.percent,
value: x.PercentComplete
}
]
};
});
this.setState({ this.setState({
isConfigured: true, isConfigured: true,
loading: false, loading: false,
errorMessage: undefined, errorMessage: undefined,
buckets: currentbuckets, buckets: currentbuckets,
tasks: [] tasks: tasks
}); });
}); });

View File

@ -2,6 +2,7 @@ define([], function() {
return { return {
"PropertyPaneDescription": "Description", "PropertyPaneDescription": "Description",
"BasicGroupName": "Basic Configuration", "BasicGroupName": "Basic Configuration",
"ListTitleFieldLabel": "List Title" "ListTitleFieldLabel": "List Title",
"PercentComplete": "Percent Complete"
} }
}); });

View File

@ -2,6 +2,7 @@ declare interface IKanbanBoardWebPartStrings {
PropertyPaneDescription: string; PropertyPaneDescription: string;
BasicGroupName: string; BasicGroupName: string;
ListTitleFieldLabel: string; ListTitleFieldLabel: string;
PercentComplete: string;
} }
declare module 'KanbanBoardWebPartStrings' { declare module 'KanbanBoardWebPartStrings' {