UNPKG

datajunction-ui

Version:
15 lines (14 loc) • 32.2 kB
"use strict";var Ne=Object.defineProperty;var je=(s,c,o)=>c in s?Ne(s,c,{enumerable:!0,configurable:!0,writable:!0,value:o}):s[c]=o;var ae=(s,c,o)=>je(s,typeof c!="symbol"?c+"":c,o);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),n=require("./index-h1A5IisM.cjs"),m=require("react"),ie=require("react-router-dom"),_e=require("./FullNameField-Q0Vq2ewv.cjs"),be=({djClient:s,value:c})=>{const[o,l]=m.useState({}),[u,i]=m.useState([]),d=n.useFormikContext(),r=d.values.upstream_node,p=m.useMemo(()=>n.langs.sql({schema:o}),[o]);m.useEffect(()=>{async function C(){try{const N=await s.metrics();i(N||[])}catch(N){console.error("Failed to load metrics for autocomplete:",N)}}C()},[s]),m.useEffect(()=>{let C=!1;async function N(){var M;const E={};if(r&&r.trim()!=="")try{const I=await s.node(r);(M=I==null?void 0:I.columns)==null||M.forEach(q=>{E[q.name]=[]})}catch(I){console.error("Failed to load upstream node columns:",I)}u.forEach(I=>{E[I]=[]}),C||l(E)}return N(),()=>{C=!0}},[s,r,u]);const x=C=>{d.setFieldValue("aggregate_expression",C)},h=!r||r.trim()==="",j=h?"Derived Metric Expression *":"Aggregate Expression *",_=h?"Reference other metrics using their full names (e.g., namespace.metric_name / namespace.other_metric)":"Use aggregate functions on columns from the upstream node (e.g., SUM(column_name))";return e.jsxs("div",{className:"QueryInput MetricQueryInput NodeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"query",component:"span"}),e.jsx("label",{htmlFor:"Query",children:j}),e.jsx("p",{className:"field-help-text",style:{fontSize:"0.85em",color:"#666",marginBottom:"8px"},children:_}),e.jsx(n.Field,{type:"textarea",style:{display:"none"},as:"textarea",name:"aggregate_expression",id:"Query"}),e.jsx("div",{role:"button",tabIndex:0,className:"relative flex bg-[#282a36]",children:e.jsx(n.ReactCodeMirror,{id:"aggregate_expression",name:"aggregate_expression",extensions:[p],value:c,options:{theme:"default",lineNumbers:!0},width:"100%",height:"100px",style:{margin:"0 0 23px 0",flex:1,fontSize:"110%",textAlign:"left"},onChange:(C,N)=>{x(C)}})})]})},Ce=/`?([a-zA-Z_][a-zA-Z0-9_]*)`?\.`?([a-zA-Z_][a-zA-Z0-9_]*)`?\.`?([a-zA-Z_][a-zA-Z0-9_]*)`?/;function Ee(s,c){const o=new RegExp(Ce.source,"g"),l=new Set(c.map(r=>r.toLowerCase())),u=new Set,i=[];let d;for(;(d=o.exec(s))!==null;){const[,r,p,x]=d;if(!l.has(r.toLowerCase()))continue;const h=`${r}.${p}.${x}`;u.has(h)||(u.add(h),i.push([r,p,x]))}return i}const Z=/`?[a-zA-Z_][a-zA-Z0-9_]*`?(?:\.`?[a-zA-Z_][a-zA-Z0-9_]*`?)+/g;function xe(s){return s.replace(/`/g,"")}const re=n.StateEffect.define();function ve(s){switch(s){case"registering":return"dj-node-chip--registering";case"valid":return"dj-node-chip--valid";case"warning":return"dj-node-chip--warning";case"invalid":return"dj-node-chip--invalid";default:return"dj-node-chip--unknown"}}function ce(s,c,o){const l=new Set((o()||[]).map(d=>d.toLowerCase())),u=s.state.doc,i=[];for(const{from:d,to:r}of s.visibleRanges){const p=u.sliceString(d,r);Z.lastIndex=0;let x;for(;(x=Z.exec(p))!==null;){const h=x[0],j=xe(h),_=c(j),C=j.split(".");let N;if(_!=null&&_.refType)N=_.refType;else if(C.length===3&&l.has(C[0].toLowerCase()))N="source";else continue;const E=`dj-node-chip dj-node-chip--${N} ${ve(_==null?void 0:_.kind)}`,M=d+x.index,I=M+h.length;i.push({from:M,to:I,deco:n.Decoration.mark({class:E,attributes:_!=null&&_.message?{title:_.message}:void 0})})}}return i.sort((d,r)=>d.from-r.from||d.to-r.to),n.Decoration.set(i.map(d=>d.deco.range(d.from,d.to)))}function we({getStatus:s,getKnownCatalogs:c}){return n.ViewPlugin.fromClass(class{constructor(o){this.decorations=ce(o,s,c)}update(o){const l=o.transactions.some(u=>u.effects.some(i=>i.is(re)));(o.docChanged||o.viewportChanged||l)&&(this.decorations=ce(o.view,s,c))}},{decorations:o=>o.decorations})}function Se(s,c){const o=s.state.doc.lineAt(c);Z.lastIndex=0;let l;for(;(l=Z.exec(o.text))!==null;){const u=o.from+l.index,i=u+l[0].length;if(c>=u&&c<=i)return{key:xe(l[0]),from:u,to:i}}return null}function le(s,c){var x;const o=document.createElement("div");o.className="dj-node-tooltip";const l=s.node||{},u=document.createElement("div");u.className="dj-node-tooltip__header";const i=document.createElement("span");i.className=`dj-node-chip dj-node-chip--${s.refType||"node"}`,i.textContent=s.refType||"node",u.appendChild(i);const d=document.createElement("span");if(d.className="dj-node-tooltip__name",d.textContent=l.name||c,u.appendChild(d),o.appendChild(u),s.kind==="invalid"){const h=document.createElement("div");return h.className="dj-node-tooltip__note",h.textContent="Not found in DJ.",o.appendChild(h),o}if(s.kind==="registering"){const h=document.createElement("div");return h.className="dj-node-tooltip__note",h.textContent="Registering…",o.appendChild(h),o}const r=document.createElement("div");r.className="dj-node-tooltip__grid";const p=(h,j)=>{if(j==null||j==="")return;const _=document.createElement("div");_.className="dj-node-tooltip__cell";const C=document.createElement("span");C.className="dj-node-tooltip__label",C.textContent=h;const N=document.createElement("span");N.className="dj-node-tooltip__value",N.textContent=j,_.appendChild(C),_.appendChild(N),r.appendChild(_)};if(l.status&&p("Status",l.status),l.version&&p("Version",l.version),l.mode&&p("Mode",l.mode),Array.isArray(l.columns)&&p("Columns",String(l.columns.length)),r.childElementCount>0&&o.appendChild(r),l.description){const h=document.createElement("div");h.className="dj-node-tooltip__description";const j=l.description;h.textContent=j.length>280?j.slice(0,277)+"…":j,o.appendChild(h)}if(Array.isArray(l.columns)&&l.columns.length>0){const h=document.createElement("div");h.className="dj-node-tooltip__columns";for(const j of l.columns){const _=document.createElement("div");_.className="dj-node-tooltip__col-row";const C=document.createElement("span");if(C.className="dj-node-tooltip__col-name",C.textContent=j.name,_.appendChild(C),j.dimension||j.dimension_column){const E=document.createElement("span");E.className="dj-node-tooltip__col-tag",E.textContent="dim",E.title=(x=j.dimension)!=null&&x.name?`Links to ${j.dimension.name}`:"Linked dimension",_.appendChild(E)}const N=document.createElement("span");N.className="dj-node-tooltip__col-type",N.textContent=(j.type||"").split(` `)[0],N.title=j.type||"",_.appendChild(N),h.appendChild(_)}o.appendChild(h)}if(l.name){const h=document.createElement("div");h.className="dj-node-tooltip__footer";const j=document.createElement("a");j.href=`/nodes/${encodeURIComponent(l.name)}`,j.target="_blank",j.rel="noreferrer noopener",j.textContent="Open node →",h.appendChild(j),o.appendChild(h)}return o}const de=new Map;function ke({getStatus:s,getKnownCatalogs:c,fetchNodeDetails:o}){return n.hoverTooltip((l,u)=>{const i=Se(l,u);if(!i)return null;const d=s(i.key);if(!d){const r=new Set((c()||[]).map(x=>x.toLowerCase())),p=i.key.split(".");if(p.length!==3||!r.has(p[0].toLowerCase()))return null}return{pos:i.from,end:i.to,above:!0,create:()=>{const r=d||{refType:"source"},p=le(r,i.key);if(o&&r.kind!=="invalid"&&r.kind!=="registering"){const x=de.get(i.key),h=x||o(i.key);x||de.set(i.key,h),Promise.resolve(h).then(j=>{if(!j)return;const _=le({...r,node:{...r.node||{},...j}},i.key);p.parentNode?p.parentNode.replaceChild(_,p):p.replaceChildren(..._.childNodes)}).catch(()=>{})}return{dom:p}}}},{hoverTime:150})}const k={bg:"#fbfbfd",surface:"#f6f6f9",gutter:"#9aa2b1",selection:"#dbe2ec",caret:"#3b3f46",text:"#27303d",muted:"#8b94a5",keyword:"#6b3aa0",string:"#0e7c5a",number:"#a96621",operator:"#475569",functionName:"#0063b4",punctuation:"#5c6573",comment:"#9ca3af"},Me=n.EditorView.theme({"&":{color:k.text,backgroundColor:k.bg,fontSize:"13px"},".cm-content":{caretColor:k.caret,fontFamily:'"JetBrains Mono", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace'},".cm-cursor, .cm-dropCursor":{borderLeftColor:k.caret},"&.cm-focused .cm-selectionBackground, ::selection, .cm-selectionBackground":{backgroundColor:k.selection},".cm-activeLine":{backgroundColor:"rgba(99, 102, 241, 0.05)"},".cm-gutters":{backgroundColor:k.surface,color:k.gutter,border:"none"},".cm-activeLineGutter":{backgroundColor:"rgba(99, 102, 241, 0.08)",color:k.text},".cm-lineNumbers .cm-gutterElement":{padding:"0 8px 0 6px"},".cm-foldGutter .cm-gutterElement":{color:k.muted},".cm-tooltip":{background:"#ffffff",border:"1px solid #e2e8f0",borderRadius:"6px",boxShadow:"0 4px 12px rgba(15, 23, 42, 0.06)"},".cm-tooltip-autocomplete > ul > li[aria-selected]":{background:"#eef2ff",color:k.text},".cm-matchingBracket, .cm-nonmatchingBracket":{backgroundColor:"#fef3c7",outline:"none"},".cm-panels":{backgroundColor:k.surface,color:k.text}},{dark:!1}),Fe=n.HighlightStyle.define([{tag:[n.tags.keyword,n.tags.modifier,n.tags.controlKeyword,n.tags.operatorKeyword],color:k.keyword,fontWeight:"500"},{tag:[n.tags.string,n.tags.special(n.tags.string)],color:k.string},{tag:[n.tags.number,n.tags.bool,n.tags.null],color:k.number},{tag:[n.tags.function(n.tags.variableName),n.tags.function(n.tags.propertyName)],color:k.functionName},{tag:[n.tags.operator,n.tags.compareOperator,n.tags.arithmeticOperator,n.tags.logicOperator],color:k.operator},{tag:[n.tags.punctuation,n.tags.paren,n.tags.brace,n.tags.bracket,n.tags.separator],color:k.punctuation},{tag:[n.tags.variableName,n.tags.propertyName,n.tags.attributeName],color:k.text},{tag:[n.tags.typeName,n.tags.className],color:k.functionName},{tag:[n.tags.comment,n.tags.lineComment,n.tags.blockComment],color:k.comment,fontStyle:"italic"},{tag:n.tags.invalid,color:"#cc2222"}]),De=[Me,n.syntaxHighlighting(Fe)],me={INVALID_SQL_QUERY:"Invalid SQL",TYPE_INFERENCE:"Type inference",INVALID_COLUMN:"Invalid column",INVALID_ARGUMENTS_TO_FUNCTION:"Invalid function arguments",MISSING_COLUMNS:"Missing columns",UNKNOWN_NODE:"Unknown node",MISSING_PARENT:"Missing parent",NODE_TYPE_ERROR:"Node type",NOT_IMPLEMENTED_ERROR:"Not implemented"},Ie=s=>{if(s==null||s==="")return"Error";const c=String(s);return me[c]?me[c]:c.toLowerCase().split("_").map(o=>o?o[0].toUpperCase()+o.slice(1):"").join(" ")},Te=({djClient:s,value:c})=>{const[o,l]=m.useState({}),u=n.useFormikContext(),i=m.useMemo(()=>n.langs.sql({schema:o}),[o]),d=m.useRef(null),r=m.useRef(null),p=m.useRef(new Set),x=m.useRef([]),[h,j]=m.useState([]),[_,C]=m.useState({}),N=m.useRef(_);m.useEffect(()=>{N.current=_},[_]);const E=m.useRef(null),M=m.useCallback((b,D)=>{N.current={...N.current,[b]:D},C(N.current),E.current&&E.current.dispatch({effects:re.of(null)})},[]);m.useEffect(()=>{typeof s.catalogs=="function"&&Promise.resolve(s.catalogs()).then(b=>{x.current=(b||[]).map(D=>D.name.toLowerCase())}).catch(()=>{})},[s]);const I=async b=>{const D=b.matchBefore(/[\.\w]*/),t=await s.nodes(D.text);l(a=>{const y={...a};let g=!1;for(const F of t)y[F]===void 0&&(y[F]=[],g=!0);return g?y:a})},q=b=>{u.setFieldValue("query",b)},W=async(b,D)=>{for(const t of Object.keys(o))if(b.includes(t)&&o[t].length===0){const a=await s.node(t),y=((a==null?void 0:a.columns)||[]).map(g=>g.name);l(g=>({...g,[t]:y}))}x.current.length>0&&(clearTimeout(d.current),d.current=setTimeout(()=>Y(b),600)),clearTimeout(r.current),r.current=setTimeout(()=>G(b),700)},G=async b=>{if(typeof s.validateNode!="function")return;const D=u.values||{};if(!D.type)return;let t;try{t=await s.validateNode(D.type,D.name||"__draft__",D.display_name||"Draft",D.description||"",b)}catch{return}const a=(t==null?void 0:t.json)||{},y=a.dependencies||[],g=a.missing_parents||[];j(Array.isArray(a.errors)?a.errors:[]);const F={...N.current};for(const v of y){const w=typeof v=="string"?v:v==null?void 0:v.name;if(!w)continue;const T=typeof v=="object"?v.type:void 0,R=typeof v=="object"?v.status:void 0,f=R&&R!=="valid"?"warning":"valid";F[w]={kind:f,refType:T||"node",node:typeof v=="object"?v:void 0,message:f==="warning"?`Node \`${w}\` is ${R}`:void 0}}for(const v of g){const w=typeof v=="string"?v:v==null?void 0:v.name;w&&(F[w]={kind:"invalid",refType:"node",message:`Node \`${w}\` not found`})}N.current=F,C(F),E.current&&E.current.dispatch({effects:re.of(null)})},Y=async b=>{const D=Ee(b,x.current);for(const[t,a,y]of D){const g=`${t}.${a}.${y}`;if(p.current.has(g))continue;if(o[g]!==void 0){p.current.add(g),M(g,{kind:"valid"});continue}p.current.add(g),M(g,{kind:"registering"});let F;try{F=await s.registerTable(t,a,y,"")}catch(T){p.current.delete(g),M(g,{kind:"invalid",message:(T==null?void 0:T.message)||"Failed to register table"});continue}const{status:v,json:w}=F;if(v===200||v===201){const T=(w==null?void 0:w.name)||g,R=((w==null?void 0:w.columns)||[]).map(f=>f.name);l(f=>{const A={...f,[T]:R};return y&&y!==T&&(A[y]=R),A}),M(g,{kind:"valid"})}else v===409?M(g,{kind:"valid"}):(p.current.delete(g),M(g,{kind:"invalid",message:(w==null?void 0:w.message)||`Registration failed (HTTP ${v})`}))}},X=m.useMemo(()=>we({getStatus:b=>N.current[b],getKnownCatalogs:()=>x.current}),[]),ee=m.useMemo(()=>ke({getStatus:b=>N.current[b],getKnownCatalogs:()=>x.current,fetchNodeDetails:b=>s.node(b).catch(()=>null)}),[s]);return e.jsxs("div",{className:"QueryInput NodeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"query",component:"span"}),e.jsx("label",{htmlFor:"Query",children:"Query *"}),e.jsx(n.Field,{type:"textarea",style:{display:"none"},as:"textarea",name:"query",id:"Query"}),h.length>0&&e.jsx("div",{className:"query-validation-errors",role:"alert",children:h.map((b,D)=>e.jsxs("div",{className:"query-validation-error",children:[e.jsx("span",{className:"query-validation-error-code",children:Ie(b.code)}),e.jsx("span",{className:"query-validation-error-message",children:b.message})]},D))}),e.jsx("div",{role:"button",tabIndex:0,className:"relative flex bg-[#282a36]",children:e.jsx(n.ReactCodeMirror,{id:"query",name:"query",extensions:[i,i.language.data.of({autocomplete:I}),...De,X,ee],onCreateEditor:b=>{E.current=b},value:c,placeholder:`SELECT primary_key, measure1, measure2, foreign_key_for_dimension1, foreign_key_for_dimension2 FROM source.source_node WHERE ...`,options:{theme:"default",lineNumbers:!0},width:"100%",height:"400px",style:{margin:"0 0 23px 0",flex:1,fontSize:"110%",textAlign:"left"},onChange:(b,D)=>{q(b),W(b)}})})]})},Ae=()=>{const s=m.useContext(n.DJClientContext).DataJunctionAPI,[c,o]=m.useState([]),[l,u]=m.useState([]);return m.useEffect(()=>{(async()=>{const d=await s.listMetricMetadata();u(d.directions),o(d.units)})().catch(console.error)},[s]),e.jsxs("div",{className:"MetricMetadataFields node-row",children:[e.jsxs("div",{className:"NodeCreationInput NodeModeInput",children:[e.jsx(n.ErrorMessage,{name:"metric_direction",component:"span"}),e.jsx("label",{htmlFor:"MetricDirection",children:"Direction"}),e.jsxs(n.Field,{as:"select",name:"metric_direction",id:"MetricDirection",children:[e.jsx("option",{value:""}),l.map(i=>e.jsx("option",{value:i,children:n.labelize(i)},i))]})]}),e.jsxs("div",{className:"NodeCreationInput NodeModeInput",children:[e.jsx(n.ErrorMessage,{name:"metric_unit",component:"span"}),e.jsx("label",{htmlFor:"MetricUnit",children:"Unit"}),e.jsxs(n.Field,{as:"select",name:"metric_unit",id:"MetricUnit",children:[e.jsx("option",{value:""}),c.map(i=>e.jsx("option",{value:i.name,children:i.label},i.name))]})]}),e.jsxs("div",{className:"NodeCreationInput NodeModeInput",children:[e.jsx(n.ErrorMessage,{name:"significant_digits",component:"span"}),e.jsx("label",{htmlFor:"SignificantDigits",children:"Significant Digits"}),e.jsxs(n.Field,{as:"select",name:"significant_digits",id:"SignificantDigits",children:[e.jsx("option",{value:""}),[1,2,3,4,5,6,7,8,9,10].map(i=>e.jsx("option",{value:i,children:i},i))]})]})]})},ue=({defaultValue:s})=>{const c=m.useContext(n.DJClientContext).DataJunctionAPI,[o,l]=m.useState([]);return m.useEffect(()=>{async function u(){const i=await c.nodesWithType("source"),d=await c.nodesWithType("transform"),r=await c.nodesWithType("dimension"),p=i.concat(d).concat(r);l(p.map(x=>({value:x,label:x})))}u()},[c]),e.jsxs("div",{className:"NodeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"upstream_node",component:"span"}),e.jsx("label",{htmlFor:"upstream_node",children:"Upstream Node"}),e.jsxs("p",{className:"field-help-text",style:{fontSize:"0.85em",color:"#666",marginBottom:"8px"},children:["Select a source, transform, or dimension for regular metrics. Leave empty for ",e.jsx("strong",{children:"derived metrics"})," that reference other metrics (e.g., ",e.jsx("code",{children:"namespace.metric_a / namespace.metric_b"}),")."]}),e.jsx("span",{"data-testid":"select-upstream-node",children:e.jsx(n.FormikSelect,{className:"",defaultValue:s,selectOptions:o,formikFieldName:"upstream_node",placeholder:"Select Upstream Node (optional for derived metrics)",isMulti:!1,isClearable:!0})})]})},pe=({defaultValue:s})=>{const c=m.useContext(n.DJClientContext).DataJunctionAPI,{currentUser:o}=n.useCurrentUser(),[,l,u]=n.useField("owners"),[i,d]=m.useState([]);return m.useEffect(()=>{async function r(){const p=await c.users();d(p.map(x=>({value:x.username,label:x.username})))}r()},[c]),m.useEffect(()=>{l.value&&l.value.length>0||(s&&s.length>0?u.setValue(s.map(r=>r.value)):o&&u.setValue([o.username]))},[s,o]),s||o?e.jsxs("div",{className:"NodeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"owners",component:"span"}),e.jsx("label",{htmlFor:"Owners",children:"Owners"}),e.jsx("span",{"data-testid":"select-owner",children:e.jsx(n.FormikSelect,{className:"",selectOptions:i,formikFieldName:"owners",placeholder:"Select Owners",isMulti:!0})})]}):""},fe=({defaultValue:s})=>{const c=m.useContext(n.DJClientContext).DataJunctionAPI,[o,l]=m.useState([]);return m.useEffect(()=>{(async()=>{const i=await c.listTags();l(i.map(d=>({value:d.name,label:d.display_name})))})().catch(console.error)},[c]),e.jsxs("div",{className:"TagsInput NodeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"tags",component:"span"}),e.jsx("label",{htmlFor:"tags",children:"Tags"}),e.jsx("span",{"data-testid":"select-tags",children:e.jsx(n.FormikSelect,{isMulti:!0,selectOptions:o,formikFieldName:"tags",className:"",placeholder:"Choose Tags",defaultValue:s})})]})},Re=({initialNamespace:s})=>{const c=m.useContext(n.DJClientContext).DataJunctionAPI,[o,l]=m.useState([]);return m.useEffect(()=>{(async()=>{const i=await c.namespaces();l(i.map(d=>({value:d.namespace,label:d.namespace})))})().catch(console.error)},[c]),e.jsxs("div",{className:"NamespaceInput",children:[e.jsx(n.ErrorMessage,{name:"namespace",component:"span"}),e.jsx("label",{htmlFor:"namespace",children:"Namespace *"}),e.jsx(n.FormikSelect,{className:"",selectOptions:o,formikFieldName:"namespace",placeholder:"Choose Namespace",defaultValue:{value:s,label:s}})]})},qe=({message:s})=>e.jsxs("div",{className:"message alert",children:[e.jsx(n.AlertIcon,{}),s]}),Oe=()=>e.jsxs("div",{className:"DisplayNameInput NodeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"display_name",component:"span"}),e.jsx("label",{htmlFor:"displayName",children:"Display Name *"}),e.jsx(n.Field,{type:"text",name:"display_name",id:"displayName",placeholder:"Human readable display name"})]}),Le=()=>e.jsxs("div",{className:"DescriptionInput NodeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"description",component:"span"}),e.jsx("label",{htmlFor:"Description",children:"Description"}),e.jsx(n.Field,{type:"textarea",as:"textarea",name:"description",id:"Description",placeholder:"Describe your node"})]}),$e=()=>e.jsxs("div",{className:"NodeModeInput NodeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"mode",component:"span"}),e.jsx("label",{htmlFor:"Mode",children:"Mode"}),e.jsxs(n.Field,{as:"select",name:"mode",id:"Mode",children:[e.jsx("option",{value:"draft",children:"Draft"}),e.jsx("option",{value:"published",children:"Published"})]})]}),ge=({defaultValue:s,style:c,className:o=""})=>{const l=m.useContext(n.DJClientContext).DataJunctionAPI,{values:u}=n.useFormikContext(),[i,d]=m.useState([]);return m.useEffect(()=>{(async()=>{if(u.upstream_node){const p=await l.node(u.upstream_node);d(p.columns.map(x=>({value:x.name,label:x.name})))}})().catch(console.error)},[l,u.upstream_node]),e.jsxs("div",{className:"RequiredDimensionsInput CubeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"required_dimensions",component:"span"}),e.jsx("label",{htmlFor:"requiredDimensions",children:"Required Dimensions"}),e.jsx(n.FormikSelect,{className:o,defaultValue:s,selectOptions:i,formikFieldName:"required_dimensions",placeholder:"Choose Required Dimensions",styles:c,isMulti:!0})]})},he=({defaultValue:s,fieldName:c,label:o,labelStyle:l={},isMulti:u=!1,isClearable:i=!0})=>{const d=m.useContext(n.DJClientContext).DataJunctionAPI,{values:r}=n.useFormikContext(),[p,x]=m.useState([]),[h,j]=m.useState(null),_=m.useMemo(()=>p&&p.length>0?p:[],[p]),C=async()=>{try{const{status:N,json:E}=await d.validateNode(r.type,r.name,r.display_name,r.description,r.query);if(E!=null&&E.columns)x(E.columns.map(M=>({value:M.name,label:M.name}))),j(null);else{const M=Array.isArray(E==null?void 0:E.errors)?E.errors.map(I=>I.message).filter(Boolean).join(` `):"";j(M||(E==null?void 0:E.message)||null),x([])}}catch(N){console.error("Error fetching columns:",N),j(N.message||"Failed to validate query. Please check your query syntax."),x([])}};return m.useEffect(()=>{C()},[r.type,r.name,r.query]),e.jsxs("div",{className:"CubeCreationInput",children:[e.jsx(n.ErrorMessage,{name:c,component:"span"}),e.jsx("label",{htmlFor:c,style:l,children:o}),h&&e.jsxs("div",{className:"validation-error",style:{color:"#d32f2f",fontSize:"0.875rem",marginBottom:"8px",padding:"8px",backgroundColor:"#ffebee",borderRadius:"4px",border:"1px solid #ef9a9a"},children:[e.jsx("strong",{children:"Validation Error:"})," ",h]}),e.jsx("span",{"data-testid":`select-${c}`,children:e.jsx(n.FormikSelect,{className:"",defaultValue:u?s.map(N=>({value:N,label:N})):s?{value:s,label:s}:null,selectOptions:_,formikFieldName:c,onFocus:N=>C(),isMulti:u,isClearable:i})})]})},Ue=({value:s})=>{const c=n.useFormikContext(),o=n.langs.json(),[l,u]=m.useState(!1);m.useEffect(()=>{if(!s||s===""){u(!1);return}const r=typeof s=="string"?s:JSON.stringify(s,null,2);try{JSON.parse(r),u(!1)}catch{u(!0)}},[s]);const i=r=>r==null?"":typeof r=="string"?r:JSON.stringify(r,null,2),d=r=>{if(c.setFieldValue("custom_metadata",r),c.setFieldTouched("custom_metadata",!0),!r||r.trim()==="")u(!1);else try{JSON.parse(r),u(!1)}catch{u(!0)}};return e.jsx("div",{className:"QueryInput NodeCreationInput",children:e.jsxs("details",{children:[e.jsx("summary",{style:{cursor:"pointer"},children:e.jsx("label",{style:{paddingLeft:"3px",display:"inline-block",pointerEvents:"none"},children:"Custom Metadata (JSON)"})}),e.jsx(n.ErrorMessage,{name:"custom_metadata",component:"span"}),e.jsx(n.Field,{type:"textarea",style:{display:"none"},as:"textarea",name:"custom_metadata",id:"CustomMetadata",validate:r=>{if(!(!r||r.trim()===""))try{const p=JSON.parse(r);if(typeof p=="object"&&p!==null&&!Array.isArray(p)){const x=Object.keys(p),h=r.match(/"([^"]+)"\s*:/g);if(h&&h.length>x.length)return"Duplicate keys detected"}return}catch{return"Invalid JSON format"}}}),e.jsx("div",{role:"button",tabIndex:0,className:`relative flex ${l?"bg-red-900/20":"bg-[#282a36]"}`,style:{border:l?"2px solid #ef4444":"none",borderRadius:"4px",boxShadow:l?"0 0 0 1px rgba(239, 68, 68, 0.3)":"none"},children:e.jsx(n.ReactCodeMirror,{id:"custom_metadata",name:"custom_metadata",extensions:[o],value:i(s),placeholder:`{ "key": "value" }`,options:{theme:"default",lineNumbers:!0},width:"100%",height:"200px",style:{margin:"0 0 23px 0",flex:1,fontSize:"110%",textAlign:"left"},onChange:(r,p)=>{d(r)}})})]})})},L=class L{constructor(c){this.name=c}};ae(L,"Add",new L("add")),ae(L,"Edit",new L("edit"));let S=L;function Je({extensions:s={}}){const c=m.useContext(n.DJClientContext).DataJunctionAPI,o=ie.useNavigate();let{nodeType:l,initialNamespace:u,name:i}=ie.useParams();const d=i!==void 0?S.Edit:S.Add,[r,p]=m.useState(void 0);m.useEffect(()=>{d===S.Edit&&r===!0&&o(`/nodes/${i}`,{replace:!0})},[d,r,i,o]);const x=u||(i?i.substring(0,i.lastIndexOf(".")):""),h={name:d===S.Edit?i:"",namespace:d===S.Add?u:"",display_name:"",query:"",type:l,description:"",primary_key:"",mode:"published",owners:[],custom_metadata:""},j=t=>{var y;const a={};return d===S.Add&&!((y=t.display_name)!=null&&y.trim())&&(a.display_name="Required"),(!t.name||t.name.endsWith(".")||t.name.startsWith(".")||t.name.includes(".."))&&(a.name="Required"),t.type!=="metric"&&!t.query&&(a.query="Required"),a},C=[async(t,{setSubmitting:a,setStatus:y})=>{d===S.Add?await W(t,y).then(g=>{window.scrollTo({top:0,left:0,behavior:"smooth"}),a(!1)}):await G(t,y).then(g=>{window.scrollTo({top:0,left:0,behavior:"smooth"}),a(!1)})}],N=d===S.Add?e.jsxs("h2",{children:["Create"," ",e.jsx("span",{className:`node_type__${l} node_type_creation_heading`,children:l})]}):e.jsx("h2",{children:"Edit"}),E=t=>e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"NodeNameInput NodeCreationInput",children:[e.jsx("label",{children:"Name"})," ",i]}),e.jsxs("div",{className:"NodeNameInput NodeCreationInput",children:[e.jsx("label",{children:"Type"})," ",t.type]})]}),M=t=>t.map(a=>a.trim()),I=t=>{if(!t||t.trim()==="")return null;try{return JSON.parse(t)}catch{return null}},q=(t,a)=>a&&a.trim()!==""?`SELECT ${t} FROM ${a}`:`SELECT ${t}`,W=async(t,a)=>{const{status:y,json:g}=await c.createNode(l,t.name,t.display_name,t.description,t.type==="metric"?q(t.aggregate_expression,t.upstream_node):t.query,t.mode,t.namespace,t.primary_key?M(t.primary_key):null,t.metric_direction,t.metric_unit,t.required_dimensions&&Array.isArray(t.required_dimensions)?t.required_dimensions:void 0,I(t.custom_metadata));y===200||y===201?(t.tags&&await c.tagsNode(t.name,t.tags),a({success:e.jsxs(e.Fragment,{children:["Successfully created ",g.type," node"," ",e.jsx("a",{href:`/nodes/${g.name}`,children:g.name}),"!"]})})):a({failure:`${g.message}`})},G=async(t,a)=>{const{status:y,json:g}=await c.patchNode(t.name,t.display_name,t.description,t.type==="metric"?q(t.aggregate_expression,t.upstream_node):t.query,t.mode,t.primary_key?M(t.primary_key):null,t.metric_direction,t.metric_unit,t.significant_digits,t.required_dimensions&&Array.isArray(t.required_dimensions)?t.required_dimensions:void 0,t.owners,I(t.custom_metadata)),F=await c.tagsNode(t.name,t.tags.map(v=>v));(y===200||y===201)&&F.status===200?a({success:e.jsxs(e.Fragment,{children:["Successfully updated ",g.type," node"," ",e.jsx("a",{href:`/nodes/${g.name}`,children:g.name}),"!"]})}):a({failure:`${g.message}`})},Y=e.jsxs("div",{className:"FullNameInput NodeCreationInput",children:[e.jsx(n.ErrorMessage,{name:"name",component:"span"}),e.jsx("label",{htmlFor:"FullName",children:"Full Name *"}),e.jsx(_e.FullNameField,{type:"text",name:"name"})]}),X=t=>new Set(["transform","metric","dimension"]).has(t),ee=async t=>{var g,F,v,w,T,R,f,A,U,J,P,z,V,B;const a=await c.getNodeForEditing(t);if(a===null)return{message:`Node ${t} does not exist`};const y={name:a.name,type:a.type.toLowerCase(),display_name:a.current.displayName,description:a.current.description,primary_key:a.current.primaryKey,query:a.current.query,tags:a.tags,mode:a.current.mode.toLowerCase(),owners:a.owners,custom_metadata:a.current.customMetadata};if(a.type==="METRIC"){const te=a.current.isDerivedMetric,$=a.current.parents.find(O=>O.type!=="METRIC");if(te){const Q=(a.current.query||"").match(/SELECT\s+(.+)/is),H=Q?Q[1].trim():((g=a.current.metricMetadata)==null?void 0:g.expression)||"";return{...y,metric_direction:(v=(F=a.current.metricMetadata)==null?void 0:F.direction)==null?void 0:v.toLowerCase(),metric_unit:(R=(T=(w=a.current.metricMetadata)==null?void 0:w.unit)==null?void 0:T.name)==null?void 0:R.toLowerCase(),significant_digits:(f=a.current.metricMetadata)==null?void 0:f.significantDigits,required_dimensions:a.current.requiredDimensions.map(ne=>ne.name),upstream_node:"",aggregate_expression:H}}else return{...y,metric_direction:(U=(A=a.current.metricMetadata)==null?void 0:A.direction)==null?void 0:U.toLowerCase(),metric_unit:(z=(P=(J=a.current.metricMetadata)==null?void 0:J.unit)==null?void 0:P.name)==null?void 0:z.toLowerCase(),significant_digits:(V=a.current.metricMetadata)==null?void 0:V.significantDigits,required_dimensions:a.current.requiredDimensions.map(O=>O.name),upstream_node:($==null?void 0:$.name)||"",aggregate_expression:(B=a.current.metricMetadata)==null?void 0:B.expression}}return y},b=(t,a,y)=>{if(t.message!==void 0){a(null),y(`Node ${i} does not exist!`);return}X(t.type)||(a(null),t.type==="cube"&&o(`/nodes/${t.name}/edit-cube`),y(`Node ${i} is of type ${t.type} and cannot be edited`))},D=(t,a,y,g,F,v,w,T)=>{["display_name","query","type","description","primary_key","mode","tags","aggregate_expression","upstream_node","metric_unit","metric_direction","significant_digits","required_dimensions","owners","custom_metadata"].forEach(f=>{if(f==="tags")a(f,t[f].map(A=>A.name));else if(f==="owners")a(f,t[f].map(A=>A.username));else if(f==="custom_metadata"){const A=t[f]?JSON.stringify(t[f],null,2):"";a(f,A,!1)}else a(f,t[f]||"",!1)}),y(t),g(e.jsx(fe,{defaultValue:t.tags.map(f=>({value:f.name,label:f.displayName}))})),F(e.jsx(he,{defaultValue:t.primary_key,fieldName:"primary_key",label:"Primary Key",isMulti:!0})),t.required_dimensions&&w(e.jsx(ge,{defaultValue:t.required_dimensions.map(f=>({value:f,label:f}))})),v(e.jsx(ue,{defaultValue:t.upstream_node?{value:t.upstream_node,label:t.upstream_node}:null})),t.owners&&T(e.jsx(pe,{defaultValue:t.owners.map(f=>({value:f.username,label:f.username}))}))};return d===S.Edit&&r!==!1?e.jsx("div",{className:"mid",children:e.jsx(n.NamespaceHeader,{namespace:x,onReadOnlyChange:p})}):e.jsxs("div",{className:"mid",children:[e.jsx(n.NamespaceHeader,{namespace:x,onReadOnlyChange:p}),e.jsx("div",{className:"node-builder",children:e.jsx("div",{className:"node-builder-main",children:e.jsx(n.Formik,{initialValues:h,validate:j,validateOnChange:!0,validateOnBlur:!0,onSubmit:async(t,{setSubmitting:a,setStatus:y})=>{try{for(const g of C)await g(t,{setSubmitting:a,setStatus:y})}catch(g){console.error("Error in submission",g)}finally{a(!1)}},children:function(a){const{isSubmitting:y,status:g,setFieldValue:F,errors:v,touched:w,isValid:T,dirty:R}=a,[f,A]=m.useState([]),[U,J]=m.useState(null),[P,z]=m.useState(null),[V,B]=m.useState(null),[te,$]=m.useState(null),[O,Q]=m.useState(null),[H,ne]=m.useState("");return m.useEffect(()=>{(async()=>{if(d===S.Edit){const K=await ee(i);b(K,A,ne),D(K,F,A,Q,J,B,z,$)}})().catch(console.error)},[F]),e.jsxs(n.Form,{children:[n.displayMessageAfterSubmit(g),d===S.Edit&&H?e.jsx(qe,{message:H}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"node-builder-form-header",children:[N,e.jsx($e,{})]}),e.jsxs("div",{className:"node-group",children:[e.jsxs("div",{className:"node-row",children:[d===S.Add?e.jsx(Re,{initialNamespace:u}):E(f),e.jsx(Oe,{})]}),d===S.Add?Y:"",e.jsx(Le,{})]}),e.jsxs("div",{className:"node-group",children:[l==="metric"||(f==null?void 0:f.type)==="metric"?d===S.Edit?V:e.jsx(ue,{}):null,l==="metric"||f.type==="metric"?e.jsx(be,{djClient:c,value:f.aggregate_expression?f.aggregate_expression:""}):e.jsx(Te,{djClient:c,value:f.query?f.query:""}),(l==="metric"||f.type==="metric")&&e.jsx(Ae,{})]}),e.jsx("div",{className:"node-group",children:l!=="metric"&&f.type!=="metric"?d===S.Edit?U:e.jsx(he,{defaultValue:[],fieldName:"primary_key",label:"Primary Key",isMulti:!0}):d===S.Edit?P:e.jsx(ge,{})}),e.jsx("div",{className:"node-group",children:e.jsxs("div",{className:"node-row",children:[d===S.Edit?te:e.jsx(pe,{}),d===S.Edit?O:e.jsx(fe,{})]})}),Object.entries(s).map(([oe,K])=>e.jsx("div",{className:"node-group",children:e.jsx(K,{node:f,action:d,registerSubmitHandler:(se,{prepend:ye}={})=>{C.includes(se)||(ye?C.unshift(se):C.push(se))}})},oe)),e.jsx("div",{className:"node-group node-group-last",children:e.jsx(Ue,{value:f.custom_metadata?f.custom_metadata:""})}),e.jsx("button",{type:"submit",disabled:y||!T,className:`save-node-btn${y?" save-node-btn--loading":""}`,children:y?e.jsxs(e.Fragment,{children:[e.jsx(n.LoadingIcon,{}),"Saving..."]}):(d===S.Add?"Create ":"Save ")+(l||"")})]})]})}})})})]})}exports.AddEditNodePage=Je; //# sourceMappingURL=index-DIi7ls1d.cjs.map