mirror of
https://github.com/grafana/grafana.git
synced 2024-11-22 08:56:43 -06:00
Plugins: Add Hide OAuth Forward config option (#36306)
* add prop * add angular conf * invert naming * undo md changes * fix wording * y u fail 4 me * refactor(datasourcesettings): rename hideForwardOAuthIdentityOption prop * refactor(datasourcesettings): rename scope.hideForwardOAuthIdentityOption * Update contribute/style-guides/e2e.md Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com> * feat(datasourcehttpsettings): add showForwardOAuthIdentityOption to angular wrappers & template Co-authored-by: Jack Westbrook <jack.westbrook@gmail.com> Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>
This commit is contained in:
parent
5231660627
commit
ae17cce316
@ -23,20 +23,13 @@ Inspired by https://martinfowler.com/bliki/PageObject.html
|
||||
Let's start with a simple [JSX](https://reactjs.org/docs/introducing-jsx.html) example containing a single input field that we want to populate during our E2E test:
|
||||
|
||||
```jsx
|
||||
<input
|
||||
className="gf-form-input login-form-input"
|
||||
type="text"
|
||||
/>
|
||||
<input className="gf-form-input login-form-input" type="text" />
|
||||
```
|
||||
|
||||
We _could_ target the field with a CSS selector like `.gf-form-input.login-form-input` but that would be brittle as style changes occur frequently. Furthermore there is nothing that signals to future developers that this input is part of an E2E test. At Grafana, we use `aria-label` attributes as our preferred way of defining selectors instead of [`data-*`](https://mdn.io/docs/Web/HTML/Global_attributes/data-*) as they also aid in [accessibility](https://mdn.io/docs/Learn/Accessibility/What_is_accessibility):
|
||||
|
||||
```jsx
|
||||
<input
|
||||
aria-label="Username input field"
|
||||
className="gf-form-input login-form-input"
|
||||
type="text"
|
||||
/>
|
||||
<input aria-label="Username input field" className="gf-form-input login-form-input" type="text" />
|
||||
```
|
||||
|
||||
The next step is to create a `Page` representation in our E2E framework to glue the test with the real implementation using the `pageFactory` function. For that function we can supply a `url` and `selectors` like in the example below:
|
||||
@ -45,7 +38,6 @@ The next step is to create a `Page` representation in our E2E framework to glue
|
||||
export const Login = {
|
||||
// Called via `Login.visit()`
|
||||
url: '/login',
|
||||
|
||||
// Called via `Login.username()`
|
||||
username: 'Username input field',
|
||||
};
|
||||
@ -67,11 +59,7 @@ Now that we have a `Page` called `Login` in our `Pages` const we can use that to
|
||||
```jsx
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
<input
|
||||
aria-label={selectors.pages.Login.username}
|
||||
className="gf-form-input login-form-input"
|
||||
type="text"
|
||||
/>
|
||||
<input aria-label={selectors.pages.Login.username} className="gf-form-input login-form-input" type="text" />;
|
||||
```
|
||||
|
||||
The last step in our example is to use our `Login` page as part of a test.
|
||||
@ -86,9 +74,7 @@ describe('Login test', () => {
|
||||
e2e.pages.Login.visit();
|
||||
// To prevent flaky tests, always do a `.should` on any selector that you expect to be in the DOM.
|
||||
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
|
||||
e2e.pages.Login.username()
|
||||
.should('be.visible')
|
||||
.type('admin');
|
||||
e2e.pages.Login.username().should('be.visible').type('admin');
|
||||
});
|
||||
});
|
||||
```
|
||||
@ -154,25 +140,28 @@ describe('List test', () => {
|
||||
e2e.pages.DataSources.visit();
|
||||
// To prevent flaky tests, always do a .should on any selector that you expect to be in the DOM.
|
||||
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
|
||||
e2e.pages.DataSources.dataSources('B')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
e2e.pages.DataSources.dataSources('B').should('be.visible').click();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Aria-Labels vs data-testid
|
||||
Our selectors are set up to work with both aria-labels and data-testid attributes. Aria-labels help assistive technologies such as screenreaders identify interactive elements of a page for our users.
|
||||
|
||||
Our selectors are set up to work with both aria-labels and data-testid attributes. Aria-labels help assistive technologies such as screenreaders identify interactive elements of a page for our users.
|
||||
|
||||
A good example of a time to use an aria-label might be if you have a button with an X to close:
|
||||
|
||||
```
|
||||
<button aria-label="close">X<button>
|
||||
```
|
||||
|
||||
It might be clear visually that the X closes the modal, but audibly it would not be clear for example.
|
||||
|
||||
```
|
||||
<button aria-label="close">Close<button>
|
||||
```
|
||||
The above example for example might read aloud to a user "Close, Close" or something similar.
|
||||
|
||||
The example might read aloud to a user as "Close, Close" or something similar.
|
||||
|
||||
However adding aria-labels to elements that are already clearly labeled or not interactive can be confusing and redundant for users with assistive technologies.
|
||||
|
||||
@ -185,16 +174,18 @@ In such cases rather than adding unnecessary aria-labels to components so as to
|
||||
We have added support for this in our selectors, to use:
|
||||
|
||||
Prefix your selector string with "data-testid":
|
||||
|
||||
```typescript
|
||||
export const Components = {
|
||||
Login: {
|
||||
openButton: "data-testid-open", // this would look for a data-testid
|
||||
closeButton: "close-button" // this would look for an aria-label
|
||||
openButton: 'data-testid-open', // this would look for a data-testid
|
||||
closeButton: 'close-button', // this would look for an aria-label
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
and in your component, import the selectors and add the data test id:
|
||||
|
||||
```
|
||||
<button data-testid={Selectors.Components.Login.openButton}>
|
||||
```
|
||||
```
|
||||
|
@ -120,7 +120,7 @@ Example use cases:
|
||||
|
||||
### Typography
|
||||
|
||||
For font family, font sizes and line heights use the variables under `theme.typography`.
|
||||
For font family, font sizes and line heights use the variables under `theme.typography`.
|
||||
|
||||
#### Using `ThemeContext` directly
|
||||
|
||||
|
@ -1,15 +1,18 @@
|
||||
# Using this docker image
|
||||
|
||||
## User
|
||||
|
||||
The user will be `circleci`
|
||||
The home directory will be `/home/circleci`
|
||||
|
||||
## Node
|
||||
|
||||
- node 14 is installed
|
||||
- yarn is installed globally
|
||||
- npm is installed globally
|
||||
|
||||
## Go
|
||||
|
||||
- Go is installed in `/usr/local/bin/go`
|
||||
- golangci-lint is installed in `/usr/local/bin/golangci-lint`
|
||||
- mage is installed in `/usr/local/bin/mage`
|
||||
@ -17,17 +20,21 @@ The home directory will be `/home/circleci`
|
||||
All of the above directories are in the path, so there is no need to specify fully qualified paths.
|
||||
|
||||
## Grafana
|
||||
|
||||
- Installed in `/home/circleci/src/grafana`
|
||||
- `yarn install` has been run
|
||||
|
||||
## Integration/Release Testing
|
||||
|
||||
There are 4 previous versions pre-downloaded to /usr/local/grafana. These versions are:
|
||||
|
||||
1. 6.6.2
|
||||
2. 6.5.3
|
||||
3. 6.4.5
|
||||
4. 6.3.7
|
||||
|
||||
To test, your CircleCI config will need a run section with something similar to the following
|
||||
|
||||
```
|
||||
- run:
|
||||
name: Setup Grafana (local install)
|
||||
@ -39,15 +46,18 @@ To test, your CircleCI config will need a run section with something similar to
|
||||
grafana-cli --version
|
||||
```
|
||||
|
||||
|
||||
# Building
|
||||
|
||||
To build, cd to `<srcroot>/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e`
|
||||
|
||||
```
|
||||
./build.sh
|
||||
```
|
||||
|
||||
# Developing/Testing
|
||||
|
||||
To test, you should have docker-compose installed.
|
||||
|
||||
```
|
||||
cd test
|
||||
./start.sh
|
||||
|
@ -62,6 +62,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
||||
onChange,
|
||||
showAccessOptions,
|
||||
sigV4AuthToggleEnabled,
|
||||
showForwardOAuthIdentityOption,
|
||||
azureAuthSettings,
|
||||
} = props;
|
||||
let urlTooltip;
|
||||
@ -250,6 +251,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
||||
<HttpProxySettings
|
||||
dataSourceConfig={dataSourceConfig}
|
||||
onChange={(jsonData) => onSettingsChange({ jsonData })}
|
||||
showForwardOAuthIdentityOption={showForwardOAuthIdentityOption}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
@ -2,7 +2,11 @@ import React from 'react';
|
||||
import { HttpSettingsBaseProps } from './types';
|
||||
import { Switch } from '../Forms/Legacy/Switch/Switch';
|
||||
|
||||
export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({ dataSourceConfig, onChange }) => {
|
||||
export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({
|
||||
dataSourceConfig,
|
||||
onChange,
|
||||
showForwardOAuthIdentityOption = true,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
@ -31,15 +35,19 @@ export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({ dataSourceC
|
||||
onChange={(event) => onChange({ ...dataSourceConfig.jsonData, tlsSkipVerify: event!.currentTarget.checked })}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form-inline">
|
||||
<Switch
|
||||
label="Forward OAuth Identity"
|
||||
labelClass="width-13"
|
||||
checked={dataSourceConfig.jsonData.oauthPassThru || false}
|
||||
onChange={(event) => onChange({ ...dataSourceConfig.jsonData, oauthPassThru: event!.currentTarget.checked })}
|
||||
tooltip="Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
|
||||
/>
|
||||
</div>
|
||||
{showForwardOAuthIdentityOption && (
|
||||
<div className="gf-form-inline">
|
||||
<Switch
|
||||
label="Forward OAuth Identity"
|
||||
labelClass="width-13"
|
||||
checked={dataSourceConfig.jsonData.oauthPassThru || false}
|
||||
onChange={(event) =>
|
||||
onChange({ ...dataSourceConfig.jsonData, oauthPassThru: event!.currentTarget.checked })
|
||||
}
|
||||
tooltip="Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -11,6 +11,8 @@ export interface HttpSettingsBaseProps {
|
||||
dataSourceConfig: DataSourceSettings<any, any>;
|
||||
/** Callback for handling changes to the configuration object */
|
||||
onChange: (config: DataSourceSettings) => void;
|
||||
/** Show the Forward OAuth identity option */
|
||||
showForwardOAuthIdentityOption?: boolean;
|
||||
}
|
||||
|
||||
export interface HttpSettingsProps extends HttpSettingsBaseProps {
|
||||
|
@ -1,13 +1,15 @@
|
||||
import { ArgsTable} from '@storybook/addon-docs/blocks';
|
||||
import { DateTimePicker } from "./DateTimePicker";
|
||||
import { ArgsTable } from '@storybook/addon-docs/blocks';
|
||||
import { DateTimePicker } from './DateTimePicker';
|
||||
|
||||
# DateTimePicker
|
||||
|
||||
A component for selecting a date _and_ time.
|
||||
|
||||
### Usage
|
||||
|
||||
```tsx
|
||||
import React, { useState} from 'react';
|
||||
import {DateTime, dateTime} from '@grafana/data';
|
||||
import React, { useState } from 'react';
|
||||
import { DateTime, dateTime } from '@grafana/data';
|
||||
import { DateTimePicker } from '@grafana/ui';
|
||||
|
||||
const [date, setDate] = useState<DateTime>(dateTime('2021-05-05 12:00:00'));
|
||||
@ -15,4 +17,5 @@ return <DateTimePicker label="Date" date={date} onChange={setDate} />;
|
||||
```
|
||||
|
||||
### Props
|
||||
|
||||
<ArgsTable of={DateTimePicker} />
|
||||
|
@ -166,6 +166,7 @@ export function registerAngularDirectives() {
|
||||
'defaultUrl',
|
||||
'showAccessOptions',
|
||||
'dataSourceConfig',
|
||||
'showForwardOAuthIdentityOption',
|
||||
['onChange', { watchDepth: 'reference', wrapApply: true }],
|
||||
]);
|
||||
react2AngularDirective('folderPicker', FolderPicker, [
|
||||
|
@ -1 +1,7 @@
|
||||
<datasource-http-settings-next on-change="onChange" dataSourceConfig="current" showAccessOptions="showAccessOption" defaultUrl="suggestUrl" />
|
||||
<datasource-http-settings-next
|
||||
on-change="onChange"
|
||||
dataSourceConfig="current"
|
||||
showAccessOptions="showAccessOption"
|
||||
defaultUrl="suggestUrl"
|
||||
showForwardOAuthIdentityOption="showForwardOAuthIdentityOption"
|
||||
/>
|
||||
|
@ -6,6 +6,7 @@ coreModule.directive('datasourceHttpSettings', () => {
|
||||
current: '=',
|
||||
suggestUrl: '@',
|
||||
noDirectAccess: '@',
|
||||
showForwardOAuthIdentityOption: '@',
|
||||
},
|
||||
templateUrl: 'public/app/features/datasources/partials/http_settings_next.html',
|
||||
link: {
|
||||
|
@ -1,12 +1,11 @@
|
||||
# Annotation List Panel - Native Plugin
|
||||
# Annotation List Panel - Native Plugin
|
||||
|
||||
This Annotations List panel is **included** with Grafana.
|
||||
|
||||
Using the annotations list panel, you can quickly collect, filter and access annotations for easy reference or referral.
|
||||
Using the annotations list panel, you can quickly collect, filter and access annotations for easy reference or referral.
|
||||
|
||||
The annotations panel can be used to show annotations present within the panels on the current dashboard, or site-wide. Additional options include the ability to limit the list of annotations based on the current time range and the tags used on the annotations.
|
||||
|
||||
Read more about it here:
|
||||
|
||||
[http://docs.grafana.org/features/panels/annolist/](http://docs.grafana.org/features/panels/annolist/)
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Geomap Panel - Native Plugin
|
||||
# Geomap Panel - Native Plugin
|
||||
|
||||
The Geomap is **included** with Grafana.
|
||||
|
Loading…
Reference in New Issue
Block a user