D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
usr
/
share
/
grafana
/
public
/
build
/
Filename :
CorrelationsPage.c84b08e25d99bf88242d.js
back
Copy
"use strict";(self.webpackChunkgrafana=self.webpackChunkgrafana||[]).push([[413],{74110:(ke,G,r)=>{r.r(G),r.d(G,{default:()=>Qe});var p=r(42844),R=r(89949),e=r(27702),w=r(86312),ce=r(73289),ue=r(15202),D=r(66670),T=r(73453),J=r(52419),N=r(63439),me=r(39695),de=r(50852),$=r(66310),ge=r(25357),j=r(44644),fe=r(66574),pe=r(48105),ve=r(18771),he=r(25695),Ee=r(35952),h=r(46089);const H=(0,e.createContext)(void 0);function ye(t){const[a,o]=(0,e.useState)(0),{pages:l,onSubmit:n,children:i}=t;return e.createElement(H.Provider,{value:{currentPage:a,CurrentPageComponent:l[a],isLastPage:a===l.length-1,nextPage:()=>o(a+1),prevPage:()=>o(a-1),onSubmit:n}},i)}const Y=()=>{const t=(0,e.useContext)(H);if(!t)throw new Error("useWizardContext must be used within a WizardContextProvider");return t};function Ce(t){const{navigation:a}=t,{handleSubmit:o}=(0,h.Gc)(),{CurrentPageComponent:l,isLastPage:n,nextPage:i,onSubmit:s}=Y(),c=a;return e.createElement("form",{onSubmit:o(d=>{n?s(d):i()})},e.createElement(l,null),e.createElement(c,null))}function k(t){const{defaultValues:a,pages:o,onSubmit:l,navigation:n}=t,i=(0,h.cI)({defaultValues:a});return e.createElement(h.RV,{...i},e.createElement(ye,{pages:o,onSubmit:l},e.createElement(Ce,{navigation:n})))}var W=r(12142),U=r(5229),y=r(22209),P=r(1128),be=r(60105);const X=(0,e.createContext)({loading:!1,correlation:void 0,readOnly:!1}),q=t=>{const{data:a,children:o}=t;return e.createElement(X.Provider,{value:a},o)},A=()=>(0,e.useContext)(X),M=(t,a)=>a?`${t}_${a.sourceUID}-${a.uid}`:t,xe=t=>({label:(0,p.css)` max-width: ${t.spacing(80)}; `,description:(0,p.css)` max-width: ${t.spacing(80)}; `}),_=()=>{const{register:t,formState:a}=(0,h.Gc)(),o=(0,$.wW)(xe),{correlation:l,readOnly:n}=A();return e.createElement(e.Fragment,null,e.createElement(U.C,{label:"Define correlation label (Step 1 of 3)"},e.createElement("p",null,"Define text that will describe the correlation."),e.createElement("input",{type:"hidden",...t("config.type")}),e.createElement(y.g,{label:"Label",description:"This name will be used as the label for the correlation. This will show as button text, a menu item, or hover text on a link.",className:o.label,invalid:!!a.errors.label,error:a.errors.label?.message},e.createElement(P.I,{id:M("label",l),...t("label",{required:{value:!0,message:"This field is required."}}),readOnly:n,placeholder:"e.g. Tempo traces"})),e.createElement(y.g,{label:"Description",description:"Optional description with more information about the link",className:(0,p.cx)(o.description)},e.createElement(be.K,{id:M("description",l),...t("description"),readOnly:n}))))};var b=r(50230),ee=r(53229),te=r(5926),Se=r(20205),F=r(24094),x=r(23852),Ie=r(56948),O=r(79978),z=r(80011),we=r(16310),De=r(28580),Te=r(67437);const $e=t=>({heading:(0,p.css)` font-size: ${t.typography.h5.fontSize}; font-weight: ${t.typography.fontWeightRegular}; `,removeButton:(0,p.css)` margin-top: 25px; `}),Pe=t=>{const{control:a,formState:o,register:l,setValue:n,watch:i,getValues:s}=(0,h.Gc)(),{readOnly:c}=t,[d,C]=(0,e.useState)([]),g=(0,$.wW)($e),E=Fe();return e.createElement(e.Fragment,null,e.createElement("input",{type:"hidden",...l("id")}),e.createElement(Ie.F,{name:"config.transformations",control:a},({fields:I,append:K,remove:v})=>e.createElement(e.Fragment,null,e.createElement(x.K,{direction:"column",alignItems:"flex-start"},e.createElement("div",{className:g.heading},"Transformations"),I.length===0&&e.createElement("div",null," No transformations defined."),I.length>0&&e.createElement("div",null,I.map((f,u)=>e.createElement(x.K,{direction:"row",key:f.id,alignItems:"top"},e.createElement(y.g,{label:e.createElement(x.K,{gap:.5},e.createElement(O._,{htmlFor:`config.transformations.${f.id}-${u}.type`},"Type"),e.createElement(z.u,{content:e.createElement("div",null,e.createElement("p",null,"The type of transformation that will be applied to the source data."))},e.createElement(T.J,{name:"info-circle",size:"sm"}))),invalid:!!o.errors?.config?.transformations?.[u]?.type,error:o.errors?.config?.transformations?.[u]?.type?.message,validationMessageHorizontalOverflow:!0},e.createElement(we.g,{render:({field:{onChange:m,ref:L,...Q}})=>e.createElement(De.Ph,{...Q,value:f.type,onChange:V=>{if(!c){const se=s().config.transformations[u];let Z=(0,R.fill)(Array(u+1),{});d.forEach((He,Ye)=>Z[Ye]=He),Z[u]={expression:se.expression,mapValue:se.mapValue},C(Z);const ie=S(V.value);ie.showExpression?n(`config.transformations.${u}.expression`,d[u]?.expression||""):n(`config.transformations.${u}.expression`,""),ie.showMapValue?n(`config.transformations.${u}.mapValue`,d[u]?.mapValue||""):n(`config.transformations.${u}.mapValue`,""),m(V.value)}},options:E,width:25,inputId:`config.transformations.${f.id}-${u}.type`}),control:a,name:`config.transformations.${u}.type`,rules:{required:{value:!0,message:"Please select a transformation type"}}})),e.createElement(y.g,{label:e.createElement(x.K,{gap:.5},e.createElement(O._,{htmlFor:`config.transformations.${f.id}.field`},"Field"),e.createElement(z.u,{content:e.createElement("div",null,e.createElement("p",null,"Optional. The field to transform. If not specified, the transformation will be applied to the results field."))},e.createElement(T.J,{name:"info-circle",size:"sm"})))},e.createElement(P.I,{...l(`config.transformations.${u}.field`),readOnly:c,defaultValue:f.field,label:"field",id:`config.transformations.${f.id}.field`})),e.createElement(y.g,{label:e.createElement(x.K,{gap:.5},e.createElement(O._,{htmlFor:`config.transformations.${f.id}.expression`},"Expression",S(i(`config.transformations.${u}.type`)).requireExpression?" *":""),e.createElement(z.u,{content:e.createElement("div",null,e.createElement("p",null,"Required for regular expression. The expression the transformation will use. Logfmt does not use further specifications."))},e.createElement(T.J,{name:"info-circle",size:"sm"}))),invalid:!!o.errors?.config?.transformations?.[u]?.expression,error:o.errors?.config?.transformations?.[u]?.expression?.message},e.createElement(P.I,{...l(`config.transformations.${u}.expression`,{required:S(i(`config.transformations.${u}.type`)).requireExpression?"Please define an expression":void 0}),defaultValue:f.expression,readOnly:c,disabled:!S(i(`config.transformations.${u}.type`)).showExpression,id:`config.transformations.${f.id}.expression`})),e.createElement(y.g,{label:e.createElement(x.K,{gap:.5},e.createElement(O._,{htmlFor:`config.transformations.${f.id}.mapValue`},"Map value"),e.createElement(z.u,{content:e.createElement("div",null,e.createElement("p",null,"Optional. Defines the name of the variable. This is currently only valid for regular expressions with a single, unnamed capture group."))},e.createElement(T.J,{name:"info-circle",size:"sm"})))},e.createElement(P.I,{...l(`config.transformations.${u}.mapValue`),defaultValue:f.mapValue,readOnly:c,disabled:!S(i(`config.transformations.${u}.type`)).showMapValue,id:`config.transformations.${f.id}.mapValue`})),!c&&e.createElement("div",{className:g.removeButton},e.createElement(Te.h,{tooltip:"Remove transformation",name:"trash-alt",onClick:()=>{v(u);const m=[...d];m[u]=void 0,C((0,R.compact)(m))}},"Remove"))))),!c&&e.createElement(D.zx,{icon:"plus",onClick:()=>K({type:void 0},{shouldFocus:!1}),variant:"secondary",type:"button"},"Add transformation")))))};function S(t){switch(t){case F.sN.Logfmt:return{label:"Logfmt",value:F.sN.Logfmt,description:"Parse provided field with logfmt to get variables",showExpression:!1,showMapValue:!1};case F.sN.Regex:return{label:"Regular expression",value:F.sN.Regex,description:"Field will be parsed with regex. Use named capture groups to return multiple variables, or a single unnamed capture group to add variable to named map value.",showExpression:!0,showMapValue:!0,requireExpression:!0};default:return{label:t,value:t,showExpression:!1,showMapValue:!1}}}const Fe=()=>Object.values(F.sN).map(t=>{const a=S(t);return{label:a.label,value:a.value,description:a.description}}),Ne=t=>({label:(0,p.css)` max-width: ${t.spacing(80)}; `,variable:(0,p.css)` font-family: ${t.typography.fontFamilyMonospace}; font-weight: ${t.typography.fontWeightMedium}; `}),ae=()=>{const{control:t,formState:a,register:o,getValues:l}=(0,h.Gc)(),n=(0,$.wW)(Ne),i=g=>E=>g(E.uid),{correlation:s,readOnly:c}=A(),d=l("config.target"),C=(0,Se.lt)(d,{}).variables.map(g=>g.variableName+(g.fieldPath?`.${g.fieldPath}`:""));return e.createElement(e.Fragment,null,e.createElement(U.C,{label:`Configure the data source that will link to ${(0,te.ak)().getInstanceSettings(s?.targetUID)?.name} (Step 3 of 3)`},e.createElement("p",null,"Define what data source will display the correlation, and what data will replace previously defined variables."),e.createElement(h.Qr,{control:t,name:"sourceUID",rules:{required:{value:!0,message:"This field is required."},validate:{writable:g=>!(0,te.ak)().getInstanceSettings(g)?.readOnly||"Source can't be a read-only data source."}},render:({field:{onChange:g,value:E}})=>e.createElement(y.g,{label:"Source",description:"Results from selected source data source have links displayed in the panel",htmlFor:"source",invalid:!!a.errors.sourceUID,error:a.errors.sourceUID?.message},e.createElement(ee.q,{onChange:i(g),noDefault:!0,current:E,inputId:"source",width:32,disabled:s!==void 0}))}),e.createElement(y.g,{label:"Results field",description:"The link will be shown next to the value of this field",className:n.label,invalid:!!a.errors?.config?.field,error:a.errors?.config?.field?.message},e.createElement(P.I,{id:M("field",s),...o("config.field",{required:"This field is required."}),readOnly:c})),C.length>0&&e.createElement(b.Z,null,e.createElement(b.Z.Heading,null,"Variables used in the target query"),e.createElement(b.Z.Description,null,"You have used following variables in the target query:"," ",C.map((g,E)=>e.createElement("span",{className:n.variable,key:E},g,E<C.length-1?", ":"")),e.createElement("br",null),"A data point needs to provide values to all variables as fields or as transformations output to make the correlation button appear in the visualization.",e.createElement("br",null),"Note: Not every variable needs to be explicitly defined below. A transformation such as"," ",e.createElement("span",{className:n.variable},"logfmt")," will create variables for every key/value pair.")),e.createElement(Pe,{readOnly:c})))};var Ae=r(25111),Oe=r(62247),ze=r(10864);const Le=({dsUid:t,invalid:a,error:o,name:l})=>{const{value:n,loading:i,error:s}=(0,Ae.Z)(async()=>{if(t)return(0,ze.F)().get(t)},[t]),c=n?.components?.QueryEditor;return e.createElement(y.g,{label:"Query",description:e.createElement("span",null,"Define the query that is run when the link is clicked. You can use"," ",e.createElement("a",{href:"https://grafana.com/docs/grafana/latest/panels-visualizations/configure-data-links/",target:"_blank",rel:"noreferrer"},"variables")," ","to access specific field values."),invalid:a,error:o},e.createElement(h.Qr,{name:l,rules:{validate:{hasQueryEditor:()=>c!==void 0||"The selected target data source must export a query editor."}},render:({field:{value:d,onChange:C}})=>i?e.createElement(J.u,{text:"Loading query editor..."}):s?e.createElement(N.b,{title:"Error loading data source"},"The selected data source could not be loaded."):n?c?e.createElement(e.Fragment,null,e.createElement(c,{onRunQuery:()=>{},app:Oe.zj.Correlations,onChange:g=>{C(g)},datasource:n,query:d})):e.createElement(N.b,{title:"Data source does not export a query editor."}):e.createElement(N.b,{title:"No data source selected",severity:"info"},"Please select a target data source first.")}))},re=()=>{const{control:t,formState:a}=(0,h.Gc)(),o=i=>s=>i(s.uid),{correlation:l}=A(),n=(0,h.qo)({name:"targetUID"})||l?.targetUID;return e.createElement(e.Fragment,null,e.createElement(U.C,{label:"Setup the target for the correlation (Step 2 of 3)"},e.createElement("p",null,"Define what data source the correlation will link to, and what query will run when the correlation is clicked."),e.createElement(h.Qr,{control:t,name:"targetUID",rules:{required:{value:!0,message:"This field is required."}},render:({field:{onChange:i,value:s}})=>e.createElement(y.g,{label:"Target",description:"Specify which data source is queried when the link is clicked",htmlFor:"target",invalid:!!a.errors.targetUID,error:a.errors.targetUID?.message},e.createElement(ee.q,{onChange:o(i),noDefault:!0,current:s,inputId:"target",width:32,disabled:l!==void 0}))}),e.createElement(Le,{name:"config.target",dsUid:n,invalid:!!a.errors?.config?.target,error:a.errors?.config?.target?.message})))};var Ve=r(64022);const ne=()=>{const{currentPage:t,prevPage:a,isLastPage:o}=Y(),{readOnly:l,loading:n,correlation:i}=A(),s=!l&&e.createElement(D.zx,{variant:"primary",icon:n?"fa fa-spinner":"save",type:"submit",disabled:n},i===void 0?"Add":"Save"),c=e.createElement(D.zx,{variant:"primary",type:"submit"},"Next");return e.createElement(Ve.Lh,{justify:"flex-start"},t>0?e.createElement(D.zx,{variant:"secondary",onClick:a},"Back"):void 0,o?s:c)},Re=t=>({panelContainer:(0,p.css)` position: relative; padding: ${t.spacing(1)}; margin-bottom: ${t.spacing(2)}; `,infoBox:(0,p.css)` margin-top: 20px; // give space for close button `}),We=({onClose:t,onCreated:a})=>{const o=(0,$.wW)(Re),{create:{execute:l,loading:n,error:i,value:s}}=(0,W.K)();(0,e.useEffect)(()=>{!i&&!n&&s&&a()},[i,n,s,a]);const c={config:{type:"query",target:{},field:""}};return e.createElement(he.l,{className:o.panelContainer},e.createElement(Ee.P,{onClick:t}),e.createElement(q,{data:{loading:n,readOnly:!1,correlation:void 0}},e.createElement(k,{defaultValues:c,pages:[_,re,ae],navigation:ne,onSubmit:l})))},Ue=({onUpdated:t,correlation:a,readOnly:o=!1})=>{const{update:{execute:l,loading:n,error:i,value:s}}=(0,W.K)(),c=d=>l({...d,sourceUID:a.sourceUID,uid:a.uid});return(0,e.useEffect)(()=>{!i&&!n&&s&&t()},[i,n,s,t]),e.createElement(q,{data:{loading:n,readOnly:o,correlation:a}},e.createElement(k,{defaultValues:a,pages:[_,re,ae],onSubmit:o?d=>()=>{}:c,navigation:ne}))};var Me=r(66970);const Be=({onClick:t,canWriteCorrelations:a})=>a?e.createElement(Me.Z,{title:"You haven't defined any correlation yet.",buttonIcon:"gf-glue",onClick:t,buttonTitle:"Add correlation",proTip:"you can also define correlations via datasource provisioning"}):e.createElement(b.Z,null,e.createElement(b.Z.Heading,null,"There are no correlations configured yet."),e.createElement(b.Z.Description,null,"Please contact your administrator to create new correlations.")),oe=(t,a,o)=>t.values[o].name.localeCompare(a.values[o].name),B=({source:t})=>t.readOnly,Ke=(0,p.css)` display: flex; justify-content: center; `;function Qe(){const t=(0,pe.q)("correlations"),[a,o]=(0,e.useState)(!1),l=(0,e.useRef)(1),n=m=>{o(m),m&&(0,w.ff)("grafana_correlations_adding_started")},{remove:i,get:{execute:s,...c}}=(0,W.K)(),d=fe.Vt.hasPermission(ve.AccessControlAction.DataSourcesWrite),C=(0,e.useCallback)(()=>{(0,w.ff)("grafana_correlations_added"),s({page:l.current}),n(!1)},[s]),g=(0,e.useCallback)(()=>{(0,w.ff)("grafana_correlations_edited"),s({page:l.current})},[s]),E=(0,e.useCallback)(async(m,L)=>{await i.execute(m),(0,w.ff)("grafana_correlations_deleted"),L&&l.current--,s({page:l.current})},[i,s]);(0,e.useEffect)(()=>{s({page:l.current})},[s]);const I=(0,e.useCallback)(({row:{index:m,original:{source:{uid:L,readOnly:Q},uid:V}}})=>!Q&&e.createElement(ue.m,{"aria-label":"delete correlation",onConfirm:()=>E({sourceUID:L,uid:V},l.current>1&&m===0&&v?.correlations.length===1),closeOnConfirm:!0}),[E]),K=(0,e.useMemo)(()=>[{id:"info",cell:je,disableGrow:!0,visible:m=>m.some(B)},{id:"source",header:"Source",cell:le,sortType:oe},{id:"target",header:"Target",cell:le,sortType:oe},{id:"label",header:"Label",sortType:"alphanumeric"},{id:"actions",cell:I,disableGrow:!0,visible:m=>d&&m.some((0,R.negate)(B))}],[I,d]),v=(0,e.useMemo)(()=>c.value,[c.value]),f=v?.correlations.length===0&&!a&&!c.error,u=d&&v?.correlations?.length!==0&&v!==void 0&&!a&&e.createElement(D.zx,{icon:"plus",onClick:()=>n(!0)},"Add new");return e.createElement(j.T,{navModel:t,subTitle:e.createElement(e.Fragment,null,"Define how data living in different data sources relates to each other. Read more in the"," ",e.createElement("a",{href:"https://grafana.com/docs/grafana/next/administration/correlations/",target:"_blank",rel:"noreferrer"},"documentation ",e.createElement(T.J,{name:"external-link-alt"}))),actions:u},e.createElement(j.T.Contents,null,e.createElement("div",null,!v&&c.loading&&e.createElement("div",{className:Ke},e.createElement(J.u,{text:"loading..."})),f&&e.createElement(Be,{canWriteCorrelations:d,onClick:()=>n(!0)}),c.error&&e.createElement(N.b,{severity:"error",title:"Error fetching correlation data",topSpacing:2},(0,ce.kW)(c.error)&&c.error.data?.message||"An unknown error occurred while fetching correlation data. Please try again."),a&&e.createElement(We,{onClose:()=>n(!1),onCreated:C}),v&&v.correlations.length>=1&&e.createElement(e.Fragment,null,e.createElement(me.e,{renderExpandedRow:m=>e.createElement(Ze,{correlation:m,onUpdated:g,readOnly:B({source:m.source})||!d}),columns:K,data:v.correlations,getRowId:m=>`${m.source.uid}-${m.uid}`}),e.createElement(de.t,{currentPage:l.current,numberOfPages:Math.ceil(v.totalCount/v.limit),onNavigate:m=>{s({page:l.current=m})}})))))}function Ze({correlation:{source:t,target:a,...o},readOnly:l,onUpdated:n}){return(0,e.useEffect)(()=>(0,w.ff)("grafana_correlations_details_expanded"),[]),e.createElement(Ue,{correlation:{...o,sourceUID:t.uid,targetUID:a.uid},onUpdated:n,readOnly:l})}const Ge=t=>({root:(0,p.css)` display: flex; align-items: center; `,dsLogo:(0,p.css)` margin-right: ${t.spacing()}; height: 16px; width: 16px; `}),le=(0,e.memo)(function({cell:{value:a}}){const o=(0,$.wW)(Ge);return e.createElement("span",{className:o.root},e.createElement("img",{src:a.meta.info.logos.small,alt:"",className:o.dsLogo}),a.name)},({cell:{value:t}},{cell:{value:a}})=>t.type===a.type&&t.name===a.name),Je=(0,p.css)` white-space: nowrap; `,je=(0,e.memo)(function({...a}){return a.row.original.source.readOnly?e.createElement(ge.C,{text:"Read only",color:"purple",className:Je}):null},(t,a)=>t.row.original.source.readOnly===a.row.original.source.readOnly)}}]); //# sourceMappingURL=CorrelationsPage.c84b08e25d99bf88242d.js.map