diff --git a/samples/react-taxonomy-file-explorer/README.md b/samples/react-taxonomy-file-explorer/README.md index 2bd866a44..ddad61e93 100644 --- a/samples/react-taxonomy-file-explorer/README.md +++ b/samples/react-taxonomy-file-explorer/README.md @@ -62,7 +62,7 @@ react-taxonomy-file-explorer| [Markus Moeller](https://github.com/mmsharepoint) Version|Date|Comments -------|----|-------- 1.0|December 26, 2021|Initial release -1.1|July 16, 2021|Added expand/collapse all, upgraded to SPFx 1.15.0, upgraded to PnPJS V3.5.1 +1.1|July 16, 2022|Added expand/collapse all, upgraded to SPFx 1.15.0, upgraded to PnPJS V3.5.1 ## Minimal Path to Awesome diff --git a/samples/react-taxonomy-file-explorer/assets/sample.json b/samples/react-taxonomy-file-explorer/assets/sample.json index 691806e3c..9be312cac 100644 --- a/samples/react-taxonomy-file-explorer/assets/sample.json +++ b/samples/react-taxonomy-file-explorer/assets/sample.json @@ -9,7 +9,7 @@ "This solution renders a given Termset as a Tree and incorporates files similar than a folder structure in file explorer." ], "creationDateTime": "2021-12-26", - "updateDateTime": "2021-12-26", + "updateDateTime": "2022-07-16", "products": [ "SharePoint" ], @@ -20,7 +20,7 @@ }, { "key": "SPFX-VERSION", - "value": "1.13.0" + "value": "1.15.0" } ], "thumbnails": [ diff --git a/samples/react-taxonomy-file-explorer/config/eslint.json b/samples/react-taxonomy-file-explorer/config/eslint.json new file mode 100644 index 000000000..a3fd3859e --- /dev/null +++ b/samples/react-taxonomy-file-explorer/config/eslint.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json.schemastore.org/eslintrc.json", + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2020, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ] +} \ No newline at end of file diff --git a/samples/react-taxonomy-file-explorer/gulpfile.js b/samples/react-taxonomy-file-explorer/gulpfile.js index be2918708..47b5f6ea2 100644 --- a/samples/react-taxonomy-file-explorer/gulpfile.js +++ b/samples/react-taxonomy-file-explorer/gulpfile.js @@ -13,4 +13,17 @@ build.rig.getTasks = function () { return result; }; +// disable tslint +build.tslintCmd.enabled = false; + +// add eslint +const eslint = require('gulp-eslint'); +const eslintSubTask = build.subTask('eslint-subTask', function (gulp, buildOptions, done) { + return gulp.src(['src/**/*.{ts,tsx}']) + .pipe(eslint('./config/eslint.json')) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()); +}); +build.rig.addPreBuildTask(build.task('eslint', eslintSubTask)); + build.initialize(require('gulp')); diff --git a/samples/react-taxonomy-file-explorer/package.json b/samples/react-taxonomy-file-explorer/package.json index 8046b66a5..f633df060 100644 --- a/samples/react-taxonomy-file-explorer/package.json +++ b/samples/react-taxonomy-file-explorer/package.json @@ -32,9 +32,13 @@ "@types/react": "16.9.51", "@types/react-dom": "16.9.8", "@types/webpack-env": "1.15.2", + "@typescript-eslint/eslint-plugin": "5.31.0", + "@typescript-eslint/parser": "5.31.0", "ajv": "6.12.5", - "eslint": "8.7.0", + "eslint": "8.20.0", + "eslint-plugin-react": "7.30.1", "eslint-plugin-react-hooks": "4.3.0", - "gulp": "~4.0.2" + "gulp": "~4.0.2", + "gulp-eslint": "6.0.0" } } diff --git a/samples/react-taxonomy-file-explorer/src/services/SPService.ts b/samples/react-taxonomy-file-explorer/src/services/SPService.ts index 1e4a6ebca..f67b14e7c 100644 --- a/samples/react-taxonomy-file-explorer/src/services/SPService.ts +++ b/samples/react-taxonomy-file-explorer/src/services/SPService.ts @@ -26,6 +26,7 @@ export class SPService { } public async getItems (termsetID: string): Promise { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const items: any[] = await this._sp.web.lists.getByTitle(this._listName).items.select('Id', this._fieldName).expand('File').getAll(); const files: IFileItem[] = []; items.forEach(i => { @@ -85,6 +86,7 @@ export class SPService { public async newTaxonomyItemByCopy (file: IFileItem, fieldName: string, newTaxonomyValue: string): Promise { const fileUrl: URL = new URL(file.url); const currentFileNamePart: string = file.title.replace(`.${file.extension}`, ''); + // eslint-disable-next-line @typescript-eslint/no-inferrable-types const newFilename: string = `${currentFileNamePart}_Copy.${file.extension}`; const destinationUrl: string = decodeURI(fileUrl.pathname).replace(file.title, newFilename); await this._sp.web.getFileByServerRelativePath(decodeURI(fileUrl.pathname)).copyByPath(destinationUrl, false, true); @@ -109,6 +111,7 @@ export class SPService { return newFile; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any public async newTaxonomyItemByUpload (file: any, fieldName: string, newTaxonomyValue: string): Promise { const libraryRoot = await this._sp.web.lists.getByTitle(this._listName).rootFolder(); // Assuming small file size, otherwise use chunks diff --git a/samples/react-taxonomy-file-explorer/src/services/TaxonomyService.ts b/samples/react-taxonomy-file-explorer/src/services/TaxonomyService.ts index 4d8d08480..7b02a663b 100644 --- a/samples/react-taxonomy-file-explorer/src/services/TaxonomyService.ts +++ b/samples/react-taxonomy-file-explorer/src/services/TaxonomyService.ts @@ -22,6 +22,7 @@ export class TaxonomyService { const parser = new DOMParser(); const xmlField = parser.parseFromString(mmFieldInfo.SchemaXml, "text/xml"); const properties = xmlField.getElementsByTagName("ArrayOfProperty")[0].childNodes; + // eslint-disable-next-line @typescript-eslint/no-inferrable-types let termsetID: string = ""; properties.forEach(prop => { if (prop.childNodes[0].textContent === "TermSetId") { diff --git a/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/ITermLabelProps.ts b/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/ITermLabelProps.ts index a18753564..c9dcce7cb 100644 --- a/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/ITermLabelProps.ts +++ b/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/ITermLabelProps.ts @@ -11,5 +11,6 @@ export interface ITermLabelProps { addTerm: (file: IFileItem, newValue: string) => void; replaceTerm: (file: IFileItem, newValue: string) => void; copyFile: (file: IFileItem, newValue: string) => void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any uploadFile: (file: any, newValue: string) => void; } \ No newline at end of file diff --git a/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/TaxonomyFileExplorer.tsx b/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/TaxonomyFileExplorer.tsx index 4c2cf7ab3..b36090b78 100644 --- a/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/TaxonomyFileExplorer.tsx +++ b/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/TaxonomyFileExplorer.tsx @@ -18,6 +18,7 @@ export const TaxonomyFileExplorer: React.FC = (props const [collapseAll, setCollapseAll] = React.useState(false); const [expandAll, setExpandAll] = React.useState(false); + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type const buildTree = async () => { const taxSvc: TaxonomyService = new TaxonomyService(props.serviceScope); const termsetID: string = await taxSvc.getTermsetInfo(props.fieldName); @@ -34,9 +35,11 @@ export const TaxonomyFileExplorer: React.FC = (props const spSrvc: SPService = new SPService(props.serviceScope, props.listName, props.fieldName); const files: IFileItem[] = await spSrvc.getItems(termsetID); setSpSvc(spSrvc); + // eslint-disable-next-line @typescript-eslint/no-use-before-define updateFiles(files, termnodetree); }; + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type const updateFiles = (files: IFileItem[], termnodetree: ITermNode[]) => { const taxSvc: TaxonomyService = new TaxonomyService(props.serviceScope); termnodetree = taxSvc.incorporateFiles(termnodetree, files); @@ -52,6 +55,7 @@ export const TaxonomyFileExplorer: React.FC = (props setSelectedTermnode(newNodeID); },[setSelectedTermnode]); + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type const reloadFiles = (file: IFileItem) => { const newFiles: IFileItem[] = []; fileItems.forEach(fi => { @@ -65,17 +69,20 @@ export const TaxonomyFileExplorer: React.FC = (props updateFiles(newFiles, terms); }; + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type const loadNewFiles = (file: IFileItem) => { const newFiles: IFileItem[] = [file].concat(fileItems); updateFiles(newFiles, terms); }; const addTerm = React.useCallback((file: IFileItem, newTaxonomyValue: string) => { + // eslint-disable-next-line @typescript-eslint/no-floating-promises spSvc.updateTaxonomyItemByAdd(file, props.fieldName, newTaxonomyValue); reloadFiles(file); },[spSvc, fileItems, terms]); // eslint-disable-line react-hooks/exhaustive-deps const replaceTerm = React.useCallback((file: IFileItem, newTaxonomyValue: string) => { + // eslint-disable-next-line @typescript-eslint/no-floating-promises spSvc.updateTaxonomyItemByReplace(file, props.fieldName, newTaxonomyValue); reloadFiles(file); },[spSvc, fileItems, terms]); // eslint-disable-line react-hooks/exhaustive-deps @@ -85,6 +92,7 @@ export const TaxonomyFileExplorer: React.FC = (props loadNewFiles(newFile); },[spSvc, fileItems, terms]); // eslint-disable-line react-hooks/exhaustive-deps + // eslint-disable-next-line @typescript-eslint/no-explicit-any const uploadFile = React.useCallback(async (file: any, newTaxonomyValue: string) => { const newFile = await spSvc.newTaxonomyItemByUpload(file, props.fieldName, newTaxonomyValue) loadNewFiles(newFile); diff --git a/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/TermLabel.tsx b/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/TermLabel.tsx index 290a68330..e73dd2eda 100644 --- a/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/TermLabel.tsx +++ b/samples/react-taxonomy-file-explorer/src/webparts/taxonomyFileExplorer/components/TermLabel.tsx @@ -26,12 +26,15 @@ export const TermLabel: React.FC = (props) => { setShowContextualMenu(false); },[setShowContextualMenu]); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const uploadWithNewTerm = React.useCallback((file: any) => { + // eslint-disable-next-line @typescript-eslint/no-inferrable-types const newTaxonomyValue: string = `${props.node.name}|${props.node.guid}`; props.uploadFile(file, newTaxonomyValue); },[]); // eslint-disable-line react-hooks/exhaustive-deps const addNewTerm = React.useCallback((file: IFileItem) => { + // eslint-disable-next-line @typescript-eslint/no-inferrable-types const newTaxonomyValue: string = `${props.node.name}|${props.node.guid}`; file.termGuid.push(props.node.guid); file.taxValue.push(newTaxonomyValue); @@ -73,7 +76,9 @@ export const TermLabel: React.FC = (props) => { setDragEntered(false); },[setDragEntered]); + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type const replaceByNewTerm = (file: IFileItem) => { + // eslint-disable-next-line @typescript-eslint/no-inferrable-types const newTaxonomyValue: string = `${props.node.name}|${props.node.guid}`; file.termGuid = [props.node.guid]; file.taxValue = [newTaxonomyValue]; @@ -81,7 +86,9 @@ export const TermLabel: React.FC = (props) => { props.addTerm(file, newTaxonomyValue); }; + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type const copyWithNewTerm = (file: IFileItem) => { + // eslint-disable-next-line @typescript-eslint/no-inferrable-types const newTaxonomyValue: string = `${props.node.name}|${props.node.guid}`; props.copyFile(file, newTaxonomyValue); }; diff --git a/samples/react-taxonomy-file-explorer/tslint.json b/samples/react-taxonomy-file-explorer/tslint.json deleted file mode 100644 index 6c3c92f28..000000000 --- a/samples/react-taxonomy-file-explorer/tslint.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json", - "rules": { - "class-name": false, - "export-name": false, - "forin": false, - "label-position": false, - "member-access": true, - "no-arg": false, - "no-console": false, - "no-construct": false, - "no-duplicate-variable": true, - "no-eval": false, - "no-function-expression": true, - "no-internal-module": true, - "no-shadowed-variable": true, - "no-switch-case-fall-through": true, - "no-unnecessary-semicolons": true, - "no-unused-expression": true, - "no-with-statement": true, - "semicolon": true, - "trailing-comma": false, - "typedef": false, - "typedef-whitespace": false, - "use-named-parameter": true, - "variable-name": false, - "whitespace": false - } -} \ No newline at end of file