PanelEdit: Show when field options have override rules or data config that overrides the default (#40250)

* First pass at showing data override dots

* Added test

* Adding override rule dots

* Added unit test

* Minor changes

* Update public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx

Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>

* Fixed ts issues

* review feedback changes

* skipp broken e2e test

Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>
This commit is contained in:
Torkel Ödegaard
2021-11-08 13:18:14 +01:00
committed by GitHub
parent e9d90231e0
commit 3dee34c009
17 changed files with 309 additions and 193 deletions

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire, createRequireFromPath } = require(`module`);
const { resolve } = require(`path`);
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = '../../../../.pnp.cjs';
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire, createRequireFromPath } = require(`module`);
const { resolve } = require(`path`);
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = '../../../../.pnp.cjs';
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);

View File

@@ -2,4 +2,5 @@
# Manual changes might be lost!
integrations:
- vim
- vscode

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire, createRequireFromPath } = require(`module`);
const { resolve } = require(`path`);
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = '../../../.pnp.cjs';
const relPnpApiPath = "../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire, createRequireFromPath } = require(`module`);
const { resolve } = require(`path`);
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = '../../../../.pnp.cjs';
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire, createRequireFromPath } = require(`module`);
const { resolve } = require(`path`);
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = '../../../../.pnp.cjs';
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire, createRequireFromPath } = require(`module`);
const { resolve } = require(`path`);
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = '../../../../.pnp.cjs';
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);

View File

@@ -1,30 +1,28 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire, createRequireFromPath } = require(`module`);
const { resolve } = require(`path`);
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = '../../../../.pnp.cjs';
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const moduleWrapper = (tsserver) => {
const moduleWrapper = tsserver => {
if (!process.versions.pnp) {
return tsserver;
}
const { isAbsolute } = require(`path`);
const {isAbsolute} = require(`path`);
const pnpApi = require(`pnpapi`);
const isVirtual = (str) => str.match(/\/(\$\$virtual|__virtual__)\//);
const normalize = (str) => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
const dependencyTreeRoots = new Set(
pnpApi.getDependencyTreeRoots().map((locator) => {
return `${locator.name}@${locator.reference}`;
})
);
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
return `${locator.name}@${locator.reference}`;
}));
// VSCode sends the zip paths to TS using the "zip://" prefix, that TS
// doesn't understand. This layer makes sure to remove the protocol
@@ -66,43 +64,33 @@ const moduleWrapper = (tsserver) => {
// Before | ^zip:/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
case `vscode <1.61`:
{
str = `^zip:${str}`;
}
break;
case `vscode <1.61`: {
str = `^zip:${str}`;
} break;
case `vscode`:
{
str = `^/zip/${str}`;
}
break;
case `vscode`: {
str = `^/zip/${str}`;
} break;
// To make "go to definition" work,
// We have to resolve the actual file system path from virtual path
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
case `coc-nvim`:
{
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = resolve(`zipfile:${str}`);
}
break;
case `coc-nvim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = resolve(`zipfile:${str}`);
} break;
// Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
// We have to resolve the actual file system path from virtual path,
// everything else is up to neovim
case `neovim`:
{
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = `zipfile:${str}`;
}
break;
case `neovim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = `zipfile:${str}`;
} break;
default:
{
str = `zip:${str}`;
}
break;
default: {
str = `zip:${str}`;
} break;
}
}
}
@@ -113,24 +101,22 @@ const moduleWrapper = (tsserver) => {
function fromEditorPath(str) {
switch (hostInfo) {
case `coc-nvim`:
case `neovim`:
{
str = str.replace(/\.zip::/, `.zip/`);
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
// So in order to convert it back, we use .* to match all the thing
// before `zipfile:`
return process.platform === `win32` ? str.replace(/^.*zipfile:\//, ``) : str.replace(/^.*zipfile:/, ``);
}
break;
case `neovim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
// So in order to convert it back, we use .* to match all the thing
// before `zipfile:`
return process.platform === `win32`
? str.replace(/^.*zipfile:\//, ``)
: str.replace(/^.*zipfile:/, ``);
} break;
case `vscode`:
default:
{
return process.platform === `win32`
? str.replace(/^\^?(zip:|\/zip)\/+/, ``)
: str.replace(/^\^?(zip:|\/zip)\/+/, `/`);
}
break;
default: {
return process.platform === `win32`
? str.replace(/^\^?(zip:|\/zip)\/+/, ``)
: str.replace(/^\^?(zip:|\/zip)\/+/, `/`);
} break;
}
}
@@ -142,8 +128,8 @@ const moduleWrapper = (tsserver) => {
// TypeScript already does local loads and if this code is running the user trusts the workspace
// https://github.com/microsoft/vscode/issues/45856
const ConfiguredProject = tsserver.server.ConfiguredProject;
const { enablePluginsWithOptions: originalEnablePluginsWithOptions } = ConfiguredProject.prototype;
ConfiguredProject.prototype.enablePluginsWithOptions = function () {
const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
ConfiguredProject.prototype.enablePluginsWithOptions = function() {
this.projectService.allowLocalPluginLoads = true;
return originalEnablePluginsWithOptions.apply(this, arguments);
};
@@ -153,12 +139,12 @@ const moduleWrapper = (tsserver) => {
// like an absolute path of ours and normalize it.
const Session = tsserver.server.Session;
const { onMessage: originalOnMessage, send: originalSend } = Session.prototype;
const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
let hostInfo = `unknown`;
Object.assign(Session.prototype, {
onMessage(/** @type {string} */ message) {
const parsedMessage = JSON.parse(message);
const parsedMessage = JSON.parse(message)
if (
parsedMessage != null &&
@@ -167,33 +153,21 @@ const moduleWrapper = (tsserver) => {
typeof parsedMessage.arguments.hostInfo === `string`
) {
hostInfo = parsedMessage.arguments.hostInfo;
if (
hostInfo === `vscode` &&
process.env.VSCODE_IPC_HOOK &&
process.env.VSCODE_IPC_HOOK.match(/Code\/1\.([1-5][0-9]|60)\./)
) {
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK && process.env.VSCODE_IPC_HOOK.match(/Code\/1\.([1-5][0-9]|60)\./)) {
hostInfo += ` <1.61`;
}
}
return originalOnMessage.call(
this,
JSON.stringify(parsedMessage, (key, value) => {
return typeof value === `string` ? fromEditorPath(value) : value;
})
);
return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => {
return typeof value === `string` ? fromEditorPath(value) : value;
}));
},
send(/** @type {any} */ msg) {
return originalSend.call(
this,
JSON.parse(
JSON.stringify(msg, (key, value) => {
return typeof value === `string` ? toEditorPath(value) : value;
})
)
);
},
return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
return typeof value === `string` ? toEditorPath(value) : value;
})));
}
});
return tsserver;

View File

@@ -1,30 +1,28 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire, createRequireFromPath } = require(`module`);
const { resolve } = require(`path`);
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = '../../../../.pnp.cjs';
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
const moduleWrapper = (tsserver) => {
const moduleWrapper = tsserver => {
if (!process.versions.pnp) {
return tsserver;
}
const { isAbsolute } = require(`path`);
const {isAbsolute} = require(`path`);
const pnpApi = require(`pnpapi`);
const isVirtual = (str) => str.match(/\/(\$\$virtual|__virtual__)\//);
const normalize = (str) => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
const dependencyTreeRoots = new Set(
pnpApi.getDependencyTreeRoots().map((locator) => {
return `${locator.name}@${locator.reference}`;
})
);
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
return `${locator.name}@${locator.reference}`;
}));
// VSCode sends the zip paths to TS using the "zip://" prefix, that TS
// doesn't understand. This layer makes sure to remove the protocol
@@ -66,43 +64,33 @@ const moduleWrapper = (tsserver) => {
// Before | ^zip:/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
case `vscode <1.61`:
{
str = `^zip:${str}`;
}
break;
case `vscode <1.61`: {
str = `^zip:${str}`;
} break;
case `vscode`:
{
str = `^/zip/${str}`;
}
break;
case `vscode`: {
str = `^/zip/${str}`;
} break;
// To make "go to definition" work,
// We have to resolve the actual file system path from virtual path
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
case `coc-nvim`:
{
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = resolve(`zipfile:${str}`);
}
break;
case `coc-nvim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = resolve(`zipfile:${str}`);
} break;
// Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
// We have to resolve the actual file system path from virtual path,
// everything else is up to neovim
case `neovim`:
{
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = `zipfile:${str}`;
}
break;
case `neovim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = `zipfile:${str}`;
} break;
default:
{
str = `zip:${str}`;
}
break;
default: {
str = `zip:${str}`;
} break;
}
}
}
@@ -113,24 +101,22 @@ const moduleWrapper = (tsserver) => {
function fromEditorPath(str) {
switch (hostInfo) {
case `coc-nvim`:
case `neovim`:
{
str = str.replace(/\.zip::/, `.zip/`);
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
// So in order to convert it back, we use .* to match all the thing
// before `zipfile:`
return process.platform === `win32` ? str.replace(/^.*zipfile:\//, ``) : str.replace(/^.*zipfile:/, ``);
}
break;
case `neovim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
// So in order to convert it back, we use .* to match all the thing
// before `zipfile:`
return process.platform === `win32`
? str.replace(/^.*zipfile:\//, ``)
: str.replace(/^.*zipfile:/, ``);
} break;
case `vscode`:
default:
{
return process.platform === `win32`
? str.replace(/^\^?(zip:|\/zip)\/+/, ``)
: str.replace(/^\^?(zip:|\/zip)\/+/, `/`);
}
break;
default: {
return process.platform === `win32`
? str.replace(/^\^?(zip:|\/zip)\/+/, ``)
: str.replace(/^\^?(zip:|\/zip)\/+/, `/`);
} break;
}
}
@@ -142,8 +128,8 @@ const moduleWrapper = (tsserver) => {
// TypeScript already does local loads and if this code is running the user trusts the workspace
// https://github.com/microsoft/vscode/issues/45856
const ConfiguredProject = tsserver.server.ConfiguredProject;
const { enablePluginsWithOptions: originalEnablePluginsWithOptions } = ConfiguredProject.prototype;
ConfiguredProject.prototype.enablePluginsWithOptions = function () {
const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
ConfiguredProject.prototype.enablePluginsWithOptions = function() {
this.projectService.allowLocalPluginLoads = true;
return originalEnablePluginsWithOptions.apply(this, arguments);
};
@@ -153,12 +139,12 @@ const moduleWrapper = (tsserver) => {
// like an absolute path of ours and normalize it.
const Session = tsserver.server.Session;
const { onMessage: originalOnMessage, send: originalSend } = Session.prototype;
const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
let hostInfo = `unknown`;
Object.assign(Session.prototype, {
onMessage(/** @type {string} */ message) {
const parsedMessage = JSON.parse(message);
const parsedMessage = JSON.parse(message)
if (
parsedMessage != null &&
@@ -167,33 +153,21 @@ const moduleWrapper = (tsserver) => {
typeof parsedMessage.arguments.hostInfo === `string`
) {
hostInfo = parsedMessage.arguments.hostInfo;
if (
hostInfo === `vscode` &&
process.env.VSCODE_IPC_HOOK &&
process.env.VSCODE_IPC_HOOK.match(/Code\/1\.([1-5][0-9]|60)\./)
) {
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK && process.env.VSCODE_IPC_HOOK.match(/Code\/1\.([1-5][0-9]|60)\./)) {
hostInfo += ` <1.61`;
}
}
return originalOnMessage.call(
this,
JSON.stringify(parsedMessage, (key, value) => {
return typeof value === `string` ? fromEditorPath(value) : value;
})
);
return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => {
return typeof value === `string` ? fromEditorPath(value) : value;
}));
},
send(/** @type {any} */ msg) {
return originalSend.call(
this,
JSON.parse(
JSON.stringify(msg, (key, value) => {
return typeof value === `string` ? toEditorPath(value) : value;
})
)
);
},
return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
return typeof value === `string` ? toEditorPath(value) : value;
})));
}
});
return tsserver;

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire, createRequireFromPath } = require(`module`);
const { resolve } = require(`path`);
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = '../../../../.pnp.cjs';
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);