@@ -11,130 +11,148 @@ import TopicPicker from "../../common/TopicPicker/TopicPicker";
1111import { DestinationTypeReference } from "../../typings/Destination" ;
1212import DestinationConfigFields from "../../common/DestinationConfigFields/DestinationConfigFields" ;
1313import { getFormValues } from "../../utils/formHelper" ;
14+ import CONFIGS from "../../config" ;
1415
15- const steps = [
16- {
17- title : "Select event topics" ,
18- sidebar_shortname : "Event topics" ,
19- description : "Select the event topics you want to send to your destination" ,
20- isValid : ( values : Record < string , any > ) => {
21- if ( values . topics ?. length > 0 ) {
22- return true ;
23- }
24- return false ;
25- } ,
26- FormFields : ( {
27- defaultValue,
28- onChange,
29- } : {
30- defaultValue : Record < string , any > ;
31- onChange : ( value : Record < string , any > ) => void ;
32- } ) => {
33- const [ selectedTopics , setSelectedTopics ] = useState < string [ ] > (
34- defaultValue . topics ? defaultValue . topics . split ( "," ) : [ ]
35- ) ;
16+ type Step = {
17+ title : string ;
18+ sidebar_shortname : string ;
19+ description : string ;
20+ isValid : ( values : Record < string , any > ) => boolean ;
21+ FormFields : ( props : {
22+ defaultValue : Record < string , any > ;
23+ onChange : ( value : Record < string , any > ) => void ;
24+ } ) => React . ReactNode ;
25+ action : string ;
26+ } ;
27+
28+ const EVENT_TOPICS_STEP : Step = {
29+ title : "Select event topics" ,
30+ sidebar_shortname : "Event topics" ,
31+ description : "Select the event topics you want to send to your destination" ,
32+ isValid : ( values : Record < string , any > ) => {
33+ if ( values . topics ?. length > 0 ) {
34+ return true ;
35+ }
36+ return false ;
37+ } ,
38+ FormFields : ( {
39+ defaultValue,
40+ onChange,
41+ } : {
42+ defaultValue : Record < string , any > ;
43+ onChange : ( value : Record < string , any > ) => void ;
44+ } ) => {
45+ const [ selectedTopics , setSelectedTopics ] = useState < string [ ] > (
46+ defaultValue . topics ? defaultValue . topics . split ( "," ) : [ ]
47+ ) ;
3648
37- useEffect ( ( ) => {
38- onChange ( { topics : selectedTopics } ) ;
39- } , [ selectedTopics ] ) ;
49+ useEffect ( ( ) => {
50+ onChange ( { topics : selectedTopics } ) ;
51+ } , [ selectedTopics ] ) ;
4052
41- return (
42- < >
43- < TopicPicker
44- selectedTopics = { selectedTopics }
45- onTopicsChange = { setSelectedTopics }
46- />
53+ return (
54+ < >
55+ < TopicPicker
56+ selectedTopics = { selectedTopics }
57+ onTopicsChange = { setSelectedTopics }
58+ />
59+ < input
60+ readOnly
61+ type = "text"
62+ name = "topics"
63+ hidden
64+ required
65+ value = { selectedTopics . length > 0 ? selectedTopics . join ( "," ) : "" }
66+ />
67+ </ >
68+ ) ;
69+ } ,
70+ action : "Next" ,
71+ } ;
72+
73+ const DESTINATION_TYPE_STEP : Step = {
74+ title : "Select destination type" ,
75+ sidebar_shortname : "Destination type" ,
76+ description :
77+ "Select the destination type you want to send to your destination" ,
78+ isValid : ( values : Record < string , any > ) => {
79+ if ( ! values . type ) {
80+ return false ;
81+ }
82+ return true ;
83+ } ,
84+ FormFields : ( {
85+ destinations,
86+ defaultValue,
87+ } : {
88+ destinations : DestinationTypeReference [ ] ;
89+ defaultValue : Record < string , any > ;
90+ } ) => (
91+ < div className = "destination-types" >
92+ { destinations ?. map ( ( destination ) => (
93+ < label key = { destination . type } className = "destination-type-card" >
4794 < input
48- readOnly
49- type = "text"
50- name = "topics"
51- hidden
95+ type = "radio"
96+ name = "type"
97+ value = { destination . type }
5298 required
53- value = { selectedTopics . length > 0 ? selectedTopics . join ( "," ) : "" }
99+ className = "destination-type-radio"
100+ defaultChecked = {
101+ defaultValue ? defaultValue . type === destination . type : undefined
102+ }
54103 />
55- </ >
56- ) ;
57- } ,
58- action : "Next" ,
59- } ,
60- {
61- title : "Select destination type" ,
62- sidebar_shortname : "Destination type" ,
63- description :
64- "Select the destination type you want to send to your destination" ,
65- isValid : ( values : Record < string , any > ) => {
66- if ( ! values . type ) {
67- return false ;
68- }
69- return true ;
70- } ,
71- FormFields : ( {
72- destinations,
73- defaultValue,
74- } : {
75- destinations : DestinationTypeReference [ ] ;
76- defaultValue : Record < string , any > ;
77- } ) => (
78- < div className = "destination-types" >
79- { destinations ?. map ( ( destination ) => (
80- < label key = { destination . type } className = "destination-type-card" >
81- < input
82- type = "radio"
83- name = "type"
84- value = { destination . type }
85- required
86- className = "destination-type-radio"
87- defaultChecked = {
88- defaultValue
89- ? defaultValue . type === destination . type
90- : undefined
91- }
92- />
93- < div className = "destination-type-content" >
94- < h3 className = "subtitle-l" >
95- < span
96- className = "destination-type-content__icon"
97- dangerouslySetInnerHTML = { { __html : destination . icon } }
98- /> { " " }
99- { destination . label }
100- </ h3 >
101- < p className = "body-m muted" > { destination . description } </ p >
102- </ div >
103- </ label >
104- ) ) }
105- </ div >
106- ) ,
107- action : "Next" ,
108- } ,
109- {
110- title : "Configure destination" ,
111- sidebar_shortname : "Configure destination" ,
112- description :
113- "Configure the destination you want to send to your destination" ,
114- FormFields : ( {
115- defaultValue,
116- destinations,
117- } : {
118- defaultValue : Record < string , any > ;
119- destinations : DestinationTypeReference [ ] ;
120- } ) => {
121- const destinationType = destinations ?. find (
122- ( d ) => d . type === defaultValue . type
123- ) ;
124- return (
125- < DestinationConfigFields
126- type = { destinationType ! }
127- destination = { undefined }
128- />
129- ) ;
130- } ,
131- action : "Create Destination" ,
104+ < div className = "destination-type-content" >
105+ < h3 className = "subtitle-l" >
106+ < span
107+ className = "destination-type-content__icon"
108+ dangerouslySetInnerHTML = { { __html : destination . icon } }
109+ /> { " " }
110+ { destination . label }
111+ </ h3 >
112+ < p className = "body-m muted" > { destination . description } </ p >
113+ </ div >
114+ </ label >
115+ ) ) }
116+ </ div >
117+ ) ,
118+ action : "Next" ,
119+ } ;
120+
121+ const CONFIGURATION_STEP : Step = {
122+ title : "Configure destination" ,
123+ sidebar_shortname : "Configure destination" ,
124+ description : "Configure the destination you want to send to your destination" ,
125+ FormFields : ( {
126+ defaultValue,
127+ destinations,
128+ } : {
129+ defaultValue : Record < string , any > ;
130+ destinations : DestinationTypeReference [ ] ;
131+ } ) => {
132+ const destinationType = destinations ?. find (
133+ ( d ) => d . type === defaultValue . type
134+ ) ;
135+ return (
136+ < DestinationConfigFields
137+ type = { destinationType ! }
138+ destination = { undefined }
139+ />
140+ ) ;
132141 } ,
133- ] ;
142+ action : "Create Destination" ,
143+ } ;
134144
135145export default function CreateDestination ( ) {
136146 const apiClient = useContext ( ApiContext ) ;
137147
148+ const AVAILABLE_TOPICS = CONFIGS . TOPICS . split ( "," ) . filter ( Boolean ) ;
149+ let steps = [ EVENT_TOPICS_STEP , DESTINATION_TYPE_STEP , CONFIGURATION_STEP ] ;
150+
151+ // If there are no topics, skip the first step
152+ if ( AVAILABLE_TOPICS . length === 0 && steps . length === 3 ) {
153+ steps = [ DESTINATION_TYPE_STEP , CONFIGURATION_STEP ] ;
154+ }
155+
138156 const navigate = useNavigate ( ) ;
139157 const [ currentStepIndex , setCurrentStepIndex ] = useState ( 0 ) ;
140158 const [ stepValues , setStepValues ] = useState < Record < string , any > > ( { } ) ;
@@ -151,12 +169,24 @@ export default function CreateDestination() {
151169
152170 const destination_type = destinations ?. find ( ( d ) => d . type === values . type ) ;
153171
172+ let topics : string [ ] ;
173+ if ( typeof values . topics === "string" ) {
174+ topics = values . topics . split ( "," ) . filter ( Boolean ) ;
175+ } else if ( typeof values . topics === "undefined" ) {
176+ topics = [ "*" ] ;
177+ } else if ( Array . isArray ( values . topics ) ) {
178+ topics = values . topics ;
179+ } else {
180+ // Default to all topics
181+ topics = [ "*" ] ;
182+ }
183+
154184 apiClient
155185 . fetch ( `destinations` , {
156186 method : "POST" ,
157187 body : JSON . stringify ( {
158188 type : values . type ,
159- topics : values . topics . split ( "," ) ,
189+ topics : topics ,
160190 config : Object . fromEntries (
161191 Object . entries ( values ) . filter ( ( [ key ] ) =>
162192 destination_type ?. config_fields . some ( ( field ) => field . key === key )
0 commit comments