Merge Refresh Rangers PR - react-kanban-board Upgrade to 1.20 (#5272)

* Upgrade to 1.20
version
Readme
sample.json
eslint bundle

* new gif updated nvmrc
This commit is contained in:
Peter Paul Kirschner 2024-10-07 00:32:55 +02:00 committed by GitHub
parent 5df1e8b4fc
commit ecb7feb45b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 7169 additions and 6980 deletions

View File

@ -20,39 +20,6 @@ module.exports = {
'@rushstack/security/no-unsafe-regexp': 1,
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
'@typescript-eslint/adjacent-overload-signatures': 1,
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
//
// CONFIGURATION: By default, these are banned: String, Boolean, Number, Object, Symbol
'@typescript-eslint/ban-types': [
1,
{
'extendDefaults': false,
'types': {
'String': {
'message': 'Use \'string\' instead',
'fixWith': 'string'
},
'Boolean': {
'message': 'Use \'boolean\' instead',
'fixWith': 'boolean'
},
'Number': {
'message': 'Use \'number\' instead',
'fixWith': 'number'
},
'Object': {
'message': 'Use \'object\' instead, or else define a proper TypeScript type:'
},
'Symbol': {
'message': 'Use \'symbol\' instead',
'fixWith': 'symbol'
},
'Function': {
'message': 'The \'Function\' type accepts any function-like value.\nIt provides no type safety when calling the function, which can be a common source of bugs.\nIt also accepts things like class declarations, which will throw at runtime as they will not be called with \'new\'.\nIf you are expecting the function to accept certain arguments, you should explicitly define the function shape.'
}
}
}
],
// RATIONALE: Code is more readable when the type of every variable is immediately obvious.
// Even if the compiler may be able to infer a type, this inference will be unavailable
// to a person who is reviewing a GitHub diff. This rule makes writing code harder,
@ -79,7 +46,7 @@ module.exports = {
// This rule should be suppressed only in very special cases such as JSON.stringify()
// where the type really can be anything. Even if the type is flexible, another type
// may be more appropriate such as "unknown", "{}", or "Record<k,V>".
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-explicit-any': 1,
// RATIONALE: The #1 rule of promises is that every promise chain must be terminated by a catch()
// handler. Thus wherever a Promise arises, the code must either append a catch handler,
// or else return the object to a caller (who assumes this responsibility). Unterminated

View File

@ -1 +1 @@
v18.17.1
v18.20.3

View File

@ -1,9 +1,9 @@
{
"@microsoft/generator-sharepoint": {
"nodeVersion": "18.17.1",
"nodeVersion": "18.20.3",
"isCreatingSolution": true,
"environment": "spo",
"version": "1.19.0",
"version": "1.20.0",
"libraryName": "react-kanban-board",
"libraryId": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
"packageManager": "npm",
@ -12,7 +12,7 @@
"plusBeta": false,
"componentType": "webpart",
"sdkVersions": {
"@microsoft/teams-js": "2.12.0",
"@microsoft/teams-js": "2.24.0",
"@microsoft/microsoft-graph-client": "3.0.2"
}
}

View File

@ -20,7 +20,7 @@ The web part uses the default columns of the SharePoint Tasks list for showing t
| Every SPFx version is only compatible with specific version(s) of Node.js. In order to be able to build this sample, please ensure that the version of Node on your workstation matches one of the versions listed in this section. This sample will not work on a different version of Node.|
|Refer to <https://aka.ms/spfx-matrix> for more information on SPFx compatibility. |
![SPFx 1.19.0](https://img.shields.io/badge/SPFx-1.19.0-green.svg)
![SPFx 1.20.0](https://img.shields.io/badge/SPFx-1.20.0-green.svg)
![Node.js v18 ](https://img.shields.io/badge/Node.js-v18-green.svg)
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
@ -64,6 +64,8 @@ Version|Date|Comments
2.0.0.0|July 10, 2020| jqwidgets replaced with a custom Kanban Board based on Office UI Component and IE11 Support
3.0.0.0|October 29, 2021| SPFx 1.13, PnPJS v2, PnP Controls v3
4.0.0.0|Jun 1, 2024| SPFx 1.19, PnPJS v4, Node 18 (Property-ListPicker and Property-Order not used from @pnp/spfx-property-controls because of an issue )
5.0.0.0|Okt 1, 2024| SPFx 1.20, PnPJS v4, Node 18
[Read More about the implementation of this Board](./src/kanban/README.md)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 320 KiB

View File

@ -3,13 +3,13 @@
"name": "pnp-sp-dev-spfx-web-parts-react-kanban-board",
"source": "pnp",
"title": "Kanban Board Web part",
"shortDescription": "This solution contains an SPFx web part which shows a Kanban board using jqxKanban ReactJS component (from JQWidgets). The web part uses the default columns of the SharePoint Tasks list for showing the board\u0027s columns and the tasks.",
"shortDescription": "This solution contains an SPFx web part which shows a Kanban board using Fluent UI. The web part uses the default columns of the SharePoint Tasks list for showing the board\u0027s columns and the tasks.",
"url": "https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-kanban-board",
"longDescription": [
"This solution contains an SPFx web part which shows a Kanban board. The web part uses the default columns of the SharePoint Tasks list for showing the board\u0027s columns and the tasks."
],
"creationDateTime": "2020-07-02",
"updateDateTime": "2024-05-26",
"updateDateTime": "2024-10-01",
"products": [
"SharePoint"
],
@ -20,7 +20,7 @@
},
{
"key": "SPFX-VERSION",
"value": "1.19.0"
"value": "1.20.0"
},
{
"key": "SPFX-TEAMSTAB",

View File

@ -3,7 +3,7 @@
"solution": {
"name": "react-kanban-board-client-side-solution",
"id": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
"version": "4.0.0.0",
"version": "5.0.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true,
"isDomainIsolated": false,
@ -30,7 +30,7 @@
"title": "react-kanban-board KanbanBoardWebPart Feature",
"description": "The feature that activates KanbanBoardWebPart from the react-kanban-board solution.",
"id": "67cd5938-806b-4c79-b589-501f7f26998e",
"version": "4.0.0.0"
"version": "5.0.0.0"
}
]

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
{
"name": "react-kanban-board",
"main": "lib/index.js",
"version": "4.0.0",
"version": "5.0.0",
"private": true,
"engines": {
"node": ">=18.17.1 <19.0.0"
@ -13,12 +13,12 @@
},
"dependencies": {
"@fluentui/react": "8.106.4",
"@microsoft/sp-adaptive-card-extension-base": "1.19.0",
"@microsoft/sp-core-library": "1.19.0",
"@microsoft/sp-lodash-subset": "1.19.0",
"@microsoft/sp-office-ui-fabric-core": "1.19.0",
"@microsoft/sp-property-pane": "1.19.0",
"@microsoft/sp-webpart-base": "1.19.0",
"@microsoft/sp-adaptive-card-extension-base": "1.20.0",
"@microsoft/sp-core-library": "1.20.0",
"@microsoft/sp-lodash-subset": "1.20.0",
"@microsoft/sp-office-ui-fabric-core": "1.20.0",
"@microsoft/sp-property-pane": "1.20.0",
"@microsoft/sp-webpart-base": "1.20.0",
"@pnp/sp": "^4.1.0",
"@pnp/spfx-controls-react": "^3.18",
"@pnp/spfx-property-controls": "^3.17",
@ -28,17 +28,18 @@
"tslib": "2.3.1"
},
"devDependencies": {
"@microsoft/eslint-config-spfx": "1.20.1",
"@microsoft/eslint-plugin-spfx": "1.20.1",
"@microsoft/eslint-config-spfx": "1.20.2",
"@microsoft/eslint-plugin-spfx": "1.20.2",
"@microsoft/rush-stack-compiler-4.7": "0.1.0",
"@microsoft/sp-build-web": "1.20.1",
"@microsoft/sp-module-interfaces": "1.20.1",
"@rushstack/eslint-config": "2.5.1",
"@microsoft/sp-build-web": "1.20.2",
"@microsoft/sp-module-interfaces": "1.20.2",
"@rushstack/eslint-config": "4.0.1",
"@types/react": "17.0.45",
"@types/react-dom": "17.0.17",
"@types/webpack-env": "1.15.2",
"@typescript-eslint/eslint-plugin": "^8.8.0",
"ajv": "6.12.5",
"eslint": "8.7.0",
"eslint": "8.57.0",
"eslint-plugin-react-hooks": "4.3.0",
"gulp": "4.0.2",
"typescript": "4.7.4"

View File

@ -16,6 +16,7 @@ export interface IKanbanTaskManagedProps {
name: string;
displayName?: string;
type: KanbanTaskMamagedPropertyType;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: string | number | IPersonaProps | IPersonaProps[] | any;
renderer?: (name: string, value: object, type: KanbanTaskMamagedPropertyType) => JSX.Element;
}

View File

@ -17,9 +17,9 @@ export interface IKanbanBucketProps extends IKanbanBucket {
toggleCompleted?: (taskId: string) => void;
addTask?: (bucket: string) => void;
onDragStart: (event: any, taskId: string, bucket: string) => void;
onDragStart: (event: React.DragEvent<HTMLDivElement>, taskId: string, bucket: string) => void;
onDragEnd: (event: any, taskId: string, bucket: string) => void;
onDragEnd: (event: React.DragEvent<HTMLDivElement>, taskId: string, bucket: string) => void;

View File

@ -88,7 +88,7 @@ export class KanbanBucketConfigurator extends React.Component<IKanbanBucketConfi
onChange={(ev, checked) => { this.setState({ useColor: checked?checked:false }); }} />
{this.state.useColor && (<ColorPicker
color={statebucket.color?statebucket.color:'white'}
onChange={(ev: any, colorObj: IColor) => {
onChange={(ev, colorObj: IColor) => {
if (this.state.bucket) {
const bucket = clone(this.state.bucket);
bucket.color = colorObj.str;

View File

@ -49,7 +49,7 @@ export enum DialogState {
export class KanbanComponent extends React.Component<IKanbanComponentProps, IKanbanComponentState> {
private dragelement?: IKanbanTask;
private bucketsref: any[];
private bucketsref: (HTMLDivElement|null)[];
constructor(props: IKanbanComponentProps) {
super(props);
@ -302,17 +302,15 @@ export class KanbanComponent extends React.Component<IKanbanComponentProps, IKan
}
}
private onDragLeave(event: any, bucket: string): void {
private onDragLeave(event: React.DragEvent<HTMLDivElement>, bucket: string): void {
const index = findIndex(this.props.buckets, element => element.bucket === bucket);
if (index !== -1 && this.bucketsref.length > index) {
//&& this.bucketsref[index].classList.contains(styles.dragover)) {
this.bucketsref[index].classList.remove(styles.dragover);
if (index !== -1 && this.bucketsref.length > index && this.bucketsref[index] !== null) {
this.bucketsref[index]?.classList.remove(styles.dragover);
}
}
private onDragEnd(event: any): void {
private onDragEnd(event:React.DragEvent<HTMLDivElement>): void {
this.dragelement = undefined;
this.setState({
@ -322,7 +320,7 @@ export class KanbanComponent extends React.Component<IKanbanComponentProps, IKan
});
}
private onDragStart(event: any, taskId: string, bucket: string): void {
private onDragStart(event: React.DragEvent<HTMLDivElement>, taskId: string, bucket: string): void {
console.log('onDragStart');
const taskitem = this.props.tasks.filter(p => p.taskId === taskId);
if (taskitem.length === 1) {
@ -344,23 +342,22 @@ export class KanbanComponent extends React.Component<IKanbanComponentProps, IKan
}
private onDragOver(event: any, targetbucket: string): void {
private onDragOver(event: React.DragEvent<HTMLDivElement>, targetbucket: string): void {
event.preventDefault();
console.log('onDragOver');
if (this.dragelement && this.dragelement?.bucket !== targetbucket) {
const index = findIndex(this.props.buckets, element => element.bucket === targetbucket);
if (index > -1 && this.bucketsref.length > index) {
//&& this.bucketsref[index].classList.contains(styles.dragover)) {
this.bucketsref[index].classList.add(styles.dragover);
if (index > -1 && this.bucketsref.length > index && this.bucketsref[index] !== null) {
this.bucketsref[index]?.classList.add(styles.dragover);
}
}
}
private onDrop(event: any, targetbucket: string): void {
private onDrop(event: React.DragEvent<HTMLDivElement>, targetbucket: string): void {
if (this.bucketsref && this.bucketsref.length > 0) {
this.bucketsref.forEach(x => { x.classList.remove(styles.dragover); });
this.bucketsref.forEach(x => { if(x!== null){ x.classList.remove(styles.dragover);} });
}
if (this.dragelement && this.dragelement?.bucket !== targetbucket) {
//event.dataTransfer.getData("text");

View File

@ -11,8 +11,8 @@ export interface IKanbanTaskProps extends IKanbanTask, IKanbanBoardTaskSettings
toggleCompleted?: (taskId: string) => void;
openDetails: (taskId: string) => void;
onDragStart: (event:any) => void;
onDragEnd: (event:any) => void;
onDragStart: (event:React.DragEvent<HTMLDivElement>) => void;
onDragEnd: (event:React.DragEvent<HTMLDivElement>) => void;
isMoving: boolean;
}

View File

@ -40,6 +40,7 @@ export default class KanbanTaskManagedProp extends React.Component<IKanbanTaskMa
//TODO maybe Formater
break;
case KanbanTaskMamagedPropertyType.percent:
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (value?<span>{`${(value as any) * 100}%`} </span>:<span/>);
//TODO maybe better Formater
break;