@@ -12,7 +12,7 @@ import {
1212 InProgress
1313} from '@carbon/icons-react' ;
1414
15- import classNames from 'classnames ' ;
15+ import { isFunction } from 'min-dash ' ;
1616
1717import { OutputVariables } from './OutputVariables' ;
1818import { PluginContext } from '../shared/plugins' ;
@@ -139,77 +139,139 @@ const HeaderLinks = (props) => {
139139
140140 const headerLinkPlugins = getPlugins ( 'output.header.link' ) ;
141141
142+ const headerLinks = headerLinkPlugins . reduce ( ( accHeaderLinks , plugin ) => {
143+ const getProp = ( value ) => isFunction ( value ) ? value ( props ) : value ;
144+
145+ const visible = getProp ( plugin . visible ) ?? true ;
146+
147+ if ( ! visible ) {
148+ return accHeaderLinks ;
149+ }
150+
151+ const content = plugin . render ( props ) ;
152+
153+ accHeaderLinks . push ( {
154+ content,
155+ href : getProp ( plugin . href ) ,
156+ target : getProp ( plugin . target ) ,
157+ className : getProp ( plugin . className ) ,
158+ onClick : getProp ( plugin . onClick ) ,
159+ role : getProp ( plugin . role ) ,
160+ tooltip : getProp ( plugin . tooltip )
161+ } ) ;
162+
163+ return accHeaderLinks ;
164+ } , /** @type {Array<{content: any, href: any, target: any, className: any, onClick: any, role: any, tooltip: any}> } */ ( [ ] ) ) ;
165+
142166 return (
143167 < >
144- { headerLinkPlugins . map ( ( link , index ) => (
145- < React . Fragment key = { index } >
146- { link . render ( props ) }
147- </ React . Fragment >
148- ) ) }
168+ { headerLinks . map ( ( { content, href, target, className, onClick, role, tooltip } , index ) => {
169+ const headerLink = (
170+ < Link
171+ key = { index }
172+ href = { href }
173+ target = { target }
174+ className = { className }
175+ onClick = { onClick }
176+ role = { role }
177+ >
178+ { content }
179+ </ Link >
180+ ) ;
181+
182+ if ( tooltip ) {
183+ return (
184+ < Tooltip key = { index } autoAlign label = { tooltip } >
185+ { headerLink }
186+ </ Tooltip >
187+ ) ;
188+ }
189+
190+ return headerLink ;
191+ } ) }
149192 </ >
150193 ) ;
151194} ;
152195
153-
154- export const HeaderLink = ( { children = null , render, priority = 100 } ) => {
196+ /**
197+ * @param {Object } props
198+ * @param {(props: Object) => React.ReactNode } props.render - Function that returns link content
199+ * @param {boolean | ((props: Object) => boolean) } [props.visible] - Whether to show the link (default: true)
200+ * @param {string | ((props: Object) => string) } [props.href] - Link URL (static or dynamic)
201+ * @param {string | ((props: Object) => string) } [props.target] - Link target (static or dynamic)
202+ * @param {string | ((props: Object) => string | undefined) } [props.className] - Link class name (static or dynamic)
203+ * @param {Function | ((props: Object) => Function) } [props.onClick] - Click handler (static or dynamic)
204+ * @param {string | ((props: Object) => string) } [props.role] - ARIA role (static or dynamic)
205+ * @param {string | ((props: Object) => string | undefined) } [props.tooltip] - Tooltip text (static or dynamic)
206+ * @param {number } [props.priority] - Priority for sorting (higher values first)
207+ * @returns {null }
208+ */
209+ export const HeaderLink = ( { render, visible, href, target, className, onClick, role, tooltip, priority = 100 } ) => {
155210 const { registerPlugin, unregisterPlugin } = useContext ( PluginContext ) ;
156211
157212 useEffect ( ( ) => {
158- const link = { render, children , priority, type : 'output.header.link' } ;
213+ const link = { render, visible , href , target , className , onClick , role , tooltip , priority, type : 'output.header.link' } ;
159214 registerPlugin ( link ) ;
160215
161216 return ( ) => {
162217 unregisterPlugin ( link ) ;
163218 } ;
164- } , [ children , render , priority , registerPlugin , unregisterPlugin ] ) ;
219+ } , [ render , visible , href , target , className , onClick , role , tooltip , priority , registerPlugin , unregisterPlugin ] ) ;
165220
166221 return null ;
167222} ;
168223
169224const OperateLink = ( ) => {
170- const render = useCallback ( ( { output, isConnectionConfigured, currentOperateUrl } ) => {
171- const showOperateUrl = isConnectionConfigured && ( currentOperateUrl || ( output && ! output . error ) ) ;
225+ const render = useCallback ( ( ) => 'View in Operate' , [ ] ) ;
172226
173- if ( ! showOperateUrl ) {
174- return null ;
175- }
227+ const getVisible = useCallback ( ( { output , isConnectionConfigured , currentOperateUrl } ) => {
228+ return isConnectionConfigured && ( currentOperateUrl || ( output && ! output . error ) ) ;
229+ } , [ ] ) ;
176230
231+ const getHref = useCallback ( ( { output, currentOperateUrl } ) => {
232+ return currentOperateUrl || output ?. operateUrl ;
233+ } , [ ] ) ;
234+
235+ const getClassName = useCallback ( ( { output, currentOperateUrl } ) => {
177236 const operateUrl = currentOperateUrl || output ?. operateUrl ;
237+ return ! operateUrl ? 'link--disabled' : undefined ;
238+ } , [ ] ) ;
178239
179- return (
180- < Tooltip
181- className = { classNames ( { 'show-tooltip' : ! operateUrl } ) }
182- autoAlign
183- label = { NO_OPERATE_URL_TOOLTIP }
184- >
185- < Link
186- className = { classNames ( { 'link--disabled' : ! operateUrl } ) }
187- href = { operateUrl }
188- target = "_blank"
189- >
190- View in Operate
191- </ Link >
192- </ Tooltip >
193- ) ;
240+ const getTooltip = useCallback ( ( { output, currentOperateUrl } ) => {
241+ const operateUrl = currentOperateUrl || output ?. operateUrl ;
242+ return ! operateUrl ? NO_OPERATE_URL_TOOLTIP : undefined ;
194243 } , [ ] ) ;
195244
196- return < HeaderLink priority = { 200 } render = { render } /> ;
245+ return < HeaderLink
246+ priority = { 200 }
247+ render = { render }
248+ visible = { getVisible }
249+ href = { getHref }
250+ target = "_blank"
251+ className = { getClassName }
252+ tooltip = { getTooltip }
253+ /> ;
197254} ;
198255
199256
200257function ResetButton ( ) {
258+ const render = useCallback ( ( ) => 'Clear' , [ ] ) ;
201259
202- const render = useCallback ( ( { onResetOutput, isConnectionConfigured, output } ) => {
203- const showResetButton = isConnectionConfigured && output ;
260+ const getVisible = useCallback ( ( { isConnectionConfigured, output } ) => {
261+ return isConnectionConfigured && output ;
262+ } , [ ] ) ;
204263
205- return showResetButton && < Link
206- onClick = { ( ) => onResetOutput ( ) }
207- role = "button" >
208- Clear
209- </ Link > ;
264+ const getOnClick = useCallback ( ( { onResetOutput } ) => {
265+ return ( ) => onResetOutput ( ) ;
210266 } , [ ] ) ;
211267
212- return < HeaderLink priority = { 100 } render = { render } /> ;
268+ return < HeaderLink
269+ priority = { 100 }
270+ render = { render }
271+ visible = { getVisible }
272+ onClick = { getOnClick }
273+ role = "button"
274+ /> ;
213275}
214276
215277
0 commit comments