From b53b9a7f5f72e2d2736eb2508114a83cf688fb9e Mon Sep 17 00:00:00 2001 From: petkir Date: Fri, 19 Jun 2020 14:58:13 +0200 Subject: [PATCH] ManagedProperties Added to Task --- .../src/kanban/IKanbanBoardRenderers.tsx | 8 ++ .../src/kanban/IKanbanBoardTaskSettings.ts | 1 + .../src/kanban/IKanbanTask.ts | 23 +++- .../src/kanban/KanbanBucket.tsx | 3 + .../src/kanban/KanbanComponent.tsx | 105 ++++++++++++++++-- .../src/kanban/KanbanTask.tsx | 22 +++- .../kanban/KanbanTaskManagedProp.module.scss | 6 + .../src/kanban/KanbanTaskManagedProp.tsx | 66 +++++++++++ .../src/kanban/MockKanban.tsx | 63 ++++++++--- .../src/kanban/loc/en-us.js | 9 +- .../src/kanban/loc/mystrings.d.ts | 1 + 11 files changed, 271 insertions(+), 36 deletions(-) create mode 100644 samples/react-kanban-board/src/kanban/IKanbanBoardRenderers.tsx create mode 100644 samples/react-kanban-board/src/kanban/KanbanTaskManagedProp.module.scss create mode 100644 samples/react-kanban-board/src/kanban/KanbanTaskManagedProp.tsx diff --git a/samples/react-kanban-board/src/kanban/IKanbanBoardRenderers.tsx b/samples/react-kanban-board/src/kanban/IKanbanBoardRenderers.tsx new file mode 100644 index 000000000..d5d765d70 --- /dev/null +++ b/samples/react-kanban-board/src/kanban/IKanbanBoardRenderers.tsx @@ -0,0 +1,8 @@ +import {IKanbanTask} from './IKanbanTask'; +import { IKanbanBucket } from './IKanbanBucket'; + +export interface IKanbanBoardRenderers{ + task?: (task:IKanbanTask) => JSX.Element ; + bucketHeadline?: (bucket:IKanbanBucket) => JSX.Element ; + taskDetail?: (task:IKanbanTask) => JSX.Element ; +} \ No newline at end of file diff --git a/samples/react-kanban-board/src/kanban/IKanbanBoardTaskSettings.ts b/samples/react-kanban-board/src/kanban/IKanbanBoardTaskSettings.ts index a94a87c51..a5e36e7b7 100644 --- a/samples/react-kanban-board/src/kanban/IKanbanBoardTaskSettings.ts +++ b/samples/react-kanban-board/src/kanban/IKanbanBoardTaskSettings.ts @@ -2,4 +2,5 @@ export interface IKanbanBoardTaskSettings { showLabels: boolean; showPriority: boolean; showAssignedTo: boolean; + showTaskDetailsButton: boolean; } \ No newline at end of file diff --git a/samples/react-kanban-board/src/kanban/IKanbanTask.ts b/samples/react-kanban-board/src/kanban/IKanbanTask.ts index e845928b2..ec9deb150 100644 --- a/samples/react-kanban-board/src/kanban/IKanbanTask.ts +++ b/samples/react-kanban-board/src/kanban/IKanbanTask.ts @@ -2,5 +2,26 @@ export interface IKanbanTask { taskId: number | string; title: string; isCompleted?: boolean; - bucket:string; + bucket: string; + mamagedProperties?: IKanbanTaskManagedProps[]; + +} + +export interface IKanbanTaskManagedProps { + name: string; + displayName?: string; + type: KanbanTaskMamagedPropertyType; + value: any; + renderer?: (name: string, value: object, type:KanbanTaskMamagedPropertyType) => JSX.Element; +} + +export enum KanbanTaskMamagedPropertyType { + + string, + number, + percent, + html, + person, + persons, + complex } \ No newline at end of file diff --git a/samples/react-kanban-board/src/kanban/KanbanBucket.tsx b/samples/react-kanban-board/src/kanban/KanbanBucket.tsx index a3112077d..06278edb0 100644 --- a/samples/react-kanban-board/src/kanban/KanbanBucket.tsx +++ b/samples/react-kanban-board/src/kanban/KanbanBucket.tsx @@ -19,6 +19,9 @@ export interface IKanbanBucketProps extends IKanbanBucket { onDragOver: (event, targetbucket: string) => void; onDragLeave: (event, targetbucket: string) => void; onDrop: (event, targetbucket: string) => void; + + + leavingTaskId?: number | string; leavingBucket?: string; diff --git a/samples/react-kanban-board/src/kanban/KanbanComponent.tsx b/samples/react-kanban-board/src/kanban/KanbanComponent.tsx index ee1d23043..bfb1687c5 100644 --- a/samples/react-kanban-board/src/kanban/KanbanComponent.tsx +++ b/samples/react-kanban-board/src/kanban/KanbanComponent.tsx @@ -3,8 +3,16 @@ import styles from './KanbanComponent.module.scss'; import { IKanbanTask } from './IKanbanTask'; import { IKanbanBoardTaskSettings } from './IKanbanBoardTaskSettings'; import { IKanbanBoardTaskActions } from './IKanbanBoardTaskActions'; +import { IKanbanBoardRenderers } from './IKanbanBoardRenderers'; import { IKanbanBucket } from './IKanbanBucket'; import KanbanBucket from './KanbanBucket'; +import KanbanTaskManagedProp from './KanbanTaskManagedProp'; + +import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog'; +import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button'; +import { IStackStyles, Stack } from 'office-ui-fabric-react/lib/Stack'; + + import { CommandBar } from 'office-ui-fabric-react/lib/CommandBar'; @@ -14,6 +22,7 @@ export interface IKanbanComponentProps { tasksettings: IKanbanBoardTaskSettings; taskactions: IKanbanBoardTaskActions; showCommandbar?: boolean; + renderers?: IKanbanBoardRenderers; /* showCommandbarNew: boolean; allowDialog: boolean; TODO im mock @@ -24,6 +33,8 @@ export interface IKanbanComponentState { leavingTaskId?: number | string; leavingBucket?: string; overBucket?: string; + openDialog: boolean; + openTaskId?: number | string; } export default class KanbanComponent extends React.Component { @@ -32,6 +43,7 @@ export default class KanbanComponent extends React.Component { const { buckets, tasks, tasksettings, taskactions, showCommandbar } = this.props; + const { openDialog } = this.state; const { leavingBucket, leavingTaskId, overBucket } = this.state return (
@@ -60,22 +73,92 @@ export default class KanbanComponent extends React.Component x.bucket == b.bucket)} tasksettings={tasksettings} taskactions={taskactions} - openDetails={(x) => alert(x)} + openDetails={this.openDialog.bind(this)} onDrop={this.onDrop.bind(this)} onDragLeave={this.onDragLeave.bind(this)} onDragOver={this.onDragOver.bind(this)} onDragStart={this.onDragStart.bind(this)} - />) + />); } )}
+ {openDialog && (this.renderDetails())} ); } + private renderDetails(): JSX.Element { + debugger; + const renderer = this.props.renderers && this.props.renderers.taskDetail ? this.props.renderers.taskDetail : this.internalTaskDetailRenderer; + const tasks = this.props.tasks.filter(t => t.taskId == this.state.openTaskId); + + if (tasks.length == 1) { + const task = tasks[0]; + + return (); + } + + // Error Not found or more than one + throw "Error Not found or more than one"; + return (
); + + } + + private internalTaskDetailRenderer(task: IKanbanTask): JSX.Element { + return ( + {/* + + % Complete + + + {task.bucket} + + + + */} + {task.mamagedProperties && ( + task.mamagedProperties.map((p, i) => { + return ( + + ); + }) + )} + + + ); + } + private closeDialog(ev?: React.MouseEvent) { + this.setState({ + openDialog: false, + openTaskId: undefined + }); + } + private openDialog(taskid: number | string) { + this.setState({ + openDialog: true, + openTaskId: taskid + }); + + } + private onDragLeave(event): void { console.log('onDragLeave'); /* if (this.bucketRef.current.classList.contains(styles.dragover)) { @@ -126,19 +209,19 @@ export default class KanbanComponent extends React.Components.bucket == sourcebucket)[0]; - const target = this.props.buckets.filter(s=>s.bucket == targetbucket)[0]; + const source = this.props.buckets.filter(s => s.bucket == sourcebucket)[0]; + const target = this.props.buckets.filter(s => s.bucket == targetbucket)[0]; const taskId = event.dataTransfer.getData("taskId"); - if(this.props.taskactions) { - let allowMove= true; - if(this.props.taskactions.allowMove) { - allowMove= this.props.taskactions.allowMove(taskId, + if (this.props.taskactions) { + let allowMove = true; + if (this.props.taskactions.allowMove) { + allowMove = this.props.taskactions.allowMove(taskId, source, target - ); + ); } - if(allowMove && this.props.taskactions.moved) { - this.props.taskactions.moved(taskId,target); + if (allowMove && this.props.taskactions.moved) { + this.props.taskactions.moved(taskId, target); } } } diff --git a/samples/react-kanban-board/src/kanban/KanbanTask.tsx b/samples/react-kanban-board/src/kanban/KanbanTask.tsx index 02c110e97..18af9decb 100644 --- a/samples/react-kanban-board/src/kanban/KanbanTask.tsx +++ b/samples/react-kanban-board/src/kanban/KanbanTask.tsx @@ -6,11 +6,12 @@ import {IKanbanTask} from './IKanbanTask'; import {IKanbanBoardTaskSettings} from './IKanbanBoardTaskSettings'; import {IKanbanBoardTaskActions} from './IKanbanBoardTaskActions'; import classNames from 'classnames'; +import { IconNames } from 'office-ui-fabric-react'; export interface IKanbanTaskProps extends IKanbanTask,IKanbanBoardTaskSettings,IKanbanBoardTaskActions { - openDetails?: (taskId: number | string) => void; + openDetails: (taskId: number | string) => void; onDragStart:(event) => void; isMoving:boolean; } @@ -24,7 +25,7 @@ export default class KanbanTask extends React.Component { - const { title, showLabels, showPriority, showAssignedTo, isCompleted,isMoving } = this.props; + const { title, showLabels, showPriority, showAssignedTo, isCompleted,isMoving,showTaskDetailsButton } = this.props; const showCompleted = !!this.props.toggleCompleted; const iconCompleted = { iconName: isCompleted ? 'RadioBtnOn' : 'RadioBtnOff' }; return ( @@ -42,6 +43,15 @@ export default class KanbanTask extends React.Component) }
{title}
+ { showTaskDetailsButton && ( + ) + } +
{showAssignedTo && (
)} @@ -58,5 +68,13 @@ export default class KanbanTask extends React.Component { + public render(): React.ReactElement { + const { displayName, name } = this.props; + return ( + + + {displayName ? displayName : name} + + + {this.renderValue()} + + + ); + } + private renderValue() { + const { name, type, value } = this.props; + if (this.props.renderer) { + return this.props.renderer(name, value, type); + } + switch (this.props.type) { + case KanbanTaskMamagedPropertyType.string: + return ({value} ); + break; + case KanbanTaskMamagedPropertyType.number: + return ({'' + value} ); + //TODO maybe Formater + break; + case KanbanTaskMamagedPropertyType.percent: + return ({`${(value as any) * 100}%`} ); + //TODO maybe better Formater + break; + case KanbanTaskMamagedPropertyType.html: + return ({ReactHtmlParser(value)}); + //TODO maybe better Formater + break; + case KanbanTaskMamagedPropertyType.person: + return (TODO); + //TODO + break; + case KanbanTaskMamagedPropertyType.persons: + return (TODO); + //TODO + break; + case KanbanTaskMamagedPropertyType.complex: + return ({JSON.stringify(value)}); + break; + default: + throw "Unknow KanbanTaskMamagedPropertyType"; + + break; + } + } +} diff --git a/samples/react-kanban-board/src/kanban/MockKanban.tsx b/samples/react-kanban-board/src/kanban/MockKanban.tsx index d00bb3512..2cd7e2726 100644 --- a/samples/react-kanban-board/src/kanban/MockKanban.tsx +++ b/samples/react-kanban-board/src/kanban/MockKanban.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import KanbanComponent from './KanbanComponent'; import { IKanbanBucket } from './IKanbanBucket'; -import { IKanbanTask } from './IKanbanTask'; +import { IKanbanTask, KanbanTaskMamagedPropertyType } from './IKanbanTask'; import { findIndex } from "lodash"; export interface IMockKanbanProps { } @@ -17,20 +17,46 @@ export class MockKanban extends React.ComponenttestBold

' + + }, + + { + name: 'Prop2', + displayName: 'Prop2 Display', + type: KanbanTaskMamagedPropertyType.complex, + value: '

testBold

', + renderer: (name, value, type) => { return (SampleRenderer); } + }, + { + name: 'Prop3', + displayName: 'String', + type: KanbanTaskMamagedPropertyType.string, + value: 'Hallo World' + + } + ] + }, + { 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' }, + ] }; } @@ -45,7 +71,8 @@ export class MockKanban extends React.Component element.taskId == taskId ); + const elementsIndex = findIndex(this.state.tasks, element => element.taskId == taskId); let newArray = [...this.state.tasks]; newArray[elementsIndex].bucket = targetBucket.bucket; - this.setState({tasks:newArray}); + this.setState({ tasks: newArray }); } } diff --git a/samples/react-kanban-board/src/kanban/loc/en-us.js b/samples/react-kanban-board/src/kanban/loc/en-us.js index 51bbe67fb..04114ac42 100644 --- a/samples/react-kanban-board/src/kanban/loc/en-us.js +++ b/samples/react-kanban-board/src/kanban/loc/en-us.js @@ -1,8 +1,9 @@ define([], function() { return { - "CompleteButton": "complete", - "IsCompleted": "IsCompleted", - "IsNotCompleted": "IsNotCompleted", - "AddTask": "AddTask" + "CompleteButton": "Complete", + "IsCompleted": "Is Completed", + "IsNotCompleted": "Is Not Completed", + "AddTask": "Add Task", + "OpenDetails":"Open Details" } }); \ No newline at end of file diff --git a/samples/react-kanban-board/src/kanban/loc/mystrings.d.ts b/samples/react-kanban-board/src/kanban/loc/mystrings.d.ts index 9b010973b..6e0f89f99 100644 --- a/samples/react-kanban-board/src/kanban/loc/mystrings.d.ts +++ b/samples/react-kanban-board/src/kanban/loc/mystrings.d.ts @@ -3,6 +3,7 @@ declare interface IKanbanBoardStrings { IsCompleted: string; IsNotCompleted: string; AddTask: string; + OpenDetails: string; } declare module 'KanbanBoardStrings' {