mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
LibraryPanels: Adds folder name to Library Panel card (#33697)
* LibraryPanels: Adds folder filter * Refactor: Adds folder filter to library search * Refactor: splits huge function into smaller functions * LibraryPanels: Adds Panels Page to Manage Folder tabs (#33618) * Chore: adds tests to LibraryPanelsSearch * Refactor: Adds reducer and tests * Chore: changes GrafanaThemeV2 * Refactor: adds folderName to get all result * Refactor: adds folderName to get result * Refactor: adds folder name to LibraryPanelDTOMeta * Refactor: adds folder name to lbirary panels result * Chore: reverts public/app/routes/routes.tsx to master * Minor style tweak * Refactor: adds folder uid to meta * Chore: updates after PR comments Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
parent
a5c13feb61
commit
605bae8e2c
@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
sqlStatmentLibrayPanelDTOWithMeta = `
|
||||
selectLibrayPanelDTOWithMeta = `
|
||||
SELECT DISTINCT
|
||||
lp.name, lp.id, lp.org_id, lp.folder_id, lp.uid, lp.type, lp.description, lp.model, lp.created, lp.created_by, lp.updated, lp.updated_by, lp.version
|
||||
, 0 AS can_edit
|
||||
@ -23,10 +23,13 @@ SELECT DISTINCT
|
||||
, u2.login AS updated_by_name
|
||||
, u2.email AS updated_by_email
|
||||
, (SELECT COUNT(dashboard_id) FROM library_panel_dashboard WHERE librarypanel_id = lp.id) AS connected_dashboards
|
||||
`
|
||||
fromLibrayPanelDTOWithMeta = `
|
||||
FROM library_panel AS lp
|
||||
LEFT JOIN user AS u1 ON lp.created_by = u1.id
|
||||
LEFT JOIN user AS u2 ON lp.updated_by = u2.id
|
||||
`
|
||||
sqlStatmentLibrayPanelDTOWithMeta = selectLibrayPanelDTOWithMeta + fromLibrayPanelDTOWithMeta
|
||||
)
|
||||
|
||||
func syncFieldsWithModel(libraryPanel *LibraryPanel) error {
|
||||
@ -328,10 +331,16 @@ func (lps *LibraryPanelService) getLibraryPanel(c *models.ReqContext, uid string
|
||||
err := lps.SQLStore.WithDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
libraryPanels := make([]LibraryPanelWithMeta, 0)
|
||||
builder := sqlstore.SQLBuilder{}
|
||||
builder.Write(sqlStatmentLibrayPanelDTOWithMeta)
|
||||
builder.Write(selectLibrayPanelDTOWithMeta)
|
||||
builder.Write(", 'General' as folder_name ")
|
||||
builder.Write(", '' as folder_uid ")
|
||||
builder.Write(fromLibrayPanelDTOWithMeta)
|
||||
builder.Write(` WHERE lp.uid=? AND lp.org_id=? AND lp.folder_id=0`, uid, c.SignedInUser.OrgId)
|
||||
builder.Write(" UNION ")
|
||||
builder.Write(sqlStatmentLibrayPanelDTOWithMeta)
|
||||
builder.Write(selectLibrayPanelDTOWithMeta)
|
||||
builder.Write(", dashboard.title as folder_name ")
|
||||
builder.Write(", dashboard.uid as folder_uid ")
|
||||
builder.Write(fromLibrayPanelDTOWithMeta)
|
||||
builder.Write(" INNER JOIN dashboard AS dashboard on lp.folder_id = dashboard.id AND lp.folder_id <> 0")
|
||||
builder.Write(` WHERE lp.uid=? AND lp.org_id=?`, uid, c.SignedInUser.OrgId)
|
||||
if c.SignedInUser.OrgRole != models.ROLE_ADMIN {
|
||||
@ -365,6 +374,8 @@ func (lps *LibraryPanelService) getLibraryPanel(c *models.ReqContext, uid string
|
||||
Version: libraryPanel.Version,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: libraryPanel.FolderName,
|
||||
FolderUID: libraryPanel.FolderUID,
|
||||
ConnectedDashboards: libraryPanel.ConnectedDashboards,
|
||||
Created: libraryPanel.Created,
|
||||
Updated: libraryPanel.Updated,
|
||||
@ -405,14 +416,20 @@ func (lps *LibraryPanelService) getAllLibraryPanels(c *models.ReqContext, query
|
||||
err := lps.SQLStore.WithDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
builder := sqlstore.SQLBuilder{}
|
||||
if folderFilter.includeGeneralFolder {
|
||||
builder.Write(sqlStatmentLibrayPanelDTOWithMeta)
|
||||
builder.Write(selectLibrayPanelDTOWithMeta)
|
||||
builder.Write(", 'General' as folder_name ")
|
||||
builder.Write(", '' as folder_uid ")
|
||||
builder.Write(fromLibrayPanelDTOWithMeta)
|
||||
builder.Write(` WHERE lp.org_id=? AND lp.folder_id=0`, c.SignedInUser.OrgId)
|
||||
writeSearchStringSQL(query, lps.SQLStore, &builder)
|
||||
writeExcludeSQL(query, &builder)
|
||||
writePanelFilterSQL(panelFilter, &builder)
|
||||
builder.Write(" UNION ")
|
||||
}
|
||||
builder.Write(sqlStatmentLibrayPanelDTOWithMeta)
|
||||
builder.Write(selectLibrayPanelDTOWithMeta)
|
||||
builder.Write(", dashboard.title as folder_name ")
|
||||
builder.Write(", dashboard.uid as folder_uid ")
|
||||
builder.Write(fromLibrayPanelDTOWithMeta)
|
||||
builder.Write(" INNER JOIN dashboard AS dashboard on lp.folder_id = dashboard.id AND lp.folder_id<>0")
|
||||
builder.Write(` WHERE lp.org_id=?`, c.SignedInUser.OrgId)
|
||||
writeSearchStringSQL(query, lps.SQLStore, &builder)
|
||||
@ -448,6 +465,8 @@ func (lps *LibraryPanelService) getAllLibraryPanels(c *models.ReqContext, query
|
||||
Version: panel.Version,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: panel.FolderName,
|
||||
FolderUID: panel.FolderUID,
|
||||
ConnectedDashboards: panel.ConnectedDashboards,
|
||||
Created: panel.Created,
|
||||
Updated: panel.Updated,
|
||||
@ -526,8 +545,12 @@ func (lps *LibraryPanelService) getLibraryPanelsForDashboardID(c *models.ReqCont
|
||||
libraryPanelMap := make(map[string]LibraryPanelDTO)
|
||||
err := lps.SQLStore.WithDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
var libraryPanels []LibraryPanelWithMeta
|
||||
sql := sqlStatmentLibrayPanelDTOWithMeta + "INNER JOIN library_panel_dashboard AS lpd ON lpd.librarypanel_id = lp.id AND lpd.dashboard_id=?"
|
||||
sess := session.SQL(sql, dashboardID)
|
||||
sql := selectLibrayPanelDTOWithMeta + ", coalesce(dashboard.title, 'General') AS folder_name, coalesce(dashboard.uid, '') AS folder_uid " + fromLibrayPanelDTOWithMeta + `
|
||||
LEFT JOIN dashboard AS dashboard ON dashboard.id = lp.folder_id AND dashboard.id=?
|
||||
INNER JOIN library_panel_dashboard AS lpd ON lpd.librarypanel_id = lp.id AND lpd.dashboard_id=?
|
||||
`
|
||||
|
||||
sess := session.SQL(sql, dashboardID, dashboardID)
|
||||
err := sess.Find(&libraryPanels)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -546,6 +569,8 @@ func (lps *LibraryPanelService) getLibraryPanelsForDashboardID(c *models.ReqCont
|
||||
Version: panel.Version,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: panel.CanEdit,
|
||||
FolderName: panel.FolderName,
|
||||
FolderUID: panel.FolderUID,
|
||||
ConnectedDashboards: panel.ConnectedDashboards,
|
||||
Created: panel.Created,
|
||||
Updated: panel.Updated,
|
||||
|
@ -109,6 +109,8 @@ func (lps *LibraryPanelService) LoadLibraryPanelsForDashboard(c *models.ReqConte
|
||||
"version": libraryPanelInDB.Version,
|
||||
"meta": map[string]interface{}{
|
||||
"canEdit": libraryPanelInDB.Meta.CanEdit,
|
||||
"folderName": libraryPanelInDB.Meta.FolderName,
|
||||
"folderUid": libraryPanelInDB.Meta.FolderUID,
|
||||
"connectedDashboards": libraryPanelInDB.Meta.ConnectedDashboards,
|
||||
"created": libraryPanelInDB.Meta.Created,
|
||||
"updated": libraryPanelInDB.Meta.Updated,
|
||||
|
@ -71,6 +71,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -104,6 +106,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[1].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[1].Meta.Updated,
|
||||
@ -166,6 +170,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -199,6 +205,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[1].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[1].Meta.Updated,
|
||||
@ -281,6 +289,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -314,6 +324,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[1].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[1].Meta.Updated,
|
||||
@ -414,6 +426,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "NewFolder",
|
||||
FolderUID: newFolder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -507,6 +521,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -540,6 +556,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[1].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[1].Meta.Updated,
|
||||
@ -602,6 +620,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -664,6 +684,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -727,6 +749,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -799,6 +823,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -869,6 +895,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
@ -902,6 +930,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[1].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[1].Meta.Updated,
|
||||
@ -966,6 +996,8 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.LibraryPanels[0].Meta.Created,
|
||||
Updated: result.Result.LibraryPanels[0].Meta.Updated,
|
||||
|
@ -41,6 +41,8 @@ func TestGetLibraryPanel(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryPanelDTOMeta{
|
||||
CanEdit: true,
|
||||
FolderName: "ScenarioFolder",
|
||||
FolderUID: sc.folder.Uid,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.Meta.Created,
|
||||
Updated: result.Result.Meta.Updated,
|
||||
|
@ -337,6 +337,8 @@ func TestLibraryPanelPermissions(t *testing.T) {
|
||||
result.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
|
||||
result.Result.Meta.UpdatedBy.Name = UserInDbName
|
||||
result.Result.Meta.UpdatedBy.AvatarUrl = UserInDbAvatar
|
||||
result.Result.Meta.FolderName = folder.Title
|
||||
result.Result.Meta.FolderUID = folder.Uid
|
||||
results = append(results, result.Result)
|
||||
}
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
@ -382,6 +384,7 @@ func TestLibraryPanelPermissions(t *testing.T) {
|
||||
result.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
|
||||
result.Result.Meta.UpdatedBy.Name = UserInDbName
|
||||
result.Result.Meta.UpdatedBy.AvatarUrl = UserInDbAvatar
|
||||
result.Result.Meta.FolderName = "General"
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
|
||||
resp = sc.service.getAllHandler(sc.reqContext)
|
||||
@ -442,6 +445,8 @@ func TestLibraryPanelPermissions(t *testing.T) {
|
||||
result.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
|
||||
result.Result.Meta.UpdatedBy.Name = UserInDbName
|
||||
result.Result.Meta.UpdatedBy.AvatarUrl = UserInDbAvatar
|
||||
result.Result.Meta.FolderName = folder.Title
|
||||
result.Result.Meta.FolderUID = folder.Uid
|
||||
results = append(results, result.Result)
|
||||
}
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
@ -462,6 +467,8 @@ func TestLibraryPanelPermissions(t *testing.T) {
|
||||
result.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
|
||||
result.Result.Meta.UpdatedBy.Name = UserInDbName
|
||||
result.Result.Meta.UpdatedBy.AvatarUrl = UserInDbAvatar
|
||||
result.Result.Meta.FolderName = "General"
|
||||
result.Result.Meta.FolderUID = ""
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
|
||||
sc.reqContext.ReplaceAllParams(map[string]string{":uid": result.Result.UID})
|
||||
|
@ -94,6 +94,8 @@ func TestLoadLibraryPanelsForDashboard(t *testing.T) {
|
||||
"version": sc.initialResult.Result.Version,
|
||||
"meta": map[string]interface{}{
|
||||
"canEdit": false,
|
||||
"folderName": "ScenarioFolder",
|
||||
"folderUid": sc.folder.Uid,
|
||||
"connectedDashboards": int64(1),
|
||||
"created": sc.initialResult.Result.Meta.Created,
|
||||
"updated": sc.initialResult.Result.Meta.Updated,
|
||||
|
@ -41,6 +41,8 @@ type LibraryPanelWithMeta struct {
|
||||
Updated time.Time
|
||||
|
||||
CanEdit bool
|
||||
FolderName string
|
||||
FolderUID string `xorm:"folder_uid"`
|
||||
ConnectedDashboards int64
|
||||
CreatedBy int64
|
||||
UpdatedBy int64
|
||||
@ -74,8 +76,10 @@ type LibraryPanelSearchResult struct {
|
||||
|
||||
// LibraryPanelDTOMeta is the meta information for LibraryPanelDTO.
|
||||
type LibraryPanelDTOMeta struct {
|
||||
CanEdit bool `json:"canEdit"`
|
||||
ConnectedDashboards int64 `json:"connectedDashboards"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
FolderName string `json:"folderName"`
|
||||
FolderUID string `json:"folderUid"`
|
||||
ConnectedDashboards int64 `json:"connectedDashboards"`
|
||||
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
|
@ -24,6 +24,7 @@ export const PanelTypeCard: React.FC<Props> = ({
|
||||
disabled,
|
||||
showBadge,
|
||||
description,
|
||||
children,
|
||||
}) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const cssClass = cx({
|
||||
@ -44,6 +45,7 @@ export const PanelTypeCard: React.FC<Props> = ({
|
||||
<div className={styles.itemContent}>
|
||||
<div className={styles.name}>{title}</div>
|
||||
{description ? <span className={styles.description}>{description}</span> : null}
|
||||
{children}
|
||||
</div>
|
||||
{showBadge && (
|
||||
<div className={cx(styles.badge, disabled && styles.disabled)}>
|
||||
@ -82,7 +84,6 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 55px;
|
||||
transition: ${theme.transitions.create(['background'], {
|
||||
duration: theme.transitions.duration.short,
|
||||
})};
|
||||
@ -94,6 +95,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
itemContent: css`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: ${theme.spacing(0, 1)};
|
||||
`,
|
||||
current: css`
|
||||
label: currentVisualizationItem;
|
||||
@ -111,7 +113,6 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
white-space: nowrap;
|
||||
font-size: ${theme.typography.size.sm};
|
||||
font-weight: ${theme.typography.fontWeightMedium};
|
||||
padding: 0 10px;
|
||||
width: 100%;
|
||||
`,
|
||||
description: css`
|
||||
@ -121,7 +122,6 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
color: ${theme.colors.text.secondary};
|
||||
font-size: ${theme.typography.bodySmall.fontSize};
|
||||
font-weight: ${theme.typography.fontWeightLight};
|
||||
padding: 0 ${theme.spacing(1.25)};
|
||||
width: 100%;
|
||||
`,
|
||||
img: css`
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
import { GrafanaRouteComponentProps } from '../../core/navigation/types';
|
||||
import { StoreState } from '../../types';
|
||||
@ -10,7 +11,6 @@ import Page from '../../core/components/Page/Page';
|
||||
import { LibraryPanelsSearch } from '../library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch';
|
||||
import { OpenLibraryPanelModal } from '../library-panels/components/OpenLibraryPanelModal/OpenLibraryPanelModal';
|
||||
import { getFolderByUid } from './state/actions';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
export interface OwnProps extends GrafanaRouteComponentProps<{ uid: string }> {}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { FolderDTO } from 'app/types';
|
||||
import { NavModel, NavModelItem } from '@grafana/data';
|
||||
|
||||
import { FolderDTO } from 'app/types';
|
||||
import { getConfig } from '../../../core/config';
|
||||
|
||||
export function buildNavModel(folder: FolderDTO): NavModelItem {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React, { useState } from 'react';
|
||||
import { PanelPluginMeta } from '@grafana/data';
|
||||
import { css } from '@emotion/css';
|
||||
import { GrafanaTheme2, PanelPluginMeta } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Icon, Link, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { LibraryPanelDTO } from '../../types';
|
||||
import { PanelTypeCard } from 'app/features/dashboard/components/VizTypePicker/PanelTypeCard';
|
||||
@ -37,7 +39,9 @@ export const LibraryPanelCard: React.FC<LibraryPanelCardProps & { children?: JSX
|
||||
plugin={panelPlugin}
|
||||
onClick={() => onClick(libraryPanel)}
|
||||
onDelete={showSecondaryActions ? () => setShowDeletionModal(true) : undefined}
|
||||
/>
|
||||
>
|
||||
<FolderLink libraryPanel={libraryPanel} />
|
||||
</PanelTypeCard>
|
||||
{showDeletionModal && (
|
||||
<DeleteLibraryPanelModal
|
||||
libraryPanel={libraryPanel}
|
||||
@ -48,3 +52,46 @@ export const LibraryPanelCard: React.FC<LibraryPanelCardProps & { children?: JSX
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
interface FolderLinkProps {
|
||||
libraryPanel: LibraryPanelDTO;
|
||||
}
|
||||
|
||||
function FolderLink({ libraryPanel }: FolderLinkProps): JSX.Element {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
if (!libraryPanel.meta.folderUid) {
|
||||
return (
|
||||
<span className={styles.metaContainer}>
|
||||
<Icon name={'folder'} size="sm" />
|
||||
{libraryPanel.meta.folderName}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link href={`/dashboards/f/${libraryPanel.meta.folderUid}`}>
|
||||
<span className={styles.metaContainer}>
|
||||
<Icon name={'folder-upload'} size="sm" />
|
||||
{libraryPanel.meta.folderName}
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
function getStyles(theme: GrafanaTheme2) {
|
||||
return {
|
||||
metaContainer: css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: ${theme.colors.text.disabled};
|
||||
font-size: ${theme.typography.bodySmall.fontSize};
|
||||
padding-top: ${theme.spacing(0.5)};
|
||||
|
||||
svg {
|
||||
margin-right: ${theme.spacing(0.5)};
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
@ -216,6 +216,8 @@ describe('LibraryPanelsSearch', () => {
|
||||
version: 1,
|
||||
meta: {
|
||||
canEdit: true,
|
||||
folderName: 'General',
|
||||
folderUid: '',
|
||||
connectedDashboards: 0,
|
||||
created: '2021-01-01 12:00:00',
|
||||
createdBy: { id: 1, name: 'Admin', avatarUrl: '' },
|
||||
@ -258,6 +260,8 @@ describe('LibraryPanelsSearch', () => {
|
||||
version: 1,
|
||||
meta: {
|
||||
canEdit: true,
|
||||
folderName: 'General',
|
||||
folderUid: '',
|
||||
connectedDashboards: 0,
|
||||
created: '2021-01-01 12:00:00',
|
||||
createdBy: { id: 1, name: 'Admin', avatarUrl: '' },
|
||||
|
@ -110,6 +110,8 @@ function mockLibraryPanel({
|
||||
model = { type: 'text', title: 'Test Panel' },
|
||||
meta = {
|
||||
canEdit: true,
|
||||
folderName: 'General',
|
||||
folderUid: '',
|
||||
connectedDashboards: 0,
|
||||
created: '2021-01-01T00:00:00',
|
||||
createdBy: { id: 1, name: 'User X', avatarUrl: '/avatar/abc' },
|
||||
|
@ -24,6 +24,8 @@ export interface LibraryPanelDTO {
|
||||
|
||||
export interface LibraryPanelDTOMeta {
|
||||
canEdit: boolean;
|
||||
folderName: string;
|
||||
folderUid: string;
|
||||
connectedDashboards: number;
|
||||
created: string;
|
||||
updated: string;
|
||||
|
Loading…
Reference in New Issue
Block a user