Bucket configurator
This commit is contained in:
parent
4b92db1f95
commit
12903a8596
|
@ -55,7 +55,7 @@ export default class KanbanBucket extends React.Component<IKanbanBucketProps, IK
|
|||
const { bucket, bucketheadline, color, buckettasks,
|
||||
tasksettings, percentageComplete,
|
||||
allowAddTask, overBucket, leavingTaskId, leavingBucket } = this.props;
|
||||
|
||||
debugger;
|
||||
return (
|
||||
<div
|
||||
className={classNames({ [styles.bucket]: true, [styles.dragover]: !!(overBucket && overBucket === bucket) })}
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
import * as React from 'react';
|
||||
|
||||
//import styles from './KanbanBucketConfigurator.module.scss';
|
||||
|
||||
import * as strings from 'KanbanBoardStrings';
|
||||
import { TextField, MaskedTextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { Stack, IStackProps, IStackStyles } from 'office-ui-fabric-react/lib/Stack';
|
||||
import { Slider } from 'office-ui-fabric-react/lib/Slider';
|
||||
import { Toggle } from 'office-ui-fabric-react/lib/Toggle';
|
||||
import { cloneDeep, clone, isEqual } from '@microsoft/sp-lodash-subset';
|
||||
import {
|
||||
ColorPicker,
|
||||
ChoiceGroup,
|
||||
IChoiceGroupOption,
|
||||
getColorFromString,
|
||||
IColor,
|
||||
IColorPickerStyles,
|
||||
IColorPickerProps,
|
||||
PrimaryButton,
|
||||
DefaultButton,
|
||||
ThemeSettingName,
|
||||
} from 'office-ui-fabric-react/lib/index';
|
||||
|
||||
import { IKanbanBucket } from './IKanbanBucket';
|
||||
|
||||
|
||||
export interface IKanbanBucketConfiguratorProps {
|
||||
index: number;
|
||||
bucket: IKanbanBucket;
|
||||
update: (index: number, value: IKanbanBucket) => void;
|
||||
}
|
||||
|
||||
export interface IKanbanBucketConfiguratorState {
|
||||
bucket?: IKanbanBucket;
|
||||
// showHeadline: boolean;
|
||||
useColor: boolean;
|
||||
}
|
||||
|
||||
export default class KanbanBucketConfigurator extends React.Component<IKanbanBucketConfiguratorProps, IKanbanBucketConfiguratorState> {
|
||||
|
||||
constructor(props: IKanbanBucketConfiguratorProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
// showHeadline: false,
|
||||
useColor: false
|
||||
};
|
||||
|
||||
}
|
||||
public componentDidMount(): void {
|
||||
this.resetState();
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: IKanbanBucketConfiguratorProps): void {
|
||||
if (prevProps.bucket && this.props.bucket && !isEqual(this.props.bucket, prevProps.bucket)) {
|
||||
this.resetState();
|
||||
}
|
||||
}
|
||||
|
||||
public render(): React.ReactElement<IKanbanBucketConfiguratorProps> {
|
||||
/*
|
||||
const columnProps: Partial<IStackProps> = {
|
||||
gap: 15,
|
||||
styles: { root: { width: 300 } },
|
||||
};*/
|
||||
/*
|
||||
const colorPickerStyles: Partial<IColorPickerStyles> = {
|
||||
panel: { padding: 12 },
|
||||
root: {
|
||||
maxWidth: 352,
|
||||
minWidth: 352,
|
||||
},
|
||||
colorRectangle: { height: 268 },
|
||||
};*/
|
||||
const statebucket = this.state.bucket;
|
||||
if (!statebucket) {
|
||||
return (<div></div>);
|
||||
}
|
||||
return (
|
||||
<Stack>
|
||||
<TextField label={strings.BucketConfigInternalName} disabled defaultValue={statebucket.bucket} />
|
||||
{/* <Toggle label={strings.BucketConfigUseCustomHeadline} onText="On" offText="Off" inlineLabel
|
||||
checked={this.state.showHeadline}
|
||||
onChange={(ev, checked) => { this.setState({ showHeadline: checked }); }} />
|
||||
*/}
|
||||
<TextField label={strings.BucketConfigHeadline} defaultValue={statebucket.bucketheadline}
|
||||
onChanged={(value: string) => {
|
||||
const bucket = clone(this.state.bucket);
|
||||
bucket.bucketheadline = value;
|
||||
this.setState({ bucket: bucket });
|
||||
}}
|
||||
/>
|
||||
|
||||
<Slider
|
||||
label={strings.BucketConfigPercentageComplete}
|
||||
max={100}
|
||||
value={statebucket.percentageComplete}
|
||||
ariaValueText={(value: number) => `${value} ${strings.Percent}`}
|
||||
valueFormat={(value: number) => `${value}%`}
|
||||
showValue
|
||||
onChange={(value: number) => {
|
||||
const bucket = clone(this.state.bucket);
|
||||
bucket.percentageComplete = value;
|
||||
this.setState({ bucket: bucket });
|
||||
}}
|
||||
/>
|
||||
<Toggle label={strings.BucketConfigAllowAddTask} onText="On" offText="Off" inlineLabel
|
||||
checked={statebucket.allowAddTask}
|
||||
onChange={(ev, checked) => {
|
||||
const bucket = clone(this.state.bucket);
|
||||
bucket.allowAddTask = checked;
|
||||
this.setState({ bucket: bucket });
|
||||
}} />
|
||||
<Toggle label={strings.BucketConfigUseColor} onText="On" offText="Off" inlineLabel
|
||||
checked={this.state.useColor}
|
||||
onChange={(ev, checked) => { this.setState({ useColor: checked }); }} />
|
||||
{this.state.useColor && (<ColorPicker
|
||||
|
||||
color={statebucket.color}
|
||||
|
||||
// alphaSliderHidden={false}
|
||||
// showPreview={true}
|
||||
onChange={(ev: any, colorObj: IColor) => {
|
||||
const bucket = clone(this.state.bucket);
|
||||
bucket.color = colorObj.str;
|
||||
this.setState({ bucket: bucket });
|
||||
}
|
||||
}
|
||||
// The ColorPicker provides default English strings for visible text.
|
||||
// If your app is localized, you MUST provide the `strings` prop with localized strings.
|
||||
/*
|
||||
FluentUI
|
||||
strings={{
|
||||
// By default, the sliders will use the text field labels as their aria labels.
|
||||
// If you'd like to provide more detailed instructions, you can use these props.
|
||||
alphaAriaLabel: 'Alpha slider: Use left and right arrow keys to change value, hold shift for a larger jump',
|
||||
transparencyAriaLabel:
|
||||
'Transparency slider: Use left and right arrow keys to change value, hold shift for a larger jump',
|
||||
hueAriaLabel: 'Hue slider: Use left and right arrow keys to change value, hold shift for a larger jump',
|
||||
}}
|
||||
*/
|
||||
/>
|
||||
)}
|
||||
<Stack>
|
||||
|
||||
<PrimaryButton text={strings.BucketConfigSave} onClick={this.submitData.bind(this)} />
|
||||
{/* <!-- TODO Confirmation --!> */}
|
||||
<DefaultButton text={strings.BucketConfigReset} onClick={this.resetState.bind(this)} />
|
||||
</Stack>
|
||||
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
private resetState():void {
|
||||
const newbucket: IKanbanBucket = clone(this.props.bucket);
|
||||
this.setState({
|
||||
bucket: newbucket,
|
||||
// showHeadline: newbucket.bucketheadline && newbucket.bucketheadline.length > 0,
|
||||
useColor: newbucket.color && newbucket.color.length > 0
|
||||
});
|
||||
}
|
||||
private submitData():void {
|
||||
debugger;
|
||||
const newbucket: IKanbanBucket = clone(this.state.bucket);
|
||||
if (!this.state.useColor) {
|
||||
newbucket.color = undefined;
|
||||
}
|
||||
/*
|
||||
if (!this.state.showHeadline) {
|
||||
newbucket.color = undefined;
|
||||
}
|
||||
*/
|
||||
if (this.props.update) {
|
||||
this.props.update(this.props.index, newbucket);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -16,7 +16,7 @@ import { IStackStyles, Stack } from 'office-ui-fabric-react/lib/Stack';
|
|||
import { clone } from '@microsoft/sp-lodash-subset';
|
||||
|
||||
import { CommandBar } from 'office-ui-fabric-react/lib/CommandBar';
|
||||
import { stringIsNullOrEmpty } from '@pnp/common';
|
||||
|
||||
import { TooltipHost } from 'office-ui-fabric-react';
|
||||
|
||||
export interface IKanbanComponentProps {
|
||||
|
@ -86,7 +86,7 @@ export default class KanbanComponent extends React.Component<IKanbanComponentPro
|
|||
{
|
||||
|
||||
buckets.map((b) => {
|
||||
const merge = { ...b, ...this.state }
|
||||
const merge = { ...b, ...this.state };
|
||||
return (<KanbanBucket
|
||||
key={b.bucket}
|
||||
{...merge}
|
||||
|
@ -275,7 +275,7 @@ export default class KanbanComponent extends React.Component<IKanbanComponentPro
|
|||
private internalAddTask(targetbucket?: string) {
|
||||
let bucket: IKanbanBucket = undefined;
|
||||
if (bucket) {
|
||||
const buckets = this.props.buckets.filter((p) => p.bucket === targetbucket)
|
||||
const buckets = this.props.buckets.filter((p) => p.bucket === targetbucket);
|
||||
if (buckets.length === 1) {
|
||||
bucket = clone(buckets[0]);
|
||||
} else {
|
||||
|
@ -414,5 +414,5 @@ export default class KanbanComponent extends React.Component<IKanbanComponentPro
|
|||
onClick: () => console.log('Info')
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import * as React from 'react';
|
||||
import KanbanComponent from './KanbanComponent';
|
||||
import KanbanBucketConfigurator from './KanbanBucketConfigurator';
|
||||
import { IKanbanBucket } from './IKanbanBucket';
|
||||
import { IKanbanTask, KanbanTaskMamagedPropertyType } from './IKanbanTask';
|
||||
import { findIndex } from "lodash";
|
||||
import { cloneDeep, clone } from '@microsoft/sp-lodash-subset';
|
||||
|
||||
export interface IMockKanbanProps { }
|
||||
|
||||
|
@ -35,7 +37,7 @@ export class MockKanban extends React.Component<IMockKanbanProps, IMockKanbanSta
|
|||
value: '<p>test<b>Bold</b></p>'
|
||||
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
name: 'Prop2',
|
||||
displayName: 'Prop2 Display',
|
||||
|
@ -69,7 +71,6 @@ export class MockKanban extends React.Component<IMockKanbanProps, IMockKanbanSta
|
|||
buckets={buckets}
|
||||
tasks={tasks}
|
||||
tasksettings={{
|
||||
showLabels: true,
|
||||
showPriority: true,
|
||||
showAssignedTo: true,
|
||||
showTaskDetailsButton: true
|
||||
|
@ -82,23 +83,43 @@ export class MockKanban extends React.Component<IMockKanbanProps, IMockKanbanSta
|
|||
}}
|
||||
showCommandbar={true}
|
||||
/>
|
||||
<div>
|
||||
<h2>
|
||||
Bucket Configuration sample
|
||||
</h2>
|
||||
{
|
||||
this.state.buckets.map((b, i) =>
|
||||
<KanbanBucketConfigurator
|
||||
key={'BucketConfig' + i}
|
||||
index={i}
|
||||
bucket={b}
|
||||
update={this.updateBucket.bind(this)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private updateBucket(index: number, value: IKanbanBucket) {
|
||||
debugger;
|
||||
const cstate = cloneDeep(this.state);
|
||||
cstate.buckets[index] = clone(value);
|
||||
this.setState(cstate);
|
||||
}
|
||||
|
||||
|
||||
private _toggleCompleted(taskId: string): void {
|
||||
private _toggleCompleted(taskId: string): void {
|
||||
//TODO
|
||||
}
|
||||
private _allowMove(taskId: string, prevBucket: IKanbanBucket, targetBucket: IKanbanBucket): boolean {
|
||||
private _allowMove(taskId: string, prevBucket: IKanbanBucket, targetBucket: IKanbanBucket): boolean {
|
||||
if (prevBucket.bucket === 'Test2' && targetBucket.bucket === 'Test3') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private _moved(taskId: string, targetBucket: IKanbanBucket): void {
|
||||
private _moved(taskId: string, targetBucket: IKanbanBucket): void {
|
||||
const elementsIndex = findIndex(this.state.tasks, element => element.taskId == taskId);
|
||||
let newArray = [...this.state.tasks];
|
||||
newArray[elementsIndex].bucket = targetBucket.bucket;
|
||||
|
|
|
@ -13,6 +13,15 @@ define([], function () {
|
|||
"EditTaskDlgHeadline": "Edit Task",
|
||||
"AssignedTo": "Assigned to",
|
||||
"HtmlDescription": "Description",
|
||||
"Priority": "Priority"
|
||||
"Priority": "Priority",
|
||||
|
||||
"BucketConfigInternalName": "Internal Name",
|
||||
"BucketConfigHeadline": "Headline",
|
||||
"BucketConfigPercentageComplete": "Bucket State Percentage Complete",
|
||||
"BucketConfigAllowAddTask": "Add Task?",
|
||||
"BucketConfigUseColor": "Use Color?",
|
||||
"BucketConfigSave": "Save",
|
||||
"BucketConfigReset": "Reset",
|
||||
"Percent":"percent"
|
||||
}
|
||||
});
|
||||
|
|
|
@ -13,7 +13,16 @@ declare interface IKanbanBoardStrings {
|
|||
|
||||
AssignedTo: string;
|
||||
HtmlDescription: string;
|
||||
Priority:string;
|
||||
Priority: string;
|
||||
|
||||
BucketConfigInternalName: string;
|
||||
BucketConfigHeadline: string;
|
||||
BucketConfigPercentageComplete: string;
|
||||
BucketConfigAllowAddTask: string;
|
||||
BucketConfigUseColor: string;
|
||||
BucketConfigSave: string;
|
||||
BucketConfigReset: string;
|
||||
Percent: string;
|
||||
}
|
||||
|
||||
declare module 'KanbanBoardStrings' {
|
||||
|
|
Loading…
Reference in New Issue