Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"WebSearch"
],
"deny": [],
"ask": []
}
}
3 changes: 3 additions & 0 deletions .config/.cprc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"version": "6.1.1"
}
18 changes: 9 additions & 9 deletions .config/.prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
*/

module.exports = {
"endOfLine": "auto",
"printWidth": 120,
"trailingComma": "es5",
"semi": true,
"jsxSingleQuote": false,
"singleQuote": true,
"useTabs": false,
"tabWidth": 2
};
endOfLine: 'auto',
printWidth: 120,
trailingComma: 'es5',
semi: true,
jsxSingleQuote: false,
singleQuote: true,
useTabs: false,
tabWidth: 2,
};
44 changes: 41 additions & 3 deletions .config/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,52 @@ ARG grafana_image=grafana-enterprise

FROM grafana/${grafana_image}:${grafana_version}

ARG anonymous_auth_enabled=true
ARG development=false
ARG TARGETARCH


ENV DEV "${development}"

# Make it as simple as possible to access the grafana instance for development purposes
# Do NOT enable these settings in a public facing / production grafana instance
ENV GF_AUTH_ANONYMOUS_ORG_ROLE "Admin"
ENV GF_AUTH_ANONYMOUS_ENABLED "true"
ENV GF_AUTH_ANONYMOUS_ENABLED "${anonymous_auth_enabled}"
ENV GF_AUTH_BASIC_ENABLED "false"
# Set development mode so plugins can be loaded without the need to sign
ENV GF_DEFAULT_APP_MODE "development"

# Inject livereload script into grafana index.html

LABEL maintainer="Grafana Labs <[email protected]>"

ENV GF_PATHS_HOME="/usr/share/grafana"
WORKDIR $GF_PATHS_HOME

USER root
RUN sed -i 's/<\/body><\/html>/<script src=\"http:\/\/localhost:35729\/livereload.js\"><\/script><\/body><\/html>/g' /usr/share/grafana/public/views/index.html

# Installing supervisor and inotify-tools
RUN if [ "${development}" = "true" ]; then \
if grep -i -q alpine /etc/issue; then \
apk add supervisor inotify-tools git; \
elif grep -i -q ubuntu /etc/issue; then \
DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y supervisor inotify-tools git && \
rm -rf /var/lib/apt/lists/*; \
else \
echo 'ERROR: Unsupported base image' && /bin/false; \
fi \
fi

COPY supervisord/supervisord.conf /etc/supervisor.d/supervisord.ini
COPY supervisord/supervisord.conf /etc/supervisor/conf.d/supervisord.conf



# Inject livereload script into grafana index.html
RUN sed -i 's|</body>|<script src="http://localhost:35729/livereload.js"></script></body>|g' /usr/share/grafana/public/views/index.html


COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
43 changes: 27 additions & 16 deletions .config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,29 @@ to issues around working with the project.

### Extending the ESLint config

Edit the `.eslintrc` file in the project root in order to extend the ESLint configuration.
Edit the `eslint.config.mjs` file in the project root to extend the ESLint configuration. The following example disables deprecation notices for source files.

**Example:**

```json
{
"extends": "./.config/.eslintrc",
"rules": {
"react/prop-types": "off"
}
}
```javascript
import { defineConfig } from 'eslint/config';
import baseConfig from './.config/eslint.config.mjs';

export default defineConfig([
{
ignores: [
//...
],
},
...baseConfig,
{
files: ['src/**/*.{ts,tsx}'],
rules: {
'@typescript-eslint/no-deprecated': 'off',
},
},
]);
```

---

### Extending the Prettier config
Expand Down Expand Up @@ -56,7 +66,7 @@ set up the Jest DOM for the testing library and to apply some polyfills. ([link

#### ESM errors with Jest

A common issue found with the current jest config involves importing an npm package which only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be this can be extended in the following way:
A common issue with the current jest config involves importing an npm package that only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this, we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be, this can be extended in the following way:

```javascript
process.env.TZ = 'UTC';
Expand Down Expand Up @@ -106,9 +116,9 @@ We are going to use [`webpack-merge`](https://github.com/survivejs/webpack-merge
// webpack.config.ts
import type { Configuration } from 'webpack';
import { merge } from 'webpack-merge';
import grafanaConfig from './.config/webpack/webpack.config';
import grafanaConfig, { type Env } from './.config/webpack/webpack.config';

const config = async (env): Promise<Configuration> => {
const config = async (env: Env): Promise<Configuration> => {
const baseConfig = await grafanaConfig(env);

return merge(baseConfig, {
Expand Down Expand Up @@ -142,7 +152,7 @@ We need to update the `scripts` in the `package.json` to use the extended Webpac

### Configure grafana image to use when running docker

By default `grafana-enterprise` will be used as the docker image for all docker related commands. If you want to override this behaviour simply alter the `docker-compose.yaml` by adding the following build arg `grafana_image`.
By default, `grafana-enterprise` will be used as the docker image for all docker related commands. If you want to override this behavior, simply alter the `docker-compose.yaml` by adding the following build arg `grafana_image`.

**Example:**

Expand All @@ -151,14 +161,15 @@ version: '3.7'

services:
grafana:
container_name: 'myorg-basic-app'
extends:
file: .config/docker-compose-base.yaml
service: grafana
build:
context: ./.config
args:
grafana_version: ${GRAFANA_VERSION:-9.1.2}
grafana_image: ${GRAFANA_IMAGE:-grafana}
```

In this example we are assigning the environment variable `GRAFANA_IMAGE` to the build arg `grafana_image` with a default value of `grafana`. This will give you the possibility to set the value while running the docker-compose commands which might be convinent in some scenarios.
In this example, we assign the environment variable `GRAFANA_IMAGE` to the build arg `grafana_image` with a default value of `grafana`. This will allow you to set the value while running the docker compose commands, which might be convenient in some scenarios.

---
43 changes: 43 additions & 0 deletions .config/bundler/externals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { Configuration, ExternalItemFunctionData } from 'webpack';

type ExternalsType = Configuration['externals'];

export const externals: ExternalsType = [
// Required for dynamic publicPath resolution
{ 'amd-module': 'module' },
'lodash',
'jquery',
'moment',
'slate',
'emotion',
'@emotion/react',
'@emotion/css',
'prismjs',
'slate-plain-serializer',
'@grafana/slate-react',
'react',
'react-dom',
'react-redux',
'redux',
'rxjs',
'i18next',
'react-router',
'd3',
'angular',
/^@grafana\/ui/i,
/^@grafana\/runtime/i,
/^@grafana\/data/i,

// Mark legacy SDK imports as external if their name starts with the "grafana/" prefix
({ request }: ExternalItemFunctionData, callback: (error?: Error, result?: string) => void) => {
const prefix = 'grafana/';
const hasPrefix = (request: string) => request.indexOf(prefix) === 0;
const stripPrefix = (request: string) => request.slice(prefix.length);

if (request && hasPrefix(request)) {
return callback(undefined, stripPrefix(request));
}

callback();
},
];
25 changes: 25 additions & 0 deletions .config/docker-compose-base.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
services:
grafana:
user: root
container_name: 'swiftmade-sankey-panel'

build:
context: .
args:
grafana_image: ${GRAFANA_IMAGE:-grafana-enterprise}
grafana_version: ${GRAFANA_VERSION:-12.2.0}
development: ${DEVELOPMENT:-false}
anonymous_auth_enabled: ${ANONYMOUS_AUTH_ENABLED:-true}
ports:
- 3000:3000/tcp
volumes:
- ../dist:/var/lib/grafana/plugins/swiftmade-sankey-panel
- ../provisioning:/etc/grafana/provisioning
- ..:/root/swiftmade-sankey-panel

environment:
NODE_ENV: development
GF_LOG_FILTERS: plugin.swiftmade-sankey-panel:debug
GF_LOG_LEVEL: debug
GF_DATAPROXY_LOGGING: 1
GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: swiftmade-sankey-panel
18 changes: 18 additions & 0 deletions .config/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh

if [ "${DEV}" = "false" ]; then
echo "Starting test mode"
exec /run.sh
fi

echo "Starting development mode"

if grep -i -q alpine /etc/issue; then
exec /usr/bin/supervisord -c /etc/supervisord.conf
elif grep -i -q ubuntu /etc/issue; then
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
else
echo 'ERROR: Unsupported base image'
exit 1
fi

38 changes: 38 additions & 0 deletions .config/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* ⚠️⚠️⚠️ 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/how-to-guides/extend-configurations#extend-the-eslint-config
*/

import { defineConfig } from 'eslint/config';
import grafanaConfig from '@grafana/eslint-config/flat.js';

export default defineConfig([
...grafanaConfig,
{
rules: {
'react/prop-types': 'off',
},
},
{
files: ['src/**/*.{ts,tsx}'],

languageOptions: {
parserOptions: {
project: './tsconfig.json',
},
},

rules: {
'@typescript-eslint/no-deprecated': 'warn',
},
},
{
files: ['./tests/**/*'],

rules: {
'react-hooks/rules-of-hooks': 'off',
},
},
]);
9 changes: 6 additions & 3 deletions .config/jest-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
* ⚠️⚠️⚠️ 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.github.io/plugin-tools/docs/advanced-configuration#extending-the-jest-config
* https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-jest-config
*/

import '@testing-library/jest-dom';
import { TextEncoder, TextDecoder } from 'util';

Object.assign(global, { TextDecoder, TextEncoder });

// 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) => ({
value: (query) => ({
matches: false,
media: query,
onchange: null,
Expand All @@ -19,7 +22,7 @@ Object.defineProperty(global, 'matchMedia', {
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
}),
});

HTMLCanvasElement.prototype.getContext = () => {};
5 changes: 3 additions & 2 deletions .config/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* ⚠️⚠️⚠️ 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.github.io/plugin-tools/docs/advanced-configuration#extending-the-jest-config
* https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-jest-config
*/

const path = require('path');
Expand All @@ -25,7 +25,7 @@ module.exports = {
'^.+\\.(t|j)sx?$': [
'@swc/jest',
{
sourceMaps: true,
sourceMaps: 'inline',
jsc: {
parser: {
syntax: 'typescript',
Expand All @@ -40,4 +40,5 @@ module.exports = {
// 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)],
watchPathIgnorePatterns: ['<rootDir>/node_modules', '<rootDir>/dist'],
};
14 changes: 11 additions & 3 deletions .config/jest/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,30 @@
* 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('|')})\/)`;
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',
'@wojtekmaj/date-utils',
'd3',
'd3-color',
'd3-force',
'd3-interpolate',
'd3-scale-chromatic',
'get-user-locale',
'marked',
'memoize',
'mimic-function',
'ol',
'react-calendar',
'react-colorful',
'rxjs',
'uuid',
];

module.exports = {
nodeModulesToTransform,
grafanaESModules
}
grafanaESModules,
};
Loading
Loading