Skip to content

Commit f9cbdd7

Browse files
fix: UI Issues P3 (#194)
* fix: persist changes for streams if stream is disabled and re-enabled * fix: reset existing source on changing connector type * fix: data filter validation added * fix: UI issues * fix: tooltip and doc link for OLake version * fix: add dialog and reset streams data on going back * fix: fix reset streams modal text * fix: fix bugs and resolve comments * fix: fix message * fix: minor fix * fix: fix ui issue * fix: resolve comments * fix: minor fix * fix: minor fix * fix: destination edit name * fix: fix ui issues * fix: destination delete issue * fix: update release notes link * fix: fix destination database prefix and name can be empty * fix: add confirm reset streams modal on job edit * fix: disable stepper on streams loading --------- Co-authored-by: deepanshupal09 <[email protected]>
1 parent 484628e commit f9cbdd7

22 files changed

+604
-253
lines changed

ui/src/modules/common/Modals/DestinationDatabaseModal.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState, useEffect } from "react"
2-
import { Modal, Radio, Input, Button } from "antd"
2+
import { Modal, Radio, Input, Button, message } from "antd"
33
import { useAppStore } from "../../../store"
44
import { validateAlphanumericUnderscore } from "../../../utils/utils"
55
import {
@@ -55,6 +55,12 @@ const DestinationDatabaseModal = ({
5555
)
5656

5757
const handleSaveChanges = () => {
58+
if (databaseName.trim() === "") {
59+
message.error(
60+
`${selectedFormat === FORMAT_OPTIONS.DYNAMIC ? `${labels.title} Prefix` : `${labels.title}`} can not be empty`,
61+
)
62+
return
63+
}
5864
onSave(selectedFormat, databaseName)
5965
setShowDestinationDatabaseModal(false)
6066
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { FC } from "react"
2+
import { WarningIcon } from "@phosphor-icons/react"
3+
import { Button, Modal } from "antd"
4+
5+
import { useAppStore } from "../../../store"
6+
import { ResetStreamsModalProps } from "../../../types"
7+
8+
const ResetStreamsModal: FC<ResetStreamsModalProps> = ({ onConfirm }) => {
9+
const { showResetStreamsModal, setShowResetStreamsModal } = useAppStore()
10+
11+
const handleCancel = () => setShowResetStreamsModal(false)
12+
13+
const handleConfirm = () => {
14+
setShowResetStreamsModal(false)
15+
onConfirm()
16+
}
17+
18+
return (
19+
<Modal
20+
open={showResetStreamsModal}
21+
onCancel={handleCancel}
22+
footer={null}
23+
closable={false}
24+
centered
25+
title={
26+
<div className="flex items-center gap-2 text-danger">
27+
<WarningIcon
28+
className="size-9"
29+
weight="fill"
30+
/>
31+
</div>
32+
}
33+
>
34+
<div className="flex flex-col items-center gap-6">
35+
<div className="flex w-full flex-col">
36+
<p className="text-xl font-medium text-slate-700">
37+
Your changes will not be saved
38+
</p>
39+
<p className="text-sm text-slate-700">
40+
Leaving this page will loose all your progress & changes.
41+
</p>
42+
<p className="mt-6">Are you sure you want to leave?</p>
43+
</div>
44+
45+
<div className="flex w-full justify-end gap-3">
46+
<Button
47+
type="primary"
48+
className="!bg-[#f5222d]"
49+
onClick={handleConfirm}
50+
>
51+
Yes, Leave
52+
</Button>
53+
<Button onClick={handleCancel}>No</Button>
54+
</div>
55+
</div>
56+
</Modal>
57+
)
58+
}
59+
60+
export default ResetStreamsModal

ui/src/modules/destinations/pages/CreateDestination.tsx

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ import {
77
} from "react"
88
import { Link, useNavigate } from "react-router-dom"
99
import { Input, message, Select, Spin } from "antd"
10-
import { ArrowLeft, ArrowRight, Info, Notebook } from "@phosphor-icons/react"
10+
import {
11+
ArrowLeftIcon,
12+
ArrowRightIcon,
13+
ArrowSquareOutIcon,
14+
InfoIcon,
15+
NotebookIcon,
16+
} from "@phosphor-icons/react"
1117
import Form from "@rjsf/antd"
1218

1319
import { useAppStore } from "../../../store"
@@ -27,6 +33,7 @@ import {
2733
import {
2834
CONNECTOR_TYPES,
2935
DESTINATION_INTERNAL_TYPES,
36+
OLAKE_LATEST_VERSION_URL,
3037
SETUP_TYPES,
3138
transformErrors,
3239
} from "../../../utils/constants"
@@ -101,6 +108,9 @@ const CreateDestination = forwardRef<
101108
const [schema, setSchema] = useState<any>(null)
102109
const [loading, setLoading] = useState(false)
103110
const [uiSchema, setUiSchema] = useState<any>(null)
111+
const [existingDestination, setExistingDestination] = useState<
112+
string | null
113+
>(null)
104114
const [filteredDestinations, setFilteredDestinations] = useState<
105115
ExtendedDestination[]
106116
>([])
@@ -395,16 +405,27 @@ const CreateDestination = forwardRef<
395405
}
396406

397407
const handleConnectorChange = (value: string) => {
398-
setFormData({})
399-
setSchema(null)
400408
setConnector(value as ConnectorType)
401-
if (onConnectorChange) {
402-
onConnectorChange(value)
409+
if (setupType === SETUP_TYPES.EXISTING) {
410+
setExistingDestination(null)
411+
setDestinationName("")
412+
onDestinationNameChange?.("")
403413
}
414+
setVersion("")
415+
setFormData({})
416+
setSchema(null)
417+
418+
// Parent callbacks
419+
onConnectorChange?.(value)
420+
onVersionChange?.("")
421+
onFormDataChange?.({})
404422
}
405423

406424
const handleSetupTypeChange = (type: SetupType) => {
407425
setSetupType(type)
426+
setDestinationName("")
427+
onDestinationNameChange?.("")
428+
408429
if (onDocsMinimizedChange) {
409430
if (type === SETUP_TYPES.EXISTING) {
410431
onDocsMinimizedChange(true)
@@ -414,12 +435,11 @@ const CreateDestination = forwardRef<
414435
}
415436
// Clear form data when switching to new destination
416437
if (type === SETUP_TYPES.NEW) {
417-
setDestinationName("")
418438
setFormData({})
419439
setSchema(null)
420440
setConnector(CONNECTOR_TYPES.DESTINATION_DEFAULT_CONNECTOR) // Reset to default connector
441+
setExistingDestination(null)
421442
// Schema will be automatically fetched due to useEffect when connector changes
422-
if (onDestinationNameChange) onDestinationNameChange("")
423443
if (onConnectorChange) onConnectorChange(CONNECTOR_TYPES.AMAZON_S3)
424444
if (onFormDataChange) onFormDataChange({})
425445
if (onVersionChange) onVersionChange("")
@@ -446,6 +466,7 @@ const CreateDestination = forwardRef<
446466
if (onFormDataChange) onFormDataChange(configObj)
447467
setDestinationName(selectedDestination.name)
448468
setFormData(configObj)
469+
setExistingDestination(value)
449470
}
450471

451472
const handleVersionChange = (value: string) => {
@@ -480,7 +501,20 @@ const CreateDestination = forwardRef<
480501
</FormField>
481502
</div>
482503
<div className="w-1/2">
483-
<FormField label="Version:">
504+
<FormField
505+
label="OLake Version:"
506+
tooltip="Choose the OLake version for the destination"
507+
info={
508+
<a
509+
href={OLAKE_LATEST_VERSION_URL}
510+
target="_blank"
511+
rel="noopener noreferrer"
512+
className="flex items-center text-primary hover:text-primary/80"
513+
>
514+
<ArrowSquareOutIcon className="size-4" />
515+
</a>
516+
}
517+
>
484518
{loadingVersions ? (
485519
<div className="flex h-8 items-center justify-center">
486520
<Spin size="small" />
@@ -498,7 +532,7 @@ const CreateDestination = forwardRef<
498532
/>
499533
) : (
500534
<div className="flex items-center gap-1 text-sm text-red-500">
501-
<Info />
535+
<InfoIcon />
502536
No versions available
503537
</div>
504538
)}
@@ -543,7 +577,7 @@ const CreateDestination = forwardRef<
543577
placeholder="Select a destination"
544578
className="w-full"
545579
onChange={handleExistingDestinationSelect}
546-
value={undefined}
580+
value={existingDestination}
547581
options={filteredDestinations.map(d => ({
548582
value: d.id,
549583
label: d.name,
@@ -615,7 +649,7 @@ const CreateDestination = forwardRef<
615649
to={"/destinations"}
616650
className="flex items-center gap-2 p-1.5 hover:rounded-md hover:bg-gray-100 hover:text-black"
617651
>
618-
<ArrowLeft className="mr-1 size-5" />
652+
<ArrowLeftIcon className="mr-1 size-5" />
619653
</Link>
620654
<div className="text-lg font-bold">Create destination</div>
621655
</div>
@@ -633,7 +667,7 @@ const CreateDestination = forwardRef<
633667
<div className="mb-6 mt-2 rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
634668
<div>
635669
<div className="mb-4 flex items-center gap-2 text-base font-medium">
636-
<Notebook className="size-5" />
670+
<NotebookIcon className="size-5" />
637671
Capture information
638672
</div>
639673

@@ -663,7 +697,7 @@ const CreateDestination = forwardRef<
663697
}}
664698
>
665699
Create
666-
<ArrowRight className="size-4 text-white" />
700+
<ArrowRightIcon className="size-4 text-white" />
667701
</button>
668702
</div>
669703
)}

ui/src/modules/destinations/pages/DestinationEdit.tsx

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
11
import React, { useState, useEffect, useRef } from "react"
22
import { useParams, Link, useNavigate } from "react-router-dom"
33
import { formatDistanceToNow } from "date-fns"
4-
import { Input, Button, Select, Switch, message, Spin, Table } from "antd"
4+
import {
5+
Input,
6+
Button,
7+
Select,
8+
Switch,
9+
message,
10+
Spin,
11+
Table,
12+
Tooltip,
13+
} from "antd"
514
import type { ColumnsType } from "antd/es/table"
6-
import { ArrowLeft, Info, Notebook, PencilSimple } from "@phosphor-icons/react"
15+
import {
16+
ArrowLeft,
17+
ArrowSquareOut,
18+
Info,
19+
Notebook,
20+
PencilSimple,
21+
} from "@phosphor-icons/react"
722
import validator from "@rjsf/validator-ajv8"
823
import Form from "@rjsf/antd"
924

@@ -31,6 +46,7 @@ import {
3146
TAB_TYPES,
3247
ENTITY_TYPES,
3348
DISPLAYED_JOBS_COUNT,
49+
OLAKE_LATEST_VERSION_URL,
3450
transformErrors,
3551
} from "../../../utils/constants"
3652
import DocumentationPanel from "../../common/components/DocumentationPanel"
@@ -136,6 +152,8 @@ const DestinationEdit: React.FC<DestinationEditProps> = ({
136152
? JSON.parse(destination.config)
137153
: destination.config
138154
setFormData(config)
155+
} else {
156+
navigate("/destinations")
139157
}
140158
}
141159
}, [destinationId, destinations, fetchDestinations])
@@ -480,13 +498,27 @@ const DestinationEdit: React.FC<DestinationEditProps> = ({
480498
onChange={updateConnector}
481499
className="h-8 w-full"
482500
options={connectorOptions}
483-
disabled={fromJobFlow}
501+
disabled
484502
/>
485503
</div>
486504
</div>
487505
<div className="w-1/2">
488-
<label className="mb-2 block text-sm font-medium text-gray-700">
489-
Version:
506+
<label className="mb-2 flex items-center gap-1 text-sm font-medium text-gray-700">
507+
OLake Version:
508+
<Tooltip title="Choose the OLake version for the destination">
509+
<Info
510+
size={16}
511+
className="cursor-help text-slate-900"
512+
/>
513+
</Tooltip>
514+
<a
515+
href={OLAKE_LATEST_VERSION_URL}
516+
target="_blank"
517+
rel="noopener noreferrer"
518+
className="flex items-center text-primary hover:text-primary/80"
519+
>
520+
<ArrowSquareOut className="size-4" />
521+
</a>
490522
</label>
491523
{loadingVersions ? (
492524
<div className="flex h-8 items-center justify-center">
@@ -524,7 +556,7 @@ const DestinationEdit: React.FC<DestinationEditProps> = ({
524556
value={destinationName}
525557
onChange={e => updateDestinationName(e.target.value)}
526558
className="h-8"
527-
disabled={fromJobFlow}
559+
disabled
528560
/>
529561
</div>
530562
</div>
@@ -678,32 +710,31 @@ const DestinationEdit: React.FC<DestinationEditProps> = ({
678710
? renderConfigTab()
679711
: renderJobsTab()}
680712
</div>
681-
682713
{/* Footer */}
683714
{!fromJobFlow && (
684715
<div className="flex justify-between border-t border-gray-200 bg-white p-4 shadow-sm">
685716
<div>
686-
{
687-
<button
688-
className="ml-1 rounded-md border border-danger px-4 py-2 text-danger transition-colors duration-200 hover:bg-danger hover:text-white"
689-
onClick={handleDelete}
690-
>
691-
Delete
692-
</button>
693-
}
694-
</div>
695-
<div className="flex space-x-4">
696717
<button
697-
className="mr-1 flex items-center justify-center gap-1 rounded-md bg-primary px-4 py-2 font-light text-white shadow-sm transition-colors duration-200 hover:bg-primary-600"
698-
onClick={() => {
699-
if (formRef.current) {
700-
formRef.current.submit()
701-
}
702-
}}
718+
className="ml-1 rounded-md border border-danger px-4 py-2 text-danger transition-colors duration-200 hover:bg-danger hover:text-white"
719+
onClick={handleDelete}
703720
>
704-
Save Changes
721+
Delete
705722
</button>
706723
</div>
724+
<div className="flex space-x-4">
725+
{activeTab === TAB_TYPES.CONFIG && (
726+
<button
727+
className="mr-1 flex items-center justify-center gap-1 rounded-md bg-primary px-4 py-2 font-light text-white shadow-sm transition-colors duration-200"
728+
onClick={() => {
729+
if (formRef.current) {
730+
formRef.current.submit()
731+
}
732+
}}
733+
>
734+
Save changes
735+
</button>
736+
)}
737+
</div>
707738
</div>
708739
)}
709740
</div>

0 commit comments

Comments
 (0)