mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Search: Sort by updated at and created at (#50416)
Co-authored-by: Artur Wierzbicki <artur.wierzbicki@grafana.com> Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
parent
0975ea4df8
commit
a2478c3a32
@ -6784,29 +6784,29 @@ exports[`better eslint`] = {
|
||||
[62, 12, 21, "Do not use any type assertions.", "976337522"],
|
||||
[63, 14, 26, "Do not use any type assertions.", "2909521803"]
|
||||
],
|
||||
"public/app/features/search/page/components/columns.tsx:2440349722": [
|
||||
[34, 20, 70, "Do not use any type assertions.", "512413936"],
|
||||
[34, 21, 13, "Do not use any type assertions.", "3933930693"],
|
||||
[34, 31, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[49, 32, 21, "Do not use any type assertions.", "3454251755"],
|
||||
[49, 50, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[145, 15, 56, "Do not use any type assertions.", "1375039711"]
|
||||
"public/app/features/search/page/components/columns.tsx:1558772443": [
|
||||
[33, 20, 70, "Do not use any type assertions.", "512413936"],
|
||||
[33, 21, 13, "Do not use any type assertions.", "3933930693"],
|
||||
[33, 31, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[52, 32, 21, "Do not use any type assertions.", "3454251755"],
|
||||
[52, 50, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[148, 15, 56, "Do not use any type assertions.", "1375039711"]
|
||||
],
|
||||
"public/app/features/search/service/bluge.ts:59496993": [
|
||||
"public/app/features/search/service/bluge.ts:3991565237": [
|
||||
[21, 15, 68, "Do not use any type assertions.", "2766474629"],
|
||||
[34, 17, 128, "Do not use any type assertions.", "437379020"],
|
||||
[36, 17, 47, "Do not use any type assertions.", "610587748"],
|
||||
[38, 13, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[72, 13, 68, "Do not use any type assertions.", "2766474629"],
|
||||
[83, 13, 39, "Do not use any type assertions.", "246018916"],
|
||||
[85, 9, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[88, 17, 26, "Do not use any type assertions.", "387817714"],
|
||||
[104, 15, 37, "Do not use any type assertions.", "1203314137"],
|
||||
[130, 20, 446, "Do not use any type assertions.", "258020179"],
|
||||
[132, 19, 354, "Do not use any type assertions.", "4208037114"],
|
||||
[145, 15, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[161, 24, 46, "Do not use any type assertions.", "1967560255"],
|
||||
[167, 22, 38, "Do not use any type assertions.", "1477056001"]
|
||||
[76, 13, 68, "Do not use any type assertions.", "2766474629"],
|
||||
[87, 13, 39, "Do not use any type assertions.", "246018916"],
|
||||
[89, 9, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[92, 17, 26, "Do not use any type assertions.", "387817714"],
|
||||
[108, 15, 37, "Do not use any type assertions.", "1203314137"],
|
||||
[134, 20, 446, "Do not use any type assertions.", "258020179"],
|
||||
[136, 19, 354, "Do not use any type assertions.", "4208037114"],
|
||||
[149, 15, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[165, 24, 46, "Do not use any type assertions.", "1967560255"],
|
||||
[171, 22, 38, "Do not use any type assertions.", "1477056001"]
|
||||
],
|
||||
"public/app/features/search/service/sql.ts:3331148655": [
|
||||
[91, 36, 3, "Unexpected any. Specify a different type.", "193409811"]
|
||||
|
@ -30,6 +30,8 @@ const (
|
||||
documentFieldTransformer = "transformer"
|
||||
documentFieldDSUID = "ds_uid"
|
||||
documentFieldDSType = "ds_type"
|
||||
DocumentFieldCreatedAt = "created_at"
|
||||
DocumentFieldUpdatedAt = "updated_at"
|
||||
)
|
||||
|
||||
func initIndex(dashboards []dashboard, logger log.Logger, extendDoc ExtendDashboardFunc) (*bluge.Reader, *bluge.Writer, error) {
|
||||
@ -139,7 +141,9 @@ func getFolderDashboardDoc(dash dashboard) *bluge.Document {
|
||||
}
|
||||
|
||||
return newSearchDocument(uid, dash.info.Title, dash.info.Description, url).
|
||||
AddField(bluge.NewKeywordField(documentFieldKind, string(entityKindFolder)).Aggregatable().StoreValue())
|
||||
AddField(bluge.NewKeywordField(documentFieldKind, string(entityKindFolder)).Aggregatable().StoreValue()).
|
||||
AddField(bluge.NewDateTimeField(DocumentFieldCreatedAt, dash.created).Sortable().StoreValue()).
|
||||
AddField(bluge.NewDateTimeField(DocumentFieldUpdatedAt, dash.updated).Sortable().StoreValue())
|
||||
}
|
||||
|
||||
func getNonFolderDashboardDoc(dash dashboard, location string) *bluge.Document {
|
||||
@ -148,7 +152,9 @@ func getNonFolderDashboardDoc(dash dashboard, location string) *bluge.Document {
|
||||
// Dashboard document
|
||||
doc := newSearchDocument(dash.uid, dash.info.Title, dash.info.Description, url).
|
||||
AddField(bluge.NewKeywordField(documentFieldKind, string(entityKindDashboard)).Aggregatable().StoreValue()).
|
||||
AddField(bluge.NewKeywordField(documentFieldLocation, location).Aggregatable().StoreValue())
|
||||
AddField(bluge.NewKeywordField(documentFieldLocation, location).Aggregatable().StoreValue()).
|
||||
AddField(bluge.NewDateTimeField(DocumentFieldCreatedAt, dash.created).Sortable().StoreValue()).
|
||||
AddField(bluge.NewDateTimeField(DocumentFieldUpdatedAt, dash.updated).Sortable().StoreValue())
|
||||
|
||||
for _, tag := range dash.info.Tags {
|
||||
doc.AddField(bluge.NewKeywordField(documentFieldTag, tag).
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { cx } from '@emotion/css';
|
||||
import { isNumber } from 'lodash';
|
||||
import React from 'react';
|
||||
import SVG from 'react-inlinesvg';
|
||||
|
||||
import { Field, getFieldDisplayName } from '@grafana/data';
|
||||
import { Field, FieldType, formattedValueToString, getDisplayProcessor, getFieldDisplayName } from '@grafana/data';
|
||||
import { config, getDataSourceSrv } from '@grafana/runtime';
|
||||
import { Checkbox, Icon, IconButton, IconName, TagList } from '@grafana/ui';
|
||||
import { PluginIconName } from 'app/features/plugins/admin/types';
|
||||
@ -15,7 +14,6 @@ import { TableColumn } from './SearchResultsTable';
|
||||
|
||||
const TYPE_COLUMN_WIDTH = 175;
|
||||
const DATASOURCE_COLUMN_WIDTH = 200;
|
||||
const SORT_FIELD_WIDTH = 175;
|
||||
|
||||
export const generateColumns = (
|
||||
response: QueryResponse,
|
||||
@ -32,9 +30,14 @@ export const generateColumns = (
|
||||
const access = response.view.fields;
|
||||
const uidField = access.uid;
|
||||
const kindField = access.kind;
|
||||
let sortFieldWith = 0;
|
||||
const sortField = (access as any)[response.view.dataFrame.meta?.custom?.sortBy] as Field;
|
||||
if (sortField) {
|
||||
availableWidth -= SORT_FIELD_WIDTH; // pre-allocate the space for the last column
|
||||
sortFieldWith = 175;
|
||||
if (sortField.type === FieldType.time) {
|
||||
sortFieldWith += 25;
|
||||
}
|
||||
availableWidth -= sortFieldWith; // pre-allocate the space for the last column
|
||||
}
|
||||
|
||||
let width = 50;
|
||||
@ -176,25 +179,20 @@ export const generateColumns = (
|
||||
columns.push(makeTagsColumn(access.tags, availableWidth, styles.tagList, onTagSelected));
|
||||
}
|
||||
|
||||
if (sortField) {
|
||||
if (sortField && sortFieldWith) {
|
||||
const disp = sortField.display ?? getDisplayProcessor({ field: sortField, theme: config.theme2 });
|
||||
columns.push({
|
||||
Header: () => <div className={styles.sortedHeader}>{getFieldDisplayName(sortField)}</div>,
|
||||
Cell: (p) => {
|
||||
let value = sortField.values.get(p.row.index);
|
||||
try {
|
||||
if (isNumber(value)) {
|
||||
value = Number(value).toLocaleString();
|
||||
}
|
||||
} catch {}
|
||||
return (
|
||||
<div {...p.cellProps} className={styles.sortedItems}>
|
||||
{`${value}`}
|
||||
{formattedValueToString(disp(sortField.values.get(p.row.index)))}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
id: `column-sort-field`,
|
||||
field: sortField,
|
||||
width: SORT_FIELD_WIDTH,
|
||||
width: sortFieldWith,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,10 @@ export class BlugeSearcher implements GrafanaSearcher {
|
||||
opts.push({ value: `-${sf.name}`, label: `${sf.display} (most)` });
|
||||
opts.push({ value: `${sf.name}`, label: `${sf.display} (least)` });
|
||||
}
|
||||
for (const sf of sortTimeFields) {
|
||||
opts.push({ value: `-${sf.name}`, label: `${sf.display} (recent)` });
|
||||
opts.push({ value: `${sf.name}`, label: `${sf.display} (oldest)` });
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve(opts);
|
||||
@ -197,6 +201,12 @@ const sortFields = [
|
||||
{ name: 'errors_last_30_days', display: 'Errors 30 days' },
|
||||
];
|
||||
|
||||
// Enterprise only time sort field values for dashboards
|
||||
const sortTimeFields = [
|
||||
{ name: 'created_at', display: 'Created time' },
|
||||
{ name: 'updated_at', display: 'Updated time' },
|
||||
];
|
||||
|
||||
/** Given the internal field name, this gives a reasonable display name for the table colum header */
|
||||
function getSortFieldDisplayName(name: string) {
|
||||
for (const sf of sortFields) {
|
||||
@ -204,5 +214,10 @@ function getSortFieldDisplayName(name: string) {
|
||||
return sf.display;
|
||||
}
|
||||
}
|
||||
for (const sf of sortTimeFields) {
|
||||
if (sf.name === name) {
|
||||
return sf.display;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user