From a9b6d098e930ad581c98a3e531a41b595889aaab Mon Sep 17 00:00:00 2001 From: Alex Khomenko Date: Mon, 12 May 2025 12:38:26 +0300 Subject: [PATCH] Chore: Add eslint no-restricted-globals rule (#104519) * Chore: Add no-restricted-globals eslint rule * Fix eslint warnings * Revert some changes * Update * Feedback --- eslint.config.js | 2 ++ package.json | 2 ++ .../PromQueryCodeEditorAutocompleteInfo.tsx | 4 ++-- .../src/components/Table/TableNG/TableNG.tsx | 4 ++-- public/app/app.ts | 2 +- public/app/core/monacoEnv.ts | 2 ++ public/app/core/services/mousetrap/Mousetrap.ts | 1 + .../components/rule-viewer/AlertRuleMenu.tsx | 2 +- .../ConfirmVersionRestoreModal.tsx | 2 +- .../unified/components/rules/GrafanaRules.tsx | 2 +- .../rules/RuleDetailsMatchingInstances.tsx | 6 +++++- .../ConfirmRestoreDeletedRuleModal.tsx | 2 +- .../alerting/unified/rule-list/RuleList.v1.tsx | 2 +- public/app/features/apiserver/client.ts | 2 +- .../saving/DetectChangesWorker.ts | 3 +++ .../dashboard-scene/scene/DashboardControls.tsx | 4 ++-- .../dashboard-scene/scene/PanelMenuBehavior.tsx | 2 +- .../dashboard-scene/sharing/ShareLinkTab.tsx | 2 +- .../app/features/dashboard/utils/getPanelMenu.ts | 2 +- .../components/DataSourceAddButton.tsx | 2 +- .../components/DataSourceCategories.tsx | 2 +- .../components/DataSourceLoadError.tsx | 2 +- .../components/DataSourceTestingStatus.tsx | 2 +- .../components/DataSourcesListCard.tsx | 4 ++-- .../components/EditDataSourceActions.tsx | 4 ++-- .../features/datasources/state/actions.test.ts | 2 +- public/app/features/datasources/state/actions.ts | 2 +- .../explore/NodeGraph/NodeGraphContainer.tsx | 2 +- .../components/Essentials.tsx | 4 ++-- .../gops/configuration-tracker/irmHooks.ts | 2 +- .../GetStartedWithPlugin/GetStartedWithApp.tsx | 4 ++-- .../plugins/admin/components/UpdateAllButton.tsx | 2 +- .../plugins/admin/components/UpdateAllModal.tsx | 4 ++-- .../admin/components/VersionInstallButton.tsx | 2 +- .../sandbox/sandbox_plugin_loader_registry.ts | 3 ++- public/app/features/search/service/searcher.ts | 2 +- .../serviceaccounts/ServiceAccountTable.tsx | 2 +- .../panel/nodeGraph/layeredLayout.worker.js | 1 + .../app/plugins/panel/nodeGraph/layout.worker.js | 1 + public/swagger/SwaggerPage.tsx | 2 +- yarn.lock | 16 ++++++++++++++++ 41 files changed, 74 insertions(+), 41 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 99d651e1819..bae736ad3d4 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,6 @@ // @ts-check const emotionPlugin = require('@emotion/eslint-plugin'); +const restrictedGlobals = require('confusing-browser-globals'); const importPlugin = require('eslint-plugin-import'); const jestPlugin = require('eslint-plugin-jest'); const jestDomPlugin = require('eslint-plugin-jest-dom'); @@ -136,6 +137,7 @@ module.exports = [ ], }, ], + 'no-restricted-globals': ['error'].concat(restrictedGlobals), // Use typescript's no-redeclare for compatibility with overrides 'no-redeclare': 'off', diff --git a/package.json b/package.json index d18601eb07f..cf9ae50a9ef 100644 --- a/package.json +++ b/package.json @@ -108,6 +108,7 @@ "@types/babel__preset-env": "^7", "@types/chance": "^1.1.3", "@types/common-tags": "^1.8.0", + "@types/confusing-browser-globals": "^1", "@types/d3": "7.4.3", "@types/d3-force": "^3.0.0", "@types/d3-scale-chromatic": "3.1.0", @@ -166,6 +167,7 @@ "chance": "^1.0.10", "chrome-remote-interface": "0.33.2", "codeowners": "^5.1.1", + "confusing-browser-globals": "^1.0.11", "copy-webpack-plugin": "12.0.2", "core-js": "3.40.0", "crashme": "0.0.15", diff --git a/packages/grafana-prometheus/src/querybuilder/components/PromQueryCodeEditorAutocompleteInfo.tsx b/packages/grafana-prometheus/src/querybuilder/components/PromQueryCodeEditorAutocompleteInfo.tsx index fb0707a3dfa..7854d8a8d6e 100644 --- a/packages/grafana-prometheus/src/querybuilder/components/PromQueryCodeEditorAutocompleteInfo.tsx +++ b/packages/grafana-prometheus/src/querybuilder/components/PromQueryCodeEditorAutocompleteInfo.tsx @@ -34,10 +34,10 @@ export function PromQueryCodeEditorAutocompleteInfo(props: Readonly) { ); useEffect(() => { - addEventListener(CODE_MODE_SUGGESTIONS_INCOMPLETE_EVENT, handleSuggestionsIncompleteEvent); + window.addEventListener(CODE_MODE_SUGGESTIONS_INCOMPLETE_EVENT, handleSuggestionsIncompleteEvent); return () => { - removeEventListener(CODE_MODE_SUGGESTIONS_INCOMPLETE_EVENT, handleSuggestionsIncompleteEvent); + window.removeEventListener(CODE_MODE_SUGGESTIONS_INCOMPLETE_EVENT, handleSuggestionsIncompleteEvent); }; }, [handleSuggestionsIncompleteEvent]); diff --git a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx index 2077097f1f0..41ddfa126b2 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx +++ b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx @@ -159,10 +159,10 @@ export function TableNG(props: TableNGProps) { setIsContextMenuOpen(false); } - addEventListener('click', onClick); + window.addEventListener('click', onClick); return () => { - removeEventListener('click', onClick); + window.removeEventListener('click', onClick); }; }, [isContextMenuOpen]); diff --git a/public/app/app.ts b/public/app/app.ts index 8ac26cad2f1..6244e79df41 100644 --- a/public/app/app.ts +++ b/public/app/app.ts @@ -122,7 +122,7 @@ export class GrafanaApp { try { await preInitTasks(); // Let iframe container know grafana has started loading - parent.postMessage('GrafanaAppInit', '*'); + window.parent.postMessage('GrafanaAppInit', '*'); const initI18nPromise = initializeI18n(config.bootData.user.language); initI18nPromise.then(({ language }) => updateConfig({ language })); diff --git a/public/app/core/monacoEnv.ts b/public/app/core/monacoEnv.ts index db63c867a1e..c491127df2a 100644 --- a/public/app/core/monacoEnv.ts +++ b/public/app/core/monacoEnv.ts @@ -2,6 +2,8 @@ import { monacoLanguageRegistry } from '@grafana/data'; import { CorsWorker as Worker } from 'app/core/utils/CorsWorker'; export function setMonacoEnv() { + // Do not use window.self here, as it will not work in the worker context + // eslint-disable-next-line no-restricted-globals self.MonacoEnvironment = { getWorker(_moduleId, label) { const language = monacoLanguageRegistry.getIfExists(label); diff --git a/public/app/core/services/mousetrap/Mousetrap.ts b/public/app/core/services/mousetrap/Mousetrap.ts index 39eddc3670f..59ab18f5b03 100644 --- a/public/app/core/services/mousetrap/Mousetrap.ts +++ b/public/app/core/services/mousetrap/Mousetrap.ts @@ -862,6 +862,7 @@ export class Mousetrap { * correct key ends up getting bound (the last key in the pattern) */ bind = (keys: string | string[], callback: MousetrapCallback, action?: string) => { + let self = this; keys = keys instanceof Array ? keys : [keys]; this._bindMultiple(keys, callback, action); return self; diff --git a/public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx b/public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx index cdbe614a591..dc3907ea026 100644 --- a/public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx +++ b/public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx @@ -155,7 +155,7 @@ interface ExportMenuItemProps { } const ExportMenuItem = ({ identifier }: ExportMenuItemProps) => { - const returnTo = location.pathname + location.search; + const returnTo = window.location.pathname + window.location.search; const url = createRelativeUrl( `/alerting/${encodeURIComponent(ruleId.stringifyIdentifier(identifier))}/modify-export`, { diff --git a/public/app/features/alerting/unified/components/rule-viewer/tabs/version-history/ConfirmVersionRestoreModal.tsx b/public/app/features/alerting/unified/components/rule-viewer/tabs/version-history/ConfirmVersionRestoreModal.tsx index 95336c85016..0ffd44eb30b 100644 --- a/public/app/features/alerting/unified/components/rule-viewer/tabs/version-history/ConfirmVersionRestoreModal.tsx +++ b/public/app/features/alerting/unified/components/rule-viewer/tabs/version-history/ConfirmVersionRestoreModal.tsx @@ -73,7 +73,7 @@ export const ConfirmVersionRestoreModal = ({ const ruleFormUrl = urlUtil.renderUrl(`/alerting/${ruleIdentifier.uid}/edit`, { isManualRestore: true, defaults: JSON.stringify(payload), - returnTo: location.pathname + location.search, + returnTo: window.location.pathname + window.location.search, }); navigate(ruleFormUrl); diff --git a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx index e5e5150f738..ecfe7ec9717 100644 --- a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx +++ b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx @@ -96,7 +96,7 @@ export const GrafanaRules = ({ namespaces, expandAll }: Props) => { {grafanaRecordingRulesEnabled && ( setAlertState(undefined); diff --git a/public/app/features/alerting/unified/components/rules/deleted-rules/ConfirmRestoreDeletedRuleModal.tsx b/public/app/features/alerting/unified/components/rules/deleted-rules/ConfirmRestoreDeletedRuleModal.tsx index ad8846052d6..39ac272e9ab 100644 --- a/public/app/features/alerting/unified/components/rules/deleted-rules/ConfirmRestoreDeletedRuleModal.tsx +++ b/public/app/features/alerting/unified/components/rules/deleted-rules/ConfirmRestoreDeletedRuleModal.tsx @@ -160,7 +160,7 @@ const redirectToRestoreForm = async (ruleToRecover: RulerGrafanaRuleDTO) => { const ruleFormUrl = createRelativeUrl(urlPath, { isManualRestore: 'true', defaults: JSON.stringify(formValues), - returnTo: location.pathname + location.search, + returnTo: window.location.pathname + window.location.search, }); locationService.push(ruleFormUrl); diff --git a/public/app/features/alerting/unified/rule-list/RuleList.v1.tsx b/public/app/features/alerting/unified/rule-list/RuleList.v1.tsx index cfab28a41bc..caa2884fa4c 100644 --- a/public/app/features/alerting/unified/rule-list/RuleList.v1.tsx +++ b/public/app/features/alerting/unified/rule-list/RuleList.v1.tsx @@ -187,7 +187,7 @@ export function CreateAlertButton() { } function ExportNewRuleButton() { - const returnTo = location.pathname + location.search; + const returnTo = window.location.pathname + window.location.search; const url = createRelativeUrl(`/alerting/export-new-rule`, { returnTo, }); diff --git a/public/app/features/apiserver/client.ts b/public/app/features/apiserver/client.ts index 317b5f1ddd7..0828ad287d7 100644 --- a/public/app/features/apiserver/client.ts +++ b/public/app/features/apiserver/client.ts @@ -45,7 +45,7 @@ export class ScopedResourceClient implements fieldSelector: this.parseListOptionsSelector(params?.fieldSelector), }; if (params?.name) { - requestParams.fieldSelector = `metadata.name=${name}`; + requestParams.fieldSelector = `metadata.name=${params.name}`; } // For now, watch over live only supports provisioning diff --git a/public/app/features/dashboard-scene/saving/DetectChangesWorker.ts b/public/app/features/dashboard-scene/saving/DetectChangesWorker.ts index 2ad61da280c..563fe0ef0f4 100644 --- a/public/app/features/dashboard-scene/saving/DetectChangesWorker.ts +++ b/public/app/features/dashboard-scene/saving/DetectChangesWorker.ts @@ -13,8 +13,11 @@ function _debounce(f: (...args: T[]) => void, timeout: number) { }; } +// Do not use window.self here, as it will not work in the worker context +// eslint-disable-next-line no-restricted-globals self.onmessage = _debounce((e: MessageEvent<{ initial: Dashboard; changed: Dashboard }>) => { const result = detectDashboardChanges(e.data.initial, e.data.changed); + // eslint-disable-next-line no-restricted-globals self.postMessage(result); }, 500); diff --git a/public/app/features/dashboard-scene/scene/DashboardControls.tsx b/public/app/features/dashboard-scene/scene/DashboardControls.tsx index 423d3e3e054..f957ee3dd21 100644 --- a/public/app/features/dashboard-scene/scene/DashboardControls.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardControls.tsx @@ -56,7 +56,7 @@ export class DashboardControls extends SceneObjectBase { const isEnabledViaUrl = (key: string) => values[key] === 'true' || values[key] === ''; // Only allow hiding, never "unhiding" from url - // Becasue this should really only change on first init it's fine to do multiple setState here + // Because this should really only change on first init it's fine to do multiple setState here if (!hideTimeControls && isEnabledViaUrl('_dash.hideTimePicker')) { this.setState({ hideTimeControls: true }); @@ -122,7 +122,7 @@ function DashboardControlsRenderer({ model }: SceneComponentProps { const formValues = await scenesPanelToRuleFormValues(panel); const ruleFormUrl = urlUtil.renderUrl('/alerting/new', { defaults: JSON.stringify(formValues), - returnTo: location.pathname + location.search, + returnTo: window.location.pathname + window.location.search, }); locationService.push(ruleFormUrl); } catch (err) { diff --git a/public/app/features/dashboard-scene/sharing/ShareLinkTab.tsx b/public/app/features/dashboard-scene/sharing/ShareLinkTab.tsx index 4ff3461734e..fa68dbbca10 100644 --- a/public/app/features/dashboard-scene/sharing/ShareLinkTab.tsx +++ b/public/app/features/dashboard-scene/sharing/ShareLinkTab.tsx @@ -83,7 +83,7 @@ export class ShareLinkTab extends SceneObjectBase implements const imageUrl = getDashboardUrl({ uid: dashboard.state.uid, - currentQueryParams: location.search, + currentQueryParams: window.location.search, updateQuery: { ...urlParamsUpdate, ...queryOptions, panelId: panel?.state.key }, absolute: true, soloRoute: true, diff --git a/public/app/features/dashboard/utils/getPanelMenu.ts b/public/app/features/dashboard/utils/getPanelMenu.ts index 0f521bff6f8..a55acb08d6b 100644 --- a/public/app/features/dashboard/utils/getPanelMenu.ts +++ b/public/app/features/dashboard/utils/getPanelMenu.ts @@ -183,7 +183,7 @@ export function getPanelMenu( } const ruleFormUrl = urlUtil.renderUrl('/alerting/new', { defaults: JSON.stringify(formValues), - returnTo: location.pathname + location.search, + returnTo: window.location.pathname + window.location.search, }); locationService.push(ruleFormUrl); diff --git a/public/app/features/datasources/components/DataSourceAddButton.tsx b/public/app/features/datasources/components/DataSourceAddButton.tsx index 7e216028917..cffdaee5002 100644 --- a/public/app/features/datasources/components/DataSourceAddButton.tsx +++ b/public/app/features/datasources/components/DataSourceAddButton.tsx @@ -12,7 +12,7 @@ import { trackAddNewDsClicked } from '../tracking'; export function DataSourceAddButton(): JSX.Element | null { const canCreateDataSource = contextSrv.hasPermission(AccessControlAction.DataSourcesCreate); const handleClick = useCallback(() => { - trackAddNewDsClicked({ path: location.pathname }); + trackAddNewDsClicked({ path: window.location.pathname }); }, []); return canCreateDataSource ? ( diff --git a/public/app/features/datasources/components/DataSourceCategories.tsx b/public/app/features/datasources/components/DataSourceCategories.tsx index a18afa82ea6..922d11e574c 100644 --- a/public/app/features/datasources/components/DataSourceCategories.tsx +++ b/public/app/features/datasources/components/DataSourceCategories.tsx @@ -26,7 +26,7 @@ export function DataSourceCategories({ categories, onClickDataSourceType }: Prop const handleClick = useCallback(() => { reportInteraction('connections_add_datasource_find_more_ds_plugins_clicked', { targetPath: moreDataSourcesLink, - path: location.pathname, + path: window.location.pathname, creator_team: 'grafana_plugins_catalog', schema_version: '1.0.0', }); diff --git a/public/app/features/datasources/components/DataSourceLoadError.tsx b/public/app/features/datasources/components/DataSourceLoadError.tsx index b754e48012d..6b2354adab1 100644 --- a/public/app/features/datasources/components/DataSourceLoadError.tsx +++ b/public/app/features/datasources/components/DataSourceLoadError.tsx @@ -13,7 +13,7 @@ export type Props = { export function DataSourceLoadError({ dataSourceRights, onDelete }: Props) { const { readOnly, hasDeleteRights } = dataSourceRights; const canDelete = !readOnly && hasDeleteRights; - const navigateBack = () => history.back(); + const navigateBack = () => window.history.back(); return ( <> diff --git a/public/app/features/datasources/components/DataSourceTestingStatus.tsx b/public/app/features/datasources/components/DataSourceTestingStatus.tsx index 4545a387fc8..67f6a6947e8 100644 --- a/public/app/features/datasources/components/DataSourceTestingStatus.tsx +++ b/public/app/features/datasources/components/DataSourceTestingStatus.tsx @@ -141,7 +141,7 @@ export function DataSourceTestingStatus({ testingStatus, exploreUrl, dataSource grafana_version: config.buildInfo.version, datasource_uid: dataSource.uid, plugin_name: dataSource.typeName, - path: location.pathname, + path: window.location.pathname, }); }; const styles = useStyles2(getTestingStatusStyles); diff --git a/public/app/features/datasources/components/DataSourcesListCard.tsx b/public/app/features/datasources/components/DataSourcesListCard.tsx index 11a431ccfa2..2de57731ebd 100644 --- a/public/app/features/datasources/components/DataSourcesListCard.tsx +++ b/public/app/features/datasources/components/DataSourcesListCard.tsx @@ -45,7 +45,7 @@ export function DataSourcesListCard({ dataSource, hasWriteRights, hasExploreRigh grafana_version: config.buildInfo.version, datasource_uid: dataSource.uid, plugin_name: dataSource.typeName, - path: location.pathname, + path: window.location.pathname, }); }} > @@ -65,7 +65,7 @@ export function DataSourcesListCard({ dataSource, hasWriteRights, hasExploreRigh grafana_version: config.buildInfo.version, datasource_uid: dataSource.uid, plugin_name: dataSource.typeName, - path: location.pathname, + path: window.location.pathname, }); }} > diff --git a/public/app/features/datasources/components/EditDataSourceActions.tsx b/public/app/features/datasources/components/EditDataSourceActions.tsx index 707006ee0ac..77c518fc683 100644 --- a/public/app/features/datasources/components/EditDataSourceActions.tsx +++ b/public/app/features/datasources/components/EditDataSourceActions.tsx @@ -28,7 +28,7 @@ export function EditDataSourceActions({ uid }: Props) { grafana_version: config.buildInfo.version, datasource_uid: dataSource.uid, plugin_name: dataSource.typeName, - path: location.pathname, + path: window.location.pathname, }); }} > @@ -45,7 +45,7 @@ export function EditDataSourceActions({ uid }: Props) { grafana_version: config.buildInfo.version, datasource_uid: dataSource.uid, plugin_name: dataSource.typeName, - path: location.pathname, + path: window.location.pathname, }); }} > diff --git a/public/app/features/datasources/state/actions.test.ts b/public/app/features/datasources/state/actions.test.ts index 3c3f120ce42..29be5fa5dba 100644 --- a/public/app/features/datasources/state/actions.test.ts +++ b/public/app/features/datasources/state/actions.test.ts @@ -394,7 +394,7 @@ describe('addDataSource', () => { plugin_version: '1.2.3', datasource_uid: 'azure23', grafana_version: '1.0', - path: location.pathname, + path: window.location.pathname, }); }); }); diff --git a/public/app/features/datasources/state/actions.ts b/public/app/features/datasources/state/actions.ts index 6229f0d1a02..48044d2ec65 100644 --- a/public/app/features/datasources/state/actions.ts +++ b/public/app/features/datasources/state/actions.ts @@ -257,7 +257,7 @@ export function addDataSource( plugin_id: plugin.id, datasource_uid: result.datasource.uid, plugin_version: result.meta?.info?.version, - path: location.pathname, + path: window.location.pathname, }); locationService.push(editLink); diff --git a/public/app/features/explore/NodeGraph/NodeGraphContainer.tsx b/public/app/features/explore/NodeGraph/NodeGraphContainer.tsx index f2396bbcfb9..995a2becf9b 100644 --- a/public/app/features/explore/NodeGraph/NodeGraphContainer.tsx +++ b/public/app/features/explore/NodeGraph/NodeGraphContainer.tsx @@ -69,7 +69,7 @@ export function UnconnectedNodeGraphContainer(props: Props) { reportInteraction('grafana_traces_node_graph_panel_clicked', { datasourceType: datasourceType, grafana_version: config.buildInfo.version, - isExpanded: !open, + isExpanded: !collapsed, }); }; diff --git a/public/app/features/gops/configuration-tracker/components/Essentials.tsx b/public/app/features/gops/configuration-tracker/components/Essentials.tsx index 6599a267233..5a0c445dcac 100644 --- a/public/app/features/gops/configuration-tracker/components/Essentials.tsx +++ b/public/app/features/gops/configuration-tracker/components/Essentials.tsx @@ -107,13 +107,13 @@ function OpenLinkButton(props: LinkButtonProps) { const { urlLink, label, urlLinkOnDone, labelOnDone, done } = props; const urlToGoWhenNotDone = urlLink?.url ? createRelativeUrl(urlLink.url, { - returnTo: location.pathname + location.search, + returnTo: window.location.pathname + window.location.search, ...urlLink.queryParams, }) : ''; const urlToGoWhenDone = urlLinkOnDone?.url ? createRelativeUrl(urlLinkOnDone.url, { - returnTo: location.pathname + location.search, + returnTo: window.location.pathname + window.location.search, ...urlLinkOnDone.queryParams, }) : ''; diff --git a/public/app/features/gops/configuration-tracker/irmHooks.ts b/public/app/features/gops/configuration-tracker/irmHooks.ts index 082d96278ab..eee6e23feee 100644 --- a/public/app/features/gops/configuration-tracker/irmHooks.ts +++ b/public/app/features/gops/configuration-tracker/irmHooks.ts @@ -121,7 +121,7 @@ export function useGetEssentialsConfiguration(): EssentialsConfigurationData { function onIntegrationClick(integrationId: string, url: RelativeUrl) { const urlToGoWithIntegration = createRelativeUrl(`${url} + ${integrationId}`, { - returnTo: location.pathname + location.search, + returnTo: window.location.pathname + window.location.search, }); locationService.push(urlToGoWithIntegration); } diff --git a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithApp.tsx b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithApp.tsx index 6624a17b4e2..f4331b60764 100644 --- a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithApp.tsx +++ b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithApp.tsx @@ -30,7 +30,7 @@ export function GetStartedWithApp({ plugin }: Props): React.ReactElement | null const enable = () => { reportInteraction('plugins_detail_enable_clicked', { - path: location.pathname, + path: window.location.pathname, plugin_id: plugin.id, creator_team: 'grafana_plugins_catalog', schema_version: '1.0.0', @@ -44,7 +44,7 @@ export function GetStartedWithApp({ plugin }: Props): React.ReactElement | null const disable = () => { reportInteraction('plugins_detail_disable_clicked', { - path: location.pathname, + path: window.location.pathname, plugin_id: plugin.id, creator_team: 'grafana_plugins_catalog', schema_version: '1.0.0', diff --git a/public/app/features/plugins/admin/components/UpdateAllButton.tsx b/public/app/features/plugins/admin/components/UpdateAllButton.tsx index 7ba9c7ad3aa..b12d12d8a4b 100644 --- a/public/app/features/plugins/admin/components/UpdateAllButton.tsx +++ b/public/app/features/plugins/admin/components/UpdateAllButton.tsx @@ -14,7 +14,7 @@ const UpdateAllButton = ({ disabled, onUpdateAll, updatablePluginsLength }: Upda No updates available ) : ( - Update all ({{ length }}) + Update all ({'{{length}}'}) )} diff --git a/public/app/features/plugins/admin/components/UpdateAllModal.tsx b/public/app/features/plugins/admin/components/UpdateAllModal.tsx index 7830b1b253e..8db91f24017 100644 --- a/public/app/features/plugins/admin/components/UpdateAllModal.tsx +++ b/public/app/features/plugins/admin/components/UpdateAllModal.tsx @@ -33,7 +33,7 @@ export const UpdateAllModal = ({ isOpen, onDismiss, isLoading, plugins }: Props) const pluginsSet = useMemo(() => new Set(plugins.map((plugin) => plugin.id)), [plugins]); const installsRemaining = plugins.length; - // Since the plugins comes from the store and changes every time we update a plugin, + // Since the plugins come from the store and changes every time we update a plugin, // we need to keep track of the initial plugins. useEffect(() => { if (initialPluginsRef.current.length === 0) { @@ -88,7 +88,7 @@ export const UpdateAllModal = ({ isOpen, onDismiss, isLoading, plugins }: Props) const onConfirm = async () => { if (!inProgress) { reportInteraction(PLUGINS_UPDATE_ALL_INTERACTION_EVENT_NAME, { - path: location.pathname, + path: window.location.pathname, count: selectedPlugins?.size, creator_team: 'grafana_plugins_catalog', schema_version: '1.0.0', diff --git a/public/app/features/plugins/admin/components/VersionInstallButton.tsx b/public/app/features/plugins/admin/components/VersionInstallButton.tsx index ba25cd73a12..baeeaacff09 100644 --- a/public/app/features/plugins/admin/components/VersionInstallButton.tsx +++ b/public/app/features/plugins/admin/components/VersionInstallButton.tsx @@ -59,7 +59,7 @@ export const VersionInstallButton = ({ const performInstallation = () => { const trackProps = { - path: location.pathname, + path: window.location.pathname, plugin_id: pluginId, version: version.version, is_latest: latestCompatibleVersion === version.version, diff --git a/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts b/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts index d7a0b01e16a..3aa489a35a9 100644 --- a/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts +++ b/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts @@ -41,7 +41,8 @@ export async function isPluginFrontendSandboxEligible({ pluginId }: SandboxEligi } // To fast-test and debug the sandbox in the browser (dev mode only). - const sandboxDisableQueryParam = location.search.includes('nosandbox') && config.buildInfo.env === 'development'; + const sandboxDisableQueryParam = + window.location.search.includes('nosandbox') && config.buildInfo.env === 'development'; if (sandboxDisableQueryParam) { return false; } diff --git a/public/app/features/search/service/searcher.ts b/public/app/features/search/service/searcher.ts index 71a44a18f7d..2710a789050 100644 --- a/public/app/features/search/service/searcher.ts +++ b/public/app/features/search/service/searcher.ts @@ -14,7 +14,7 @@ export function getGrafanaSearcher(): GrafanaSearcher { const useBluge = config.featureToggles.panelTitleSearch; searcher = useBluge ? new BlugeSearcher(sqlSearcher) : sqlSearcher; - if (useBluge && location.search.includes('do-frontend-query')) { + if (useBluge && window.location.search.includes('do-frontend-query')) { return new FrontendSearcher(searcher); } diff --git a/public/app/features/serviceaccounts/ServiceAccountTable.tsx b/public/app/features/serviceaccounts/ServiceAccountTable.tsx index b448d01d396..a180b1bdd26 100644 --- a/public/app/features/serviceaccounts/ServiceAccountTable.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountTable.tsx @@ -124,7 +124,7 @@ const getCellContent = ( return columnName === 'avatarUrl' ? : ; } const href = `/org/serviceaccounts/${original.uid}`; - const ariaLabel = `Edit service account's ${name} details`; + const ariaLabel = `Edit service account's ${original.name} details`; switch (columnName) { case 'avatarUrl': return ( diff --git a/public/app/plugins/panel/nodeGraph/layeredLayout.worker.js b/public/app/plugins/panel/nodeGraph/layeredLayout.worker.js index 7fa2caec2c9..09bee59ee79 100644 --- a/public/app/plugins/panel/nodeGraph/layeredLayout.worker.js +++ b/public/app/plugins/panel/nodeGraph/layeredLayout.worker.js @@ -1,6 +1,7 @@ import { layout } from './layeredLayout'; // Separate from main implementation so it does not trip out tests +// eslint-disable-next-line no-restricted-globals addEventListener('message', async (event) => { const { nodes, edges, config } = event.data; const [newNodes, newEdges] = layout(nodes, edges, config); diff --git a/public/app/plugins/panel/nodeGraph/layout.worker.js b/public/app/plugins/panel/nodeGraph/layout.worker.js index ff5c3936109..96cdc683716 100644 --- a/public/app/plugins/panel/nodeGraph/layout.worker.js +++ b/public/app/plugins/panel/nodeGraph/layout.worker.js @@ -1,6 +1,7 @@ import { layout } from './forceLayout'; // Separate from main implementation so it does not trip out tests +// eslint-disable-next-line no-restricted-globals addEventListener('message', (event) => { const { nodes, edges, config } = event.data; layout(nodes, edges, config); diff --git a/public/swagger/SwaggerPage.tsx b/public/swagger/SwaggerPage.tsx index 48a1eadc9ce..83b0d040a8c 100644 --- a/public/swagger/SwaggerPage.tsx +++ b/public/swagger/SwaggerPage.tsx @@ -98,7 +98,7 @@ export const Page = () => { } else { url.searchParams.delete('api'); } - history.pushState(null, '', url); + window.history.pushState(null, '', url); setURL(v); }} value={url} diff --git a/yarn.lock b/yarn.lock index 809987a82ca..ce0bae795ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8758,6 +8758,13 @@ __metadata: languageName: node linkType: hard +"@types/confusing-browser-globals@npm:^1": + version: 1.0.3 + resolution: "@types/confusing-browser-globals@npm:1.0.3" + checksum: 10/596d9ea69fb2b6e5be9b37560e86593a0992e8554850de1a790aea66407c9453b78bc86909da5fd9f4fede99d7652c2b0dfeb9f89ef5d8eca35fadaca3271707 + languageName: node + linkType: hard + "@types/connect-history-api-fallback@npm:^1.5.4": version: 1.5.4 resolution: "@types/connect-history-api-fallback@npm:1.5.4" @@ -13103,6 +13110,13 @@ __metadata: languageName: node linkType: hard +"confusing-browser-globals@npm:^1.0.11": + version: 1.0.11 + resolution: "confusing-browser-globals@npm:1.0.11" + checksum: 10/3afc635abd37e566477f610e7978b15753f0e84025c25d49236f1f14d480117185516bdd40d2a2167e6bed8048641a9854964b9c067e3dcdfa6b5d0ad3c3a5ef + languageName: node + linkType: hard + "connect-history-api-fallback@npm:^2.0.0": version: 2.0.0 resolution: "connect-history-api-fallback@npm:2.0.0" @@ -17735,6 +17749,7 @@ __metadata: "@types/babel__preset-env": "npm:^7" "@types/chance": "npm:^1.1.3" "@types/common-tags": "npm:^1.8.0" + "@types/confusing-browser-globals": "npm:^1" "@types/d3": "npm:7.4.3" "@types/d3-force": "npm:^3.0.0" "@types/d3-scale-chromatic": "npm:3.1.0" @@ -17807,6 +17822,7 @@ __metadata: combokeys: "npm:^3.0.0" comlink: "npm:4.4.2" common-tags: "npm:1.8.2" + confusing-browser-globals: "npm:^1.0.11" copy-webpack-plugin: "npm:12.0.2" core-js: "npm:3.40.0" crashme: "npm:0.0.15"