wrong brunch
This commit is contained in:
parent
1b18bc75e7
commit
68e53f2bc5
|
@ -13,6 +13,7 @@
|
||||||
},
|
},
|
||||||
"externals": {},
|
"externals": {},
|
||||||
"localizedResources": {
|
"localizedResources": {
|
||||||
|
"KanbanBoardStrings": "lib/kanban/loc/{locale}.js",
|
||||||
"KanbanBoardWebPartStrings": "lib/webparts/kanbanBoard/loc/{locale}.js"
|
"KanbanBoardWebPartStrings": "lib/webparts/kanbanBoard/loc/{locale}.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-kanban-board-client-side-solution",
|
"name": "react-kanban-board-client-side-solution",
|
||||||
"id": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
|
"id": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
|
||||||
"version": "1.0.0.0",
|
"version": "1.0.1.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/react-kanban-board.sppkg"
|
"zippedPackage": "solution/react-kanban-board.sppkg"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { IKanbanBucket } from "./IKanbanBucket";
|
||||||
|
|
||||||
|
export interface IKanbanBoardTaskActions {
|
||||||
|
|
||||||
|
toggleCompleted?: (taskId: number | string) => void;
|
||||||
|
allowMove?: (taskId: number | string, prevBucket: IKanbanBucket, targetBucket: IKanbanBucket) => boolean;
|
||||||
|
moved?: (taskId: number | string, targetBucket: IKanbanBucket) => void;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
export interface IKanbanBoardTaskSettings {
|
||||||
|
showLabels: boolean;
|
||||||
|
showPriority: boolean;
|
||||||
|
showAssignedTo: boolean;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
export interface IKanbanBucket {
|
||||||
|
bucket:string;
|
||||||
|
bucketheadline:string;
|
||||||
|
percentageComplete: number;
|
||||||
|
color?:string;
|
||||||
|
allowAddTask?:boolean;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
export interface IKanbanTask {
|
||||||
|
taskId: number | string;
|
||||||
|
title: string;
|
||||||
|
isCompleted?: boolean;
|
||||||
|
bucket:string;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
.bucket {
|
||||||
|
display: table-cell;
|
||||||
|
|
||||||
|
|
||||||
|
border-right: 1px solid gray;
|
||||||
|
.headline {
|
||||||
|
padding: 2px 10px;
|
||||||
|
line-height: 2em;
|
||||||
|
font-weight: 700;
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid gray;
|
||||||
|
.colorindicator {
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import styles from './KanbanBucket.module.scss';
|
||||||
|
import { IKanbanBucket } from './IKanbanBucket';
|
||||||
|
import { IKanbanTask } from './IKanbanTask';
|
||||||
|
import { IKanbanBoardTaskSettings } from './IKanbanBoardTaskSettings';
|
||||||
|
import { IKanbanBoardTaskActions } from './IKanbanBoardTaskActions';
|
||||||
|
import { ProgressIndicator } from 'office-ui-fabric-react/lib/ProgressIndicator';
|
||||||
|
import { ActionButton } from 'office-ui-fabric-react';
|
||||||
|
import KanbanTask from './KanbanTask';
|
||||||
|
import * as strings from 'KanbanBoardStrings';
|
||||||
|
|
||||||
|
export interface IKanbanBucketProps extends IKanbanBucket {
|
||||||
|
buckettasks: IKanbanTask[];
|
||||||
|
tasksettings: IKanbanBoardTaskSettings;
|
||||||
|
taskactions: IKanbanBoardTaskActions;
|
||||||
|
|
||||||
|
openDetails?: (taskId: number | string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IKanbanBucketState { }
|
||||||
|
|
||||||
|
export default class KanbanBucket extends React.Component<IKanbanBucketProps, IKanbanBucketState> {
|
||||||
|
|
||||||
|
constructor(props: IKanbanBucketProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
nice to use a object merge
|
||||||
|
ECMAScript 2018 Standard Method
|
||||||
|
{...t, ...tasksettings, ...taskactions}
|
||||||
|
hope this will be translated
|
||||||
|
*/
|
||||||
|
public render(): React.ReactElement<IKanbanBucketProps> {
|
||||||
|
const { bucketheadline, color, buckettasks, tasksettings, taskactions, percentageComplete, allowAddTask } = this.props;
|
||||||
|
return (
|
||||||
|
<div className={styles.bucket}
|
||||||
|
onDragOver={(event) => this.onDragOver(event)}
|
||||||
|
onDrop={this.onDrop.bind(this)}
|
||||||
|
>
|
||||||
|
<div className={styles.headline}>
|
||||||
|
<span>{bucketheadline}</span>
|
||||||
|
{color && <div style={{ backgroundColor: color }} className={styles.colorindicator}></div>}
|
||||||
|
<ProgressIndicator percentComplete={percentageComplete / 100} />
|
||||||
|
</div>
|
||||||
|
{allowAddTask && (<ActionButton
|
||||||
|
iconProps={{ iconName: 'Add' }}
|
||||||
|
allowDisabledFocus={true}
|
||||||
|
|
||||||
|
>
|
||||||
|
{strings.AddTask}
|
||||||
|
</ActionButton>)}
|
||||||
|
{
|
||||||
|
buckettasks.map((t) => {
|
||||||
|
const merge = { ...t, ...tasksettings, ...taskactions };
|
||||||
|
return (
|
||||||
|
<KanbanTask
|
||||||
|
{...merge}
|
||||||
|
openDetails={this.props.openDetails}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private onDragOver(event): void {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDrop(event): void {
|
||||||
|
// this.props.name
|
||||||
|
// let taskName = event.dataTransfer.getData("taskName");
|
||||||
|
/*
|
||||||
|
let tasks = this.state.tasks.filter((task) => {
|
||||||
|
if (task.taskName == taskName) {
|
||||||
|
task.type = cat;
|
||||||
|
}
|
||||||
|
return task;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
...this.state,
|
||||||
|
tasks
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
.kanbanBoard {
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import styles from './KanbanComponent.module.scss';
|
||||||
|
import { IKanbanTask } from './IKanbanTask';
|
||||||
|
import { IKanbanBoardTaskSettings } from './IKanbanBoardTaskSettings';
|
||||||
|
import { IKanbanBoardTaskActions } from './IKanbanBoardTaskActions';
|
||||||
|
import { IKanbanBucket } from './IKanbanBucket';
|
||||||
|
import KanbanBucket from './KanbanBucket';
|
||||||
|
|
||||||
|
import { CommandBar } from 'office-ui-fabric-react/lib/CommandBar';
|
||||||
|
|
||||||
|
export interface IKanbanComponentProps {
|
||||||
|
buckets: IKanbanBucket[];
|
||||||
|
tasks: IKanbanTask[];
|
||||||
|
tasksettings: IKanbanBoardTaskSettings;
|
||||||
|
taskactions: IKanbanBoardTaskActions;
|
||||||
|
showCommandbar?: boolean;
|
||||||
|
/*
|
||||||
|
showCommandbarNew: boolean;
|
||||||
|
allowDialog: boolean; TODO im mock
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IKanbanComponentState { }
|
||||||
|
|
||||||
|
export default class KanbanComponent extends React.Component<IKanbanComponentProps, IKanbanComponentState> {
|
||||||
|
|
||||||
|
constructor(props: IKanbanComponentProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): React.ReactElement<IKanbanComponentProps> {
|
||||||
|
const { buckets, tasks, tasksettings, taskactions, showCommandbar } = this.props;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{showCommandbar && <CommandBar
|
||||||
|
items={this.getItems()}
|
||||||
|
|
||||||
|
farItems={this.getFarItems()}
|
||||||
|
ariaLabel={'Use left and right arrow keys to navigate between commands'}
|
||||||
|
/>}
|
||||||
|
<div className={styles.kanbanBoard}>
|
||||||
|
{buckets.map((b) =>
|
||||||
|
(<KanbanBucket
|
||||||
|
{...b}
|
||||||
|
buckettasks={tasks.filter((x) => x.bucket == b.bucket)}
|
||||||
|
tasksettings={tasksettings}
|
||||||
|
taskactions={taskactions}
|
||||||
|
openDetails={(x) => alert(x)}
|
||||||
|
/>)
|
||||||
|
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getItems = () => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'newItem',
|
||||||
|
name: 'New',
|
||||||
|
cacheKey: 'myCacheKey', // changing this key will invalidate this items cache
|
||||||
|
iconProps: {
|
||||||
|
iconName: 'Add'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
private getFarItems = () => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'info',
|
||||||
|
name: 'Info',
|
||||||
|
ariaLabel: 'Info',
|
||||||
|
iconProps: {
|
||||||
|
iconName: 'Info'
|
||||||
|
},
|
||||||
|
iconOnly: true,
|
||||||
|
onClick: () => console.log('Info')
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
.taskcard {
|
||||||
|
display: block;
|
||||||
|
.titlerow {
|
||||||
|
.title{
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.membersAndLabels {
|
||||||
|
.labels,
|
||||||
|
.priority,
|
||||||
|
.assignedto {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import styles from './KanbanTask.module.scss';
|
||||||
|
import * as strings from 'KanbanBoardStrings';
|
||||||
|
import { IconButton } from 'office-ui-fabric-react/lib/Button';
|
||||||
|
import {IKanbanTask} from './IKanbanTask';
|
||||||
|
import {IKanbanBoardTaskSettings} from './IKanbanBoardTaskSettings';
|
||||||
|
import {IKanbanBoardTaskActions} from './IKanbanBoardTaskActions';
|
||||||
|
|
||||||
|
export interface IKanbanTaskProps extends IKanbanTask,IKanbanBoardTaskSettings,IKanbanBoardTaskActions {
|
||||||
|
|
||||||
|
|
||||||
|
openDetails?: (taskId: number | string) => void;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IKanbanTaskState { }
|
||||||
|
|
||||||
|
export default class KanbanTask extends React.Component<IKanbanTaskProps, IKanbanTaskState> {
|
||||||
|
constructor(props: IKanbanTaskProps) {
|
||||||
|
super(props);
|
||||||
|
this.state = {};
|
||||||
|
}
|
||||||
|
public render(): React.ReactElement<IKanbanTaskProps> {
|
||||||
|
|
||||||
|
const { title, showLabels, showPriority, showAssignedTo, isCompleted } = this.props;
|
||||||
|
const showCompleted = !!this.props.toggleCompleted;
|
||||||
|
const iconCompleted = { iconName: isCompleted ? 'RadioBtnOn' : 'RadioBtnOff' };
|
||||||
|
return (
|
||||||
|
<div className={styles.taskcard}
|
||||||
|
onDragStart = {(event) => this.onDragStart(event)}
|
||||||
|
>
|
||||||
|
<div className={styles.titlerow}>
|
||||||
|
{showCompleted && (
|
||||||
|
<IconButton
|
||||||
|
iconProps={iconCompleted}
|
||||||
|
title={isCompleted ? strings.IsCompleted : strings.IsNotCompleted}
|
||||||
|
ariaLabel={isCompleted ? strings.IsCompleted : strings.IsNotCompleted}
|
||||||
|
onClick={this._toggleCompleted.bind(this)}
|
||||||
|
/>)
|
||||||
|
}
|
||||||
|
<div className={styles.title}>{title}</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.membersAndLabels}>
|
||||||
|
{showAssignedTo && (<div className={styles.assignedto}></div>)}
|
||||||
|
{showLabels && (<div className={styles.labels}></div>)}
|
||||||
|
{showPriority && (<div className={styles.priority}></div>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _toggleCompleted(): void {
|
||||||
|
if (this.props.toggleCompleted) {
|
||||||
|
this.props.toggleCompleted(this.props.taskId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDragStart(event): void {
|
||||||
|
console.log('dragstart on div: ', this.props.taskId);
|
||||||
|
event.dataTransfer.setData("taskId", this.props.taskId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import KanbanComponent from './KanbanComponent';
|
||||||
|
import { IKanbanBucket } from './IKanbanBucket';
|
||||||
|
import { IKanbanTask } from './IKanbanTask';
|
||||||
|
|
||||||
|
export interface IMockKanbanProps { }
|
||||||
|
|
||||||
|
export interface IMockKanbanState {
|
||||||
|
buckets: IKanbanBucket[];
|
||||||
|
tasks: IKanbanTask[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MockKanban extends React.Component<IMockKanbanProps, IMockKanbanState> {
|
||||||
|
|
||||||
|
constructor(props: IMockKanbanProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
buckets:[
|
||||||
|
{bucket:'Not Started', bucketheadline:'Not Started Head',percentageComplete:0, color:'yellow' ,allowAddTask:true},
|
||||||
|
{bucket:'Test1', bucketheadline:'Test1 Head',percentageComplete:10, color:'orange',allowAddTask:true },
|
||||||
|
{bucket:'Test2', bucketheadline:'Test2 Head',percentageComplete:50, color:'green' },
|
||||||
|
{bucket:'Test3', bucketheadline:'Test3 Head',percentageComplete:50, color:'#FF0000' },
|
||||||
|
{bucket:'Test4', bucketheadline:'Test4 Head',percentageComplete:0 ,allowAddTask:true }
|
||||||
|
],
|
||||||
|
tasks: [
|
||||||
|
{taskId: 1, title:'test1',bucket:'Not Started'},
|
||||||
|
{taskId: 2, title:'test2',bucket:'Not Started'},
|
||||||
|
{taskId: 3, title:'test3',bucket:'Not Started'},
|
||||||
|
{taskId: '4', title:'test 4',bucket:'Test4'},
|
||||||
|
{taskId: '5', title:'test 5',bucket:'Test3'},
|
||||||
|
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): React.ReactElement<IMockKanbanProps> {
|
||||||
|
const { buckets, tasks } = this.state;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<KanbanComponent
|
||||||
|
buckets={buckets}
|
||||||
|
tasks={tasks}
|
||||||
|
tasksettings={{
|
||||||
|
showLabels: true,
|
||||||
|
showPriority: true,
|
||||||
|
showAssignedTo: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskactions={{
|
||||||
|
toggleCompleted: this._toggleCompleted.bind(this),
|
||||||
|
allowMove: this._allowMove.bind(this),
|
||||||
|
moved: this._moved.bind(this),
|
||||||
|
}}
|
||||||
|
showCommandbar={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _toggleCompleted(taskId: number | string): void {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
private _allowMove(taskId: number | string, prevBucket: IKanbanBucket, targetBucket: IKanbanBucket): boolean {
|
||||||
|
//TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _moved(taskId: number | string, targetBucket: IKanbanBucket): void {
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
Property Panel:
|
||||||
|
Liste Laden
|
||||||
|
auswahl vom Status mittels Drag n drop PNP COntrol
|
||||||
|
Edit percentrage and color for each State
|
|
@ -0,0 +1,8 @@
|
||||||
|
define([], function() {
|
||||||
|
return {
|
||||||
|
"CompleteButton": "complete",
|
||||||
|
"IsCompleted": "IsCompleted",
|
||||||
|
"IsNotCompleted": "IsNotCompleted",
|
||||||
|
"AddTask": "AddTask"
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,11 @@
|
||||||
|
declare interface IKanbanBoardStrings {
|
||||||
|
CompleteButton: string;
|
||||||
|
IsCompleted: string;
|
||||||
|
IsNotCompleted: string;
|
||||||
|
AddTask: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'KanbanBoardStrings' {
|
||||||
|
const strings: IKanbanBoardStrings;
|
||||||
|
export = strings;
|
||||||
|
}
|
|
@ -14,6 +14,8 @@ import { IKanbanBoardProps } from './components/IKanbanBoardProps';
|
||||||
import "@pnp/polyfill-ie11";
|
import "@pnp/polyfill-ie11";
|
||||||
import {sp} from '@pnp/sp';
|
import {sp} from '@pnp/sp';
|
||||||
|
|
||||||
|
import {MockKanban,IMockKanbanProps} from '../../kanban/MockKanban';
|
||||||
|
|
||||||
export interface IKanbanBoardWebPartProps {
|
export interface IKanbanBoardWebPartProps {
|
||||||
listTitle: string;
|
listTitle: string;
|
||||||
lists: Array<any>;
|
lists: Array<any>;
|
||||||
|
@ -36,7 +38,7 @@ 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,
|
||||||
{
|
{
|
||||||
|
@ -44,6 +46,13 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
|
||||||
webUrl: this.context.pageContext.web.absoluteUrl
|
webUrl: this.context.pageContext.web.absoluteUrl
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
const element: React.ReactElement<IMockKanbanProps > = React.createElement(
|
||||||
|
MockKanban,
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
ReactDom.render(element, this.domElement);
|
ReactDom.render(element, this.domElement);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue