rozetko
2 years ago
34 changed files with 3910 additions and 525 deletions
@ -1,2 +0,0 @@
|
||||
export const SOURCE_DIR = 'src'; |
||||
export const DIST_DIR = 'dist'; |
@ -1,9 +0,0 @@
|
||||
{ |
||||
"compilerOptions": { |
||||
"module": "commonjs", |
||||
"target": "es5", |
||||
"esModuleInterop": true |
||||
}, |
||||
"transpileOnly": true, |
||||
"transpiler": "ts-node/transpilers/swc-experimental" |
||||
} |
@ -1,42 +0,0 @@
|
||||
import fs from 'fs'; |
||||
import path from 'path'; |
||||
import util from 'util'; |
||||
import glob from 'glob'; |
||||
import { SOURCE_DIR } from './constants'; |
||||
|
||||
const globAsync = util.promisify(glob); |
||||
|
||||
export function getPackageJson() { |
||||
return require(path.resolve(process.cwd(), 'package.json')); |
||||
} |
||||
|
||||
export function getPluginId() { |
||||
const { id } = require(path.resolve(process.cwd(), `${SOURCE_DIR}/plugin.json`)); |
||||
|
||||
return id; |
||||
} |
||||
|
||||
export function hasReadme() { |
||||
return fs.existsSync(path.resolve(process.cwd(), SOURCE_DIR, 'README.md')); |
||||
} |
||||
|
||||
export async function getEntries(): Promise<Record<string, string>> { |
||||
const parent = '..'; |
||||
const pluginsJson = await globAsync('**/src/**/plugin.json'); |
||||
|
||||
const plugins = await Promise.all(pluginsJson.map(pluginJson => { |
||||
const folder = path.dirname(pluginJson); |
||||
return globAsync(`${folder}/module.{ts,tsx,js}`); |
||||
})); |
||||
|
||||
return plugins.reduce((result, modules) => { |
||||
return modules.reduce((result, module) => { |
||||
const pluginPath = path.resolve(path.dirname(module), parent); |
||||
const pluginName = path.basename(pluginPath); |
||||
const entryName = plugins.length > 1 ? `${pluginName}/module` : 'module'; |
||||
|
||||
result[entryName] = path.join(parent, module); |
||||
return result; |
||||
}, result); |
||||
}, {}); |
||||
} |
@ -1,3 +1,4 @@
|
||||
node_modules |
||||
dist |
||||
.eslintcache |
||||
yarn-error.log |
||||
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<testsuites name="jest tests" tests="3" failures="0" errors="0" time="2.424"> |
||||
<testsuite name="RemoveCurrentConfigurationButton" errors="0" failures="0" skipped="0" timestamp="2022-12-19T18:00:28" time="1.512" tests="3"> |
||||
<testcase classname="RemoveCurrentConfigurationButton It renders properly when enabled" name="RemoveCurrentConfigurationButton It renders properly when enabled" time="0.022"> |
||||
</testcase> |
||||
<testcase classname="RemoveCurrentConfigurationButton It renders properly when disabled" name="RemoveCurrentConfigurationButton It renders properly when disabled" time="0.003"> |
||||
</testcase> |
||||
<testcase classname="RemoveCurrentConfigurationButton It calls the onClick handler when clicked" name="RemoveCurrentConfigurationButton It calls the onClick handler when clicked" time="0.164"> |
||||
</testcase> |
||||
</testsuite> |
||||
</testsuites> |
@ -1,2 +0,0 @@
|
||||
// Jest setup provided by Grafana scaffolding
|
||||
import './.config/jest-setup'; |
@ -1,4 +1,8 @@
|
||||
module.exports = { |
||||
// Jest configuration provided by Grafana scaffolding
|
||||
...require('./.config/jest.config'), |
||||
}; |
||||
// This file is needed because it is used by vscode and other tools that
|
||||
// call `jest` directly. However, unless you are doing anything special
|
||||
// do not edit this file
|
||||
|
||||
const standard = require('@grafana/toolkit/src/config/jest.plugin.config'); |
||||
|
||||
// This process will use the same config that `yarn test` is using
|
||||
module.exports = standard.jestConfig(); |
||||
|
@ -0,0 +1,4 @@
|
||||
export const getBackendSrv = () => ({ |
||||
get: jest.fn(), |
||||
post: jest.fn(), |
||||
}); |
@ -1,32 +0,0 @@
|
||||
import React from 'react'; |
||||
import { AppRootProps, PluginType } from '@grafana/data'; |
||||
import { render, screen } from '@testing-library/react'; |
||||
import { App } from './App'; |
||||
|
||||
describe('Components/App', () => { |
||||
let props: AppRootProps; |
||||
|
||||
beforeEach(() => { |
||||
jest.resetAllMocks(); |
||||
|
||||
props = { |
||||
basename: 'a/sample-app', |
||||
meta: { |
||||
id: 'sample-app', |
||||
name: 'Sample App', |
||||
type: PluginType.app, |
||||
enabled: true, |
||||
jsonData: {}, |
||||
}, |
||||
query: {}, |
||||
path: '', |
||||
onNavChanged: jest.fn(), |
||||
} as unknown as AppRootProps; |
||||
}); |
||||
|
||||
test('renders without an error"', () => { |
||||
render(<App {...props} />); |
||||
|
||||
expect(screen.queryByText(/Hello Grafana!/i)).toBeInTheDocument(); |
||||
}); |
||||
}); |
@ -1,8 +0,0 @@
|
||||
import * as React from 'react'; |
||||
import { AppRootProps } from '@grafana/data'; |
||||
|
||||
export class App extends React.PureComponent<AppRootProps> { |
||||
render() { |
||||
return <div className="page-container">Hello Grafana!</div>; |
||||
} |
||||
} |
@ -1 +1,3 @@
|
||||
import '../../style/vars.css'; |
||||
import '../../style/global.css'; |
||||
export * from './PluginConfigPage'; |
||||
|
@ -0,0 +1,36 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
||||
|
||||
exports[`RemoveCurrentConfigurationButton It renders properly when disabled 1`] = ` |
||||
<body> |
||||
<div> |
||||
<button |
||||
class="css-mk7eo3-button" |
||||
disabled="" |
||||
type="button" |
||||
> |
||||
<span |
||||
class="css-1mhnkuh" |
||||
> |
||||
Remove current configuration |
||||
</span> |
||||
</button> |
||||
</div> |
||||
</body> |
||||
`; |
||||
|
||||
exports[`RemoveCurrentConfigurationButton It renders properly when enabled 1`] = ` |
||||
<body> |
||||
<div> |
||||
<button |
||||
class="css-mk7eo3-button" |
||||
type="button" |
||||
> |
||||
<span |
||||
class="css-1mhnkuh" |
||||
> |
||||
Remove current configuration |
||||
</span> |
||||
</button> |
||||
</div> |
||||
</body> |
||||
`; |
@ -1,12 +0,0 @@
|
||||
import React from 'react'; |
||||
|
||||
import { render } from '@testing-library/react'; |
||||
|
||||
import StatusMessageBlock from '.'; |
||||
|
||||
describe('StatusMessageBlock', () => { |
||||
test('It renders properly', async () => { |
||||
const component = render(<StatusMessageBlock text="helloooo" />); |
||||
expect(component.baseElement).toMatchSnapshot(); |
||||
}); |
||||
}); |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,6 @@
|
||||
declare module '*.css'; |
||||
|
||||
declare module '*.scss' { |
||||
const content: Record<string, string>; |
||||
export default content; |
||||
} |
@ -0,0 +1,15 @@
|
||||
// @ts-ignore
|
||||
export default global.matchMedia = |
||||
global.matchMedia || |
||||
function (query) { |
||||
return { |
||||
matches: false, |
||||
media: query, |
||||
onchange: null, |
||||
addListener: jest.fn(), |
||||
removeListener: jest.fn(), |
||||
addEventListener: jest.fn(), |
||||
removeEventListener: jest.fn(), |
||||
dispatchEvent: jest.fn(), |
||||
}; |
||||
}; |
@ -0,0 +1,8 @@
|
||||
module.exports = { |
||||
process() { |
||||
return { code: 'module.exports = {};' }; |
||||
}, |
||||
getCacheKey() { |
||||
return 'svgTransform'; |
||||
}, |
||||
}; |
@ -0,0 +1,13 @@
|
||||
export function mockUseStore() { |
||||
jest.mock('state/useStore', () => ({ |
||||
useStore: () => ({ |
||||
isUserActionAllowed: jest.fn().mockReturnValue(true), |
||||
}), |
||||
})); |
||||
} |
||||
|
||||
export function mockGrafanaLocationSrv() { |
||||
jest.mock('@grafana/runtime', () => ({ |
||||
getLocationSrv: jest.fn(), |
||||
})); |
||||
} |
@ -0,0 +1,45 @@
|
||||
.configure-plugin { |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
@keyframes fadeIn { |
||||
from { |
||||
opacity: 0; |
||||
} |
||||
} |
||||
|
||||
/* Spinner */ |
||||
|
||||
.spin { |
||||
width: 100%; |
||||
margin-top: 200px; |
||||
margin-bottom: 200px; |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: center; |
||||
align-items: center; |
||||
} |
||||
|
||||
.spin-text { |
||||
margin-top: 20px; |
||||
} |
||||
|
||||
/* Tables */ |
||||
|
||||
.disabled-row { |
||||
background: #f0f0f0; |
||||
} |
||||
|
||||
.highlighted-row { |
||||
background: var(--highlighted-row-bg); |
||||
} |
||||
|
||||
/* Navigation */ |
||||
|
||||
.navbarRootFallback { |
||||
margin-top: 24px; |
||||
} |
||||
|
||||
.page-title { |
||||
margin-bottom: 16px; |
||||
} |
@ -0,0 +1,78 @@
|
||||
:root { |
||||
--maintenance-background: repeating-linear-gradient(45deg, #f6ba52, #f6ba52 20px, #ffd180 20px, #ffd180 40px); |
||||
--gren-5: #6ccf8e; |
||||
--green-6: #73d13d; |
||||
--red-5: #ff4d4f; |
||||
--orange-5: #ffa940; |
||||
--blue-2: #bae7ff; |
||||
--gray-5: #d9d9d9; |
||||
--gray-8: #595959; |
||||
--gray-9: #434343; |
||||
--cyan-1: #e6fffb; |
||||
--purple-9: #22075e; |
||||
--border-radius: 2px; |
||||
--gradient-brandHorizontal: linear-gradient(90deg, #f83 0%, #f53e4c 100%); |
||||
--gradient-brandVertical: linear-gradient(0.01deg, #f53e4c -31.2%, #f83 113.07%); |
||||
--always-gray: #ccccdc; |
||||
--title-marginBottom: 16px; |
||||
} |
||||
|
||||
.theme-light { |
||||
--cards-background: var(--blue-2); |
||||
--highlighted-row-bg: var(--cyan-1); |
||||
--disabled-button-color: #bdbdbd; |
||||
--primary-background: rgb(255, 255, 255); |
||||
--secondary-background: rgb(244, 245, 245); |
||||
--border: 1px solid rgba(36, 41, 46, 0.12); |
||||
--primary-text-color: rgb(36, 41, 46); |
||||
--secondary-text-color: rgba(36, 41, 46, 0.75); |
||||
--disabled-text-color: rgba(36, 41, 46, 0.5); |
||||
--warning-text-color: #8a6c00; |
||||
--success-text-color: rgb(10, 118, 78); |
||||
--error-text-color: rgb(207, 14, 91); |
||||
--primary-text-link: #1f62e0; |
||||
--timeline-icon-background: rgba(70, 76, 84, 0); |
||||
--timeline-icon-background-resolution-note: rgba(50, 116, 217, 0); |
||||
--oncall-icon-stroke-color: #fff; |
||||
--hover-selected: #f4f5f5; |
||||
--background-canvas: #f4f5f5; |
||||
--background-primary: #fff; |
||||
--background-secondary: #f4f5f5; |
||||
--border-medium: 1px solid rgba(36, 41, 46, 0.3); |
||||
--border-strong: 1px solid rgba(36, 41, 46, 0.4); |
||||
--border-weak: 1px solid rgba(36, 41, 46, 0.12); |
||||
--shadows-z1: 0 1px 2px rgba(24, 26, 27, 0.2); |
||||
--shadows-z2: 0 4px 8px rgba(24, 26, 27, 0.2); |
||||
--shadows-z3: 0 13px 20px 1px rgba(24, 26, 27, 0.18); |
||||
} |
||||
|
||||
.theme-dark { |
||||
--cards-background: var(--gray-9); |
||||
--highlighted-row-bg: var(--gray-9); |
||||
--disabled-button-color: hsla(0, 0%, 100%, 0.08); |
||||
--primary-background: rgb(24, 27, 31); |
||||
--secondary-background: rgb(34, 37, 43); |
||||
--border: 1px solid rgba(204, 204, 220, 0.15); |
||||
--primary-text-color: rgb(204, 204, 220); |
||||
--secondary-text-color: rgba(204, 204, 220, 0.65); |
||||
--disabled-text-color: rgba(204, 204, 220, 0.4); |
||||
--warning-text-color: #f8d06b; |
||||
--success-text-color: rgb(108, 207, 142); |
||||
--error-text-color: rgb(255, 82, 134); |
||||
--primary-text-link: #6e9fff; |
||||
--timeline-icon-background: rgba(70, 76, 84, 1); |
||||
--timeline-icon-background-resolution-note: rgba(50, 116, 217, 1); |
||||
--focused-box-shadow: rgb(17 18 23) 0 0 0 2px, rgb(61 113 217) 0 0 0 4px; |
||||
--hover-selected: rgba(204, 204, 220, 0.12); |
||||
--hover-selected-hardcoded: #34363d; |
||||
--oncall-icon-stroke-color: #181b1f; |
||||
--background-canvas: #111217; |
||||
--background-primary: #181b1f; |
||||
--background-secondary: #22252b; |
||||
--border-medium: 1px solid rgba(204, 204, 220, 0.15); |
||||
--border-strong: 1px solid rgba(204, 204, 220, 0.25); |
||||
--border-weak: 1px solid rgba(204, 204, 220, 0.07); |
||||
--shadows-z1: 0 1px 2px rgba(24, 26, 27, 0.75); |
||||
--shadows-z2: 0 4px 8px rgba(24, 26, 27, 0.75); |
||||
--shadows-z3: 0 8px 24px rgb(1, 4, 9); |
||||
} |
@ -0,0 +1,147 @@
|
||||
const webpack = require('webpack'); |
||||
const path = require('path'); |
||||
|
||||
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, |
||||
}); |
||||
|
||||
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(), |
||||
}), |
||||
], |
||||
|
||||
resolve: { |
||||
...config.resolve, |
||||
symlinks: false, |
||||
modules: [path.resolve(__dirname, './frontend_enterprise/src'), ...config.resolve.modules], |
||||
}, |
||||
}; |
||||
|
||||
return newConfig; |
||||
}; |
Loading…
Reference in new issue