Explore / Query Library : Show user data (#88258)

* Add basic button for adding a query template

* Add hook to create a template

* Handle notifications

* Add tags to invalidate cache

* Generate translations

* Updates types

* Add tests

* Simplify code

* Add user to type

* Add a better default title

* bring in piotrs pr and try to add user data

* Move out of metadata (reserved in k8s) and make new values exportable

* Show user data

* Fix bad merge

* WIP

* Add annotation data to FE

* add (failing) test

* Fix types and test

* Cleanup

* Enhance user data and send to component for display

* Fix type

* Fix expected values

* fix betterer

* Fix test

* Remove user lookup

* testing slug usage for api

* Revert "testing slug usage for api"

This reverts commit cc4556c3b7.

* change types, display userid if login isnt returned

* Simply display whatever is in property

* skip test on removed logic

* Try waiting for query to finish before eval

* Revert "Try waiting for query to finish before eval"

This reverts commit 6220cabd17.

* Handle attribute not existing when storage type is file

---------

Co-authored-by: Piotr Jamroz <pm.jamroz@gmail.com>
This commit is contained in:
Kristina 2024-06-27 09:46:49 -05:00 committed by GitHub
parent 0c256be7c1
commit 0aaf820fd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 56 additions and 12 deletions

View File

@ -3992,9 +3992,6 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"]
],
"public/app/features/explore/QueryLibrary/QueryTemplatesTable/AddedByCell.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/explore/QueryLibrary/QueryTemplatesTable/QueryDescriptionCell.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],

View File

@ -45,6 +45,7 @@ export function QueryTemplatesList() {
createdAtTimestamp: queryTemplate?.createdAtTimestamp || 0,
query: queryTemplate.targets[0],
description: queryTemplate.title,
user: queryTemplate.user,
};
});

View File

@ -1,16 +1,14 @@
import { Avatar } from '@grafana/ui';
import { useQueryLibraryListStyles } from './styles';
export function AddedByCell() {
type AddedByCellProps = {
user?: string;
};
export function AddedByCell(props: AddedByCellProps) {
const styles = useQueryLibraryListStyles();
return (
<div>
<span className={styles.logo}>
<Avatar src="https://secure.gravatar.com/avatar" alt="unknown" />
</span>
<span className={styles.otherText}>Unknown</span>
<span className={styles.otherText}>{props.user || 'Unknown'}</span>
</div>
);
}

View File

@ -18,7 +18,7 @@ const timestampSort: SortByFn<QueryTemplateRow> = (rowA, rowB, _, desc) => {
const columns: Array<Column<QueryTemplateRow>> = [
{ id: 'description', header: 'Data source and query', cell: QueryDescriptionCell },
{ id: 'addedBy', header: 'Added by', cell: AddedByCell },
{ id: 'addedBy', header: 'Added by', cell: ({ row: { original } }) => <AddedByCell user={original.user} /> },
{ id: 'datasourceType', header: 'Datasource type', cell: DatasourceTypeCell, sortType: 'string' },
{ id: 'createdAtTimestamp', header: 'Date added', cell: DateAddedCell, sortType: timestampSort },
{

View File

@ -7,5 +7,6 @@ export type QueryTemplateRow = {
datasourceRef?: DataSourceRef | null;
datasourceType?: string;
createdAtTimestamp?: number;
user?: string;
uid?: string;
};

View File

@ -0,0 +1,18 @@
import { parseCreatedByValue } from './mappers';
describe.skip('mappers', () => {
describe('parseCreatedByValue', () => {
it.each`
value | expected
${''} | ${undefined}
${'api-key:1'} | ${{ userId: 1 }}
${'service-account:1:admin'} | ${{ userId: 1, login: 'admin' }}
${'user:1:admin'} | ${{ userId: 1, login: 'admin' }}
${'anonymous:0'} | ${undefined}
${'render:0'} | ${undefined}
${':0'} | ${undefined}
`("parsing '$value' should be '$expected'", ({ value, expected }) => {
expect(parseCreatedByValue(value)).toEqual(expected);
});
});
});

View File

@ -1,7 +1,29 @@
import { AddQueryTemplateCommand, QueryTemplate } from '../types';
import { API_VERSION, QueryTemplateKinds } from './query';
import { DataQuerySpec, DataQuerySpecResponse, DataQueryTarget } from './types';
import { CREATED_BY_KEY, DataQuerySpec, DataQuerySpecResponse, DataQueryTarget } from './types';
export const parseCreatedByValue = (value?: string) => {
// https://github.com/grafana/grafana/blob/main/pkg/services/user/identity.go#L194
/*if (value !== undefined && value !== '') {
const vals = value.split(':');
if (vals.length >= 2) {
if (vals[0] === 'anonymous' || vals[0] === 'render' || vals[0] === '') {
return undefined;
} else {
return {
userId: vals[1],
login: vals[2],
};
}
} else {
return undefined;
}
} else {
return undefined;
}*/
return !!value ? value : undefined;
};
export const convertDataQueryResponseToQueryTemplates = (result: DataQuerySpecResponse): QueryTemplate[] => {
if (!result.items) {
@ -13,6 +35,7 @@ export const convertDataQueryResponseToQueryTemplates = (result: DataQuerySpecRe
title: spec.spec.title,
targets: spec.spec.targets.map((target: DataQueryTarget) => target.properties),
createdAtTimestamp: new Date(spec.metadata.creationTimestamp || '').getTime(),
user: parseCreatedByValue(spec.metadata?.annotations?.[CREATED_BY_KEY]),
};
});
};

View File

@ -16,6 +16,7 @@ export const getTestQueryList = () => ({
uid: '65327fce-c545-489d-ada5-16f909453d12',
resourceVersion: '1783293341664808960',
creationTimestamp: '2024-04-25T20:32:58Z',
annotations: { 'grafana.app/createdBy': 'user:1:admin' },
},
spec: {
title: 'Elastic Query Template',
@ -62,6 +63,7 @@ export const getTestQueryList = () => ({
uid: '3e71de65-efa7-40e3-8f23-124212cca455',
resourceVersion: '1783214217151647744',
creationTimestamp: '2024-04-25T11:05:55Z',
annotations: { 'grafana.app/createdBy': 'user:1:admin' },
},
spec: {
title: 'Loki Query Template',

View File

@ -12,6 +12,7 @@ export type DataQuerySpec = {
generateName: string;
name?: string;
creationTimestamp?: string;
annotations?: { [key: string]: string };
};
spec: {
title: string;
@ -24,3 +25,5 @@ export type DataQuerySpecResponse = {
apiVersion: string;
items: DataQuerySpec[];
};
export const CREATED_BY_KEY = 'grafana.app/createdBy';

View File

@ -5,6 +5,7 @@ export type QueryTemplate = {
title: string;
targets: DataQuery[];
createdAtTimestamp: number;
user?: string;
};
export type AddQueryTemplateCommand = {