@@ -2,30 +2,35 @@ import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
22import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" ;
33import classNames from "classnames" ;
44import { Field , Form , Formik , FieldArray , FieldProps , FormikHelpers } from "formik" ;
5+ import { ReactNode } from "react" ;
6+ import { FormattedMessage , useIntl } from "react-intl" ;
57import { Link } from "react-router-dom" ;
6- import { array , object , number } from "yup" ;
8+ import * as yup from "yup" ;
79
810import { FormChangeTracker } from "components/common/FormChangeTracker" ;
911import { Button } from "components/ui/Button" ;
1012import { Card } from "components/ui/Card" ;
1113import { Input } from "components/ui/Input" ;
14+ import { Text } from "components/ui/Text" ;
1215
1316import { WebBackendConnectionRead } from "core/request/AirbyteClient" ;
1417import { useCurrentWorkspace } from "hooks/services/useWorkspace" ;
1518import { DbtCloudJob , useDbtIntegration } from "packages/cloud/services/dbtCloud" ;
1619import { RoutePaths } from "pages/routePaths" ;
1720
21+ import dbtLogo from "./dbt-bit_tm.svg" ;
1822import styles from "./DbtCloudTransformationsCard.module.scss" ;
23+ import octaviaWorker from "./octavia-worker.png" ;
1924
2025interface DbtJobListValues {
2126 jobs : DbtCloudJob [ ] ;
2227}
2328
24- const dbtCloudJobListSchema = object ( {
25- jobs : array ( ) . of (
26- object ( {
27- account : number ( ) . required ( ) . positive ( ) . integer ( ) ,
28- job : number ( ) . required ( ) . positive ( ) . integer ( ) ,
29+ const dbtCloudJobListSchema = yup . object ( {
30+ jobs : yup . array ( ) . of (
31+ yup . object ( {
32+ account : yup . number ( ) . required ( ) . positive ( ) . integer ( ) ,
33+ job : yup . number ( ) . required ( ) . positive ( ) . integer ( ) ,
2934 } )
3035 ) ,
3136} ) ;
@@ -47,12 +52,12 @@ export const DbtCloudTransformationsCard = ({ connection }: { connection: WebBac
4752 } ;
4853
4954 return (
50- < Formik // TODO extract to parent component, see if that helps with input focus issues
55+ < Formik
5156 onSubmit = { onSubmit }
5257 initialValues = { { jobs : dbtCloudJobs } }
5358 validationSchema = { dbtCloudJobListSchema }
5459 render = { ( { values, isValid, dirty } ) => {
55- return (
60+ return hasDbtIntegration ? (
5661 < Form className = { styles . jobListForm } >
5762 < FormChangeTracker changed = { dirty } />
5863 < FieldArray
@@ -62,29 +67,33 @@ export const DbtCloudTransformationsCard = ({ connection }: { connection: WebBac
6267 < Card
6368 title = {
6469 < span className = { styles . jobListTitle } >
65- Transformations
66- { hasDbtIntegration && (
67- < Button
68- variant = "secondary"
69- onClick = { ( ) => push ( { account : "" , job : "" } ) }
70- icon = { < FontAwesomeIcon icon = { faPlus } /> }
71- >
72- Add transformation
73- </ Button >
74- ) }
70+ < FormattedMessage id = "connection.dbtCloudJobs.cardTitle" />
71+ < Button
72+ variant = "secondary"
73+ onClick = { ( ) => push ( { account : "" , job : "" } ) }
74+ icon = { < FontAwesomeIcon icon = { faPlus } /> }
75+ >
76+ < FormattedMessage id = "connection.dbtCloudJobs.addJob" />
77+ </ Button >
7578 </ span >
7679 }
7780 >
78- { hasDbtIntegration ? (
79- < DbtJobsList jobs = { values . jobs } remove = { remove } isValid = { isValid } dirty = { dirty } />
80- ) : (
81- < NoDbtIntegration className = { styles . jobListContainer } />
82- ) }
81+ < DbtJobsList jobs = { values . jobs } remove = { remove } isValid = { isValid } dirty = { dirty } />
8382 </ Card >
8483 ) ;
8584 } }
8685 />
8786 </ Form >
87+ ) : (
88+ < Card
89+ title = {
90+ < span className = { styles . jobListTitle } >
91+ < FormattedMessage id = "connection.dbtCloudJobs.cardTitle" />
92+ </ span >
93+ }
94+ >
95+ < NoDbtIntegration />
96+ </ Card >
8897 ) ;
8998 } }
9099 />
@@ -102,14 +111,20 @@ const DbtJobsList = ({
102111 isValid : boolean ;
103112 dirty : boolean ;
104113} ) => (
105- < div className = { classNames ( styles . jobListContainer , styles . emptyListContent ) } >
106- < p className = { styles . contextExplanation } > After an Airbyte sync job has completed, the following jobs will run</ p >
114+ < div className = { classNames ( styles . jobListContainer ) } >
107115 { jobs . length ? (
108- jobs . map ( ( _j , i ) => < JobsListItem key = { i } jobIndex = { i } removeJob = { ( ) => remove ( i ) } /> )
116+ < >
117+ < Text className = { styles . contextExplanation } >
118+ < FormattedMessage id = "connection.dbtCloudJobs.explanation" />
119+ </ Text >
120+ { jobs . map ( ( _ , i ) => (
121+ < JobsListItem key = { i } jobIndex = { i } removeJob = { ( ) => remove ( i ) } />
122+ ) ) }
123+ </ >
109124 ) : (
110125 < >
111- < img src = "/images/octavia/worker.png" alt = "An octopus wearing a hard hat, tools at the ready" />
112- No transformations
126+ < img src = { octaviaWorker } alt = "" className = { styles . emptyListImage } />
127+ < FormattedMessage id = "connection.dbtCloudJobs.noJobs" />
113128 </ >
114129 ) }
115130 < div className = { styles . jobListButtonGroup } >
@@ -125,19 +140,20 @@ const DbtJobsList = ({
125140
126141// TODO give feedback on validation errors (red outline and validation message)
127142const JobsListItem = ( { jobIndex, removeJob } : { jobIndex : number ; removeJob : ( ) => void } ) => {
143+ const { formatMessage } = useIntl ( ) ;
128144 return (
129145 < Card className = { styles . jobListItem } >
130146 < div className = { styles . jobListItemIntegrationName } >
131- < img src = "/images/external/dbt-bit_tm.png" alt = "dbt logo" />
132- dbt Cloud transform
147+ < img src = { dbtLogo } alt = "" className = { styles . dbtLogo } />
148+ < FormattedMessage id = "connection.dbtCloudJobs.job.title" />
133149 </ div >
134150 < div className = { styles . jobListItemInputGroup } >
135151 < div className = { styles . jobListItemInput } >
136152 < Field name = { `jobs.${ jobIndex } .account` } >
137153 { ( { field } : FieldProps < string > ) => (
138154 < >
139155 < label htmlFor = { `jobs.${ jobIndex } .account` } className = { styles . jobListItemInputLabel } >
140- Account ID
156+ < FormattedMessage id = "connection.dbtCloudJobs.job.accountId" />
141157 </ label >
142158 < Input { ...field } type = "text" />
143159 </ >
@@ -149,33 +165,40 @@ const JobsListItem = ({ jobIndex, removeJob }: { jobIndex: number; removeJob: ()
149165 { ( { field } : FieldProps < string > ) => (
150166 < >
151167 < label htmlFor = { `jobs.${ jobIndex } .job` } className = { styles . jobListItemInputLabel } >
152- Job ID
168+ < FormattedMessage id = "connection.dbtCloudJobs.job.jobId" />
153169 </ label >
154170 < Input { ...field } type = "text" />
155171 </ >
156172 ) }
157173 </ Field >
158174 </ div >
159- < button type = "button" className = { styles . jobListItemDelete } onClick = { removeJob } >
175+ < Button
176+ variant = "clear"
177+ size = "lg"
178+ className = { styles . jobListItemDelete }
179+ onClick = { removeJob }
180+ aria-label = { formatMessage ( { id : "connection.dbtCloudJobs.job.deleteButton" } ) }
181+ >
160182 < FontAwesomeIcon icon = { faXmark } />
161- </ button >
183+ </ Button >
162184 </ div >
163185 </ Card >
164186 ) ;
165187} ;
166188
167- const NoDbtIntegration = ( { className } : { className : string } ) => {
189+ const NoDbtIntegration = ( ) => {
168190 const { workspaceId } = useCurrentWorkspace ( ) ;
169191 const dbtSettingsPath = `/${ RoutePaths . Workspaces } /${ workspaceId } /${ RoutePaths . Settings } /dbt-cloud` ;
170192 return (
171- < div className = { classNames ( className , styles . emptyListContent ) } >
172- < p className = { styles . contextExplanation } > After an Airbyte sync job has completed, the following jobs will run</ p >
173- < p className = { styles . contextExplanation } >
174- Go to your < Link to = { dbtSettingsPath } > settings</ Link > to connect your dbt Cloud account
175- </ p >
176- < DbtCloudSignupBanner />
193+ < div className = { classNames ( styles . jobListContainer ) } >
194+ < Text className = { styles . contextExplanation } >
195+ < FormattedMessage
196+ id = "connection.dbtCloudJobs.noIntegration"
197+ values = { {
198+ settingsLink : ( linkText : ReactNode ) => < Link to = { dbtSettingsPath } > { linkText } </ Link > ,
199+ } }
200+ />
201+ </ Text >
177202 </ div >
178203 ) ;
179204} ;
180-
181- const DbtCloudSignupBanner = ( ) => < div /> ;
0 commit comments