Skip to content

Commit 7829c15

Browse files
[MISC] Remove success alerts from deployments and pipelines (#1755)
* [FEAT] Remove success alerts from deployments and pipelines Remove success alerts from API deployments, pipelines, and file history operations to reduce notification clutter. Co-Authored-By: Claude Opus 4.5 <[email protected]> * [FEAT] Remove success alerts from custom tools and settings components Remove non-critical success alerts from 11 frontend components: - Document parser, users, list of tools, file history modal - Default triad, LLM profiles, pre/post amble modal - Custom data/synonyms, tool settings, configure data source Co-Authored-By: Claude Opus 4.5 <[email protected]> * Added alert for Test Connection * [MISC] Enhance Save UX in prompt studio settings components (#1761) [FIX] Fix Save→Saved button text not showing in settings components Fix useEffect dependency bug that was resetting isSaved state immediately after save, preventing "Saved" text from displaying on Save button. Co-authored-by: Claude Opus 4.5 <[email protected]> * [FIX] Add Save button UX to CustomSynonyms and PreAndPostAmbleModal - Add hasChanges/isSaved state to track modifications - Reset state on tool_id change to prevent stale button state - Disable Save button until changes are made - Show "Saved" feedback after successful save Co-Authored-By: Claude Opus 4.5 <[email protected]> --------- Co-authored-by: Claude Opus 4.5 <[email protected]>
1 parent cb2aa68 commit 7829c15

File tree

14 files changed

+59
-120
lines changed

14 files changed

+59
-120
lines changed

frontend/src/components/custom-tools/custom-data-settings/CustomDataSettings.jsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,14 @@ function CustomDataSettings() {
5555
const [jsonError, setJsonError] = useState(null);
5656
const [isLoading, setIsLoading] = useState(false);
5757
const [hasChanges, setHasChanges] = useState(false);
58+
const [isSaved, setIsSaved] = useState(false);
5859
const { sessionDetails } = useSessionStore();
5960
const { details, isPublicSource, updateCustomTool } = useCustomToolStore();
6061
const { setAlertDetails } = useAlertStore();
6162
const axiosPrivate = useAxiosPrivate();
6263
const handleException = useExceptionHandler();
6364

64-
// Initialize editor with current custom_data
65+
// Initialize editor with current custom_data (only on tab switch)
6566
useEffect(() => {
6667
const customData = details?.custom_data;
6768
if (customData && Object.keys(customData).length > 0) {
@@ -70,7 +71,8 @@ function CustomDataSettings() {
7071
setJsonValue("{\n \n}");
7172
}
7273
setHasChanges(false);
73-
}, [details?.custom_data]);
74+
setIsSaved(false);
75+
}, [details?.tool_id]);
7476

7577
// Extract variables from active prompts
7678
const extractedVariables = useMemo(() => {
@@ -113,6 +115,9 @@ function CustomDataSettings() {
113115
const handleEditorChange = (value) => {
114116
setJsonValue(value || "");
115117
setHasChanges(true);
118+
if (isSaved) {
119+
setIsSaved(false);
120+
}
116121

117122
// Validate JSON
118123
try {
@@ -158,11 +163,8 @@ function CustomDataSettings() {
158163
setIsLoading(true);
159164
axiosPrivate(requestOptions)
160165
.then((res) => {
161-
setAlertDetails({
162-
type: "success",
163-
content: "Custom data saved successfully",
164-
});
165166
setHasChanges(false);
167+
setIsSaved(true);
166168
// Update the store with the new details
167169
const updatedDetails = res?.data;
168170
if (updatedDetails) {
@@ -292,7 +294,7 @@ function CustomDataSettings() {
292294
loading={isLoading}
293295
disabled={isPublicSource || !!jsonError || !hasChanges}
294296
>
295-
Save
297+
{isSaved ? "Saved" : "Save"}
296298
</CustomButton>
297299
</Space>
298300
</div>

frontend/src/components/custom-tools/custom-synonyms/CustomSynonyms.jsx

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,20 @@ function CustomSynonyms() {
4545
const [rows, setRows] = useState([]);
4646
const [isLoading, setIsLoading] = useState(false);
4747
const [currentPage, setCurrentPage] = useState(1);
48+
const [hasChanges, setHasChanges] = useState(false);
49+
const [isSaved, setIsSaved] = useState(false);
4850
const { sessionDetails } = useSessionStore();
4951
const { details, isPublicSource } = useCustomToolStore();
5052
const { setAlertDetails } = useAlertStore();
5153
const axiosPrivate = useAxiosPrivate();
5254
const handleException = useExceptionHandler();
5355

56+
// Reset state on tool switch
57+
useEffect(() => {
58+
setHasChanges(false);
59+
setIsSaved(false);
60+
}, [details?.tool_id]);
61+
5462
useEffect(() => {
5563
const promptGrammar = details?.prompt_grammer;
5664
if (!promptGrammar || Object.keys(promptGrammar).length === 0) {
@@ -121,6 +129,8 @@ function CustomSynonyms() {
121129
const updatedSynonyms = [...synonyms];
122130
updatedSynonyms[index][propertyName] = value;
123131
setSynonyms(updatedSynonyms);
132+
setHasChanges(true);
133+
setIsSaved(false);
124134
};
125135

126136
const handleAddRow = () => {
@@ -137,6 +147,8 @@ function CustomSynonyms() {
137147
const updatedSynonyms = [...synonyms];
138148
updatedSynonyms.push(data);
139149
setSynonyms(updatedSynonyms);
150+
setHasChanges(true);
151+
setIsSaved(false);
140152

141153
const newPage = updatedSynonyms?.length / PAGE_SIZE;
142154
if (newPage + 1 > currentPage) {
@@ -163,15 +175,10 @@ function CustomSynonyms() {
163175
promptGrammar[item.word] = item.synonyms || [];
164176
});
165177

166-
let successMsg = "";
167-
let failureMsg = "";
168-
if (actionType === actionTypes.save) {
169-
successMsg = "Saved synonyms successfully";
170-
failureMsg = "Failed to save synonyms";
171-
} else {
172-
successMsg = "Deleted synonyms successfully";
173-
failureMsg = "Failed to delete synonyms";
174-
}
178+
const failureMsg =
179+
actionType === actionTypes.save
180+
? "Failed to save synonyms"
181+
: "Failed to delete synonyms";
175182

176183
const body = {
177184
prompt_grammer: promptGrammar,
@@ -193,10 +200,10 @@ function CustomSynonyms() {
193200
if (actionType === actionTypes.delete) {
194201
setSynonyms(listOfSynonyms);
195202
}
196-
setAlertDetails({
197-
type: "success",
198-
content: successMsg,
199-
});
203+
setHasChanges(false);
204+
if (actionType === actionTypes.save) {
205+
setIsSaved(true);
206+
}
200207
})
201208
.catch((err) => {
202209
setAlertDetails(handleException(err, failureMsg));
@@ -245,9 +252,9 @@ function CustomSynonyms() {
245252
type="primary"
246253
onClick={() => updateSynonyms(synonyms, actionTypes.save)}
247254
loading={isLoading}
248-
disabled={isPublicSource}
255+
disabled={isPublicSource || !hasChanges}
249256
>
250-
Save
257+
{isSaved ? "Saved" : "Save"}
251258
</CustomButton>
252259
</Space>
253260
</div>

frontend/src/components/custom-tools/document-parser/DocumentParser.jsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,6 @@ function DocumentParser({
196196
);
197197
modifiedDetails["prompts"] = modifiedPrompts;
198198
updateCustomTool({ details: modifiedDetails });
199-
setAlertDetails({
200-
type: "success",
201-
content: "Deleted successfully",
202-
});
203199
})
204200
.catch((err) => {
205201
setAlertDetails(handleException(err, "Failed to delete"));

frontend/src/components/custom-tools/list-of-tools/ListOfTools.jsx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,6 @@ function ListOfTools() {
177177
(filterToll) => filterToll?.tool_id !== tool.tool_id
178178
);
179179
setListOfTools(tools);
180-
setAlertDetails({
181-
type: "success",
182-
content: `${tool?.tool_name} - Deleted successfully`,
183-
});
184180
})
185181
.catch((err) => {
186182
setAlertDetails(handleException(err, "Failed to Delete"));
@@ -338,10 +334,6 @@ function ListOfTools() {
338334
axiosPrivate(requestOptions)
339335
.then((response) => {
340336
setOpenSharePermissionModal(false);
341-
setAlertDetails({
342-
type: "success",
343-
content: "Sharing settings updated successfully",
344-
});
345337
})
346338
.catch((err) => {
347339
setAlertDetails(handleException(err, "Failed to load"));

frontend/src/components/custom-tools/manage-llm-profiles/ManageLlmProfiles.jsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,6 @@ function ManageLlmProfiles() {
102102
defaultLlmProfile: data?.default_profile,
103103
};
104104
updateCustomTool(updatedState);
105-
setAlertDetails({
106-
type: "success",
107-
content: "Default LLM Profile updated successfully",
108-
});
109105
})
110106
.catch((err) => {
111107
handleException(err, "Failed to set default LLM Profile");

frontend/src/components/custom-tools/pre-and-post-amble-modal/PreAndPostAmbleModal.jsx

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ function PreAndPostAmbleModal({ type, handleUpdateTool }) {
2121
const [title, setTitle] = useState("");
2222
const [text, setText] = useState("");
2323
const [expandModalVisible, setExpandModalVisible] = useState(false);
24+
const [hasChanges, setHasChanges] = useState(false);
25+
const [isLoading, setIsLoading] = useState(false);
26+
const [isSaved, setIsSaved] = useState(false);
2427
const textAreaRef = useRef(null);
2528
const { details, updateCustomTool, isPublicSource } = useCustomToolStore();
2629
const { setAlertDetails } = useAlertStore();
@@ -34,18 +37,28 @@ function PreAndPostAmbleModal({ type, handleUpdateTool }) {
3437
setTitle("Postamble Settings");
3538
setText(details?.postamble || "");
3639
}
40+
setHasChanges(false);
3741
}, [type, details]);
3842

43+
// Reset isSaved on tool switch (separate from text initialization)
44+
useEffect(() => {
45+
setIsSaved(false);
46+
}, [details?.tool_id]);
47+
3948
const setDefaultPrompt = () => {
4049
if (type === fieldNames.preamble) {
4150
setText(DefaultPrompts.preamble);
4251
} else if (type === fieldNames.postamble) {
4352
setText(DefaultPrompts.postamble);
4453
}
54+
setHasChanges(true);
55+
setIsSaved(false);
4556
};
4657

4758
const handleTextChange = (e) => {
4859
setText(e.target.value);
60+
setHasChanges(true);
61+
setIsSaved(false);
4962
};
5063

5164
const toggleExpandModal = () => {
@@ -61,6 +74,7 @@ function PreAndPostAmbleModal({ type, handleUpdateTool }) {
6174
if (type === fieldNames.postamble) {
6275
body["postamble"] = text;
6376
}
77+
setIsLoading(true);
6478
handleUpdateTool(body)
6579
.then((res) => {
6680
const data = res?.data;
@@ -70,13 +84,14 @@ function PreAndPostAmbleModal({ type, handleUpdateTool }) {
7084
};
7185
const updatedDetails = { ...details, ...updatedData };
7286
updateCustomTool({ details: updatedDetails });
73-
setAlertDetails({
74-
type: "success",
75-
content: "Saved successfully",
76-
});
87+
setHasChanges(false);
88+
setIsSaved(true);
7789
})
7890
.catch((err) => {
7991
setAlertDetails(handleException(err, "Failed to update."));
92+
})
93+
.finally(() => {
94+
setIsLoading(false);
8095
});
8196
};
8297

@@ -149,9 +164,10 @@ function PreAndPostAmbleModal({ type, handleUpdateTool }) {
149164
<CustomButton
150165
type="primary"
151166
onClick={handleSave}
152-
disabled={isPublicSource}
167+
loading={isLoading}
168+
disabled={isPublicSource || !hasChanges}
153169
>
154-
Save
170+
{isSaved ? "Saved" : "Save"}
155171
</CustomButton>
156172
</Space>
157173
</div>

frontend/src/components/deployments/api-deployment/ApiDeployment.jsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,7 @@ function ApiDeployment() {
247247
record.is_active = !record?.is_active;
248248
apiDeploymentsApiService
249249
.updateApiDeployment(record)
250-
.then((res) => {
251-
setAlertDetails({
252-
type: "success",
253-
content: "Status updated successfully",
254-
});
255-
})
250+
.then(() => {})
256251
.catch((err) => {
257252
setAlertDetails(handleException(err));
258253
})

frontend/src/components/input-output/configure-ds/ConfigureDs.jsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,6 @@ function ConfigureDs({
323323
if (data) {
324324
addNewItem(data, !!editItemId);
325325
}
326-
setAlertDetails({
327-
type: "success",
328-
content: `Successfully ${
329-
method === "POST" ? "added" : "updated"
330-
} connector`,
331-
});
332326
if (!isConnector && method === "POST") {
333327
updateSession(type);
334328
}

frontend/src/components/pipelines-or-deployments/file-history-modal/FileHistoryModal.jsx

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,6 @@ const FileHistoryModal = ({ open, setOpen, workflowId, workflowName }) => {
236236
const handleDeleteSingle = async (fileHistoryId) => {
237237
try {
238238
await workflowApiService.deleteFileHistory(workflowId, fileHistoryId);
239-
setAlertDetails({
240-
type: "success",
241-
message: "File history deleted successfully",
242-
});
243239
// Refresh data
244240
fetchFileHistories(pagination.current, pagination.pageSize);
245241
setSelectedRowKeys([]);
@@ -262,18 +258,11 @@ const FileHistoryModal = ({ open, setOpen, workflowId, workflowName }) => {
262258

263259
setLoading(true);
264260
try {
265-
const response = await workflowApiService.bulkDeleteFileHistoriesByIds(
261+
await workflowApiService.bulkDeleteFileHistoriesByIds(
266262
workflowId,
267263
selectedRowKeys
268264
);
269265

270-
setAlertDetails({
271-
type: "success",
272-
message:
273-
response?.data?.message ||
274-
`${selectedRowKeys.length} file histories deleted successfully`,
275-
});
276-
277266
// Refresh data
278267
fetchFileHistories(pagination.current, pagination.pageSize);
279268
setSelectedRowKeys([]);
@@ -358,17 +347,7 @@ const FileHistoryModal = ({ open, setOpen, workflowId, workflowName }) => {
358347
filters.file_path = appliedFilters.filePath;
359348
}
360349

361-
const response = await workflowApiService.bulkClearFileHistories(
362-
workflowId,
363-
filters
364-
);
365-
366-
setAlertDetails({
367-
type: "success",
368-
message:
369-
response?.data?.message ||
370-
`${response?.data?.deleted_count} file histories cleared`,
371-
});
350+
await workflowApiService.bulkClearFileHistories(workflowId, filters);
372351

373352
// Refresh data
374353
fetchFileHistories(1, pagination.pageSize);

frontend/src/components/pipelines-or-deployments/pipelines/Pipelines.jsx

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,6 @@ function Pipelines({ type }) {
150150
const data = res?.data?.pipeline;
151151
fieldsToUpdate.last_run_status = data?.last_run_status;
152152
fieldsToUpdate.last_run_time = data?.last_run_time;
153-
setAlertDetails({
154-
type: "success",
155-
content: "Pipeline Sync Initiated",
156-
});
157153
})
158154
.catch((err) => {
159155
setAlertDetails(handleException(err, "Failed to sync."));
@@ -232,12 +228,6 @@ function Pipelines({ type }) {
232228
axiosPrivate(requestOptions)
233229
.then(() => {
234230
getPipelineList();
235-
setAlertDetails({
236-
type: "success",
237-
content: value
238-
? "Pipeline Enabled Successfully"
239-
: "Pipeline Disabled Successfully",
240-
});
241231
})
242232
.catch((err) => {
243233
setAlertDetails(handleException(err));
@@ -284,10 +274,7 @@ function Pipelines({ type }) {
284274

285275
const clearFileMarkers = async () => {
286276
const workflowId = selectedPorD?.workflow_id;
287-
const success = await clearFileHistory(
288-
workflowId,
289-
"Pipeline File History Cleared Successfully"
290-
);
277+
const success = await clearFileHistory(workflowId);
291278
if (success && openDeleteModal) {
292279
setOpenDeleteModal(false);
293280
}

0 commit comments

Comments
 (0)