From 4e63d368524c7be6e1186eb05fe741c8edb51075 Mon Sep 17 00:00:00 2001 From: Shridhar TL Date: Wed, 18 Dec 2024 16:52:00 +0530 Subject: [PATCH 1/3] Upgraded to latest version of libraries --- package.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 21c5d297..e156b960 100644 --- a/package.json +++ b/package.json @@ -51,10 +51,10 @@ } }, "dependencies": { - "@forge/api": "^4.1.0", - "@forge/bridge": "^4.1.0", - "@forge/resolver": "^1.5.32", - "@fortawesome/fontawesome-free": "^6.5.2", + "@forge/api": "^4.1.2", + "@forge/bridge": "^4.2.0", + "@forge/resolver": "^1.6.3", + "@fortawesome/fontawesome-free": "^6.7.2", "@fullcalendar/core": "^6.1.15", "@fullcalendar/daygrid": "^6.1.15", "@fullcalendar/interaction": "^6.1.15", @@ -64,9 +64,9 @@ "@fullcalendar/timegrid": "^6.1.15", "bootstrap": "^5.3.3", "bootstrap-daterangepicker": "^3.1.0", - "chart.js": "^4.4.3", + "chart.js": "^4.4.7", "classnames": "^2.5.1", - "dexie": "^4.0.4", + "dexie": "^4.0.10", "electron-about-window": "^1.15.2", "electron-is-dev": "^3.0.1", "electron-updater": "^6.1.8", @@ -96,20 +96,20 @@ "react-router-dom": "^6.23.1", "react-scripts": "github:shridhar-tl/react-scripts", "static-eval": "^2.1.1", - "zustand": "^5.0.1" + "zustand": "^5.0.2" }, "devDependencies": { "@craco/craco": "^7.1.0", - "concurrently": "^9.0.1", + "concurrently": "^9.1.0", "cross-env": "^7.0.3", - "electron": "^33.0.2", + "electron": "^33.1.1", "electron-builder": "^25.1.8", "electronmon": "^2.0.3", - "eslint": "^9.14.0", - "eslint-plugin-react-hooks": "^5.0.0", + "eslint": "^9.17.0", + "eslint-plugin-react-hooks": "^5.1.0", "gh-pages": "^6.1.1", "react-app-alias": "^2.2.2", - "sass": "^1.80.6", + "sass": "^1.83.0", "wait-on": "^8.0.1", "webpack-bundle-analyzer": "^4.10.2" }, From 8bd5db073f2d27bbed33fe96d5fcd945e79b5889 Mon Sep 17 00:00:00 2001 From: Shridhar TL Date: Thu, 19 Dec 2024 15:46:02 +0530 Subject: [PATCH 2/3] Removed report builder permenantly and upgraded to latest version of libraries --- jsconfig.json | 3 - package.json | 18 +- src/_nav.js | 14 +- src/common/jsExec.js | 62 ------ src/components/ContextMenu.jsx | 57 +++++ .../GroupableGrid/GroupedColumnList.jsx | 2 +- src/customize.js | 1 - src/display-controls/TicketDisplay.jsx | 2 +- src/electron/menu.js | 3 +- src/externals/jsd-report.js | 4 - src/gadgets/BaseGadget.jsx | 2 +- src/gadgets/Calendar/Calendar.jsx | 2 +- src/gadgets/DateWiseWorklog.jsx | 2 +- src/gadgets/Gadget.jsx | 2 +- src/gadgets/MyBookmarks.jsx | 2 +- src/gadgets/MyOpenTickets.jsx | 2 +- src/gadgets/PendingWorklog.jsx | 2 +- src/gadgets/TicketWiseWorklog.jsx | 2 +- src/layouts/DefaultLayout/DefaultLayout.jsx | 2 +- src/layouts/DefaultLayout/LaunchWeb.jsx | 2 +- .../DefaultLayout/header/HeaderRight.jsx | 2 +- src/routes.jsx | 9 - src/services/base-service.d.ts | 1 - src/services/index.d.ts | 1 - src/services/index.register.js | 2 - src/services/injector-service.d.ts | 1 - src/services/reportconfig-service.js | 21 +- src/views/dashboard/Dashboard.jsx | 2 - src/views/dashboard/Header.jsx | 2 +- src/views/pages/integrate/Integrate.jsx | 2 +- .../pivot-report/editor/body/index.jsx | 5 +- .../pivot-report/editor/controls/index.jsx | 3 +- src/views/reports/pivot-report/index.jsx | 3 +- .../report-builder/JQLEditorDialog.jsx | 50 ----- .../reports/report-builder/ReportBuilder.jsx | 196 ------------------ .../reports/report-builder/ReportBuilder.scss | 17 -- .../reports/report-builder/ReportViewer.jsx | 116 ----------- .../reports/report-builder/ReportViewer.scss | 47 ----- 38 files changed, 91 insertions(+), 575 deletions(-) create mode 100644 src/components/ContextMenu.jsx delete mode 100644 src/externals/jsd-report.js delete mode 100644 src/views/reports/report-builder/JQLEditorDialog.jsx delete mode 100644 src/views/reports/report-builder/ReportBuilder.jsx delete mode 100644 src/views/reports/report-builder/ReportBuilder.scss delete mode 100644 src/views/reports/report-builder/ReportViewer.jsx delete mode 100644 src/views/reports/report-builder/ReportViewer.scss diff --git a/jsconfig.json b/jsconfig.json index 6d06daee..576fc636 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -2,9 +2,6 @@ "compilerOptions": { "baseUrl": "./", "paths": { - "js-report-builder/*": [ - "./node_modules/js-report-builder/src/lib/*" - ], "react-controls/*": [ "./node_modules/react-controls/src/*" ], diff --git a/package.json b/package.json index e156b960..36c5e97a 100644 --- a/package.json +++ b/package.json @@ -70,12 +70,11 @@ "electron-about-window": "^1.15.2", "electron-is-dev": "^3.0.1", "electron-updater": "^6.1.8", - "espree": "^9.6.1", + "espree": "^10.3.0", "exceljs": "^4.4.0", - "firebase": "^10.12.0", + "firebase": "^11.1.0", "jquery": "^3.7.1", "js-sql-parser": "^1.6.0", - "jsd-report": "^0.1.11", "jspdf": "github:shridhar-tl/jsPDF", "jspdf-autotable": "^3.8.2", "moment": "^2.30.1", @@ -83,15 +82,15 @@ "papaparse": "^5.4.1", "patternomaly": "^1.3.2", "primeflex": "^3.3.1", - "primeicons": "^6.0.1", + "primeicons": "^7.0.0", "primereact": "^9.6.4", "queue": "^7.0.0", "rc-time-picker": "^3.7.3", "react": "^18.3.1", "react-bootstrap-daterangepicker": "^8.0.0", "react-controls": "github:shridhar-tl/react-controls", - "react-dnd": "^14.0.4", - "react-dnd-html5-backend": "^14.0.2", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", "react-router-dom": "^6.23.1", "react-scripts": "github:shridhar-tl/react-scripts", @@ -211,11 +210,6 @@ ] }, "aliases": { - "js-report-builder": [ - "externals/js-report-builder/src/lib", - "node_modules/js-report-builder/src/lib", - "node_modules/jsd-report/build" - ], "react-controls": [ "externals/react-controls/src/", "node_modules/react-controls/src/" @@ -224,4 +218,4 @@ "node_modules/jspdf/dist/" ] } -} \ No newline at end of file +} diff --git a/src/_nav.js b/src/_nav.js index 858a644d..36850952 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -24,14 +24,14 @@ const { dashboards, calendar, importWorklog, importIssues, planningPoker, // Reports - worklogReport, worklogReportOld, sprintReport, customReport, estimateVsActual, reportBuilder, pivotReport, sayDoRatioReport, + worklogReport, worklogReportOld, sprintReport, customReport, estimateVsActual, pivotReport, sayDoRatioReport, // Settings userGroups, generalSettings, advancedSettings, // Menu groups activitiesGroup = calendar || importWorklog || importIssues || planningPoker, - reportsGroup = worklogReport || worklogReportOld || sprintReport || customReport || estimateVsActual || reportBuilder, + reportsGroup = worklogReport || worklogReportOld || sprintReport || customReport || estimateVsActual, settingsGroup = userGroups || generalSettings || advancedSettings } = config.modules; @@ -138,16 +138,6 @@ const navigation = [ id: 'R-EA', url: '/reports/estimateactual', icon: 'fa fa-bar-chart' - }, - reportBuilder && { - name: 'Report Builder', - id: 'R-CG', - url: '/reports/advanced', - icon: 'fa fa-table', - badge: { - variant: 'danger', - text: 'DEPR' - } } ].filter(Boolean) }, diff --git a/src/common/jsExec.js b/src/common/jsExec.js index 1f7a03f1..cdacd0c2 100644 --- a/src/common/jsExec.js +++ b/src/common/jsExec.js @@ -9,68 +9,6 @@ const parserOptions = { } }; -export default function compileExpression(expression, props, { array, getObjVal, sandbox: exclude }) { - if (props?.$this) { - expression = `(function () { return ${expression};}).call(_$this_)`; - } - - const env = {}; - - if (props?.$this) { - env._$this_ = props?.$this; - } - - const ast = parse(expression, parserOptions)?.body[0]; - - const valueFunc = function () { - return exec(ast, env); - }; - - const isNoWrap = props?.noWrap === true; - let wrapFunction = null; - if (!isNoWrap) { - - wrapFunction = function (Fields, RowGroup, ColGroup, Variables) { - env.Fields = Fields; - env.RowGroup = RowGroup; - env.ColGroup = ColGroup; - env.Variables = Variables; - - env.Field = function (key) { - return getObjVal(Fields, key); - }; - - return valueFunc(); - }; - } - - let funcToReturn = function (CommonFunctions, MyFunctions, Parameters, Datasets, array, getObjVal, ReportState, setReportState) { - env.CommonFunctions = CommonFunctions; - env.MyFunctions = MyFunctions; - env.Parameters = Parameters; - env.Datasets = Datasets; - env.array = array; - env.getObjVal = getObjVal; - env.ReportState = ReportState; - env.setReportState = setReportState; - - if (isNoWrap) { - return valueFunc(); - } - else { - return wrapFunction; - } - }; - - if (props) { - const { commonFunctions, myFunctions, parameters, datasets, setReportState, getReportState } = props; - - funcToReturn = funcToReturn(commonFunctions, myFunctions, parameters, datasets, array, getObjVal, getReportState, setReportState); - } - - return funcToReturn; -} - export function parseCustExpr(expression) { if (expression.indexOf('\n') > -1) { expression = `(function () { ${expression} }).call(this)`; diff --git a/src/components/ContextMenu.jsx b/src/components/ContextMenu.jsx new file mode 100644 index 00000000..b9604f19 --- /dev/null +++ b/src/components/ContextMenu.jsx @@ -0,0 +1,57 @@ +import React, { PureComponent } from 'react'; +import { Menu } from 'primereact/menu'; +import { ContextMenu as CMenu } from 'primereact/contextmenu'; + +let contextHandler = () => { /* Nothing to do */ }; +export function showContextMenu(event, model) { + if (event.preventDefault) { + event.preventDefault(); + } + contextHandler(event, model); +} + +export function hideContextMenu() { + contextHandler(); +} + +export class ContextMenu extends PureComponent { + state = { contextItems: [] }; + + componentDidMount() { + contextHandler = (event, contextItems) => { + if (!event) { + this.menu.hide({}); + this.contextMenu.hide({}); + return; + } + const isContextMenu = event.type === "contextmenu"; + + if (!isContextMenu) { + contextItems = contextItems.filter(c => !c.disabled || !c.items || c.items.length === 0); + } + + if (!this.state.contextItems?.length || this.state.contextItems !== contextItems) { + this.setState({ contextItems }); + } + + if (isContextMenu) { + this.menu.hide({}); + this.contextMenu.show(event); + } + else { + this.contextMenu.hide({}); + this.menu.toggle(event); + } + }; + } + + setMenuRef = el => this.menu = el; + setContextMenuRef = el => this.contextMenu = el; + + render() { + return <> + + + ; + } +} \ No newline at end of file diff --git a/src/components/GroupableGrid/GroupedColumnList.jsx b/src/components/GroupableGrid/GroupedColumnList.jsx index 18145447..bf98eb04 100644 --- a/src/components/GroupableGrid/GroupedColumnList.jsx +++ b/src/components/GroupableGrid/GroupedColumnList.jsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { Sortable } from '../../controls'; import PropTypes from 'prop-types'; -import { showContextMenu } from '../../externals/jsd-report'; +import { showContextMenu } from '../ContextMenu'; const emptyGroupPlaceholder = Drag and drop column here to group data; const addGroupItemPlaceholder = Drag and drop more columns here; diff --git a/src/customize.js b/src/customize.js index dc690197..72867b7b 100644 --- a/src/customize.js +++ b/src/customize.js @@ -18,7 +18,6 @@ const config = { sprintReport: !isPluginBuild, customReport: true, estimateVsActual: true, - reportBuilder: true, // Settings userGroups: true, diff --git a/src/display-controls/TicketDisplay.jsx b/src/display-controls/TicketDisplay.jsx index 63f6c57d..41902435 100644 --- a/src/display-controls/TicketDisplay.jsx +++ b/src/display-controls/TicketDisplay.jsx @@ -1,7 +1,7 @@ import React from 'react'; import { inject } from '../services/injector-service'; import BaseControl from './BaseControl'; -import { showContextMenu } from '../externals/jsd-report'; +import { showContextMenu } from '../components/ContextMenu'; import { WorklogContext } from '../common/context'; import Link from '../controls/Link'; diff --git a/src/electron/menu.js b/src/electron/menu.js index 16c92f2a..bc9f2527 100644 --- a/src/electron/menu.js +++ b/src/electron/menu.js @@ -49,8 +49,7 @@ module.exports = function (window, basePath) { getMenu('Worklog report', '/reports/userdaywise'), getMenu('Sprint report', '/reports/sprint'), getMenu('Custom report', '/reports/custom'), - getMenu('Estimate vs Actual', '/reports/estimateactual'), - getMenu('Report builder', '/reports/advanced') + getMenu('Estimate vs Actual', '/reports/estimateactual') ] }, // { role: 'windowMenu' } diff --git a/src/externals/jsd-report.js b/src/externals/jsd-report.js deleted file mode 100644 index 759753b1..00000000 --- a/src/externals/jsd-report.js +++ /dev/null @@ -1,4 +0,0 @@ -import { ReportBuilder, ReportViewer, initReportBuilder, ContextMenu, showContextMenu, hideContextMenu, Table } from 'jsd-report'; -import 'jsd-report/build/css/style.css'; - -export { ReportBuilder, ReportViewer, initReportBuilder, ContextMenu, showContextMenu, hideContextMenu, Table }; diff --git a/src/gadgets/BaseGadget.jsx b/src/gadgets/BaseGadget.jsx index 77c281c7..2245fd2a 100644 --- a/src/gadgets/BaseGadget.jsx +++ b/src/gadgets/BaseGadget.jsx @@ -4,7 +4,7 @@ import { Tooltip } from 'primereact/tooltip'; import { EventEmitter } from 'events'; import { Button, Loader } from '../controls'; import classNames from 'classnames'; -import { showContextMenu } from '../externals/jsd-report'; +import { showContextMenu } from '../components/ContextMenu'; import { ExportHelper } from '../common/ExportHelper'; import { ExportFormat } from '../common/Exporter'; import { GadgetActionType } from './_constants'; diff --git a/src/gadgets/Calendar/Calendar.jsx b/src/gadgets/Calendar/Calendar.jsx index 4e7a154b..54d57a19 100644 --- a/src/gadgets/Calendar/Calendar.jsx +++ b/src/gadgets/Calendar/Calendar.jsx @@ -12,7 +12,7 @@ import { inject } from '../../services/injector-service'; import { GadgetActionType } from '../_constants'; import { Button } from '../../controls'; import SelectBox from '../../controls/SelectBox'; -import { hideContextMenu, showContextMenu } from '../../externals/jsd-report'; +import { hideContextMenu, showContextMenu } from '../../components/ContextMenu'; import AddWorklog from '../../dialogs/AddWorklog'; import { OverlayPanel } from 'primereact/overlaypanel'; import MeetingDetails from './MeetingDetails'; diff --git a/src/gadgets/DateWiseWorklog.jsx b/src/gadgets/DateWiseWorklog.jsx index ac895d1a..b7575ec9 100644 --- a/src/gadgets/DateWiseWorklog.jsx +++ b/src/gadgets/DateWiseWorklog.jsx @@ -3,7 +3,7 @@ import BaseGadget, { GadgetActionType } from './BaseGadget'; import { inject } from '../services'; import moment from 'moment'; import { DatePicker } from '../controls'; -import { showContextMenu } from '../externals/jsd-report'; +import { showContextMenu } from '../components/ContextMenu'; import ChangeTracker from '../components/ChangeTracker'; import { WorklogContext } from '../common/context'; import UserDateWiseWorklog from '../components/shared/UserDateWiseWorklog'; diff --git a/src/gadgets/Gadget.jsx b/src/gadgets/Gadget.jsx index 2588369a..7cdc7e90 100644 --- a/src/gadgets/Gadget.jsx +++ b/src/gadgets/Gadget.jsx @@ -4,7 +4,7 @@ import { Tooltip } from 'primereact/tooltip'; //import { EventEmitter } from 'events'; import { Button, Loader } from '../controls'; import classNames from 'classnames'; -import { showContextMenu } from '../externals/jsd-report'; +import { showContextMenu } from '../components/ContextMenu'; import { ExportHelper } from '../common/ExportHelper'; import { ExportFormat } from '../common/Exporter'; import { GadgetActionType } from './_constants'; diff --git a/src/gadgets/MyBookmarks.jsx b/src/gadgets/MyBookmarks.jsx index fe6f84d7..af4fbc89 100644 --- a/src/gadgets/MyBookmarks.jsx +++ b/src/gadgets/MyBookmarks.jsx @@ -2,7 +2,7 @@ import React from 'react'; import BaseGadget from './BaseGadget'; import { GadgetActionType } from '.'; import { ScrollableTable, THead, TBody, Column, NoDataRow } from '../components/ScrollableTable'; -import { showContextMenu } from '../externals/jsd-report'; +import { showContextMenu } from '../components/ContextMenu'; import { inject } from '../services/injector-service'; import { Button, Checkbox, Image } from '../controls'; import AddBookmark from '../dialogs/AddBookmark'; diff --git a/src/gadgets/MyOpenTickets.jsx b/src/gadgets/MyOpenTickets.jsx index 22be0d6f..a68ac9c8 100644 --- a/src/gadgets/MyOpenTickets.jsx +++ b/src/gadgets/MyOpenTickets.jsx @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { inject } from '../services/injector-service'; import BaseGadget, { GadgetActionType } from './BaseGadget'; import { ScrollableTable, THead, TBody, Column, NoDataRow } from '../components/ScrollableTable'; -import { showContextMenu } from '../externals/jsd-report'; +import { showContextMenu } from '../components/ContextMenu'; import { TicketDisplay } from '../display-controls'; import { Image } from '../controls'; diff --git a/src/gadgets/PendingWorklog.jsx b/src/gadgets/PendingWorklog.jsx index 989d14db..9b402113 100644 --- a/src/gadgets/PendingWorklog.jsx +++ b/src/gadgets/PendingWorklog.jsx @@ -2,7 +2,7 @@ import React from 'react'; import BaseGadget, { GadgetActionType } from './BaseGadget'; import { ScrollableTable, THead, TBody, Column, NoDataRow } from '../components/ScrollableTable'; import { inject } from '../services/injector-service'; -import { showContextMenu } from '../externals/jsd-report'; +import { showContextMenu } from '../components/ContextMenu'; import { Button, Checkbox } from '../controls'; import Dialog from '../dialogs'; import ChangeTracker from '../components/ChangeTracker'; diff --git a/src/gadgets/TicketWiseWorklog.jsx b/src/gadgets/TicketWiseWorklog.jsx index 4aedf30f..f778108f 100644 --- a/src/gadgets/TicketWiseWorklog.jsx +++ b/src/gadgets/TicketWiseWorklog.jsx @@ -2,7 +2,7 @@ import React from 'react'; import * as moment from 'moment'; import BaseGadget from './BaseGadget'; import { inject } from '../services'; -import { showContextMenu } from '../externals/jsd-report'; +import { showContextMenu } from '../components/ContextMenu'; import { ScrollableTable, THead, TBody, NoDataRow, Column } from '../components/ScrollableTable'; import { DatePicker } from '../controls'; import { DateDisplay } from '../display-controls'; diff --git a/src/layouts/DefaultLayout/DefaultLayout.jsx b/src/layouts/DefaultLayout/DefaultLayout.jsx index 142e7d9f..882f939c 100644 --- a/src/layouts/DefaultLayout/DefaultLayout.jsx +++ b/src/layouts/DefaultLayout/DefaultLayout.jsx @@ -3,7 +3,7 @@ import Dialog from "../../dialogs"; // sidebar nav config import navigation, { getDashboardMenu } from '../../_nav'; import { inject } from '../../services/injector-service'; -import { ContextMenu } from '../../externals/jsd-report'; +import { ContextMenu } from '../../components/ContextMenu'; import { setStartOfWeek } from '../../common/utils'; import { WorklogContextProvider } from '../../common/context'; import { isWebBuild, redirectToRoute } from '../../constants/build-info'; diff --git a/src/layouts/DefaultLayout/LaunchWeb.jsx b/src/layouts/DefaultLayout/LaunchWeb.jsx index 49bb7d6f..973b8bed 100644 --- a/src/layouts/DefaultLayout/LaunchWeb.jsx +++ b/src/layouts/DefaultLayout/LaunchWeb.jsx @@ -3,7 +3,7 @@ import { isExtnBuild, isWebBuild } from '../../constants/build-info'; import { JAWebLaunchUrl } from '../../constants/urls'; import { withRouter } from '../../pollyfills'; import { inject } from '../../services/injector-service'; -import { showContextMenu } from 'src/externals/jsd-report'; +import { showContextMenu } from 'src/components/ContextMenu'; import { Button } from '../../controls'; const options = isWebBuild ? { diff --git a/src/layouts/DefaultLayout/header/HeaderRight.jsx b/src/layouts/DefaultLayout/header/HeaderRight.jsx index 139606bd..2f470b38 100644 --- a/src/layouts/DefaultLayout/header/HeaderRight.jsx +++ b/src/layouts/DefaultLayout/header/HeaderRight.jsx @@ -25,7 +25,7 @@ function HeaderRight(props) { } = props; const { version, isBeta } = notifications?.updatesAvailable || {}; return (<> -
    +
      {allowWebVersion && !isAppBuild && !isQuickView && } {!!version && import('./views/reports/sprint-report/SprintReport')); const WorklogReportComponent = config.modules.worklogReportOld && React.lazy(() => import('./views/reports/worklog-report/WorklogReport')); const NewWorklogReportComponent = config.modules.worklogReport && React.lazy(() => import('./views/reports/worklog-report/NewWorklogReport')); -const ReportBuilderComponent = config.modules.reportBuilder && React.lazy(() => import('./views/reports/report-builder/ReportBuilder')); // Settings const GeneralSettingsComponent = config.modules.generalSettings && React.lazy(() => import('./views/settings/general/GeneralSettings')); @@ -79,14 +78,6 @@ const sessionBasedRoute = [ path: '/reports/custom', component: CustomReportComponent }, - ReportBuilderComponent && { - path: '/reports/advanced/:reportId', - component: ReportBuilderComponent - }, - ReportBuilderComponent && { - path: '/reports/advanced', - component: ReportBuilderComponent - }, ImportWorklogComponent && { path: '/import/worklog', component: ImportWorklogComponent diff --git a/src/services/base-service.d.ts b/src/services/base-service.d.ts index cd64bd30..acfc522f 100644 --- a/src/services/base-service.d.ts +++ b/src/services/base-service.d.ts @@ -47,7 +47,6 @@ export default class BaseService { $outlook: OutlookCalendar $q: QueueService $report: ReportService - $reportConfig: ReportConfigService $session: SessionService $settings: SettingsService $storage: StorageService diff --git a/src/services/index.d.ts b/src/services/index.d.ts index 19f6716e..664ecad5 100644 --- a/src/services/index.d.ts +++ b/src/services/index.d.ts @@ -56,7 +56,6 @@ export interface IServicesList { $outlook: OutlookCalendar $q: QueueService $report: ReportService - $reportConfig: ReportConfigService $session: SessionService $settings: SettingsService $sprint: SprintService diff --git a/src/services/index.register.js b/src/services/index.register.js index a04c1fbf..62c57894 100644 --- a/src/services/index.register.js +++ b/src/services/index.register.js @@ -17,7 +17,6 @@ import OutlookOAuthService from './outlook-oauth-service'; import OutlookCalendar from './outlook-service'; import QueueService from './queue-service'; import ReportService from './report-service'; -import ReportConfigService from './reportconfig-service'; import SessionService from './session-service'; import TicketService from './ticket-service'; import UserService from './user-service'; @@ -66,7 +65,6 @@ export default function registerServices() { injectable(OutlookCalendar, "OutlookService", "$outlook"); injectable(QueueService, "QueueService", "$q", { isSingleton: false }); injectable(ReportService, "ReportService", "$report"); - injectable(ReportConfigService, "ReportConfigService", "$reportConfig"); injectable(SessionService, "SessionService", "$session"); injectable(SettingsService, "SettingsService", "$settings", { isSingleton: true }); injectable(SprintService, "SprintService", "$sprint"); diff --git a/src/services/injector-service.d.ts b/src/services/injector-service.d.ts index 3810f143..9f15e9c5 100644 --- a/src/services/injector-service.d.ts +++ b/src/services/injector-service.d.ts @@ -54,7 +54,6 @@ export interface IServicesList { $outlook: OutlookCalendar $q: QueueService $report: ReportService - $reportConfig: ReportConfigService $session: SessionService $settings: SettingsService $storage: StorageService diff --git a/src/services/reportconfig-service.js b/src/services/reportconfig-service.js index 8e7bafbf..c11fe25c 100644 --- a/src/services/reportconfig-service.js +++ b/src/services/reportconfig-service.js @@ -1,5 +1,5 @@ import React from 'react'; -import { initReportBuilder } from '../externals/jsd-report'; +import { initReportBuilder } from '../components/ContextMenu'; import EventEmitter from 'events'; import { GadgetActionType } from '../gadgets/_constants'; import { getUserName } from '../common/utils'; @@ -21,29 +21,14 @@ export default class ReportConfigService { this.eventPipe = new EventEmitter(); } - hasScriptExecPermission() { - try { - // eslint-disable-next-line no-new-func - return !!Function("return true")(); - } catch { - // eslint-disable-next-line no-console - console.log("Jira Assistant is not granted permission for executing expressions. Hence some dynamic expressions in Report Builder will not work."); - return false; - } - } - configureReport() { if (this.isConfigured) { return; } - const selfHandleScriptExecution = !this.hasScriptExecPermission(); + const selfHandleScriptExecution = true; - const compiler = selfHandleScriptExecution ? exec : - function (code, sandbox) { - // eslint-disable-next-line no-new-func - return Function(...sandbox, code)(); - }; + const compiler = exec; const { dateFormat, timeFormat, jiraUrl } = this.$session.CurrentUser; const dateTimeFormat = `${dateFormat} ${timeFormat}`; diff --git a/src/views/dashboard/Dashboard.jsx b/src/views/dashboard/Dashboard.jsx index 5b907885..763470f2 100644 --- a/src/views/dashboard/Dashboard.jsx +++ b/src/views/dashboard/Dashboard.jsx @@ -10,7 +10,6 @@ import AddGadget from './AddGadget'; import AddWorklog from '../../dialogs/AddWorklog'; import BaseGadget, { onDashboardEvent } from '../../gadgets/BaseGadget'; import CustomReport from '../reports/custom-groupable/ReportViewer'; -import AdvancedReport from '../reports/report-builder/ReportViewer'; import { Sortable } from '../../controls'; import './Dashboard.scss'; @@ -227,7 +226,6 @@ function getGadgetsList() { listWeek: { title: "Calendar", control: Calendar, getProps: () => ({ viewMode: "listWeek" }) }, listMonth: { title: "Calendar", control: Calendar, getProps: () => ({ viewMode: "listMonth" }) }, CR: { title: "Custom report", control: CustomReport, getProps: (sett, opts) => ({ reportId: parseInt(opts[0]), title: opts[1] }) }, - AR: { title: "Advanced report", control: AdvancedReport, getProps: (sett, opts) => ({ reportId: parseInt(opts[0]), title: opts[1] }) }, }; controls.myBookmarks = controls.bookmarksList; diff --git a/src/views/dashboard/Header.jsx b/src/views/dashboard/Header.jsx index 492670de..dd26b86b 100644 --- a/src/views/dashboard/Header.jsx +++ b/src/views/dashboard/Header.jsx @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { Button } from '../../controls'; import DashboardName from './DashboardName'; import { inject } from '../../services/injector-service'; -import { showContextMenu } from '../../externals/jsd-report'; +import { showContextMenu } from '../../components/ContextMenu'; class Header extends PureComponent { constructor(props) { diff --git a/src/views/pages/integrate/Integrate.jsx b/src/views/pages/integrate/Integrate.jsx index 2ac50d32..cfa5f30a 100644 --- a/src/views/pages/integrate/Integrate.jsx +++ b/src/views/pages/integrate/Integrate.jsx @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; import browser from '../../../common/browsers'; -import { showContextMenu, ContextMenu } from '../../../externals/jsd-report'; +import { showContextMenu, ContextMenu } from '../../../components/ContextMenu'; import { inject } from '../../../services'; import { Button, TextBox } from '../../../controls'; import { ApiUrls } from '../../../constants/api-urls'; diff --git a/src/views/reports/pivot-report/editor/body/index.jsx b/src/views/reports/pivot-report/editor/body/index.jsx index 73e55df9..c9104648 100644 --- a/src/views/reports/pivot-report/editor/body/index.jsx +++ b/src/views/reports/pivot-report/editor/body/index.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import { useShallow } from 'zustand/react/shallow'; import GroupTable from './group-table'; import { updateParameters, usePivotConfig, useReportData } from '../../store/pivot-config'; import ReportInfo from './ReportInfo'; @@ -7,9 +8,9 @@ import { Button } from 'react-controls/controls'; import { generateReport } from '../../viewer/generator'; function EditorBody() { - const { hasReportData, reportErrors, isFetching, showParameters } = useReportData(({ + const { hasReportData, reportErrors, isFetching, showParameters } = useReportData(useShallow(({ reportData, reportErrors, isFetching, showParameters - }) => ({ hasReportData: !!reportData, reportErrors, isFetching, showParameters })); + }) => ({ hasReportData: !!reportData, reportErrors, isFetching, showParameters }))); if (isFetching) { return (
      diff --git a/src/views/reports/pivot-report/editor/controls/index.jsx b/src/views/reports/pivot-report/editor/controls/index.jsx index 906a1ebc..fc24095f 100644 --- a/src/views/reports/pivot-report/editor/controls/index.jsx +++ b/src/views/reports/pivot-report/editor/controls/index.jsx @@ -11,6 +11,7 @@ import { updateJQL, updateDataSourceType, usePivotConfig, useSelectedItem } from import ControlButtons from './ControlButtons'; import useToggler from 'react-controls/hooks/useToggler'; import './Controls.scss'; +import { useShallow } from 'zustand/react/shallow'; function EditorControls({ show, onHide, reportId }) { const [showSource, toggleSource] = useToggler(!reportId); @@ -30,7 +31,7 @@ function EditorControls({ show, onHide, reportId }) { export default EditorControls; function Source({ onDone }) { - const { jql, dataSourceType } = usePivotConfig(({ jql, dataSourceType }) => ({ jql, dataSourceType })); + const { jql, dataSourceType } = usePivotConfig(useShallow(({ jql, dataSourceType }) => ({ jql, dataSourceType }))); return (

      diff --git a/src/views/reports/pivot-report/index.jsx b/src/views/reports/pivot-report/index.jsx index f43d2a0b..ecda64d0 100644 --- a/src/views/reports/pivot-report/index.jsx +++ b/src/views/reports/pivot-report/index.jsx @@ -20,7 +20,8 @@ function PivotReport() { }, [reportId]); const isLoading = useReportData(({ isFetching }) => isFetching); - const { queryName: reportName, parameters } = usePivotConfig(({ queryName, parameters }) => ({ queryName, parameters })); + const reportName = usePivotConfig(({ queryName }) => queryName); + const parameters = usePivotConfig(({ parameters }) => parameters); const hasParams = parameters && Object.keys(parameters).length > 0; diff --git a/src/views/reports/report-builder/JQLEditorDialog.jsx b/src/views/reports/report-builder/JQLEditorDialog.jsx deleted file mode 100644 index d18d4893..00000000 --- a/src/views/reports/report-builder/JQLEditorDialog.jsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; -import BaseDialog from '../../../dialogs/BaseDialog'; -import { Button } from '../../../controls'; -import QueryEditor from '../custom-report/QueryEditor'; -import { inject } from '../../../services/injector-service'; - -class JQLEditorDialog extends BaseDialog { - constructor(props) { - super(props, "Select dataset fields"); - inject(this, "JiraService", "ReportConfigService"); - - this.style = { width: "900px" }; - const { filterQuery } = props; - this.state = { showDialog: true, filterQuery }; - } - - onDone = () => { - const query = this.state.filterQuery; - - this.$jira.searchTickets(this.$reportConfig.prepareJQL(query.jql), query.outputFields.map(f => f.id)) - .then(data => this.props.onResolve(query, data)); - }; - - queryChanged = (filterQuery) => this.setState({ filterQuery }); - - getFooter() { - let isSaveEnabled = false; - - if (this.editorInstance) { - isSaveEnabled = this.editorInstance.isSaveEnabled(); - } - - return <> -

      } - -
      -
      -
      ; - } - - hideDatasetPopup = () => this.setState({ selectedDatasetType: null }); - - render() { - const { - state: { reportDefinition, reportMode, showSaveDialog, selectedDatasetType } - } = this; - - const isEditing = reportDefinition.id > 0; - - if (reportMode) { - return ; - } - else { - return super.renderBase(<> - {reportDefinition && } - {showSaveDialog && } - {selectedDatasetType === 'JQL' && } - - ); - } - } -} - -export default ReportBuilder; \ No newline at end of file diff --git a/src/views/reports/report-builder/ReportBuilder.scss b/src/views/reports/report-builder/ReportBuilder.scss deleted file mode 100644 index c989a0ba..00000000 --- a/src/views/reports/report-builder/ReportBuilder.scss +++ /dev/null @@ -1,17 +0,0 @@ -.report-builder { - height: calc(100vh - 152px) !important; - - .report-controls-cntr { - width: 265px !important; - } - - .report-display-cntr { - width: calc(100% - 267px) !important; - overflow: auto; - } - - // This style is to remove the gadget specific overrides - .p-panel-content { - height: auto !important; - } -} \ No newline at end of file diff --git a/src/views/reports/report-builder/ReportViewer.jsx b/src/views/reports/report-builder/ReportViewer.jsx deleted file mode 100644 index 1bfd8fc4..00000000 --- a/src/views/reports/report-builder/ReportViewer.jsx +++ /dev/null @@ -1,116 +0,0 @@ -import React from 'react'; -import BaseGadget from '../../../gadgets/BaseGadget'; -import { inject } from '../../../services'; -import { Button } from '../../../controls'; -import { ReportViewer as JSRViewer } from '../../../externals/jsd-report'; -import GroupEditor from '../../../dialogs/GroupEditor'; -import "./ReportViewer.scss"; -import AddWorklog from '../../../dialogs/AddWorklog'; -import { EventCategory } from '../../../constants/settings'; - -class ReportViewer extends BaseGadget { - constructor(props) { - super(props, 'Advanced report viewer', 'fa-clock'); - inject(this, "ReportConfigService", "AnalyticsService", "ReportService"); - - this.viewer = {}; - - this.$reportConfig.configureViewer(); - - this.$reportConfig.parameters.removeAllListeners(); - this.$reportConfig.parameters.on("click", this.parameterClicked.bind(this)); - this.$reportConfig.eventPipe.on("addWorklog", this.addWorklog.bind(this)); - const { definition } = props; - this.state.definition = definition; - } - - componentDidMount() { - super.componentDidMount(); - this.refreshData(); - } - - UNSAFE_componentWillReceiveProps(props) { - if (props.definition) { - this.setReportDefinition(props.definition); - } else if (props.reportId) { - this.refreshData(); - } - else { - this.setReportDefinition({}); - } - } - - addWorklog(data) { - if (this.isGadget) { - super.addWorklog(data); - } - else { - this.worklogItem = data; - this.setState({ showWorklogPopup: true }); - } - } - - parameterClicked(e) { - this.parameterEvent = e; - this.setState({ showGroupsPopup: true }); - } - - usersSelected = (groups) => { - this.parameterEvent.onChange(this.parameterEvent.definition, groups); - this.parameterEvent = null; - this.setState({ showGroupsPopup: false, groups }); - }; - - refreshData = () => { - if (this.props.reportId > 0) { - this.$report.getReportDefinition(this.props.reportId).then(qm => { - this.setReportDefinition(qm); - this.$analytics.trackEvent("Advanced report viewed", EventCategory.UserActions); - }); - } - else if (this.state.definition) { - this.title = this.state.definition.queryName; - this.$analytics.trackEvent("Advanced report viewed", EventCategory.UserActions); - } - }; - - setReportDefinition(definition) { - if (definition && definition.queryName) { - this.title = definition.queryName; - } - - this.setState({ definition }); - } - - getApi = (api) => this.viewer = api; - - worklogAdded = (result) => { - // ToDo: - this.hideWorklog(); - }; - - hideWorklog = () => { - this.setState({ showWorklogPopup: false }); - }; - - renderCustomActions() { - return <> - {!this.isGadget &&