Integrations Page: Remove edit integration from UI, Render duplicate error message, Unique integration naming convention (#5577)
This commit is contained in:
@@ -0,0 +1 @@
|
||||
* Remove the ability to edit a Jira integration as integrations fields are unique to each integration
|
||||
@@ -174,35 +174,6 @@ const createConfig = {
|
||||
},
|
||||
};
|
||||
|
||||
const editConfig = {
|
||||
...getConfig,
|
||||
integrations: {
|
||||
jira: [
|
||||
{
|
||||
url: "https://fleetdm.atlassian.com",
|
||||
username: "jira1@example.com",
|
||||
api_token: "jira123",
|
||||
project_key: "PROJECT 1",
|
||||
enable_software_vulnerabilities: false,
|
||||
},
|
||||
{
|
||||
url: "https://fleetdm.atlassian.com",
|
||||
username: "jira0@example.com",
|
||||
api_token: "jira0123",
|
||||
project_key: "PROJECT 0",
|
||||
enable_software_vulnerabilities: false,
|
||||
},
|
||||
{
|
||||
url: "https://fleetdm.atlassian.com",
|
||||
username: "jira3@example.com",
|
||||
api_token: "jira123",
|
||||
project_key: "PROJECT 3",
|
||||
enable_software_vulnerabilities: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const deleteConfig = {
|
||||
...getConfig,
|
||||
integrations: {
|
||||
@@ -564,51 +535,6 @@ describe("App settings flow", () => {
|
||||
console.log(JSON.stringify(configStub));
|
||||
});
|
||||
});
|
||||
it("edits jira integration", () => {
|
||||
cy.getAttached("tbody>tr")
|
||||
.should("have.length", 3)
|
||||
.eq(1)
|
||||
.within(() => {
|
||||
cy.findByText(/action/i).click();
|
||||
cy.findByText(/edit/i).click();
|
||||
});
|
||||
cy.findByLabelText(/jira site url/i)
|
||||
.clear()
|
||||
.type("https://fleetdm.atlassian.com");
|
||||
cy.findByLabelText(/jira username/i)
|
||||
.clear()
|
||||
.type("jira0@example.com");
|
||||
cy.findByLabelText(/jira api token/i)
|
||||
.clear()
|
||||
.type("jira0123");
|
||||
cy.findByLabelText(/jira project key/i)
|
||||
.clear()
|
||||
.type("PROJECT 0");
|
||||
cy.intercept("PATCH", "/api/latest/fleet/config", editConfig).as(
|
||||
"editIntegration"
|
||||
);
|
||||
cy.intercept("GET", "/api/latest/fleet/config", editConfig).as(
|
||||
"editedIntegration"
|
||||
);
|
||||
cy.getAttached(".integration-form__btn-wrap")
|
||||
.contains("button", /save/i)
|
||||
.click();
|
||||
cy.wait("@editIntegration").then((configStub) => {
|
||||
cy.log(JSON.stringify(configStub));
|
||||
console.log(JSON.stringify(configStub));
|
||||
});
|
||||
cy.wait("@editedIntegration").then((configStub) => {
|
||||
cy.log(JSON.stringify(configStub));
|
||||
console.log(JSON.stringify(configStub));
|
||||
cy.findByText(/successfully edited/i).should("exist");
|
||||
cy.getAttached("tbody>tr")
|
||||
.should("have.length", 3)
|
||||
.eq(0)
|
||||
.within(() => {
|
||||
cy.findByText(/fleetdm.atlassian.com - project 0/i).should("exist");
|
||||
});
|
||||
});
|
||||
});
|
||||
it("deletes jira integration", () => {
|
||||
cy.getAttached("tbody>tr")
|
||||
.eq(1)
|
||||
|
||||
@@ -143,6 +143,12 @@ const IntegrationsPage = (): JSX.Element => {
|
||||
jiraIntegrationSubmitData[
|
||||
jiraIntegrationSubmitData.length - 1
|
||||
].url
|
||||
}{" "}
|
||||
-{" "}
|
||||
{
|
||||
jiraIntegrationSubmitData[
|
||||
jiraIntegrationSubmitData.length - 1
|
||||
].project_key
|
||||
}
|
||||
</b>
|
||||
</>
|
||||
@@ -154,11 +160,36 @@ const IntegrationsPage = (): JSX.Element => {
|
||||
.catch((createError: { data: IApiError }) => {
|
||||
if (createError.data.message.includes("Validation Failed")) {
|
||||
renderFlash("error", VALIDATION_FAILED_ERROR);
|
||||
}
|
||||
if (createError.data.message.includes("Bad request")) {
|
||||
renderFlash("error", BAD_REQUEST_ERROR);
|
||||
}
|
||||
if (createError.data.message.includes("Unknown Error")) {
|
||||
} else if (createError.data.message.includes("Bad request")) {
|
||||
if (
|
||||
createError.data.errors[0].reason.includes(
|
||||
"duplicate Jira integration for project key"
|
||||
)
|
||||
) {
|
||||
renderFlash(
|
||||
"error",
|
||||
<>
|
||||
Could not add add{" "}
|
||||
<b>
|
||||
{
|
||||
jiraIntegrationSubmitData[
|
||||
jiraIntegrationSubmitData.length - 1
|
||||
].url
|
||||
}{" "}
|
||||
-{" "}
|
||||
{
|
||||
jiraIntegrationSubmitData[
|
||||
jiraIntegrationSubmitData.length - 1
|
||||
].project_key
|
||||
}
|
||||
</b>
|
||||
. This integration already exists
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
renderFlash("error", BAD_REQUEST_ERROR);
|
||||
}
|
||||
} else if (createError.data.message.includes("Unknown Error")) {
|
||||
renderFlash("error", UNKNOWN_ERROR);
|
||||
} else {
|
||||
renderFlash(
|
||||
@@ -194,7 +225,10 @@ const IntegrationsPage = (): JSX.Element => {
|
||||
renderFlash(
|
||||
"success",
|
||||
<>
|
||||
Successfully deleted <b>{integrationEditing.url}</b>
|
||||
Successfully deleted{" "}
|
||||
<b>
|
||||
{integrationEditing.url} - {integrationEditing.project_key}
|
||||
</b>
|
||||
</>
|
||||
);
|
||||
refetchIntegrations();
|
||||
@@ -203,8 +237,11 @@ const IntegrationsPage = (): JSX.Element => {
|
||||
renderFlash(
|
||||
"error",
|
||||
<>
|
||||
Could not delete <b>{integrationEditing.url}</b>. Please try
|
||||
again.
|
||||
Could not delete{" "}
|
||||
<b>
|
||||
{integrationEditing.url} - {integrationEditing.project_key}
|
||||
</b>
|
||||
. Please try again.
|
||||
</>
|
||||
);
|
||||
})
|
||||
@@ -226,7 +263,11 @@ const IntegrationsPage = (): JSX.Element => {
|
||||
<>
|
||||
Successfully edited{" "}
|
||||
<b>
|
||||
{jiraIntegrationSubmitData[integrationEditing?.index].url}
|
||||
{jiraIntegrationSubmitData[integrationEditing?.index].url} -{" "}
|
||||
{
|
||||
jiraIntegrationSubmitData[integrationEditing?.index]
|
||||
.project_key
|
||||
}
|
||||
</b>
|
||||
</>
|
||||
);
|
||||
@@ -248,8 +289,12 @@ const IntegrationsPage = (): JSX.Element => {
|
||||
renderFlash(
|
||||
"error",
|
||||
<>
|
||||
Could not edit <b>{integrationEditing?.url}</b>. Please try
|
||||
again.
|
||||
Could not edit{" "}
|
||||
<b>
|
||||
{integrationEditing?.url} -{" "}
|
||||
{integrationEditing?.project_key}
|
||||
</b>
|
||||
. Please try again.
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -356,6 +401,7 @@ const IntegrationsPage = (): JSX.Element => {
|
||||
onCancel={toggleDeleteIntegrationModal}
|
||||
onSubmit={onDeleteSubmit}
|
||||
url={integrationEditing?.url || ""}
|
||||
projectKey={integrationEditing?.project_key || ""}
|
||||
/>
|
||||
)}
|
||||
{showEditIntegrationModal && (
|
||||
|
||||
@@ -100,11 +100,6 @@ const generateTableHeaders = (
|
||||
// NOTE: may need current user ID later for permission on actions.
|
||||
const generateActionDropdownOptions = (): IDropdownOption[] => {
|
||||
return [
|
||||
{
|
||||
label: "Edit",
|
||||
disabled: false,
|
||||
value: "edit",
|
||||
},
|
||||
{
|
||||
label: "Delete",
|
||||
disabled: false,
|
||||
|
||||
+6
-1
@@ -7,12 +7,14 @@ const baseClass = "delete-integration-modal";
|
||||
|
||||
interface IDeleteIntegrationModalProps {
|
||||
url: string;
|
||||
projectKey: string;
|
||||
onSubmit: () => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
const DeleteIntegrationModal = ({
|
||||
url,
|
||||
projectKey,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
}: IDeleteIntegrationModalProps): JSX.Element => {
|
||||
@@ -34,7 +36,10 @@ const DeleteIntegrationModal = ({
|
||||
<form className={`${baseClass}__form`}>
|
||||
<p>
|
||||
This action will delete the{" "}
|
||||
<span className={`${baseClass}__url`}>{url}</span> integration.
|
||||
<span className={`${baseClass}__url`}>
|
||||
{url} - {projectKey}
|
||||
</span>{" "}
|
||||
integration.
|
||||
</p>
|
||||
<p>The automations that use this integration will be turned off.</p>
|
||||
<div className="modal-cta-wrap">
|
||||
|
||||
Reference in New Issue
Block a user