diff --git a/.version b/.version index b966e81a45..f0bb29e763 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.2.4 \ No newline at end of file +1.3.0 diff --git a/frontend/src/Editor/Components/Multiselect.jsx b/frontend/src/Editor/Components/Multiselect.jsx index e439b5c16e..74a466d9ad 100644 --- a/frontend/src/Editor/Components/Multiselect.jsx +++ b/frontend/src/Editor/Components/Multiselect.jsx @@ -51,7 +51,7 @@ export const Multiselect = function Multiselect({ setCurrentValue(properties.value); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [value]); + }, []); useEffect(() => { selectRef.current.querySelector('.select-search__input').style.borderRadius = `${Number.parseFloat( @@ -61,7 +61,7 @@ export const Multiselect = function Multiselect({ }, [borderRadius, selectRef.current]); const handleChange = (value) => { - setCurrentValue(value); + // setCurrentValue(value); setExposedVariable('values', value).then(() => fireEvent('onSelect')); }; diff --git a/plugins/jest.config.js b/plugins/jest.config.js index 8cbf8940cc..61bcc4a0d1 100644 --- a/plugins/jest.config.js +++ b/plugins/jest.config.js @@ -2,4 +2,5 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', + rootDir: '.', }; \ No newline at end of file diff --git a/plugins/package-lock.json b/plugins/package-lock.json index b0da9b41f4..fa2490660e 100644 --- a/plugins/package-lock.json +++ b/plugins/package-lock.json @@ -35,6 +35,7 @@ "@tooljet-plugins/typesense": "file:packages/typesense" }, "devDependencies": { + "@types/jest": "^27.4.1", "jest": "^27.4.5", "lerna": "^4.0.0", "rimraf": "^3.0.2", @@ -4575,6 +4576,16 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jest": { + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "dev": true, + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, "node_modules/@types/keyv": { "version": "3.1.3", "license": "MIT", @@ -19312,6 +19323,16 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "dev": true, + "requires": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, "@types/keyv": { "version": "3.1.3", "requires": { diff --git a/plugins/package.json b/plugins/package.json index a1be9c5ec6..ad6e090adf 100644 --- a/plugins/package.json +++ b/plugins/package.json @@ -12,7 +12,8 @@ "build": "npm run create:client && npm run create:server && npm run build:packages && npm run build:server", "prebuild:packages": "npm run clean:packages", "build:packages": "npx lerna run build --stream", - "clean:packages": "npx lerna run clean --parallel" + "clean:packages": "npx lerna run clean --parallel", + "test": "NODE_ENV=test jest" }, "dependencies": { "@tooljet-plugins/airtable": "file:packages/airtable", @@ -42,6 +43,7 @@ "@tooljet-plugins/typesense": "file:packages/typesense" }, "devDependencies": { + "@types/jest": "^27.4.1", "jest": "^27.4.5", "lerna": "^4.0.0", "rimraf": "^3.0.2", diff --git a/plugins/packages/googlesheets/__tests__/googlesheets.test.js b/plugins/packages/googlesheets/__tests__/googlesheets.test.js index 5ea0a5ca74..89de2a501a 100644 --- a/plugins/packages/googlesheets/__tests__/googlesheets.test.js +++ b/plugins/packages/googlesheets/__tests__/googlesheets.test.js @@ -1,7 +1,30 @@ 'use strict'; - -const googlesheets = require('../lib'); +const { makeRequestBodyToBatchUpdate } =require('../lib/operations'); describe('googlesheets', () => { - it.todo('needs tests'); + it('should generate the request body for update operation' ,() => { + const requestBody = { + caseOne: { Gender: 'Female' }, + caseTwo: { extra: '0 points' }, + caseThree: { Gender: 'Female', extra: '0 points' } + } + const filterCondition = { key: 'Student Name', value: 'Anna' } + const filterOperator = '===' + const data = [ + [ 'ID', '1', '2' ],[ 'Student Name', 'John', 'Anna' ],[ 'Major', 'Science', 'English' ],[],[ 'Gender', 'Male', 'Female' ],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[ 'extra', 'extra-update', '0 points' ] + ] + + const queryOptionsOne = { requestBody: requestBody.caseOne, filterCondition, filterOperator, data } + const queryOptionsTwo = { requestBody: requestBody.caseTwo, filterCondition, filterOperator, data } + const queryOptionsThree = { requestBody: requestBody.caseThree, filterCondition, filterOperator, data } + + const expectedBodyForCaseOne = makeRequestBodyToBatchUpdate(queryOptionsOne.requestBody, queryOptionsOne.filterCondition, queryOptionsOne.filterOperator, queryOptionsOne.data) + const expectedBodyForCaseTwo = makeRequestBodyToBatchUpdate(queryOptionsTwo.requestBody, queryOptionsOne.filterCondition, queryOptionsOne.filterOperator, queryOptionsOne.data) + const expectedBodyForCaseThree = makeRequestBodyToBatchUpdate(queryOptionsThree.requestBody, queryOptionsOne.filterCondition, queryOptionsOne.filterOperator, queryOptionsOne.data) + + + expect(expectedBodyForCaseOne).toEqual([{ cellValue: 'Female', cellIndex: 'E3' }]); + expect(expectedBodyForCaseTwo).toEqual([{ cellValue: '0 points', cellIndex: 'AB3' }]); + expect(expectedBodyForCaseThree).toEqual([{ cellValue: 'Female', cellIndex: 'E3' }, { cellValue: '0 points', cellIndex: 'AB3' }]); + }); }); diff --git a/plugins/packages/googlesheets/lib/index.ts b/plugins/packages/googlesheets/lib/index.ts index e7d4aabc9b..6c801ba4a7 100644 --- a/plugins/packages/googlesheets/lib/index.ts +++ b/plugins/packages/googlesheets/lib/index.ts @@ -132,6 +132,7 @@ export default class GooglesheetsQueryService implements QueryService { case "update": result = await batchUpdateToSheet( spreadsheetId, + spreadsheetRange, queryOptions.sheet, queryOptions.body, queryOptionFilter, diff --git a/plugins/packages/googlesheets/lib/operations.json b/plugins/packages/googlesheets/lib/operations.json index 9e5ca64c6a..ec54be57c6 100644 --- a/plugins/packages/googlesheets/lib/operations.json +++ b/plugins/packages/googlesheets/lib/operations.json @@ -166,6 +166,17 @@ "className": "codehinter-plugins", "placeholder": "Enter spreadsheet_id" }, + "spreadsheet_range": { + "label": "Range", + "key": "spreadsheet_range", + "type": "codehinter", + "lineNumbers": false, + "placeholder": "A1:Z500", + "description": "Enter range", + "width": "320px", + "height": "36px", + "className": "codehinter-plugins" + }, "sheet": { "label": "Sheet name", "key": "sheet", diff --git a/plugins/packages/googlesheets/lib/operations.ts b/plugins/packages/googlesheets/lib/operations.ts index bb3f2aa0c4..1ccff84d91 100644 --- a/plugins/packages/googlesheets/lib/operations.ts +++ b/plugins/packages/googlesheets/lib/operations.ts @@ -35,6 +35,7 @@ async function makeRequestToLookUpCellValues(spreadSheetId: string, range: strin export async function batchUpdateToSheet( spreadSheetId: string, + spreadsheetRange: string='A1:Z500', sheet: string='', requestBody: any, filterData: any, @@ -45,44 +46,21 @@ export async function batchUpdateToSheet( return new Error('filterOperator is required'); } - const lookUpData = await lookUpSheetData(spreadSheetId, sheet, authHeader); + const lookUpData = await lookUpSheetData(spreadSheetId,spreadsheetRange, sheet, authHeader); + const body = await makeRequestBodyToBatchUpdate(requestBody, filterData, filterOperator, lookUpData); - const updateBody = (requestBody, filterCondition, filterOperator, data) => { - const rowsIndexes = getRowsIndex(filterCondition, filterOperator, data) as any[]; - const colIndexes = getInputKeys(requestBody, data); - const updateCellIndexes = []; - colIndexes.map((col) => { - rowsIndexes.map((rowIndex) => - updateCellIndexes.push({ - ...col, - cellIndex: `${col.colIndex}${rowIndex}`, - }) - ); - }); + const _data = body.map((data) => { + return { + majorDimension: 'ROWS', + range: `${sheet}!${data.cellIndex}`, + values: [[data.cellValue]], + }; + }); - const body = []; - Object.entries(requestBody).map((item) => { - updateCellIndexes.map((cell) => { - if (item[0] === cell.col) { - body.push({ cellValue: item[1], cellIndex: cell.cellIndex }); - } - }); - }); - - const _data = body.map((data) => { - return { - majorDimension: 'ROWS', - range: `${sheet}!${data.cellIndex}`, - values: [[data.cellValue]], - }; - }); - - return _data; - }; const reqBody = { - data: updateBody(requestBody, filterData, filterOperator, lookUpData), + data: _data, valueInputOption: 'USER_ENTERED', includeValuesInResponse: true, }; @@ -183,8 +161,8 @@ export async function deleteData( return await deleteDataFromSheet(spreadSheetId, sheet, rowIndex, authHeader); } -async function lookUpSheetData(spreadSheetId: string, sheet:string, authHeader: any) { - const range = `${sheet}!A1:Z500`; +async function lookUpSheetData(spreadSheetId: string, spreadsheetRange:string, sheet:string, authHeader: any) { + const range = `${sheet}!${spreadsheetRange}`; const responseLookUpCellValues = await makeRequestToLookUpCellValues(spreadSheetId, range, authHeader); const data = await responseLookUpCellValues['values']; @@ -196,11 +174,16 @@ const getInputKeys = (inputBody, data) => { const keys = Object.keys(inputBody); const arr = []; keys.map((key) => - data.filter((val, index) => { + data.forEach((val, index) => { if (val[0] === key) { - const kIndex = `${String.fromCharCode(65 + index)}`; - arr.push({ col: val[0], colIndex: kIndex }); - } + let keyIndex = ''; + if(index >= 26) { + keyIndex = numberToLetters(index); + } else { + keyIndex = `${String.fromCharCode(65 + index)}`; + } + arr.push({ col: val[0], colIndex: keyIndex }); + } }) ); return arr; @@ -236,3 +219,38 @@ const getRowsIndex = (inputFilter, filterOperator, response) => { return rowIndex; }; + +function numberToLetters(num) { + let letters = '' + while (num >= 0) { + letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[num % 26] + letters + num = Math.floor(num / 26) - 1 + } + return letters +} + +export const makeRequestBodyToBatchUpdate = (requestBody, filterCondition, filterOperator, data) => { + const rowsIndexes = getRowsIndex(filterCondition, filterOperator, data) as any[]; + const colIndexes = getInputKeys(requestBody, data); + + const updateCellIndexes = []; + colIndexes.map((col) => { + rowsIndexes.map((rowIndex) => + updateCellIndexes.push({ + ...col, + cellIndex: `${col.colIndex}${rowIndex}`, + }) + ); + }); + + const body = []; + Object.entries(requestBody).map((item) => { + updateCellIndexes.map((cell) => { + if (item[0] === cell.col) { + body.push({ cellValue: item[1], cellIndex: cell.cellIndex }); + } + }); + }); + + return body +}; \ No newline at end of file diff --git a/plugins/tsconfig.json b/plugins/tsconfig.json index 06a361f85d..a88c8575b9 100644 --- a/plugins/tsconfig.json +++ b/plugins/tsconfig.json @@ -7,7 +7,6 @@ "sourceMap": true, "strict": false, - "skipLibCheck": true, "outDir": "./dist", "esModuleInterop": true, @@ -18,5 +17,5 @@ "composite": true, "resolveJsonModule": true }, - "exclude": ["packages/*/lib/*.json", "packages/*/__tests__/*", "dist"] + "exclude": ["packages/*/lib/*.json", "/__tests__/*", "dist"] }