Migrate from grafana-toolkit to grafana plugin tools (#3837)
# What this PR does Migrate from grafana-toolkit to grafana plugin tools ## Which issue(s) this PR fixes https://github.com/grafana/oncall/issues/3651 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --------- Co-authored-by: Michael Derynck <michael.derynck@grafana.com> Co-authored-by: Dominik <dominik.broj@grafana.com>
This commit is contained in:
parent
d0ee58cb68
commit
828b0a3f4e
34 changed files with 3040 additions and 4073 deletions
28
.drone.yml
28
.drone.yml
|
|
@ -20,8 +20,8 @@ steps:
|
||||||
- name: Sign and Package Plugin
|
- name: Sign and Package Plugin
|
||||||
image: node:18.16.0-buster
|
image: node:18.16.0-buster
|
||||||
environment:
|
environment:
|
||||||
GRAFANA_API_KEY:
|
GRAFANA_ACCESS_POLICY_TOKEN:
|
||||||
from_secret: gcom_plugin_publisher_api_key
|
from_secret: cloud_access_policy_token
|
||||||
depends_on:
|
depends_on:
|
||||||
- Build Plugin
|
- Build Plugin
|
||||||
commands:
|
commands:
|
||||||
|
|
@ -30,9 +30,7 @@ steps:
|
||||||
- cd grafana-plugin
|
- cd grafana-plugin
|
||||||
- yarn sign
|
- yarn sign
|
||||||
- if [ ! -f dist/MANIFEST.txt ]; then echo "Sign failed, MANIFEST.txt not created, aborting." && exit 1; fi
|
- if [ ! -f dist/MANIFEST.txt ]; then echo "Sign failed, MANIFEST.txt not created, aborting." && exit 1; fi
|
||||||
- yarn ci-build:finish
|
- mv dist grafana-oncall-app
|
||||||
- yarn ci-package
|
|
||||||
- cd ci/dist
|
|
||||||
- zip -r grafana-oncall-app.zip ./grafana-oncall-app
|
- zip -r grafana-oncall-app.zip ./grafana-oncall-app
|
||||||
# yamllint disable rule:line-length
|
# yamllint disable rule:line-length
|
||||||
- if [ -z "$DRONE_TAG" ]; then echo "No tag, skipping archive"; else cp grafana-oncall-app.zip grafana-oncall-app-${DRONE_TAG}.zip; fi
|
- if [ -z "$DRONE_TAG" ]; then echo "No tag, skipping archive"; else cp grafana-oncall-app.zip grafana-oncall-app-${DRONE_TAG}.zip; fi
|
||||||
|
|
@ -192,8 +190,8 @@ steps:
|
||||||
- name: sign and package plugin
|
- name: sign and package plugin
|
||||||
image: node:18.16.0-buster
|
image: node:18.16.0-buster
|
||||||
environment:
|
environment:
|
||||||
GRAFANA_API_KEY:
|
GRAFANA_ACCESS_POLICY_TOKEN:
|
||||||
from_secret: gcom_plugin_publisher_api_key
|
from_secret: cloud_access_policy_token
|
||||||
depends_on:
|
depends_on:
|
||||||
- build plugin
|
- build plugin
|
||||||
commands:
|
commands:
|
||||||
|
|
@ -202,9 +200,7 @@ steps:
|
||||||
- cd grafana-plugin
|
- cd grafana-plugin
|
||||||
- yarn sign
|
- yarn sign
|
||||||
- if [ ! -f dist/MANIFEST.txt ]; then echo "Sign failed, MANIFEST.txt not created, aborting." && exit 1; fi
|
- if [ ! -f dist/MANIFEST.txt ]; then echo "Sign failed, MANIFEST.txt not created, aborting." && exit 1; fi
|
||||||
- yarn ci-build:finish
|
- mv dist grafana-oncall-app
|
||||||
- yarn ci-package
|
|
||||||
- cd ci/dist
|
|
||||||
- zip -r grafana-oncall-app.zip ./grafana-oncall-app
|
- zip -r grafana-oncall-app.zip ./grafana-oncall-app
|
||||||
# yamllint disable rule:line-length
|
# yamllint disable rule:line-length
|
||||||
- if [ -z "$DRONE_TAG" ]; then echo "No tag, skipping archive"; else cp grafana-oncall-app.zip grafana-oncall-app-${DRONE_TAG}.zip; fi
|
- if [ -z "$DRONE_TAG" ]; then echo "No tag, skipping archive"; else cp grafana-oncall-app.zip grafana-oncall-app-${DRONE_TAG}.zip; fi
|
||||||
|
|
@ -355,6 +351,7 @@ get:
|
||||||
path: infra/data/ci/docker_hub
|
path: infra/data/ci/docker_hub
|
||||||
kind: secret
|
kind: secret
|
||||||
name: docker_username
|
name: docker_username
|
||||||
|
|
||||||
---
|
---
|
||||||
get:
|
get:
|
||||||
name: password
|
name: password
|
||||||
|
|
@ -377,8 +374,17 @@ get:
|
||||||
path: ci/data/repo/grafana/oncall/drone
|
path: ci/data/repo/grafana/oncall/drone
|
||||||
kind: secret
|
kind: secret
|
||||||
name: github_api_token
|
name: github_api_token
|
||||||
|
|
||||||
|
---
|
||||||
|
# Secret for signing plugin
|
||||||
|
get:
|
||||||
|
name: cloud_access_policy_token
|
||||||
|
path: ci/data/repo/grafana/oncall/sign_plugin
|
||||||
|
kind: secret
|
||||||
|
name: cloud_access_policy_token
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: signature
|
kind: signature
|
||||||
hmac: f717f3a2708568d8d9ad3e8c738544b96a82455ecd1413feec9f502414807397
|
hmac: 5bf89aaec69ebec6d4489b6ef712f92d10ede5b242b88c8f62930d78ba780f7d
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Change plugin build to use new packages instead of deprecated grafana-toolkit @maskin25 ([#3837](https://github.com/grafana/oncall/pull/3837))
|
||||||
|
|
||||||
## v1.3.106 (2024-02-20)
|
## v1.3.106 (2024-02-20)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
25
grafana-plugin/.config/.eslintrc
Normal file
25
grafana-plugin/.config/.eslintrc
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||||
|
*
|
||||||
|
* In order to extend the configuration follow the steps in
|
||||||
|
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-eslint-config
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
"extends": ["@grafana/eslint-config"],
|
||||||
|
"root": true,
|
||||||
|
"rules": {
|
||||||
|
"react/prop-types": "off"
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"plugins": ["deprecation"],
|
||||||
|
"files": ["src/**/*.{ts,tsx}"],
|
||||||
|
"rules": {
|
||||||
|
"deprecation/deprecation": "warn"
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"project": "./tsconfig.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
16
grafana-plugin/.config/.prettierrc.js
Normal file
16
grafana-plugin/.config/.prettierrc.js
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||||
|
*
|
||||||
|
* In order to extend the configuration follow the steps in .config/README.md
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
endOfLine: 'auto',
|
||||||
|
printWidth: 120,
|
||||||
|
trailingComma: 'es5',
|
||||||
|
semi: true,
|
||||||
|
jsxSingleQuote: false,
|
||||||
|
singleQuote: true,
|
||||||
|
useTabs: false,
|
||||||
|
tabWidth: 2,
|
||||||
|
};
|
||||||
25
grafana-plugin/.config/jest-setup.js
Normal file
25
grafana-plugin/.config/jest-setup.js
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||||
|
*
|
||||||
|
* In order to extend the configuration follow the steps in
|
||||||
|
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-jest-config
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '@testing-library/jest-dom';
|
||||||
|
|
||||||
|
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
|
||||||
|
Object.defineProperty(global, 'matchMedia', {
|
||||||
|
writable: true,
|
||||||
|
value: jest.fn().mockImplementation((query) => ({
|
||||||
|
matches: false,
|
||||||
|
media: query,
|
||||||
|
onchange: null,
|
||||||
|
addListener: jest.fn(), // deprecated
|
||||||
|
removeListener: jest.fn(), // deprecated
|
||||||
|
addEventListener: jest.fn(),
|
||||||
|
removeEventListener: jest.fn(),
|
||||||
|
dispatchEvent: jest.fn(),
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
|
||||||
|
HTMLCanvasElement.prototype.getContext = () => {};
|
||||||
43
grafana-plugin/.config/jest.config.js
Normal file
43
grafana-plugin/.config/jest.config.js
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||||
|
*
|
||||||
|
* In order to extend the configuration follow the steps in
|
||||||
|
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-jest-config
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
moduleNameMapper: {
|
||||||
|
'\\.(css|scss|sass)$': 'identity-obj-proxy',
|
||||||
|
'react-inlinesvg': path.resolve(__dirname, 'jest', 'mocks', 'react-inlinesvg.tsx'),
|
||||||
|
},
|
||||||
|
modulePaths: ['<rootDir>/src'],
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/jest-setup.js'],
|
||||||
|
testEnvironment: 'jest-environment-jsdom',
|
||||||
|
testMatch: [
|
||||||
|
'<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
|
||||||
|
'<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}',
|
||||||
|
'<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}',
|
||||||
|
],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.(t|j)sx?$': [
|
||||||
|
'@swc/jest',
|
||||||
|
{
|
||||||
|
sourceMaps: 'inline',
|
||||||
|
jsc: {
|
||||||
|
parser: {
|
||||||
|
syntax: 'typescript',
|
||||||
|
tsx: true,
|
||||||
|
decorators: false,
|
||||||
|
dynamicImport: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Jest will throw `Cannot use import statement outside module` if it tries to load an
|
||||||
|
// ES module without it being transformed first. ./config/README.md#esm-errors-with-jest
|
||||||
|
transformIgnorePatterns: [nodeModulesToTransform(grafanaESModules)],
|
||||||
|
};
|
||||||
25
grafana-plugin/.config/jest/mocks/react-inlinesvg.tsx
Normal file
25
grafana-plugin/.config/jest/mocks/react-inlinesvg.tsx
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Due to the grafana/ui Icon component making fetch requests to
|
||||||
|
// `/public/img/icon/<icon_name>.svg` we need to mock react-inlinesvg to prevent
|
||||||
|
// the failed fetch requests from displaying errors in console.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
type Callback = (...args: any[]) => void;
|
||||||
|
|
||||||
|
export interface StorageItem {
|
||||||
|
content: string;
|
||||||
|
queue: Callback[];
|
||||||
|
status: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const cacheStore: { [key: string]: StorageItem } = Object.create(null);
|
||||||
|
|
||||||
|
const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/;
|
||||||
|
|
||||||
|
const InlineSVG = ({ src }: { src: string }) => {
|
||||||
|
// testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`)
|
||||||
|
const testId = src.replace(SVG_FILE_NAME_REGEX, '$2');
|
||||||
|
return <svg xmlns="http://www.w3.org/2000/svg" data-testid={testId} viewBox="0 0 24 24" />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default InlineSVG;
|
||||||
31
grafana-plugin/.config/jest/utils.js
Normal file
31
grafana-plugin/.config/jest/utils.js
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||||
|
*
|
||||||
|
* In order to extend the configuration follow the steps in .config/README.md
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This utility function is useful in combination with jest `transformIgnorePatterns` config
|
||||||
|
* to transform specific packages (e.g.ES modules) in a projects node_modules folder.
|
||||||
|
*/
|
||||||
|
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!.*(${moduleNames.join('|')})\/.*)`;
|
||||||
|
|
||||||
|
// Array of known nested grafana package dependencies that only bundle an ESM version
|
||||||
|
const grafanaESModules = [
|
||||||
|
'.pnpm', // Support using pnpm symlinked packages
|
||||||
|
'@grafana/schema',
|
||||||
|
'd3',
|
||||||
|
'd3-color',
|
||||||
|
'd3-force',
|
||||||
|
'd3-interpolate',
|
||||||
|
'd3-scale-chromatic',
|
||||||
|
'ol',
|
||||||
|
'react-colorful',
|
||||||
|
'rxjs',
|
||||||
|
'uuid',
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
nodeModulesToTransform,
|
||||||
|
grafanaESModules,
|
||||||
|
};
|
||||||
26
grafana-plugin/.config/tsconfig.json
Normal file
26
grafana-plugin/.config/tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||||
|
*
|
||||||
|
* In order to extend the configuration follow the steps in
|
||||||
|
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-typescript-config
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"alwaysStrict": true,
|
||||||
|
"declaration": false,
|
||||||
|
"rootDir": "../src",
|
||||||
|
"baseUrl": "../src",
|
||||||
|
"typeRoots": ["../node_modules/@types"],
|
||||||
|
"resolveJsonModule": true
|
||||||
|
},
|
||||||
|
"ts-node": {
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"esModuleInterop": true
|
||||||
|
},
|
||||||
|
"transpileOnly": true
|
||||||
|
},
|
||||||
|
"include": ["../src", "./types"],
|
||||||
|
"extends": "@grafana/tsconfig"
|
||||||
|
}
|
||||||
37
grafana-plugin/.config/types/custom.d.ts
vendored
Normal file
37
grafana-plugin/.config/types/custom.d.ts
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Image declarations
|
||||||
|
declare module '*.gif' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.jpg' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.jpeg' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.png' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.webp' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.svg' {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Font declarations
|
||||||
|
declare module '*.woff';
|
||||||
|
declare module '*.woff2';
|
||||||
|
declare module '*.eot';
|
||||||
|
declare module '*.ttf';
|
||||||
|
declare module '*.otf';
|
||||||
2
grafana-plugin/.config/webpack/constants.ts
Normal file
2
grafana-plugin/.config/webpack/constants.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export const SOURCE_DIR = 'src';
|
||||||
|
export const DIST_DIR = 'dist';
|
||||||
58
grafana-plugin/.config/webpack/utils.ts
Normal file
58
grafana-plugin/.config/webpack/utils.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
import fs from 'fs';
|
||||||
|
import process from 'process';
|
||||||
|
import os from 'os';
|
||||||
|
import path from 'path';
|
||||||
|
import { glob } from 'glob';
|
||||||
|
import { SOURCE_DIR } from './constants';
|
||||||
|
|
||||||
|
export function isWSL() {
|
||||||
|
if (process.platform !== 'linux') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (os.release().toLowerCase().includes('microsoft')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPackageJson() {
|
||||||
|
return require(path.resolve(process.cwd(), 'package.json'));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPluginJson() {
|
||||||
|
return require(path.resolve(process.cwd(), `${SOURCE_DIR}/plugin.json`));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hasReadme() {
|
||||||
|
return fs.existsSync(path.resolve(process.cwd(), SOURCE_DIR, 'README.md'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support bundling nested plugins by finding all plugin.json files in src directory
|
||||||
|
// then checking for a sibling module.[jt]sx? file.
|
||||||
|
export async function getEntries(): Promise<Record<string, string>> {
|
||||||
|
const pluginsJson = await glob('**/src/**/plugin.json', { absolute: true });
|
||||||
|
|
||||||
|
const plugins = await Promise.all(
|
||||||
|
pluginsJson.map((pluginJson) => {
|
||||||
|
const folder = path.dirname(pluginJson);
|
||||||
|
return glob(`${folder}/module.{ts,tsx,js,jsx}`, { absolute: true });
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return plugins.reduce((result, modules) => {
|
||||||
|
return modules.reduce((result, module) => {
|
||||||
|
const pluginPath = path.dirname(module);
|
||||||
|
const pluginName = path.relative(process.cwd(), pluginPath).replace(/src\/?/i, '');
|
||||||
|
const entryName = pluginName === '' ? 'module' : `${pluginName}/module`;
|
||||||
|
|
||||||
|
result[entryName] = module;
|
||||||
|
return result;
|
||||||
|
}, result);
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
218
grafana-plugin/.config/webpack/webpack.config.ts
Normal file
218
grafana-plugin/.config/webpack/webpack.config.ts
Normal file
|
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||||
|
*
|
||||||
|
* In order to extend the configuration follow the steps in
|
||||||
|
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-webpack-config
|
||||||
|
*/
|
||||||
|
|
||||||
|
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||||
|
import ESLintPlugin from 'eslint-webpack-plugin';
|
||||||
|
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
||||||
|
import LiveReloadPlugin from 'webpack-livereload-plugin';
|
||||||
|
import path from 'path';
|
||||||
|
import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin';
|
||||||
|
import { Configuration } from 'webpack';
|
||||||
|
|
||||||
|
import { getPackageJson, getPluginJson, hasReadme, getEntries, isWSL } from './utils';
|
||||||
|
import { SOURCE_DIR, DIST_DIR } from './constants';
|
||||||
|
|
||||||
|
const pluginJson = getPluginJson();
|
||||||
|
|
||||||
|
const config = async (env): Promise<Configuration> => {
|
||||||
|
const baseConfig: Configuration = {
|
||||||
|
cache: {
|
||||||
|
type: 'filesystem',
|
||||||
|
buildDependencies: {
|
||||||
|
config: [__filename],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
context: path.join(process.cwd(), SOURCE_DIR),
|
||||||
|
|
||||||
|
devtool: env.production ? 'source-map' : 'eval-source-map',
|
||||||
|
|
||||||
|
entry: await getEntries(),
|
||||||
|
|
||||||
|
externals: [
|
||||||
|
'lodash',
|
||||||
|
'jquery',
|
||||||
|
'moment',
|
||||||
|
'slate',
|
||||||
|
'emotion',
|
||||||
|
'@emotion/react',
|
||||||
|
'@emotion/css',
|
||||||
|
'prismjs',
|
||||||
|
'slate-plain-serializer',
|
||||||
|
'@grafana/slate-react',
|
||||||
|
'react',
|
||||||
|
'react-dom',
|
||||||
|
'react-redux',
|
||||||
|
'redux',
|
||||||
|
'rxjs',
|
||||||
|
'react-router',
|
||||||
|
'react-router-dom',
|
||||||
|
'd3',
|
||||||
|
'angular',
|
||||||
|
'@grafana/ui',
|
||||||
|
'@grafana/runtime',
|
||||||
|
'@grafana/data',
|
||||||
|
|
||||||
|
// Mark legacy SDK imports as external if their name starts with the "grafana/" prefix
|
||||||
|
({ request }, callback) => {
|
||||||
|
const prefix = 'grafana/';
|
||||||
|
const hasPrefix = (request) => request.indexOf(prefix) === 0;
|
||||||
|
const stripPrefix = (request) => request.substr(prefix.length);
|
||||||
|
|
||||||
|
if (hasPrefix(request)) {
|
||||||
|
return callback(undefined, stripPrefix(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
mode: env.production ? 'production' : 'development',
|
||||||
|
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
exclude: /(node_modules)/,
|
||||||
|
test: /\.[tj]sx?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'swc-loader',
|
||||||
|
options: {
|
||||||
|
jsc: {
|
||||||
|
baseUrl: path.resolve(__dirname, 'src'),
|
||||||
|
target: 'es2015',
|
||||||
|
loose: false,
|
||||||
|
parser: {
|
||||||
|
syntax: 'typescript',
|
||||||
|
tsx: true,
|
||||||
|
decorators: false,
|
||||||
|
dynamicImport: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ['style-loader', 'css-loader'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.s[ac]ss$/,
|
||||||
|
use: ['style-loader', 'css-loader', 'sass-loader'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpe?g|gif|svg)$/,
|
||||||
|
type: 'asset/resource',
|
||||||
|
generator: {
|
||||||
|
// Keep publicPath relative for host.com/grafana/ deployments
|
||||||
|
publicPath: `public/plugins/${pluginJson.id}/img/`,
|
||||||
|
outputPath: 'img/',
|
||||||
|
filename: Boolean(env.production) ? '[hash][ext]' : '[file]',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/,
|
||||||
|
type: 'asset/resource',
|
||||||
|
generator: {
|
||||||
|
// Keep publicPath relative for host.com/grafana/ deployments
|
||||||
|
publicPath: `public/plugins/${pluginJson.id}/fonts/`,
|
||||||
|
outputPath: 'fonts/',
|
||||||
|
filename: Boolean(env.production) ? '[hash][ext]' : '[name][ext]',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
output: {
|
||||||
|
clean: {
|
||||||
|
keep: new RegExp(`(.*?_(amd64|arm(64)?)(.exe)?|go_plugin_build_manifest)`),
|
||||||
|
},
|
||||||
|
filename: '[name].js',
|
||||||
|
library: {
|
||||||
|
type: 'amd',
|
||||||
|
},
|
||||||
|
path: path.resolve(process.cwd(), DIST_DIR),
|
||||||
|
publicPath: `public/plugins/${pluginJson.id}/`,
|
||||||
|
uniqueName: pluginJson.id,
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
new CopyWebpackPlugin({
|
||||||
|
patterns: [
|
||||||
|
// If src/README.md exists use it; otherwise the root README
|
||||||
|
// To `compiler.options.output`
|
||||||
|
{ from: hasReadme() ? 'README.md' : '../README.md', to: '.', force: true },
|
||||||
|
{ from: 'plugin.json', to: '.' },
|
||||||
|
{ from: '../LICENSE', to: '.' },
|
||||||
|
{ from: '../CHANGELOG.md', to: '.', noErrorOnMissing: true, force: true },
|
||||||
|
{ from: '**/*.json', to: '.' }, // TODO<Add an error for checking the basic structure of the repo>
|
||||||
|
{ from: '**/*.svg', to: '.', noErrorOnMissing: true }, // Optional
|
||||||
|
{ from: '**/*.png', to: '.', noErrorOnMissing: true }, // Optional
|
||||||
|
{ from: '**/*.html', to: '.', noErrorOnMissing: true }, // Optional
|
||||||
|
{ from: 'img/**/*', to: '.', noErrorOnMissing: true }, // Optional
|
||||||
|
{ from: 'libs/**/*', to: '.', noErrorOnMissing: true }, // Optional
|
||||||
|
{ from: 'static/**/*', to: '.', noErrorOnMissing: true }, // Optional
|
||||||
|
{ from: '**/query_help.md', to: '.', noErrorOnMissing: true }, // Optional
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
// Replace certain template-variables in the README and plugin.json
|
||||||
|
new ReplaceInFileWebpackPlugin([
|
||||||
|
{
|
||||||
|
dir: DIST_DIR,
|
||||||
|
files: ['plugin.json', 'README.md'],
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
search: /\%VERSION\%/g,
|
||||||
|
replace: getPackageJson().version,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
search: /\%TODAY\%/g,
|
||||||
|
replace: new Date().toISOString().substring(0, 10),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
search: /\%PLUGIN_ID\%/g,
|
||||||
|
replace: pluginJson.id,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
...(env.development
|
||||||
|
? [
|
||||||
|
new LiveReloadPlugin(),
|
||||||
|
new ForkTsCheckerWebpackPlugin({
|
||||||
|
async: Boolean(env.development),
|
||||||
|
issue: {
|
||||||
|
include: [{ file: '**/*.{ts,tsx}' }],
|
||||||
|
},
|
||||||
|
typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') },
|
||||||
|
}),
|
||||||
|
new ESLintPlugin({
|
||||||
|
extensions: ['.ts', '.tsx'],
|
||||||
|
lintDirtyModulesOnly: Boolean(env.development), // don't lint on start, only lint changed files
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
],
|
||||||
|
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||||
|
// handle resolving "rootDir" paths
|
||||||
|
modules: [path.resolve(process.cwd(), 'src'), 'node_modules'],
|
||||||
|
unsafeCache: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isWSL()) {
|
||||||
|
baseConfig.watchOptions = {
|
||||||
|
poll: 3000,
|
||||||
|
ignored: /node_modules/,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
|
|
@ -2,7 +2,7 @@ const rulesDirPlugin = require('eslint-plugin-rulesdir');
|
||||||
rulesDirPlugin.RULES_DIR = 'tools/eslint-rules';
|
rulesDirPlugin.RULES_DIR = 'tools/eslint-rules';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
extends: ['@grafana/eslint-config'],
|
extends: ['./.config/.eslintrc'],
|
||||||
plugins: ['rulesdir', 'import'],
|
plugins: ['rulesdir', 'import'],
|
||||||
settings: {
|
settings: {
|
||||||
'import/internal-regex':
|
'import/internal-regex':
|
||||||
|
|
|
||||||
1
grafana-plugin/.nvmrc
Normal file
1
grafana-plugin/.nvmrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
18.16.0
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...require('@grafana/toolkit/src/config/prettier.plugin.config.json'),
|
// Prettier configuration provided by Grafana scaffolding
|
||||||
|
...require('./.config/.prettierrc.js'),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
"presets": [
|
|
||||||
["@babel/preset-env", { "targets": { "node": "current" } }],
|
|
||||||
"@babel/preset-react",
|
|
||||||
"@babel/preset-typescript"
|
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
["@babel/plugin-proposal-decorators", { "legacy": true }],
|
|
||||||
["@babel/plugin-transform-destructuring", { "useBuiltIns": true }],
|
|
||||||
"@babel/plugin-transform-runtime",
|
|
||||||
["@babel/plugin-proposal-class-properties", { "loose": false }],
|
|
||||||
"@babel/transform-regenerator",
|
|
||||||
"@babel/plugin-transform-template-literals"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
|
// force timezone to UTC to allow tests to work regardless of local timezone
|
||||||
|
// generally used by snapshots, but can affect specific tests
|
||||||
|
process.env.TZ = 'UTC';
|
||||||
|
|
||||||
const esModules = ['@grafana', 'uplot', 'ol', 'd3', 'react-colorful', 'uuid', 'openapi-fetch'].join('|');
|
const esModules = ['@grafana', 'uplot', 'ol', 'd3', 'react-colorful', 'uuid', 'openapi-fetch'].join('|');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
...require('./.config/jest.config'),
|
||||||
testEnvironment: 'jsdom',
|
testEnvironment: 'jsdom',
|
||||||
|
|
||||||
moduleDirectories: ['node_modules', 'src'],
|
moduleDirectories: ['node_modules', 'src'],
|
||||||
|
|
@ -23,4 +28,20 @@ module.exports = {
|
||||||
|
|
||||||
testTimeout: 10000,
|
testTimeout: 10000,
|
||||||
testPathIgnorePatterns: ['/node_modules/', '/e2e-tests/'],
|
testPathIgnorePatterns: ['/node_modules/', '/e2e-tests/'],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.(t|j)sx?$': [
|
||||||
|
'@swc/jest',
|
||||||
|
{
|
||||||
|
sourceMaps: 'inline',
|
||||||
|
jsc: {
|
||||||
|
parser: {
|
||||||
|
syntax: 'typescript',
|
||||||
|
tsx: true,
|
||||||
|
decorators: true,
|
||||||
|
dynamicImport: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,10 @@ import '@testing-library/jest-dom';
|
||||||
|
|
||||||
import 'plugin/dayjs';
|
import 'plugin/dayjs';
|
||||||
|
|
||||||
|
import { TextEncoder, TextDecoder } from 'util';
|
||||||
|
|
||||||
|
Object.assign(global, { TextDecoder, TextEncoder });
|
||||||
|
|
||||||
// https://stackoverflow.com/a/66055672
|
// https://stackoverflow.com/a/66055672
|
||||||
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
|
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
|
||||||
Object.defineProperty(window, 'matchMedia', {
|
Object.defineProperty(window, 'matchMedia', {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
"lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --quiet ./src ./e2e-tests",
|
"lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --quiet ./src ./e2e-tests",
|
||||||
"stylelint": "stylelint ./src/**/*.{css,scss,module.css,module.scss}",
|
"stylelint": "stylelint ./src/**/*.{css,scss,module.css,module.scss}",
|
||||||
"stylelint:fix": "stylelint --fix ./src/**/*.{css,scss,module.css,module.scss}",
|
"stylelint:fix": "stylelint --fix ./src/**/*.{css,scss,module.css,module.scss}",
|
||||||
"build": "grafana-toolkit plugin:build",
|
"build": "webpack -c ./webpack.config.ts --env production",
|
||||||
"build:dev": "grafana-toolkit plugin:build --skipTest --skipLint",
|
"build:dev": "webpack -c ./webpack.config.ts --env development",
|
||||||
"labels:link": "yarn --cwd ../../gops-labels/frontend link && yarn link \"@grafana/labels\" && yarn --cwd ../../gops-labels/frontend watch",
|
"labels:link": "yarn --cwd ../../gops-labels/frontend link && yarn link \"@grafana/labels\" && yarn --cwd ../../gops-labels/frontend watch",
|
||||||
"labels:unlink": "yarn --cwd ../../gops-labels/frontend unlink",
|
"labels:unlink": "yarn --cwd ../../gops-labels/frontend unlink",
|
||||||
"test": "jest --verbose",
|
"test": "jest --verbose",
|
||||||
|
|
@ -19,12 +19,9 @@
|
||||||
"test:e2e:gen": "yarn playwright codegen http://localhost:3000",
|
"test:e2e:gen": "yarn playwright codegen http://localhost:3000",
|
||||||
"e2e-show-report": "yarn playwright show-report",
|
"e2e-show-report": "yarn playwright show-report",
|
||||||
"generate-types": "cd ./src/network/oncall-api/types-generator && yarn generate",
|
"generate-types": "cd ./src/network/oncall-api/types-generator && yarn generate",
|
||||||
"dev": "grafana-toolkit plugin:dev",
|
"dev": "webpack -c ./.config/webpack/webpack.config.ts --env development",
|
||||||
"watch": "grafana-toolkit plugin:dev --watch",
|
"watch": "webpack -w -c ./.config/webpack/webpack.config.ts --env development",
|
||||||
"sign": "grafana-toolkit plugin:sign",
|
"sign": "npx --yes @grafana/sign-plugin@latest",
|
||||||
"ci-build:finish": "grafana-toolkit plugin:ci-build --finish",
|
|
||||||
"ci-package": "grafana-toolkit plugin:ci-package",
|
|
||||||
"ci-report": "grafana-toolkit plugin:ci-report",
|
|
||||||
"start": "yarn watch",
|
"start": "yarn watch",
|
||||||
"plop": "plop",
|
"plop": "plop",
|
||||||
"setversion": "setversion",
|
"setversion": "setversion",
|
||||||
|
|
@ -50,6 +47,7 @@
|
||||||
"author": "Grafana Labs",
|
"author": "Grafana Labs",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.21.4",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||||
"@babel/plugin-proposal-decorators": "^7.20.0",
|
"@babel/plugin-proposal-decorators": "^7.20.0",
|
||||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
|
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
|
||||||
|
|
@ -64,17 +62,21 @@
|
||||||
"@babel/preset-env": "^7.18.10",
|
"@babel/preset-env": "^7.18.10",
|
||||||
"@babel/preset-react": "^7.18.6",
|
"@babel/preset-react": "^7.18.6",
|
||||||
"@babel/preset-typescript": "^7.18.6",
|
"@babel/preset-typescript": "^7.18.6",
|
||||||
"@grafana/eslint-config": "^5.1.0",
|
"@grafana/eslint-config": "^6.0.0",
|
||||||
"@grafana/toolkit": "^9.5.2",
|
"@grafana/tsconfig": "^1.2.0-rc1",
|
||||||
"@jest/globals": "^27.5.1",
|
"@jest/globals": "^27.5.1",
|
||||||
"@playwright/test": "^1.39.0",
|
"@playwright/test": "^1.39.0",
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@swc/core": "^1.3.90",
|
||||||
"@testing-library/react": "12",
|
"@swc/helpers": "^0.5.0",
|
||||||
|
"@swc/jest": "^0.2.26",
|
||||||
|
"@testing-library/jest-dom": "6.1.4",
|
||||||
|
"@testing-library/react": "14.0.0",
|
||||||
"@testing-library/user-event": "^14.4.3",
|
"@testing-library/user-event": "^14.4.3",
|
||||||
"@types/dompurify": "^2.3.4",
|
"@types/dompurify": "^2.3.4",
|
||||||
"@types/jest": "27.5.1",
|
"@types/jest": "^29.5.0",
|
||||||
|
"@types/lodash": "^4.14.194",
|
||||||
"@types/lodash-es": "^4.17.6",
|
"@types/lodash-es": "^4.17.6",
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^20.8.7",
|
||||||
"@types/query-string": "^6.3.0",
|
"@types/query-string": "^6.3.0",
|
||||||
"@types/react-copy-to-clipboard": "^5.0.4",
|
"@types/react-copy-to-clipboard": "^5.0.4",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
|
|
@ -82,19 +84,26 @@
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/react-test-renderer": "^18.0.5",
|
"@types/react-test-renderer": "^18.0.5",
|
||||||
"@types/react-transition-group": "^4.4.5",
|
"@types/react-transition-group": "^4.4.5",
|
||||||
|
"@types/testing-library__jest-dom": "5.14.8",
|
||||||
"@types/throttle-debounce": "^5.0.0",
|
"@types/throttle-debounce": "^5.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.40.1",
|
"@typescript-eslint/eslint-plugin": "^5.40.1",
|
||||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||||
"copy-webpack-plugin": "^11.0.0",
|
"copy-webpack-plugin": "^11.0.0",
|
||||||
|
"css-loader": "^6.7.3",
|
||||||
"dompurify": "^2.3.12",
|
"dompurify": "^2.3.12",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"eslint": "^8.25.0",
|
"eslint": "^8.25.0",
|
||||||
|
"eslint-plugin-deprecation": "^2.0.0",
|
||||||
"eslint-plugin-jsdoc": "^44.2.4",
|
"eslint-plugin-jsdoc": "^44.2.4",
|
||||||
"eslint-plugin-react": "^7.31.10",
|
"eslint-plugin-react": "^7.31.10",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"eslint-plugin-rulesdir": "^0.2.1",
|
"eslint-plugin-rulesdir": "^0.2.1",
|
||||||
"jest": "27.5.1",
|
"eslint-webpack-plugin": "^4.0.1",
|
||||||
"jest-environment-jsdom": "^27.5.1",
|
"fork-ts-checker-webpack-plugin": "^8.0.0",
|
||||||
|
"glob": "^10.2.7",
|
||||||
|
"identity-obj-proxy": "3.0.0",
|
||||||
|
"jest": "^29.5.0",
|
||||||
|
"jest-environment-jsdom": "^29.5.0",
|
||||||
"lint-staged": "^10.2.11",
|
"lint-staged": "^10.2.11",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mailslurp-client": "^15.14.1",
|
"mailslurp-client": "^15.14.1",
|
||||||
|
|
@ -102,26 +111,35 @@
|
||||||
"openapi-typescript": "^7.0.0-next.4",
|
"openapi-typescript": "^7.0.0-next.4",
|
||||||
"plop": "^2.7.4",
|
"plop": "^2.7.4",
|
||||||
"postcss-loader": "^7.0.1",
|
"postcss-loader": "^7.0.1",
|
||||||
|
"prettier": "^2.8.7",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-test-renderer": "^18.0.2",
|
"react-test-renderer": "^18.0.2",
|
||||||
|
"replace-in-file-webpack-plugin": "^1.0.6",
|
||||||
|
"sass": "1.63.2",
|
||||||
|
"sass-loader": "13.3.1",
|
||||||
|
"style-loader": "3.3.3",
|
||||||
"stylelint-config-prettier": "^9.0.3",
|
"stylelint-config-prettier": "^9.0.3",
|
||||||
"stylelint-prettier": "^2.0.0",
|
"stylelint-prettier": "^2.0.0",
|
||||||
|
"swc-loader": "^0.2.3",
|
||||||
"ts-jest": "29.0.3",
|
"ts-jest": "29.0.3",
|
||||||
"ts-loader": "^9.3.1",
|
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "4.6.4",
|
"tsconfig-paths": "^4.2.0",
|
||||||
|
"typescript": "4.8.4",
|
||||||
|
"webpack": "^5.86.0",
|
||||||
"webpack-bundle-analyzer": "^4.6.1",
|
"webpack-bundle-analyzer": "^4.6.1",
|
||||||
|
"webpack-cli": "^5.1.4",
|
||||||
"webpack-livereload-plugin": "^3.0.2"
|
"webpack-livereload-plugin": "^3.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": "~18.16.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dnd-kit/core": "^6.0.8",
|
"@dnd-kit/core": "^6.0.8",
|
||||||
"@dnd-kit/modifiers": "^7.0.0",
|
"@dnd-kit/modifiers": "^7.0.0",
|
||||||
"@dnd-kit/sortable": "^7.0.2",
|
"@dnd-kit/sortable": "^7.0.2",
|
||||||
"@dnd-kit/utilities": "^3.2.1",
|
"@dnd-kit/utilities": "^3.2.1",
|
||||||
|
"@emotion/css": "11.10.6",
|
||||||
"@grafana/data": "^10.2.3",
|
"@grafana/data": "^10.2.3",
|
||||||
"@grafana/faro-web-sdk": "^1.0.0-beta4",
|
"@grafana/faro-web-sdk": "^1.0.0-beta4",
|
||||||
"@grafana/faro-web-tracing": "^1.0.0-beta4",
|
"@grafana/faro-web-tracing": "^1.0.0-beta4",
|
||||||
|
|
@ -133,6 +151,8 @@
|
||||||
"@lifeomic/attempt": "^3.0.3",
|
"@lifeomic/attempt": "^3.0.3",
|
||||||
"@opentelemetry/api": "^1.3.0",
|
"@opentelemetry/api": "^1.3.0",
|
||||||
"array-move": "^4.0.0",
|
"array-move": "^4.0.0",
|
||||||
|
"axios": "^1.6.7",
|
||||||
|
"babel-loader": "^9.1.3",
|
||||||
"change-case": "^4.1.1",
|
"change-case": "^4.1.1",
|
||||||
"circular-dependency-plugin": "^5.2.2",
|
"circular-dependency-plugin": "^5.2.2",
|
||||||
"dayjs": "^1.11.5",
|
"dayjs": "^1.11.5",
|
||||||
|
|
@ -142,11 +162,12 @@
|
||||||
"mobx-react": "9.1.0",
|
"mobx-react": "9.1.0",
|
||||||
"object-hash": "^3.0.0",
|
"object-hash": "^3.0.0",
|
||||||
"openapi-fetch": "^0.8.1",
|
"openapi-fetch": "^0.8.1",
|
||||||
"prettier": "^2.8.2",
|
|
||||||
"qrcode.react": "^3.1.0",
|
"qrcode.react": "^3.1.0",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
"rc-table": "^7.17.1",
|
"rc-table": "^7.17.1",
|
||||||
|
"react": "18.2.0",
|
||||||
"react-copy-to-clipboard": "^5.0.2",
|
"react-copy-to-clipboard": "^5.0.2",
|
||||||
|
"react-dom": "18.2.0",
|
||||||
"react-draggable": "^4.4.5",
|
"react-draggable": "^4.4.5",
|
||||||
"react-emoji-render": "^1.2.4",
|
"react-emoji-render": "^1.2.4",
|
||||||
"react-modal": "^3.15.1",
|
"react-modal": "^3.15.1",
|
||||||
|
|
@ -155,9 +176,10 @@
|
||||||
"react-sortable-hoc": "^1.11.0",
|
"react-sortable-hoc": "^1.11.0",
|
||||||
"react-string-replace": "^0.4.4",
|
"react-string-replace": "^0.4.4",
|
||||||
"react-transition-group": "^4.4.5",
|
"react-transition-group": "^4.4.5",
|
||||||
"sass-loader": "^13.0.2",
|
|
||||||
"stylelint": "^13.13.1",
|
"stylelint": "^13.13.1",
|
||||||
"stylelint-config-standard": "^22.0.0",
|
"stylelint-config-standard": "^22.0.0",
|
||||||
"throttle-debounce": "^2.1.0"
|
"throttle-debounce": "^2.1.0",
|
||||||
}
|
"tslib": "2.5.3"
|
||||||
|
},
|
||||||
|
"packageManager": "yarn@1.22.21"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ const getStyles = (theme: GrafanaTheme2, color?: string, size?: string) => {
|
||||||
color: ${fontColor};
|
color: ${fontColor};
|
||||||
font-size: ${theme.typography.bodySmall.fontSize};
|
font-size: ${theme.typography.bodySmall.fontSize};
|
||||||
|
|
||||||
border-radius: ${theme.shape.borderRadius(2)};
|
border-radius: ${theme.shape.radius.default};
|
||||||
`,
|
`,
|
||||||
label: css`
|
label: css`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -68,8 +68,8 @@ const getStyles = (theme: GrafanaTheme2, color?: string, size?: string) => {
|
||||||
background: ${backgroundColor};
|
background: ${backgroundColor};
|
||||||
|
|
||||||
border: solid 1px ${borderColor};
|
border: solid 1px ${borderColor};
|
||||||
border-top-left-radius: ${theme.shape.borderRadius(2)};
|
border-top-left-radius: ${theme.shape.radius.default};
|
||||||
border-bottom-left-radius: ${theme.shape.borderRadius(2)};
|
border-bottom-left-radius: ${theme.shape.radius.default};
|
||||||
`,
|
`,
|
||||||
value: css`
|
value: css`
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
|
@ -78,8 +78,8 @@ const getStyles = (theme: GrafanaTheme2, color?: string, size?: string) => {
|
||||||
|
|
||||||
border: solid 1px ${borderColor};
|
border: solid 1px ${borderColor};
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-top-right-radius: ${theme.shape.borderRadius(2)};
|
border-top-right-radius: ${theme.shape.radius.default};
|
||||||
border-bottom-right-radius: ${theme.shape.borderRadius(2)};
|
border-bottom-right-radius: ${theme.shape.radius.default};
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ exports[`Unauthorized renders properly - access control enabled: false 1`] = `
|
||||||
<div
|
<div
|
||||||
className="css-8tu8mo-vertical-group"
|
className="css-8tu8mo-vertical-group"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"height": "100%",
|
"height": "100%",
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
}
|
}
|
||||||
|
|
@ -22,7 +22,7 @@ exports[`Unauthorized renders properly - access control enabled: false 1`] = `
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +40,7 @@ exports[`Unauthorized renders properly - access control enabled: false 1`] = `
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +65,7 @@ exports[`Unauthorized renders properly - access control enabled: true 1`] = `
|
||||||
<div
|
<div
|
||||||
className="css-8tu8mo-vertical-group"
|
className="css-8tu8mo-vertical-group"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"height": "100%",
|
"height": "100%",
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +80,7 @@ exports[`Unauthorized renders properly - access control enabled: true 1`] = `
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +98,7 @@ exports[`Unauthorized renders properly - access control enabled: true 1`] = `
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +123,7 @@ exports[`Unauthorized renders properly the grammar for different roles - Admin 1
|
||||||
<div
|
<div
|
||||||
className="css-8tu8mo-vertical-group"
|
className="css-8tu8mo-vertical-group"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"height": "100%",
|
"height": "100%",
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +138,7 @@ exports[`Unauthorized renders properly the grammar for different roles - Admin 1
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +156,7 @@ exports[`Unauthorized renders properly the grammar for different roles - Admin 1
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +181,7 @@ exports[`Unauthorized renders properly the grammar for different roles - Editor
|
||||||
<div
|
<div
|
||||||
className="css-8tu8mo-vertical-group"
|
className="css-8tu8mo-vertical-group"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"height": "100%",
|
"height": "100%",
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +196,7 @@ exports[`Unauthorized renders properly the grammar for different roles - Editor
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -214,7 +214,7 @@ exports[`Unauthorized renders properly the grammar for different roles - Editor
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -239,7 +239,7 @@ exports[`Unauthorized renders properly the grammar for different roles - Viewer
|
||||||
<div
|
<div
|
||||||
className="css-8tu8mo-vertical-group"
|
className="css-8tu8mo-vertical-group"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"height": "100%",
|
"height": "100%",
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
}
|
}
|
||||||
|
|
@ -254,7 +254,7 @@ exports[`Unauthorized renders properly the grammar for different roles - Viewer
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -272,7 +272,7 @@ exports[`Unauthorized renders properly the grammar for different roles - Viewer
|
||||||
<span
|
<span
|
||||||
className="root text text--undefined text--medium"
|
className="root text text--undefined text--medium"
|
||||||
style={
|
style={
|
||||||
Object {
|
{
|
||||||
"maxWidth": undefined,
|
"maxWidth": undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ describe('AddRespondersPopup', () => {
|
||||||
},
|
},
|
||||||
grafanaTeamStore: {
|
grafanaTeamStore: {
|
||||||
getSearchResult: jest.fn().mockReturnValue(teams),
|
getSearchResult: jest.fn().mockReturnValue(teams),
|
||||||
|
updateItems: jest.fn(),
|
||||||
},
|
},
|
||||||
userStore: {
|
userStore: {
|
||||||
search: jest.fn().mockReturnValue({ results: [] }),
|
search: jest.fn().mockReturnValue({ results: [] }),
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ describe('reloadPageWithPluginConfiguredQueryParams', () => {
|
||||||
describe('removePluginConfiguredQueryParams', () => {
|
describe('removePluginConfiguredQueryParams', () => {
|
||||||
test('it removes all the query params if history.pushState is available, and plugin is enabled', () => {
|
test('it removes all the query params if history.pushState is available, and plugin is enabled', () => {
|
||||||
removePluginConfiguredQueryParams(true);
|
removePluginConfiguredQueryParams(true);
|
||||||
expect(window.history.pushState).toBeCalledWith({ path: MOCK_URL }, '', MOCK_URL);
|
expect(window.history.pushState).toHaveBeenCalledWith({ path: MOCK_URL }, '', MOCK_URL);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it does not remove all the query params if history.pushState is available, and plugin is disabled', () => {
|
test('it does not remove all the query params if history.pushState is available, and plugin is disabled', () => {
|
||||||
|
|
@ -148,7 +148,7 @@ describe('PluginConfigPage', () => {
|
||||||
await screen.findByTestId(STATUS_MESSAGE_BLOCK_DATA_ID);
|
await screen.findByTestId(STATUS_MESSAGE_BLOCK_DATA_ID);
|
||||||
|
|
||||||
// assertions
|
// assertions
|
||||||
expect(window.history.pushState).toBeCalledWith({ path: MOCK_URL }, '', MOCK_URL);
|
expect(window.history.pushState).toHaveBeenCalledWith({ path: MOCK_URL }, '', MOCK_URL);
|
||||||
|
|
||||||
expect(PluginState.updatePluginStatus).toHaveBeenCalledTimes(1);
|
expect(PluginState.updatePluginStatus).toHaveBeenCalledTimes(1);
|
||||||
expect(PluginState.updatePluginStatus).toHaveBeenCalledWith(metaJsonDataOnCallApiUrl);
|
expect(PluginState.updatePluginStatus).toHaveBeenCalledWith(metaJsonDataOnCallApiUrl);
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ class _IncidentsPage extends React.Component<IncidentsPageProps, IncidentsPageSt
|
||||||
}
|
}
|
||||||
|
|
||||||
private rootElRef: React.RefObject<HTMLDivElement>;
|
private rootElRef: React.RefObject<HTMLDivElement>;
|
||||||
private pollingIntervalId: NodeJS.Timer = undefined;
|
private pollingIntervalId: ReturnType<typeof setInterval> = undefined;
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { store } = this.props;
|
const { store } = this.props;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export class _ChatOpsPage extends React.Component<ChatOpsProps, ChatOpsState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { query } = this.props;
|
const { query } = this.props; // eslint-disable-line
|
||||||
|
|
||||||
this.handleChatopsTabChange(query?.tab || ChatOpsTab.Slack);
|
this.handleChatopsTabChange(query?.tab || ChatOpsTab.Slack);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -254,20 +254,23 @@ describe('PluginState.installPlugin', () => {
|
||||||
onCallAPIResponse: mockedResponse,
|
onCallAPIResponse: mockedResponse,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(PluginState.createGrafanaToken).toBeCalledTimes(1);
|
expect(PluginState.createGrafanaToken).toHaveBeenCalledTimes(1);
|
||||||
expect(PluginState.createGrafanaToken).toBeCalledWith();
|
expect(PluginState.createGrafanaToken).toHaveBeenCalledWith();
|
||||||
|
|
||||||
expect(PluginState.updateGrafanaPluginSettings).toBeCalledTimes(1);
|
expect(PluginState.updateGrafanaPluginSettings).toHaveBeenCalledTimes(1);
|
||||||
expect(PluginState.updateGrafanaPluginSettings).toBeCalledWith({
|
expect(PluginState.updateGrafanaPluginSettings).toHaveBeenCalledWith({
|
||||||
secureJsonData: {
|
secureJsonData: {
|
||||||
grafanaToken,
|
grafanaToken,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(makeRequest).toBeCalledTimes(1);
|
expect(makeRequest).toHaveBeenCalledTimes(1);
|
||||||
expect(makeRequest).toBeCalledWith(`${PluginState.ONCALL_BASE_URL}/${selfHosted ? 'self-hosted/' : ''}install`, {
|
expect(makeRequest).toHaveBeenCalledWith(
|
||||||
method: 'POST',
|
`${PluginState.ONCALL_BASE_URL}/${selfHosted ? 'self-hosted/' : ''}install`,
|
||||||
});
|
{
|
||||||
|
method: 'POST',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ export const getCoords = (elem) => {
|
||||||
const body = document.body;
|
const body = document.body;
|
||||||
const docEl = document.documentElement;
|
const docEl = document.documentElement;
|
||||||
|
|
||||||
const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
|
const scrollTop = window.scrollY || docEl.scrollTop || body.scrollTop;
|
||||||
const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
|
const scrollLeft = window.scrollX || docEl.scrollLeft || body.scrollLeft;
|
||||||
|
|
||||||
const clientTop = docEl.clientTop || body.clientTop || 0;
|
const clientTop = docEl.clientTop || body.clientTop || 0;
|
||||||
const clientLeft = docEl.clientLeft || body.clientLeft || 0;
|
const clientLeft = docEl.clientLeft || body.clientLeft || 0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { OnCallAppPluginMeta } from 'types';
|
import { OnCallAppPluginMeta } from 'types';
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
import plugin from '../../package.json'; // eslint-disable-line
|
import plugin from '../../package.json'; // eslint-disable-line
|
||||||
|
|
||||||
// Navbar
|
// Navbar
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { TimeOption, TimeRange, TimeZone, rangeUtil } from '@grafana/data';
|
import { TimeOption, TimeRange, rangeUtil } from '@grafana/data';
|
||||||
|
import { TimeZone } from '@grafana/schema';
|
||||||
|
|
||||||
// Valid mapping accepted by @grafana/ui and @grafana/data packages
|
// Valid mapping accepted by @grafana/ui and @grafana/data packages
|
||||||
export const quickOptions = [
|
export const quickOptions = [
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
{
|
{
|
||||||
"extends": "@grafana/toolkit/src/config/tsconfig.plugin.json",
|
"extends": "./.config/tsconfig.json",
|
||||||
"include": ["src", "e2e-tests", "playwright.config.ts"],
|
"include": ["src", "e2e-tests", "playwright.config.ts"],
|
||||||
"types": ["node", "@emotion/core"],
|
"types": ["node", "@emotion/core"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDirs": ["src"],
|
"rootDir": "",
|
||||||
"baseUrl": "src",
|
|
||||||
"typeRoots": ["./node_modules/@types"],
|
"typeRoots": ["./node_modules/@types"],
|
||||||
"noUnusedLocals": false,
|
"noUnusedLocals": false,
|
||||||
"noUnusedParameters": false,
|
"noUnusedParameters": false,
|
||||||
|
|
|
||||||
|
|
@ -1,158 +0,0 @@
|
||||||
const webpack = require('webpack');
|
|
||||||
const path = require('path');
|
|
||||||
const dotenv = require('dotenv');
|
|
||||||
const LiveReloadPlugin = require('webpack-livereload-plugin');
|
|
||||||
|
|
||||||
const CircularDependencyPlugin = require('circular-dependency-plugin');
|
|
||||||
|
|
||||||
const MONACO_DIR = path.resolve(__dirname, './node_modules/monaco-editor');
|
|
||||||
|
|
||||||
Object.defineProperty(RegExp.prototype, 'toJSON', {
|
|
||||||
value: RegExp.prototype.toString,
|
|
||||||
});
|
|
||||||
|
|
||||||
dotenv.config({ path: path.resolve(__dirname, '.env') });
|
|
||||||
|
|
||||||
module.exports.getWebpackConfig = (config, options) => {
|
|
||||||
const cssLoader = config.module.rules.find((rule) => rule.test.toString() === '/\\.css$/');
|
|
||||||
|
|
||||||
cssLoader.exclude.push(/\.module\.css$/, MONACO_DIR);
|
|
||||||
|
|
||||||
const grafanaRules = config.module.rules.filter((a) => a.test.toString() !== /\.s[ac]ss$/.toString());
|
|
||||||
|
|
||||||
const newConfig = {
|
|
||||||
...config,
|
|
||||||
module: {
|
|
||||||
...config.module,
|
|
||||||
rules: [
|
|
||||||
...grafanaRules,
|
|
||||||
|
|
||||||
{
|
|
||||||
test: /\.(ts|tsx)$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: 'babel-loader',
|
|
||||||
options: {
|
|
||||||
cacheDirectory: true,
|
|
||||||
cacheCompression: false,
|
|
||||||
presets: [
|
|
||||||
[
|
|
||||||
'@babel/preset-env',
|
|
||||||
{
|
|
||||||
modules: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'@babel/preset-typescript',
|
|
||||||
{
|
|
||||||
allowNamespaces: true,
|
|
||||||
allowDeclareFields: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
['@babel/preset-react'],
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
[
|
|
||||||
'@babel/plugin-transform-typescript',
|
|
||||||
{
|
|
||||||
allowNamespaces: true,
|
|
||||||
allowDeclareFields: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@babel/plugin-proposal-class-properties',
|
|
||||||
[
|
|
||||||
'@babel/plugin-proposal-object-rest-spread',
|
|
||||||
{
|
|
||||||
loose: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'@babel/plugin-proposal-decorators',
|
|
||||||
{
|
|
||||||
legacy: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@babel/plugin-transform-react-constant-elements',
|
|
||||||
'@babel/plugin-proposal-nullish-coalescing-operator',
|
|
||||||
'@babel/plugin-proposal-optional-chaining',
|
|
||||||
'@babel/plugin-syntax-dynamic-import',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'ts-loader',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
test: /\.module\.css$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
use: [
|
|
||||||
'style-loader',
|
|
||||||
{
|
|
||||||
loader: 'css-loader',
|
|
||||||
options: {
|
|
||||||
importLoaders: 1,
|
|
||||||
sourceMap: true,
|
|
||||||
modules: {
|
|
||||||
localIdentName: options.production ? '[name]__[hash:base64]' : '[path][name]__[local]',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
test: /\.module\.scss$/i,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
use: [
|
|
||||||
'style-loader',
|
|
||||||
{
|
|
||||||
loader: 'css-loader',
|
|
||||||
options: {
|
|
||||||
importLoaders: 1,
|
|
||||||
sourceMap: true,
|
|
||||||
modules: {
|
|
||||||
localIdentName: options.production ? '[name]__[hash:base64]' : '[path][name]__[local]',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'postcss-loader',
|
|
||||||
'sass-loader',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
plugins: [
|
|
||||||
...config.plugins,
|
|
||||||
new CircularDependencyPlugin({
|
|
||||||
// exclude detection of files based on a RegExp
|
|
||||||
exclude: /node_modules/,
|
|
||||||
// include specific files based on a RegExp
|
|
||||||
// add errors to webpack instead of warnings
|
|
||||||
failOnError: true,
|
|
||||||
// allow import cycles that include an asyncronous import,
|
|
||||||
// e.g. via import(/* webpackMode: "weak" */ './file.js')
|
|
||||||
allowAsyncCycles: false,
|
|
||||||
// set the current working directory for displaying module paths
|
|
||||||
cwd: process.cwd(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From docs (https://webpack.js.org/plugins/environment-plugin/):
|
|
||||||
* Default values of null and undefined behave differently.
|
|
||||||
* Use undefined for variables that must be provided during bundling, or null if they are optional.
|
|
||||||
*/
|
|
||||||
new webpack.EnvironmentPlugin({
|
|
||||||
ONCALL_API_URL: null,
|
|
||||||
}),
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
'process.env': JSON.stringify(dotenv.config().parsed),
|
|
||||||
}),
|
|
||||||
...(options.production ? [] : [new LiveReloadPlugin({ appendScriptTag: true, useSourceHash: true })]),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
return newConfig;
|
|
||||||
};
|
|
||||||
42
grafana-plugin/webpack.config.ts
Normal file
42
grafana-plugin/webpack.config.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import type { Configuration } from 'webpack';
|
||||||
|
import { mergeWithRules, CustomizeRule } from 'webpack-merge';
|
||||||
|
import grafanaConfig from './.config/webpack/webpack.config';
|
||||||
|
|
||||||
|
const config = async (env): Promise<Configuration> => {
|
||||||
|
const baseConfig = await grafanaConfig(env);
|
||||||
|
const customConfig = {
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.[tj]sx?$/,
|
||||||
|
use: {
|
||||||
|
options: {
|
||||||
|
jsc: {
|
||||||
|
parser: {
|
||||||
|
decorators: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
watchOptions: {
|
||||||
|
ignored: ['**/node_modules/', '**/dist'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return mergeWithRules({
|
||||||
|
module: {
|
||||||
|
rules: {
|
||||||
|
test: CustomizeRule.Match,
|
||||||
|
use: CustomizeRule.Merge,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watchOptions: {
|
||||||
|
use: CustomizeRule.Merge,
|
||||||
|
},
|
||||||
|
})(baseConfig, customConfig);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue