Bucket configurator
This commit is contained in:
parent
881f37f254
commit
29641985f4
|
@ -55,7 +55,7 @@ export default class KanbanBucket extends React.Component<IKanbanBucketProps, IK
|
||||||
const { bucket, bucketheadline, color, buckettasks,
|
const { bucket, bucketheadline, color, buckettasks,
|
||||||
tasksettings, percentageComplete,
|
tasksettings, percentageComplete,
|
||||||
allowAddTask, overBucket, leavingTaskId, leavingBucket } = this.props;
|
allowAddTask, overBucket, leavingTaskId, leavingBucket } = this.props;
|
||||||
|
debugger;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames({ [styles.bucket]: true, [styles.dragover]: !!(overBucket && overBucket === bucket) })}
|
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 { clone } from '@microsoft/sp-lodash-subset';
|
||||||
|
|
||||||
import { CommandBar } from 'office-ui-fabric-react/lib/CommandBar';
|
import { CommandBar } from 'office-ui-fabric-react/lib/CommandBar';
|
||||||
import { stringIsNullOrEmpty } from '@pnp/common';
|
|
||||||
import { TooltipHost } from 'office-ui-fabric-react';
|
import { TooltipHost } from 'office-ui-fabric-react';
|
||||||
|
|
||||||
export interface IKanbanComponentProps {
|
export interface IKanbanComponentProps {
|
||||||
|
@ -86,7 +86,7 @@ export default class KanbanComponent extends React.Component<IKanbanComponentPro
|
||||||
{
|
{
|
||||||
|
|
||||||
buckets.map((b) => {
|
buckets.map((b) => {
|
||||||
const merge = { ...b, ...this.state }
|
const merge = { ...b, ...this.state };
|
||||||
return (<KanbanBucket
|
return (<KanbanBucket
|
||||||
key={b.bucket}
|
key={b.bucket}
|
||||||
{...merge}
|
{...merge}
|
||||||
|
@ -275,7 +275,7 @@ export default class KanbanComponent extends React.Component<IKanbanComponentPro
|
||||||
private internalAddTask(targetbucket?: string) {
|
private internalAddTask(targetbucket?: string) {
|
||||||
let bucket: IKanbanBucket = undefined;
|
let bucket: IKanbanBucket = undefined;
|
||||||
if (bucket) {
|
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) {
|
if (buckets.length === 1) {
|
||||||
bucket = clone(buckets[0]);
|
bucket = clone(buckets[0]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -414,5 +414,5 @@ export default class KanbanComponent extends React.Component<IKanbanComponentPro
|
||||||
onClick: () => console.log('Info')
|
onClick: () => console.log('Info')
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import KanbanComponent from './KanbanComponent';
|
import KanbanComponent from './KanbanComponent';
|
||||||
|
import KanbanBucketConfigurator from './KanbanBucketConfigurator';
|
||||||
import { IKanbanBucket } from './IKanbanBucket';
|
import { IKanbanBucket } from './IKanbanBucket';
|
||||||
import { IKanbanTask, KanbanTaskMamagedPropertyType } from './IKanbanTask';
|
import { IKanbanTask, KanbanTaskMamagedPropertyType } from './IKanbanTask';
|
||||||
import { findIndex } from "lodash";
|
import { findIndex } from "lodash";
|
||||||
|
import { cloneDeep, clone } from '@microsoft/sp-lodash-subset';
|
||||||
|
|
||||||
export interface IMockKanbanProps { }
|
export interface IMockKanbanProps { }
|
||||||
|
|
||||||
|
@ -69,7 +71,6 @@ export class MockKanban extends React.Component<IMockKanbanProps, IMockKanbanSta
|
||||||
buckets={buckets}
|
buckets={buckets}
|
||||||
tasks={tasks}
|
tasks={tasks}
|
||||||
tasksettings={{
|
tasksettings={{
|
||||||
showLabels: true,
|
|
||||||
showPriority: true,
|
showPriority: true,
|
||||||
showAssignedTo: true,
|
showAssignedTo: true,
|
||||||
showTaskDetailsButton: true
|
showTaskDetailsButton: true
|
||||||
|
@ -82,11 +83,31 @@ export class MockKanban extends React.Component<IMockKanbanProps, IMockKanbanSta
|
||||||
}}
|
}}
|
||||||
showCommandbar={true}
|
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>
|
</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
|
//TODO
|
||||||
|
|
|
@ -13,6 +13,15 @@ define([], function () {
|
||||||
"EditTaskDlgHeadline": "Edit Task",
|
"EditTaskDlgHeadline": "Edit Task",
|
||||||
"AssignedTo": "Assigned to",
|
"AssignedTo": "Assigned to",
|
||||||
"HtmlDescription": "Description",
|
"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;
|
AssignedTo: string;
|
||||||
HtmlDescription: 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' {
|
declare module 'KanbanBoardStrings' {
|
||||||
|
|
Loading…
Reference in New Issue