From b6dc37f1d6745bc258fc9608170584c0749a482b Mon Sep 17 00:00:00 2001 From: Antanas Valencius Date: Tue, 9 Jan 2024 12:56:35 +0200 Subject: [PATCH] 493: fixed issue with oe formatting, updated project formatting and settings, updated imports --- .eslintrc.json | 3 +- .prettierrc | 15 +- .vscode/settings.json | 7 + jest.config.js | 14 +- package-lock.json | 11 +- package.json | 1 + .../viewTest/utils/oe/format/oeFormat.test.ts | 57 + src/view/app/Connection/index.tsx | 33 +- src/view/app/Fields/index.tsx | 33 +- src/view/app/Indexes/index.tsx | 32 +- src/view/app/Query/Update/update.tsx | 99 +- src/view/app/Query/index.tsx | 15 +- src/view/app/Query/query.css | 2 +- src/view/app/Query/query.tsx | 1759 +++++++++-------- src/view/app/Welcome/index.tsx | 1 - src/view/app/Welcome/welcome.tsx | 22 +- src/view/app/utils/oe/format/oeFormat.ts | 45 + src/view/app/utils/oe/oeDataTypeEnum.ts | 20 + src/view/tsconfig.json | 20 +- webpack.config.js | 113 +- 20 files changed, 1227 insertions(+), 1075 deletions(-) create mode 100644 src/test/viewTest/utils/oe/format/oeFormat.test.ts create mode 100644 src/view/app/utils/oe/format/oeFormat.ts create mode 100644 src/view/app/utils/oe/oeDataTypeEnum.ts diff --git a/.eslintrc.json b/.eslintrc.json index 1c3a9408..fcfce9a4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -20,7 +20,8 @@ "curly": "warn", "eqeqeq": "warn", "no-throw-literal": "warn", - "semi": "off" + "semi": "off", + "quotes": [1, "single", { "avoidEscape": true }] }, "ignorePatterns": [ "out", diff --git a/.prettierrc b/.prettierrc index 72c0d1ad..946eb10c 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,8 +1,11 @@ { - "editor.formatOnSave": true, - "prettier.singleQuote": true, - "prettier.printWidth": 70, - "[javascript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - } + "editor.formatOnSave": true, + "prettier.singleQuote": true, + "singleQuote": true, + "jsxSingleQuote": true, + "tabWidth": 4, + "prettier.printWidth": 70, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } } diff --git a/.vscode/settings.json b/.vscode/settings.json index c08590a9..d9d4b8ed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,7 +20,14 @@ // Turn off tsc task auto detection since we have the necessary tasks as npm scripts "typescript.tsc.autoDetect": "off", "editor.formatOnSave": true, + "editor.tabSize": 4, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, } \ No newline at end of file diff --git a/jest.config.js b/jest.config.js index 142b64dd..c53b2bba 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,13 +1,11 @@ /* eslint-disable @typescript-eslint/naming-convention */ -const path = require("path"); +const path = require('path'); /** @type {import('jest').Config} */ const config = { - roots: [ - "/src/test/nodeTest" - ], + roots: ['/src/test/nodeTest', '/src/test/viewTest'], globals: { - __DEV__: true - }, - }; + __DEV__: true, + }, +}; - module.exports = config; \ No newline at end of file +module.exports = config; diff --git a/package-lock.json b/package-lock.json index 72ab3e19..a411457f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pro-bro", - "version": "1.3.2", + "version": "1.5.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pro-bro", - "version": "1.3.2", + "version": "1.5.2", "dependencies": { "@emotion/react": "^11.10.0", "@emotion/styled": "^11.10.0", @@ -49,6 +49,7 @@ "jest": "^29.4.3", "mocha": "^9.2.2", "npm-run-all": "^4.1.5", + "resolve-ts-aliases": "^1.0.1", "style-loader": "^3.3.1", "ts-loader": "^9.3.0", "typescript": "^4.6.4", @@ -11190,6 +11191,12 @@ "node": ">=8" } }, + "node_modules/resolve-ts-aliases": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-ts-aliases/-/resolve-ts-aliases-1.0.1.tgz", + "integrity": "sha512-BEFJ2lO9FhuJ+QVK8ZJxuDaFM2/oXt0YJJU9bS2R4zoWfMQOmrT0fLeSClXo7PMAD/kEbRfcGUHqhYKn/ZFPOg==", + "dev": true + }, "node_modules/resolve.exports": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", diff --git a/package.json b/package.json index d56641aa..de149b6a 100644 --- a/package.json +++ b/package.json @@ -329,6 +329,7 @@ "jest": "^29.4.3", "mocha": "^9.2.2", "npm-run-all": "^4.1.5", + "resolve-ts-aliases": "^1.0.1", "style-loader": "^3.3.1", "ts-loader": "^9.3.0", "typescript": "^4.6.4", diff --git a/src/test/viewTest/utils/oe/format/oeFormat.test.ts b/src/test/viewTest/utils/oe/format/oeFormat.test.ts new file mode 100644 index 00000000..356e342d --- /dev/null +++ b/src/test/viewTest/utils/oe/format/oeFormat.test.ts @@ -0,0 +1,57 @@ +import { expect } from "@jest/globals"; +import { getOEFormatLength } from "../../../../../view/app/utils/oe/format/oeFormat"; + +describe("getOEFormatLength", () => { + it('should return the correct length for "xxx"', () => { + expect(getOEFormatLength("xxx")).toBe(3); + }); + + it('should return the correct length for "x(40)"', () => { + expect(getOEFormatLength("x(40)")).toBe(40); + }); + + it('should return the correct length for "$>>.>>>"', () => { + expect(getOEFormatLength("$>>.>>>")).toBe(6); + }); + + it('should return the correct length for "99.>>>"', () => { + expect(getOEFormatLength("99.>>>")).toBe(5); + }); + + it('should return the correct length for "9(7)"', () => { + expect(getOEFormatLength("9(7)")).toBe(7); + }); + + it('should return the correct length for "99"', () => { + expect(getOEFormatLength("99")).toBe(2); + }); + + it('should return the correct length for "ABBBBEEEE"', () => { + expect(getOEFormatLength("ABBBBEEEE")).toBe(9); + }); + + it('should return the correct length for "99KKTB"', () => { + expect(getOEFormatLength("99KKTB")).toBe(6); + }); + + it('should return the correct length for "zzz,zzz,zz"', () => { + expect(getOEFormatLength("zzz,zzz,zz")).toBe(8); + }); + + it('should return the correct length for "z"', () => { + expect(getOEFormatLength("z")).toBe(1); + }); + + it('should return the correct length for ""', () => { + expect(getOEFormatLength("")).toBe(6); + }); + + it("should return 100 if the calculated length is greater than 100", () => { + const longFormat = "X".repeat(200); + expect(getOEFormatLength(longFormat)).toBe(100); + }); + + it("should return 6 if the calculated length is less than or equal to 0", () => { + expect(getOEFormatLength("")).toBe(6); + }); +}); diff --git a/src/view/app/Connection/index.tsx b/src/view/app/Connection/index.tsx index f511bb1e..458a98d1 100644 --- a/src/view/app/Connection/index.tsx +++ b/src/view/app/Connection/index.tsx @@ -1,26 +1,25 @@ -import * as React from "react"; -import { createRoot } from "react-dom/client"; +import { createRoot } from 'react-dom/client'; -import "./connection.css"; -import ConnectionForm from "./connectionForm"; -import { IConfig } from "../model"; -import { ISettings } from "../../../common/IExtensionSettings"; +import './connection.css'; +import ConnectionForm from './connectionForm'; +import { IConfig } from '@app/model'; +import { ISettings } from '@src/common/IExtensionSettings'; declare global { - interface Window { - acquireVsCodeApi(): any; - initialData: IConfig; - configuration: ISettings; - } + interface Window { + acquireVsCodeApi(): any; + initialData: IConfig; + configuration: ISettings; + } } const vscode = window.acquireVsCodeApi(); -const root = createRoot(document.getElementById("root")); +const root = createRoot(document.getElementById('root')); root.render( - + ); diff --git a/src/view/app/Fields/index.tsx b/src/view/app/Fields/index.tsx index d47c1f46..b10f4dc9 100644 --- a/src/view/app/Fields/index.tsx +++ b/src/view/app/Fields/index.tsx @@ -1,25 +1,24 @@ -import * as React from "react"; -import { createRoot } from "react-dom/client"; -import "./fields.css"; -import Fields from "./fields"; -import { TableDetails } from "../model"; -import { ISettings } from "../../../common/IExtensionSettings"; +import { createRoot } from 'react-dom/client'; +import './fields.css'; +import Fields from './fields'; +import { TableDetails } from '@app/model'; +import { ISettings } from '@src/common/IExtensionSettings'; declare global { - interface Window { - acquireVsCodeApi(): any; - tableDetails: TableDetails; - configuration: ISettings; - } + interface Window { + acquireVsCodeApi(): any; + tableDetails: TableDetails; + configuration: ISettings; + } } const vscode = window.acquireVsCodeApi(); -const root = createRoot(document.getElementById("root")); +const root = createRoot(document.getElementById('root')); root.render( - + ); diff --git a/src/view/app/Indexes/index.tsx b/src/view/app/Indexes/index.tsx index 3285d8fd..f69e6975 100644 --- a/src/view/app/Indexes/index.tsx +++ b/src/view/app/Indexes/index.tsx @@ -1,19 +1,23 @@ -import * as React from "react"; - -import { createRoot } from "react-dom/client"; -import { TableDetails } from "../model"; -import "./indexes.css"; -import Indexes from "./indexes"; -import { ISettings } from "../../../common/IExtensionSettings"; +import { createRoot } from 'react-dom/client'; +import { TableDetails } from '@app/model'; +import './indexes.css'; +import Indexes from './indexes'; +import { ISettings } from '@src/common/IExtensionSettings'; declare global { - interface Window { - acquireVsCodeApi(): any; - tableDetails: TableDetails; - configuration: ISettings; - } + interface Window { + acquireVsCodeApi(): any; + tableDetails: TableDetails; + configuration: ISettings; + } } const vscode = window.acquireVsCodeApi(); -const root = createRoot(document.getElementById("root")); -root.render(); +const root = createRoot(document.getElementById('root')); +root.render( + +); diff --git a/src/view/app/Query/Update/update.tsx b/src/view/app/Query/Update/update.tsx index 5315e852..729f380e 100644 --- a/src/view/app/Query/Update/update.tsx +++ b/src/view/app/Query/Update/update.tsx @@ -212,18 +212,7 @@ export default function UpdatePopup({ {ProcessAction[action]} - ) : ( - } - onClick={() => { - setOpen(false); - updateRecord(); - }} - > - UPDATE - - )} + ) : null} { @@ -239,53 +228,51 @@ export default function UpdatePopup({ {isWindowSmall ? ( <> - {!isReadOnly && ( - <> - } - onClick={selectedRows.size === 1 ? copyRecord : insertRecord} - disabled={selectedRows.size > 0 ? false : false} - > - } - onClick={updateRecord} - disabled={selectedRows.size === 1 ? false : true} - > - } - onClick={deleteRecord} - disabled={selectedRows.size > 0 ? false : true} - > - - )} + {!isReadOnly && ( + <>} + onClick={selectedRows.size === 1 ? copyRecord : insertRecord} + disabled={selectedRows.size > 0 ? false : false} + > + } + onClick={updateRecord} + disabled={selectedRows.size === 1 ? false : true} + > + } + onClick={deleteRecord} + disabled={selectedRows.size > 0 ? false : true} + > + + )} ) : ( <> - {!isReadOnly && ( - <> - } - onClick={selectedRows.size === 1 ? copyRecord : insertRecord} - disabled={selectedRows.size > 0 ? false : false} - > - {selectedRows.size === 1 ? "Copy" : "Create"} - - } - onClick={updateRecord} - disabled={selectedRows.size === 1 ? false : true} - > - Update - - } - onClick={deleteRecord} - disabled={selectedRows.size > 0 ? false : true} - > - Delete - - - )} + {!isReadOnly && ( + <>} + onClick={selectedRows.size === 1 ? copyRecord : insertRecord} + disabled={selectedRows.size > 0 ? false : false} + > + {selectedRows.size === 1 ? "Copy" : "Create"} + + } + onClick={updateRecord} + disabled={selectedRows.size === 1 ? false : true} + > + Update + + } + onClick={deleteRecord} + disabled={selectedRows.size > 0 ? false : true} + > + Delete + + + )} )} diff --git a/src/view/app/Query/index.tsx b/src/view/app/Query/index.tsx index bba85f3a..8237d812 100644 --- a/src/view/app/Query/index.tsx +++ b/src/view/app/Query/index.tsx @@ -1,10 +1,9 @@ -import * as React from "react"; -import { createRoot } from "react-dom/client"; +import { createRoot } from 'react-dom/client'; -import "./query.css"; -import QueryForm from "./query"; -import { IOETableData } from "../../../db/Oe"; -import { ISettings } from "../../../common/IExtensionSettings"; +import './query.css'; +import QueryForm from './query'; +import { IOETableData } from '@src/db/Oe'; +import { ISettings } from '@src/common/IExtensionSettings'; declare global { interface Window { @@ -12,13 +11,13 @@ declare global { tableData: IOETableData; tableName: string; configuration: ISettings; - isReadOnly:boolean; + isReadOnly: boolean; } } const vscode = window.acquireVsCodeApi(); -const root = createRoot(document.getElementById("root")); +const root = createRoot(document.getElementById('root')); root.render( (""); - const [isLoading, setIsLoading] = React.useState(false); - const [windowHeight, setWindowHeight] = React.useState(window.innerHeight); - const [isFormatted, setIsFormatted] = React.useState(false); - const [isError, setIsError] = React.useState(false); - const [isDataRetrieved, setIsDataRetrieved] = React.useState(false); - const [errorObject, setErrorObject] = React.useState(); - const [statisticsObject, setStatisticsObject] = - React.useState(); - - const [rawRows, setRawRows] = React.useState(() => tableData.data); - const [formattedRows, setFormattedRows] = React.useState( - () => tableData.data - ); - const [columns, setColumns] = React.useState(() => tableData.columns); - const [selectedColumns, setSelectedColumns] = React.useState([]); - const [columnsCRUD, setColumnsCRUD] = React.useState(() => []); - const [recordsCRUD, setRecordsCRUD] = React.useState(() => []); - const [loaded, setLoaded] = React.useState(() => 0); - const [rowID, setRowID] = React.useState(""); - const [scrollHeight, setScrollHeight] = React.useState(() => 0); - const [isWindowSmall, setIsWindowSmall] = React.useState(false); - - const [sortColumns, setSortColumns] = React.useState( - [] - ); - const [sortAction, setSortAction] = React.useState(false); - const [initialDataLoad, setInitialDataLoad] = React.useState(true); - const [recordColor, setRecordColor] = React.useState("red"); - const [anchorEl, setAnchorEl] = React.useState(null); - const [selectedOption, setSelectedOption] = React.useState("JSON"); - const logger = new Logger(configuration.logging.react); - - window.addEventListener( - "contextmenu", - (e) => { - e.stopImmediatePropagation(); - }, - true - ); - - const [filters, _setFilters] = React.useState({ - columns: {}, - enabled: true, - }); - const filtersRef = React.useRef(filters); - const setFilters = (data) => { - filtersRef.current = data; - _setFilters(data); - }; - - const [selectedRows, setSelectedRows] = React.useState( - (): ReadonlySet => new Set() - ); - - const windowResize = () => { - setWindowHeight(window.innerHeight); - }; - - let inputQuery: HTMLButtonElement = undefined; - React.useEffect(() => { - if (inputQuery) { - inputQuery.click(); - } - }, []); + const [wherePhrase, setWherePhrase] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const [windowHeight, setWindowHeight] = useState(window.innerHeight); + const [isFormatted, setIsFormatted] = useState(false); + const [isError, setIsError] = useState(false); + const [isDataRetrieved, setIsDataRetrieved] = useState(false); + const [errorObject, setErrorObject] = useState(); + const [statisticsObject, setStatisticsObject] = + useState(); + + const [rawRows, setRawRows] = useState(() => tableData.data); + const [formattedRows, setFormattedRows] = useState(() => tableData.data); + const [columns, setColumns] = useState(() => tableData.columns); + const [selectedColumns, setSelectedColumns] = useState([]); + const [columnsCRUD, setColumnsCRUD] = useState(() => []); + const [recordsCRUD, setRecordsCRUD] = useState(() => []); + const [loaded, setLoaded] = useState(() => 0); + const [rowID, setRowID] = useState(''); + const [scrollHeight, setScrollHeight] = useState(() => 0); + const [isWindowSmall, setIsWindowSmall] = useState(false); + + const [sortColumns, setSortColumns] = useState([]); + const [sortAction, setSortAction] = useState(false); + const [initialDataLoad, setInitialDataLoad] = useState(true); + const [recordColor, setRecordColor] = useState('red'); + const logger = new Logger(configuration.logging.react); + + window.addEventListener( + 'contextmenu', + (e) => { + e.stopImmediatePropagation(); + }, + true + ); + + const [filters, _setFilters] = useState({ + columns: {}, + enabled: true, + }); + const filtersRef = useRef(filters); + const setFilters = (data) => { + filtersRef.current = data; + _setFilters(data); + }; + + const [selectedRows, setSelectedRows] = useState( + (): ReadonlySet => new Set() + ); - React.useEffect(() => { - window.addEventListener("resize", windowResize); + const getDataFormat = () => { + setIsFormatted(!isFormatted); + }; - return () => { - window.removeEventListener("resize", windowResize); + const windowResize = () => { + setWindowHeight(window.innerHeight); }; - }, []); - React.useEffect(() => { - const handleResize = () => { - setIsWindowSmall(window.innerWidth <= 828); // Adjust the breakpoint value as needed + let inputQuery: HTMLButtonElement = undefined; + useEffect(() => { + if (inputQuery) { + inputQuery.click(); + } + }, []); + + useEffect(() => { + window.addEventListener('resize', windowResize); + + return () => { + window.removeEventListener('resize', windowResize); + }; + }, []); + + useEffect(() => { + const handleResize = () => { + setIsWindowSmall(window.innerWidth <= 828); // Adjust the breakpoint value as needed + }; + + window.addEventListener('resize', handleResize); + handleResize(); + + return () => { + window.removeEventListener('resize', handleResize); + }; + }, []); + + const messageEvent = (event) => { + const message = event.data; + logger.log('got query data', message); + switch (message.command) { + case 'columns': + setSelectedColumns([...message.columns]); + break; + case 'submit': + if (message.data.error) { + // should be displayed in UpdatePopup window + setErrorObject({ + error: message.data.error, + description: message.data.description, + trace: message.data.trace, + }); + setIsError(true); + setIsDataRetrieved(false); + } else { + setSelectedRows(new Set()); + setOpen(false); + reloadData( + loaded + (action === ProcessAction.Insert ? 1 : 0) + ); + } + break; + case 'crud': + if (message.data.error) { + setErrorObject({ + error: message.data.error, + description: message.data.description, + trace: message.data.trace, + }); + setIsError(true); + setIsDataRetrieved(false); + } else { + setColumnsCRUD(message.data.columns); + setRecordsCRUD(message.data.rawData); + setOpen(true); + } + break; + case 'data': + if (message.data.error) { + setErrorObject({ + error: message.data.error, + description: message.data.description, + trace: message.data.trace, + }); + setIsError(true); + setIsDataRetrieved(false); + } else { + if (message.data.columns.length !== columns.length) { + const fontSize = +window + .getComputedStyle( + document.getElementsByClassName( + 'rdg-header-row' + )[0] + ) + .getPropertyValue('font-size') + .match(/\d+[.]?\d+/); + message.data.columns.forEach((column) => { + if (column.key !== OEDataTypePrimitive.Rowid) { + column.headerRenderer = function ({ + column, + sortDirection, + priority, + onSort, + isCellSelected, + }) { + function handleKeyDown(event) { + if ( + event.key === ' ' || + event.key === 'Enter' + ) { + event.preventDefault(); + onSort( + event.ctrlKey || event.metaKey + ); + } + } + + function handleClick(event) { + onSort(event.ctrlKey || event.metaKey); + } + + var timer; + function handleKeyInputTimeout() { + clearTimeout(timer); + timer = setTimeout(() => { + reloadData( + configuration.initialBatchSizeLoad + ); + }, 500); + } + function testKeyDown(event) { + if (event.key === 'Enter') { + event.preventDefault(); + reloadData( + configuration.initialBatchSizeLoad + ); + } + } + + function handleInputKeyDown(event) { + const tempFilters = filters; + tempFilters.columns[column.key] = + event.target.value; + setFilters(tempFilters); + if ( + configuration.filterAsYouType === + true + ) { + handleKeyInputTimeout(); + } + } + + return ( + +
+ + + {column.name} + + + + {sortDirection === + 'ASC' && ( + + )} + {sortDirection === + 'DESC' && ( + + )} + + {priority} + + +
+ {filters.enabled && ( +
+ +
+ )} +
+ ); + }; + } + column.minWidth = column.name.length * fontSize; + column.width = + getOEFormatLength(column.format ?? '') * + (fontSize - 4); + switch (column.type.toUpperCase()) { + case OEDataTypePrimitive.Integer: + case OEDataTypePrimitive.Decimal: + case OEDataTypePrimitive.Int64: + column.cellClass = 'rightAlign'; + column.headerCellClass = 'rightAlign'; + break; + default: + break; + } + }); + setColumns([SelectColumn, ...message.data.columns]); + if (message.columns !== undefined) { + setSelectedColumns([...message.columns]); + } else { + setSelectedColumns( + [ + ...message.data.columns.map( + (column) => column.name + ), + ].filter( + (column) => + column !== OEDataTypePrimitive.Rowid + ) + ); + } + } + const boolField = message.data.columns.filter( + (field) => field.type === OEDataTypePrimitive.Logical + ); + if (boolField.length !== 0) { + message.data.rawData.forEach((row) => { + boolField.forEach((field) => { + if (row[field.name] !== null) { + row[field.name] = + row[field.name].toString(); + } + }); + }); + } + setRawRows([...rawRows, ...message.data.rawData]); + setRowID( + message.data.rawData.length > 0 + ? message.data.rawData[ + message.data.rawData.length - 1 + ].ROWID + : rowID + ); + setLoaded(loaded + message.data.rawData.length); + setFormattedRows([ + ...formattedRows, + ...message.data.formattedData, + ]); + setLoaded(loaded + message.data.formattedData.length); + setIsError(false); + setIsDataRetrieved(true); + setStatisticsObject({ + recordsRetrieved: message.data.debug.recordsRetrieved, + recordsRetrievalTime: + message.data.debug.recordsRetrievalTime, + connectTime: message.data.debug.timeConnect, + }); + allRecordsRetrieved( + message.data.debug.recordsRetrieved, + message.data.debug.recordsRetrievalTime + ); + } + } + setIsLoading(false); }; - window.addEventListener("resize", handleResize); - handleResize(); + useEffect(() => { + window.addEventListener('message', messageEvent); + return () => { + window.removeEventListener('message', messageEvent); + }; + }); - return () => { - window.removeEventListener("resize", handleResize); + const prepareQuery = () => { + if (isLoading) { + return; + } + setIsLoading(true); + setLoaded(0); + setRawRows([]); + setFormattedRows([]); + setInitialDataLoad(true); + makeQuery( + 0, + configuration.initialBatchSizeLoad /*number of records for first load*/, + '', + sortColumns, + filters, + configuration.batchMaxTimeout /*ms for data retrieval*/, + configuration.batchMinTimeout + ); }; - }, []); - - const messageEvent = (event) => { - const message = event.data; - logger.log("got query data", message); - switch (message.command) { - case "columns": - setSelectedColumns([...message.columns]); - break; - case "submit": - if (message.data.error) { - // should be displayed in UpdatePopup window - setErrorObject({ - error: message.data.error, - description: message.data.description, - trace: message.data.trace, - }); - setIsError(true); - setIsDataRetrieved(false); - } else { - setSelectedRows(new Set()); - setOpen(false); - reloadData(loaded + (actionMode === ProcessAction.Insert ? 1 : 0)); + + const onQueryClick = (event: MouseEvent) => { + event.preventDefault(); + prepareQuery(); + }; + + let input = document.getElementById('input'); + + const handleKeyDown = (e) => { + let selected = document.querySelector('.selected') as HTMLLIElement; + if (e.key === 'Enter' && selected === null) { + e.preventDefault(); + prepareQuery(); } - break; - case "crud": - if (message.data.error) { - setErrorObject({ - error: message.data.error, - description: message.data.description, - trace: message.data.trace, - }); - setIsError(true); - setIsDataRetrieved(false); - } else { - setColumnsCRUD(message.data.columns); - setRecordsCRUD(message.data.rawData); - setOpen(true); + + if (e.key === 'Enter' && selected !== null) { + e.preventDefault(); + const selectedText = + document.querySelector('.selected').textContent; + + addText(input, selectedText); + createListener(document.getElementById('input'), selectedColumns); } - break; - case "data": - if (message.data.error) { - setErrorObject({ - error: message.data.error, - description: message.data.description, - trace: message.data.trace, - }); - setIsError(true); - setIsDataRetrieved(false); - } else { - if (message.data.columns.length !== columns.length) { - const fontSize = +window - .getComputedStyle( - document.getElementsByClassName("rdg-header-row")[0] - ) - .getPropertyValue("font-size") - .match(/\d+[.]?\d+/); - message.data.columns.forEach((column) => { - if (column.key !== "ROWID") { - column.headerRenderer = function ({ - column, - sortDirection, - priority, - onSort, - isCellSelected, - }) { - function handleKeyDown(event) { - if (event.key === " " || event.key === "Enter") { - event.preventDefault(); - onSort(event.ctrlKey || event.metaKey); - } - } - - function handleClick(event) { - onSort(event.ctrlKey || event.metaKey); - } - - var timer; - function handleKeyInputTimeout() { - clearTimeout(timer); - timer = setTimeout(() => { - reloadData(configuration.initialBatchSizeLoad); - }, 500); - } - function testKeyDown(event) { - if (event.key === "Enter") { - event.preventDefault(); - reloadData(configuration.initialBatchSizeLoad); - } - } - - function handleInputKeyDown(event) { - const tempFilters = filters; - tempFilters.columns[column.key] = event.target.value; - setFilters(tempFilters); - if (configuration.filterAsYouType === true) { - handleKeyInputTimeout(); - } - } - - return ( - -
- - - {column.name} - - - - {sortDirection === "ASC" && ( - - )} - {sortDirection === "DESC" && ( - - )} - - {priority} - - -
- {filters.enabled && ( -
- -
- )} -
- ); - }; - } - column.minWidth = column.name.length * fontSize; - switch (column.type) { - case "integer": - case "decimal": - case "int64": - column.cellClass = "rightAlign"; - column.headerCellClass = "rightAlign"; - column.width = column.format.length * (fontSize - 3); - break; - case "character": - let dataLength = column.format.length; - if (/x\(\d+\)/.test(column.format)) { - dataLength = +column.format.match(/\d+/); - } - column.width = dataLength * (fontSize - 3); - break; - case "date": - case "datetime": - case "datetime-tz": - column.width = column.format.length * (fontSize - 3); - break; - case "logical": - column.width = column.name.length * (fontSize - 3); - break; - default: - break; - } - }); - setColumns([SelectColumn, ...message.data.columns]); - if (message.columns !== undefined) { - setSelectedColumns([...message.columns]); + + if (e.keyCode === 38) { + if (selected === null) { + document + .querySelectorAll('.autocomplete-list li') + .item(0) + .classList.add('selected'); } else { - setSelectedColumns( - [...message.data.columns.map((column) => column.name)].filter( - (column) => column !== "ROWID" - ) - ); - } - } - const boolField = message.data.columns.filter( - (field) => field.type === "logical" - ); - if (boolField.length !== 0) { - message.data.rawData.forEach((row) => { - boolField.forEach((field) => { - if (row[field.name] !== null) { - row[field.name] = row[field.name].toString(); + document + .querySelectorAll('.autocomplete-list li') + .forEach(function (item) { + item.classList.remove('selected'); + }); + if (selected.previousElementSibling === null) { + selected.parentElement.lastElementChild.classList.add( + 'selected' + ); + } else { + selected.previousElementSibling.classList.add('selected'); } - }); - }); - } - setRawRows([...rawRows, ...message.data.rawData]); - setRowID( - message.data.rawData.length > 0 - ? message.data.rawData[message.data.rawData.length - 1].ROWID - : rowID - ); - setLoaded(loaded + message.data.rawData.length); - setFormattedRows([...formattedRows, ...message.data.formattedData]); - setLoaded(loaded + message.data.formattedData.length); - setIsError(false); - setIsDataRetrieved(true); - setStatisticsObject({ - recordsRetrieved: message.data.debug.recordsRetrieved, - recordsRetrievalTime: message.data.debug.recordsRetrievalTime, - connectTime: message.data.debug.timeConnect, - }); - allRecordsRetrieved( - message.data.debug.recordsRetrieved, - message.data.debug.recordsRetrievalTime - ); + } + selected = document.querySelector('.selected'); + selected.scrollIntoView(); + selected.focus(); } - } - setIsLoading(false); - }; - React.useEffect(() => { - window.addEventListener("message", messageEvent); - return () => { - window.removeEventListener("message", messageEvent); + if (e.keyCode === 40) { + if (selected === null) { + document + .querySelectorAll('.autocomplete-list li') + .item(0) + .classList.add('selected'); + } else { + document + .querySelectorAll('.autocomplete-list li') + .forEach(function (item) { + item.classList.remove('selected'); + }); + + if (selected.nextElementSibling === null) { + selected.parentElement.firstElementChild.classList.add( + 'selected' + ); + } else { + selected.nextElementSibling.classList.add('selected'); + } + } + selected = document.querySelector('.selected'); + selected.scrollIntoView(); + selected.focus(); + } }; - }); - const prepareQuery = () => { - if (isLoading) { - return; + function reloadData(loaded: number) { + setLoaded(0); + setRawRows([]); + setFormattedRows([]); + makeQuery(0, loaded, '', sortColumns, filters, 0, 0); } - setIsLoading(true); - setLoaded(0); - setRawRows([]); - setFormattedRows([]); - setInitialDataLoad(true); - makeQuery( - 0, - configuration.initialBatchSizeLoad /*number of records for first load*/, - "", - sortColumns, - filters, - configuration.batchMaxTimeout /*ms for data retrieval*/, - configuration.batchMinTimeout - ); - }; - const onQueryClick = (event: React.MouseEvent) => { - event.preventDefault(); - prepareQuery(); - }; + function makeQuery( + loaded, + pageLength, + lastRowID, + sortColumns, + inputFilters, + timeOut, + minTime + ) { + const command: ICommand = { + id: 'Query', + action: CommandAction.Query, + params: { + wherePhrase: wherePhrase, + start: loaded, + pageLength: pageLength, + lastRowID: lastRowID, + sortColumns: sortColumns, + filters: inputFilters, + timeOut: timeOut, + minTime: minTime, + }, + }; + logger.log('make query', command); + vscode.postMessage(command); + } - let input = document.getElementById("input"); + function isAtBottom({ currentTarget }: UIEvent): boolean { + return ( + currentTarget.scrollTop + 10 >= + currentTarget.scrollHeight - currentTarget.clientHeight + ); + } - const handleKeyDown = (e) => { - let selected = document.querySelector(".selected") as HTMLLIElement; - if (e.key === "Enter" && selected === null) { - e.preventDefault(); - prepareQuery(); + function isHorizontalScroll({ + currentTarget, + }: UIEvent): boolean { + return currentTarget.scrollTop === scrollHeight; } - if (e.key === "Enter" && selected !== null) { - e.preventDefault(); - const selectedText = document.querySelector(".selected").textContent; + async function handleScroll(event: UIEvent) { + if (isLoading || !isAtBottom(event) || isHorizontalScroll(event)) { + return; + } + setScrollHeight(event.currentTarget.scrollTop); + setIsLoading(true); + makeQuery( + loaded, + configuration.batchSize, + rowID, + sortColumns, + filters, + configuration.batchMaxTimeout, + configuration.batchMinTimeout + ); + } - addText(input, selectedText); - createListener(document.getElementById("input"), selectedColumns); + function onSortClick(inputSortColumns: SortColumn[]) { + if (isLoading) { + return; + } + setSortAction(true); + setSortColumns(inputSortColumns); + setLoaded(0); + setRawRows([]); + setFormattedRows([]); + makeQuery(0, loaded, '', inputSortColumns, filters, 0, 0); } - if (e.keyCode === 38) { - if (selected === null) { - document - .querySelectorAll(".autocomplete-list li") - .item(0) - .classList.add("selected"); - } else { - document - .querySelectorAll(".autocomplete-list li") - .forEach(function (item) { - item.classList.remove("selected"); - }); - if (selected.previousElementSibling === null) { - selected.parentElement.lastElementChild.classList.add("selected"); + function allRecordsRetrieved( + recentRecords: number, + recentRetrievalTime: number + ) { + if (!sortAction) { + const currentBatchSize: number = initialDataLoad + ? configuration.initialBatchSizeLoad + : configuration.batchSize; + setInitialDataLoad(false); + setRecordColor( + recentRecords < currentBatchSize && + recentRetrievalTime < configuration.batchMaxTimeout + ? 'green' + : 'red' + ); } else { - selected.previousElementSibling.classList.add("selected"); + setSortAction(false); } - } - selected = document.querySelector(".selected"); - selected.scrollIntoView(); - selected.focus(); } - if (e.keyCode === 40) { - if (selected === null) { - document - .querySelectorAll(".autocomplete-list li") - .item(0) - .classList.add("selected"); - } else { - document - .querySelectorAll(".autocomplete-list li") - .forEach(function (item) { - item.classList.remove("selected"); - }); - - if (selected.nextElementSibling === null) { - selected.parentElement.firstElementChild.classList.add("selected"); + function getLoaded() { + if (recordColor === 'red') { + return '> ' + loaded; } else { - selected.nextElementSibling.classList.add("selected"); + return loaded; } - } - selected = document.querySelector(".selected"); - selected.scrollIntoView(); - selected.focus(); } - }; - - function reloadData(loaded: number) { - setLoaded(0); - setRawRows([]); - setFormattedRows([]); - makeQuery(0, loaded, "", sortColumns, filters, 0, 0); - } - - function makeQuery( - loaded, - pageLength, - lastRowID, - sortColumns, - inputFilters, - timeOut, - minTime - ) { - const command: ICommand = { - id: "Query", - action: CommandAction.Query, - params: { - wherePhrase: wherePhrase, - start: loaded, - pageLength: pageLength, - lastRowID: lastRowID, - sortColumns: sortColumns, - filters: inputFilters, - timeOut: timeOut, - minTime: minTime, - }, - }; - logger.log("make query", command); - vscode.postMessage(command); - } - - function isAtBottom({ - currentTarget, - }: React.UIEvent): boolean { - return ( - currentTarget.scrollTop + 10 >= - currentTarget.scrollHeight - currentTarget.clientHeight - ); - } - function isHorizontalScroll({ - currentTarget, - }: React.UIEvent): boolean { - return currentTarget.scrollTop === scrollHeight; - } - - async function handleScroll(event: React.UIEvent) { - if (isLoading || !isAtBottom(event) || isHorizontalScroll(event)) { - return; + function getFooterTag() { + if (isError) { + return ( +
+
{`Error: ${errorObject.error}
+Description: ${errorObject.description}`}
+
+ ); + } else if (isDataRetrieved) { + return ( +
+
+                        {'Records in grid:'}
+                        
+                            {getLoaded()}
+                        
+                    
+ {isWindowSmall ? null : ( +
+                            {`Recent records numbers: ${statisticsObject.recordsRetrieved}`}
+                        
+ )} +
{`Recent retrieval time: ${statisticsObject.recordsRetrievalTime}`}
+
+ ); + } else { + return <>; + } } - setScrollHeight(event.currentTarget.scrollTop); - setIsLoading(true); - makeQuery( - loaded, - configuration.batchSize, - rowID, - sortColumns, - filters, - configuration.batchMaxTimeout, - configuration.batchMinTimeout - ); - } - function onSortClick(inputSortColumns: SortColumn[]) { - if (isLoading) { - return; - } - setSortAction(true); - setSortColumns(inputSortColumns); - setLoaded(0); - setRawRows([]); - setFormattedRows([]); - makeQuery(0, loaded, "", inputSortColumns, filters, 0, 0); - } - - function allRecordsRetrieved( - recentRecords: number, - recentRetrievalTime: number - ) { - if (!sortAction) { - const currentBatchSize: number = initialDataLoad - ? configuration.initialBatchSizeLoad - : configuration.batchSize; - setInitialDataLoad(false); - setRecordColor( - recentRecords < currentBatchSize && - recentRetrievalTime < configuration.batchMaxTimeout - ? "green" - : "red" - ); - } else { - setSortAction(false); + function rowKeyGetter(row: any) { + return row.ROWID; } - } - function getLoaded() { - if (recordColor === "red") { - return "> " + loaded; - } else { - return loaded; - } - } + // CRUD operations + const [open, setOpen] = useState(false); + const [action, setAction] = useState(); + const [readRow, setReadRow] = useState([]); - function getFooterTag() { - if (isError) { - return ( -
-
{`Error: ${errorObject.error}
-Description: ${errorObject.description}`}
-
- ); - } else if (isDataRetrieved) { - return ( -
-
-            {`Records in grid:`}
-            {getLoaded()}
-          
- {isWindowSmall ? null : ( -
-              {`Recent records numbers: ${statisticsObject.recordsRetrieved}`}
-            
- )} -
{`Recent retrieval time: ${statisticsObject.recordsRetrievalTime}`}
-
- ); - } else { - return <>; - } - } - - function rowKeyGetter(row: any) { - return row.ROWID; - } - - // CRUD operations - const [open, setOpen] = React.useState(false); - const [actionMode, setActionMode] = React.useState(); - const [readRow, setReadRow] = React.useState([]); - - const readRecord = (row) => { - let selectedRowsSet = new Set(); - selectedRowsSet.add(row.ROWID); - setSelectedRows(selectedRowsSet); - setActionMode(ProcessAction.Read); - setReadRow(row); - setOpen(true); - }; - - const insertRecord = () => { - processRecord(ProcessAction.Insert); - }; - const updateRecord = () => { - setSelectedRows(new Set()); - processRecord(ProcessAction.Update); - }; - - const deleteRecord = () => { - processRecord(ProcessAction.Delete); - }; - const copyRecord = () => { - processRecord(ProcessAction.Copy); - }; - - const processRecord = (mode: ProcessAction) => { - setActionMode(mode); - const rowids: string[] = []; - selectedRows.forEach((element) => { - rowids.push(element); - }); + const readRecord = (row: string[]) => { + setAction(ProcessAction.Read); + setReadRow(row); + setOpen(true); + }; + + const insertRecord = () => { + processRecord(ProcessAction.Insert); + }; + const updateRecord = () => { + processRecord(ProcessAction.Update); + }; + const deleteRecord = () => { + processRecord(ProcessAction.Delete); + }; + const copyRecord = () => { + processRecord(ProcessAction.Copy); + }; - const command: ICommand = { - id: "CRUD", - action: CommandAction.CRUD, - params: { - start: 0, - pageLength: selectedRows.size, - timeOut: 1000, - minTime: 1000, - lastRowID: selectedRows.values().next().value, - crud: rowids, - mode: ProcessAction[mode], - }, + const processRecord = (mode: ProcessAction) => { + setAction(mode); + const rowids: string[] = []; + selectedRows.forEach((element) => { + rowids.push(element); + }); + + const command: ICommand = { + id: 'CRUD', + action: CommandAction.CRUD, + params: { + start: 0, + pageLength: selectedRows.size, + timeOut: 1000, + minTime: 1000, + lastRowID: selectedRows.values().next().value, + crud: rowids, + mode: ProcessAction[mode], + }, + }; + logger.log('crud data request', command); + vscode.postMessage(command); }; - logger.log("crud data request", command); - vscode.postMessage(command); - }; - - function filterColumns() { - if (selectedColumns.length !== 0) { - const selection = columns.filter((column) => { - let testColumn = column.key; - if (/\[\d+\]$/.test(column.key)) { - testColumn = column.key.match(/[^[]+/)[0]; + + function filterColumns() { + if (selectedColumns.length !== 0) { + const selection = columns.filter((column) => { + let testColumn = column.key; + if (/\[\d+\]$/.test(column.key)) { + testColumn = column.key.match(/[^[]+/)[0]; + } + return ( + selectedColumns.includes(testColumn) || + testColumn === 'select-row' + ); + }); + return selection; + } else { + return []; } - return ( - selectedColumns.includes(testColumn) || testColumn === "select-row" - ); - }); - return selection; - } else { - return []; } - } - const selected = filterColumns(); + const selected = filterColumns(); - function handleCopy({ sourceRow, sourceColumnKey }: CopyEvent): void { - if (window.isSecureContext) { - navigator.clipboard.writeText(sourceRow[sourceColumnKey]); + function handleCopy({ sourceRow, sourceColumnKey }: CopyEvent): void { + if (window.isSecureContext) { + navigator.clipboard.writeText(sourceRow[sourceColumnKey]); + } } - } - const suggestions = document.querySelector("#column-list"); + const suggestions = document.querySelector('#column-list'); - function autocomplete(input, list) { - let lastWord = input.value.split(" ").pop(); + function autocomplete(input, list) { + let lastWord = input.value.split(' ').pop(); - suggestions.innerHTML = ""; + suggestions.innerHTML = ''; - for (const item of list) { - if ( - item.toUpperCase().includes(lastWord.toUpperCase()) || - lastWord === null - ) { - const suggestion = document.createElement("li"); - suggestion.innerHTML = item; - suggestion.style.cursor = "pointer"; - suggestions.appendChild(suggestion); - } + for (const item of list) { + if ( + item.toUpperCase().includes(lastWord.toUpperCase()) || + lastWord === null + ) { + const suggestion = document.createElement('li'); + suggestion.innerHTML = item; + suggestion.style.cursor = 'pointer'; + suggestions.appendChild(suggestion); + } + } } - } - - function addText(input, newText) { - let wordArray = input.value.split(" "); - wordArray.pop(); - input.value = ""; - for (const word of wordArray) { - input.value += word; - input.value += " "; + + function addText(input, newText) { + let wordArray = input.value.split(' '); + wordArray.pop(); + input.value = ''; + for (const word of wordArray) { + input.value += word; + input.value += ' '; + } + input.value += newText; + input.value += ' '; + setWherePhrase(input.value); } - input.value += newText; - input.value += " "; - setWherePhrase(input.value); - } - - function mouseoverListener() { - document.querySelectorAll(".autocomplete-list li").forEach(function (item) { - item.addEventListener("mouseover", function () { + + function mouseoverListener() { document - .querySelectorAll(".autocomplete-list li") - .forEach(function (item) { - item.classList.remove("selected"); - }); - this.classList.add("selected"); - }); - item.addEventListener("click", function () { - addText(input, this.innerHTML); - document.getElementById("input").focus(); - setTimeout(() => { - createListener(document.getElementById("input"), selectedColumns); - }, 301); - }); - }); - } - - function createListener(input, list) { - input.addEventListener("input", autocomplete(input, list)); - mouseoverListener(); - } - - function hideSuggestions() { - setTimeout(() => { - suggestions.innerHTML = ""; - }, 300); - } - - const handleFormat = (format) => { - if (format === "JSON") { - setIsFormatted(false); - } else if (format === "PROGRESS") { - setIsFormatted(true); + .querySelectorAll('.autocomplete-list li') + .forEach(function (item) { + item.addEventListener('mouseover', function () { + document + .querySelectorAll('.autocomplete-list li') + .forEach(function (item) { + item.classList.remove('selected'); + }); + this.classList.add('selected'); + }); + item.addEventListener('click', function () { + addText(input, this.innerHTML); + document.getElementById('input').focus(); + setTimeout(() => { + createListener( + document.getElementById('input'), + selectedColumns + ); + }, 301); + }); + }); } - setSelectedOption(format); - setAnchorEl(null); - }; - const calculateHeight = () => { - const rowCount = isFormatted ? formattedRows.length : rawRows.length; - let minHeight; - if (configuration.gridTextSize === "Large") { - minHeight = 40; - } else if (configuration.gridTextSize === "Medium") { - minHeight = 30; - } else if (configuration.gridTextSize === "Small") { - minHeight = 20; + + function createListener(input, list) { + input.addEventListener('input', autocomplete(input, list)); + mouseoverListener(); } - const startingHeight = 85; - const calculatedHeight = startingHeight + rowCount * minHeight; - return calculatedHeight; - }; - - const setRowHeight = () => { - let height = 0; - - if (configuration.gridTextSize === "Large") { - height = 40; - } else if (configuration.gridTextSize === "Medium") { - height = 30; - } else if (configuration.gridTextSize === "Small") { - height = 20; + + function hideSuggestions() { + setTimeout(() => { + suggestions.innerHTML = ''; + }, 300); } - return height; - }; - - return ( - -
-
Query
-
-
-
-
- { - createListener( - document.getElementById("input"), - selectedColumns - ); - }} - onBlur={hideSuggestions} - onChange={(event) => { - createListener( - document.getElementById("input"), - selectedColumns - ); - setWherePhrase(event.target.value); - }} - onKeyDown={handleKeyDown} - /> - {isWindowSmall ? ( - (inputQuery = input)} - startIcon={} - onClick={onQueryClick} - /> - ) : ( - (inputQuery = input)} - startIcon={} - onClick={onQueryClick} - > - Query - - )} -
+ const calculateHeight = () => { + const rowCount = isFormatted ? formattedRows.length : rawRows.length; + let minHeight; + if (configuration.gridTextSize === 'Large') { + minHeight = 40; + } else if (configuration.gridTextSize === 'Medium') { + minHeight = 30; + } else if (configuration.gridTextSize === 'Small') { + minHeight = 20; + } + const startingHeight = 85; + const calculatedHeight = startingHeight + rowCount * minHeight; + return calculatedHeight; + }; + + const setRowHeight = () => { + let height = 0; + + if (configuration.gridTextSize === 'Large') { + height = 40; + } else if (configuration.gridTextSize === 'Medium') { + height = 30; + } else if (configuration.gridTextSize === 'Small') { + height = 20; + } + + return height; + }; + + return ( + +
+
Query
+
+ +
+
+ { + createListener( + document.getElementById('input'), + selectedColumns + ); + }} + onBlur={hideSuggestions} + onChange={(event) => { + createListener( + document.getElementById('input'), + selectedColumns + ); + setWherePhrase(event.target.value); + }} + onKeyDown={handleKeyDown} + /> + {isWindowSmall ? ( + (inputQuery = input)} + startIcon={} + onClick={onQueryClick} + /> + ) : ( + (inputQuery = input)} + startIcon={} + onClick={onQueryClick} + > + Query + + )} +
+
+
    + +
    + + + ) : ( + + ) + } + > + {' '} + +
    +
    + +
    +
    +
    +
    +
    -
      - -
      - -
      - <> - setAnchorEl(event.currentTarget)}> - FORMAT - - setAnchorEl(null)} - sx={{ - "& .MuiPaper-root": { - backgroundColor: "var(--vscode-input-background)", - maxWidth: "200px", - fontSize: "small", - }, - }} - > - handleFormat("JSON")} - sx={{ - color: "var(--vscode-input-foreground)", - }} - > - - {selectedOption === "JSON" && } - - - - handleFormat("PROGRESS")} - sx={{ - color: "var(--vscode-input-foreground)", - }} - > - - {selectedOption === "PROGRESS" && } - - - - - -
      - -
      -
      -
      -
      - -
      -
      {getFooterTag()}
      - {isLoading &&
      Loading more rows...
      } - - ); +
      {getFooterTag()}
      + {isLoading &&
      Loading more rows...
      } + + ); } export default QueryForm; diff --git a/src/view/app/Welcome/index.tsx b/src/view/app/Welcome/index.tsx index 51bcfb19..7fda6383 100644 --- a/src/view/app/Welcome/index.tsx +++ b/src/view/app/Welcome/index.tsx @@ -1,4 +1,3 @@ -import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { Welcome } from './welcome'; diff --git a/src/view/app/Welcome/welcome.tsx b/src/view/app/Welcome/welcome.tsx index 6bf694ea..68fe8daa 100644 --- a/src/view/app/Welcome/welcome.tsx +++ b/src/view/app/Welcome/welcome.tsx @@ -1,20 +1,18 @@ -import * as React from 'react'; -import '../Welcome/welcome.css'; - +import './welcome.css'; import ReactMarkdown from 'react-markdown'; -import readme from '../../../../README.md'; -import changelog from './../../../../CHANGELOG.md'; +import readme from '@root/README.md'; +import changelog from '@root/CHANGELOG.md'; // Welcome.tsx function Welcome() { - return ( -
      - {readme} -
      - {changelog} -
      - ); + return ( +
      + {readme} +
      + {changelog} +
      + ); } export { Welcome }; diff --git a/src/view/app/utils/oe/format/oeFormat.ts b/src/view/app/utils/oe/format/oeFormat.ts new file mode 100644 index 00000000..55de111b --- /dev/null +++ b/src/view/app/utils/oe/format/oeFormat.ts @@ -0,0 +1,45 @@ +// Progress OpenEdge specific utils + +/** + * Returns the length of an OE format + * https://chat.openai.com/share/c045c5bb-050e-40e0-b1cf-148cc1324dfd + * @param {string} formatStr OE format string. See https://docs.progress.com/bundle/openedge-abl-essentials-117/page/Defining-formats.html + * @return {number} length of format + */ +export const getOEFormatLength = (formatStr: string): number => { + let length = 0; + + for (let i = 0; i < formatStr.length; i++) { + const char = formatStr[i]; + + switch (char) { + case "(": + // Handle the (n) format + const closingParenIndex = formatStr.indexOf(")", i + 1); + if (closingParenIndex !== -1) { + const repeatCount = parseInt( + formatStr.slice(i + 1, closingParenIndex), + 10 + ); + length += Math.max(repeatCount - 1, 0); // Ensure repeatCount is non-negative + i = closingParenIndex; // Skip the characters inside the parentheses + } + break; + case ",": + case ".": + // do nothing + break; + default: + length++; + break; + } + } + + if (length > 100) { + length = 100; + } else if (length <= 0) { + length = 6; + } + + return length; +}; diff --git a/src/view/app/utils/oe/oeDataTypeEnum.ts b/src/view/app/utils/oe/oeDataTypeEnum.ts new file mode 100644 index 00000000..2b548f10 --- /dev/null +++ b/src/view/app/utils/oe/oeDataTypeEnum.ts @@ -0,0 +1,20 @@ +export enum OEDataTypePrimitive { + Blob = "BLOB", + Character = "CHARACTER", + Clob = "CLOB", + ComHandle = "COM-HANDLE", + Date = "DATE", + Datetime = "DATETIME", + DatetimeTz = "DATETIME-TZ", + Decimal = "DECIMAL", + Handle = "HANDLE", + Int64 = "INT64", + Integer = "INTEGER", + Logical = "LOGICAL", + Longchar = "LONGCHAR", + Memptr = "MEMPTR", + Raw = "RAW", + Recid = "RECID", + Rowid = "ROWID", + WidgetHandle = "WIDGET-HANDLE", +} diff --git a/src/view/tsconfig.json b/src/view/tsconfig.json index 124f1d06..1fd5f78c 100644 --- a/src/view/tsconfig.json +++ b/src/view/tsconfig.json @@ -5,14 +5,28 @@ "target": "es6", "outDir": "out/view/app", "lib": ["es6", "dom"], - "jsx": "react", + "jsx": "react-jsx", "sourceMap": true, - "rootDir": "..", + "rootDir": "../", "noUnusedLocals": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "experimentalDecorators": true, - "resolveJsonModule": true + "resolveJsonModule": true, + "baseUrl": ".", + "paths": { + "@assets/*": ["app/assets/*"], + "@Connection/*": ["app/Connection/*"], + "@Fields/*": ["app/Fields/*"], + "@Indexes/*": ["app/Indexes/*"], + "@Query/*": ["app/Query/*"], + "@utils/*": ["app/utils/*"], + "@Welcome/*": ["app/Welcome/*"], + "@app/*": ["app/*"], + "@view/*": ["./*"], + "@src/*": ["../*"], + "@root/*": ["../../*"] + } }, "exclude": ["node_modules"] } diff --git a/webpack.config.js b/webpack.config.js index 9d7f3a19..46bdb3b3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,60 +1,61 @@ -const path = require("path"); +const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); +const { resolveTsAliases } = require('resolve-ts-aliases'); module.exports = { - entry: { - connection: "./src/view/app/Connection/", - fields: "./src/view/app/Fields", - indexes: "./src/view/app/Indexes", - query: "./src/view/app/Query", - welcome: "./src/view/app/Welcome", - }, - output: { - path: path.resolve(__dirname, "out/view/app"), - filename: "[name].js" - }, - devtool: "eval-source-map", - resolve: { - extensions: [".js", ".ts", ".tsx", ".json"] - }, - module: { - rules: [ - { - test: /\.(jpg|png|svg|gif)$/, - loader: 'url-loader', - options: { - limit: 25000, - name: 'images/[name].[hash:8].[ext]', - }, - }, - { - test: /\.md$/, - use: [ - { - loader: 'raw-loader', - }, + entry: { + connection: './src/view/app/Connection', + fields: './src/view/app/Fields', + indexes: './src/view/app/Indexes', + query: './src/view/app/Query', + welcome: './src/view/app/Welcome', + }, + output: { + path: path.resolve(__dirname, 'out/view/app'), + filename: '[name].js', + }, + devtool: 'eval-source-map', + resolve: { + extensions: ['.js', '.ts', '.tsx', '.json'], + alias: resolveTsAliases(path.resolve('src/view/tsconfig.json')), + }, + module: { + rules: [ + { + test: /\.(jpg|png|svg|gif)$/, + loader: 'url-loader', + options: { + limit: 25000, + name: 'images/[name].[hash:8].[ext]', + }, + }, + { + test: /\.md$/, + use: [ + { + loader: 'raw-loader', + }, + ], + }, + { + test: /\.(ts|tsx)$/, + loader: 'ts-loader', + options: {}, + }, + { + test: /\.css$/, + use: [ + { + loader: 'style-loader', + }, + { + loader: 'css-loader', + }, + ], + }, ], - }, - { - test: /\.(ts|tsx)$/, - loader: "ts-loader", - options: {} - }, - { - test: /\.css$/, - use: [ - { - loader: "style-loader" - }, - { - loader: "css-loader" - }, - - ] - } - ] - }, - performance: { - hints: false - } -}; \ No newline at end of file + }, + performance: { + hints: false, + }, +};