1- import React , { FC } from 'react'
1+ // Libraries
2+ import React , { FC , ChangeEvent , useEffect , useState } from 'react'
3+ import { useDispatch } from 'react-redux'
24import { useHistory , useParams } from 'react-router-dom'
5+
6+ // Components
37import {
48 ComponentSize ,
59 Dropdown ,
10+ EmptyState ,
611 Form ,
712 IconFont ,
813 Input ,
14+ RemoteDataState ,
15+ TechnoSpinner ,
916} from '@influxdata/clockface'
1017
18+ // APIs
19+ import { fetchScripts } from 'src/scripts/apis/index'
20+
21+ // Notifications
22+ import { getScriptsFail } from 'src/shared/copy/notifications/categories/scripts'
23+ import { notify } from 'src/shared/actions/notifications'
24+
25+ // Types
26+ import { Script } from 'src/types/scripts'
27+
1128// Utils
1229import { SafeBlankLink } from 'src/utils/SafeBlankLink'
1330
14- export const ScriptSelector : FC = ( ) => {
31+ interface Props {
32+ selectedScript : Script
33+ setSelectedScript : ( script : Script ) => void
34+ }
35+
36+ export const ScriptSelector : FC < Props > = ( {
37+ selectedScript,
38+ setSelectedScript,
39+ } ) => {
40+ const [ scripts , setScripts ] = useState < Script [ ] > ( [ ] )
41+ const [ searchTerm , setSearchTerm ] = useState ( '' )
42+ const [ scriptsLoadingStatus , setScriptsLoadingStatus ] = useState (
43+ RemoteDataState . NotStarted
44+ )
45+ const dispatch = useDispatch ( )
1546 const { orgID} = useParams < { orgID : string } > ( )
1647 const history = useHistory ( )
48+
1749 const fluxScriptEditorLink = `/orgs/${ orgID } /data-explorer?fluxScriptEditor`
1850
51+ useEffect ( ( ) => {
52+ setScriptsLoadingStatus ( RemoteDataState . Loading )
53+ const getScripts = async ( ) => {
54+ try {
55+ const scripts = await fetchScripts ( )
56+ setScripts ( scripts . scripts )
57+ setScriptsLoadingStatus ( RemoteDataState . Done )
58+ } catch ( error ) {
59+ setScriptsLoadingStatus ( RemoteDataState . Error )
60+ dispatch ( notify ( getScriptsFail ( ) ) )
61+ }
62+ }
63+ getScripts ( )
64+ } , [ dispatch ] )
65+
66+ const filterScripts = ( ) =>
67+ scripts . filter ( script =>
68+ script . name . toLocaleLowerCase ( ) . includes ( searchTerm . toLocaleLowerCase ( ) )
69+ )
70+
71+ const searchForTerm = ( event : ChangeEvent < HTMLInputElement > ) => {
72+ setSearchTerm ( event . target . value )
73+ }
74+
1975 const openScriptEditor = ( ) => {
2076 history . push ( `/orgs/${ orgID } /data-explorer?fluxScriptEditor` )
2177 }
2278
23- const createScriptInEditor = (
24- < Dropdown . Item onClick = { openScriptEditor } >
25- + Create Script in Editor
26- </ Dropdown . Item >
27- )
79+ const handleSelectScript = script => {
80+ setSelectedScript ( script )
81+ }
82+
83+ let scriptsList
2884
29- const dropdownButtonText = 'Select a Script'
85+ if (
86+ scriptsLoadingStatus === RemoteDataState . NotStarted ||
87+ scriptsLoadingStatus === RemoteDataState . Loading
88+ ) {
89+ scriptsList = (
90+ < div >
91+ < TechnoSpinner strokeWidth = { ComponentSize . Small } diameterPixels = { 32 } />
92+ </ div >
93+ )
94+ }
95+
96+ if ( scriptsLoadingStatus === RemoteDataState . Error ) {
97+ scriptsList = (
98+ < div >
99+ < p > Could not get scripts</ p >
100+ </ div >
101+ )
102+ }
103+
104+ if ( scriptsLoadingStatus === RemoteDataState . Done ) {
105+ const filteredScripts = filterScripts ( )
106+ scriptsList = (
107+ < >
108+ { filteredScripts . map ( script => (
109+ < Dropdown . Item
110+ key = { script . id }
111+ value = { script . name }
112+ onClick = { ( ) => handleSelectScript ( script ) }
113+ selected = { script . name === selectedScript ?. name }
114+ >
115+ { script . name }
116+ </ Dropdown . Item >
117+ ) ) }
118+ </ >
119+ )
120+ if ( ! filteredScripts . length ) {
121+ if ( searchTerm ) {
122+ scriptsList = (
123+ < EmptyState >
124+ < p > { `No Scripts match "${ searchTerm } "` } </ p >
125+ </ EmptyState >
126+ )
127+ } else {
128+ scriptsList = (
129+ < EmptyState >
130+ < p > No Scripts found</ p >
131+ </ EmptyState >
132+ )
133+ }
134+ }
135+ }
136+
137+ let dropdownButtonText = 'Select a Script'
138+
139+ if ( scriptsLoadingStatus === RemoteDataState . Done && selectedScript ?. name ) {
140+ dropdownButtonText = selectedScript . name
141+ }
30142
31143 return (
32144 < div className = "select-script" >
33145 < div className = "create-task-titles script" > Select a Script</ div >
34146 < Form . Element label = "Script" required = { true } className = "script-dropdown" >
35147 < Dropdown
36148 button = { ( active , onClick ) => (
37- < Dropdown . Button
38- active = { active }
39- onClick = { onClick }
40- testID = "variable-type-dropdown--button"
41- >
149+ < Dropdown . Button active = { active } onClick = { onClick } >
42150 { dropdownButtonText }
43151 </ Dropdown . Button >
44152 ) }
@@ -47,12 +155,18 @@ export const ScriptSelector: FC = () => {
47155 < Input
48156 size = { ComponentSize . Small }
49157 icon = { IconFont . Search_New }
50- value = ""
158+ value = { searchTerm }
51159 placeholder = "Search Scripts..."
52- onChange = { ( ) => { } }
160+ onChange = { searchForTerm }
53161 />
54162 < Dropdown . Menu onCollapse = { onCollapse } >
55- { createScriptInEditor }
163+ < Dropdown . Item
164+ onClick = { openScriptEditor }
165+ className = "create-script-btn"
166+ >
167+ + Create Script in Editor
168+ </ Dropdown . Item >
169+ { scriptsList }
56170 </ Dropdown . Menu >
57171 </ >
58172 ) }
0 commit comments