Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/confirmation text for custom tasks #3094

Merged
2 changes: 2 additions & 0 deletions services/api-db/docker-entrypoint-initdb.d/00-tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ CREATE TABLE IF NOT EXISTS advanced_task_definition (
group_name varchar(2000) NULL,
permission ENUM('GUEST', 'DEVELOPER', 'MAINTAINER') DEFAULT 'GUEST',
command text DEFAULT '',
confirmation_text varchar(2000) NULL,
created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
UNIQUE(name, environment, project, group_name)
Expand All @@ -299,6 +300,7 @@ CREATE TABLE IF NOT EXISTS advanced_task_definition_argument (
id int NOT NULL auto_increment PRIMARY KEY,
advanced_task_definition int REFERENCES advanved_task_definition(id),
name varchar(300) NOT NULL UNIQUE,
display_name varchar(500) NULL,
type ENUM('NUMERIC', 'STRING', 'ENVIRONMENT_SOURCE_NAME')
);

Expand Down
35 changes: 35 additions & 0 deletions services/api-db/docker-entrypoint-initdb.d/01-migrations.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,39 @@ CREATE OR REPLACE PROCEDURE
END;
$$

CREATE OR REPLACE PROCEDURE
add_confirmation_text_to_advanced_task_def()

BEGIN
IF NOT EXISTS (
SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
table_name = 'advanced_task_definition'
AND column_name = 'confirmation_text'
) THEN
ALTER TABLE `advanced_task_definition`
ADD `confirmation_text` varchar(2000) NULL;
END IF;
END;
$$

CREATE OR REPLACE PROCEDURE
add_display_name_to_advanced_task_argument()
BEGIN
IF NOT EXISTS (
SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
table_name = 'advanced_task_definition_argument'
AND column_name = 'display_name'
) THEN
ALTER TABLE `advanced_task_definition`
ADD `display_name` varchar(500) NULL;
END IF;
END;
$$

CREATE OR REPLACE PROCEDURE
add_ecdsa_ssh_key_types()

Expand Down Expand Up @@ -1679,6 +1712,8 @@ CALL add_priority_to_deployment();
CALL add_bulk_id_to_deployment();
CALL drop_legacy_permissions();
CALL change_name_index_for_advanced_task_argument();
CALL add_confirmation_text_to_advanced_task_def();
CALL add_display_name_to_advanced_task_argument();
CALL add_ecdsa_ssh_key_types();

-- Drop legacy SSH key procedures
Expand Down
10 changes: 8 additions & 2 deletions services/api/src/resources/task/sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const Sql = {
group_name,
environment,
permission,
confirmation_text,
}: {
id: number,
name: string,
Expand All @@ -93,6 +94,7 @@ export const Sql = {
group_name: string,
environment: number,
permission: string,
confirmation_text: string
}) =>
knex('advanced_task_definition')
.insert({
Expand All @@ -108,25 +110,29 @@ export const Sql = {
group_name,
environment,
permission,
confirmation_text,
})
.toString(),
insertAdvancedTaskDefinitionArgument: ({
id,
advanced_task_definition,
name,
type
type,
displayName,
}: {
id: number,
advanced_task_definition: number,
name: string,
type: string,
displayName: string,
}) =>
knex('advanced_task_definition_argument')
.insert({
id,
advanced_task_definition,
name,
type
type,
display_name: displayName
})
.toString(),
updateAdvancedTaskDefinition: ({ id, patch }: { id: number; patch: { [key: string]: any } }) =>
Expand Down
39 changes: 21 additions & 18 deletions services/api/src/resources/task/task_definition_resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import sql from '../user/sql';
import convertDateToMYSQLDateTimeFormat from '../../util/convertDateToMYSQLDateTimeFormat';
import * as advancedTaskToolbox from './advancedtasktoolbox';
import { IKeycloakAuthAttributes, KeycloakUnauthorizedError } from '../../util/auth';
import { Environment } from '../../resolvers';

enum AdvancedTaskDefinitionTarget {
Group,
Expand Down Expand Up @@ -231,7 +232,8 @@ export const addAdvancedTaskDefinition = async (
environment,
permission,
advancedTaskDefinitionArguments,
created
created,
confirmationText,
} = input;

const atb = advancedTaskToolbox.advancedTaskFunctions(
Expand Down Expand Up @@ -308,7 +310,8 @@ export const addAdvancedTaskDefinition = async (
project,
environment,
group_name: groupName,
permission
permission,
confirmation_text: confirmationText,
})
);

Expand All @@ -321,7 +324,8 @@ export const addAdvancedTaskDefinition = async (
id: null,
advanced_task_definition: insertId,
name: advancedTaskDefinitionArguments[i].name,
type: advancedTaskDefinitionArguments[i].type
type: advancedTaskDefinitionArguments[i].type,
displayName: advancedTaskDefinitionArguments[i].displayName,
})
);
}
Expand Down Expand Up @@ -353,13 +357,9 @@ export const updateAdvancedTaskDefinition = async (
type,
service,
command,
project,
groupName,
environment,
permission,
advancedTaskDefinitionArguments,
created,
deleted
confirmationText
}
}
},
Expand All @@ -369,17 +369,24 @@ export const updateAdvancedTaskDefinition = async (
throw new Error('Input patch requires at least 1 attribute');
}

const atb = advancedTaskToolbox.advancedTaskFunctions(
sqlClientPool, models, hasPermission
);

let task = await atb.advancedTaskDefinitionById(id);

let projectObj = await getProjectByEnvironmentIdOrProjectId(
sqlClientPool,
environment,
project
task.environment,
task.project
);


await checkAdvancedTaskPermissions(patch, hasPermission, models, projectObj);
await checkAdvancedTaskPermissions(task, hasPermission, models, projectObj);

validateAdvancedTaskDefinitionData(patch, image, command, type);

//We actually don't want them to be able to update group, project, environment - so those aren't
await query(
sqlClientPool,
Sql.updateAdvancedTaskDefinition({
Expand All @@ -389,14 +396,9 @@ export const updateAdvancedTaskDefinition = async (
description,
image,
command,
created,
deleted,
type,
service,
project,
environment,
group_name: groupName,
permission,
confirmation_text: confirmationText
}
})
);
Expand All @@ -417,14 +419,15 @@ export const updateAdvancedTaskDefinition = async (
id: null,
advanced_task_definition: id,
name: advancedTaskDefinitionArguments[i].name,
displayName: advancedTaskDefinitionArguments[i].displayName,
type: advancedTaskDefinitionArguments[i].type
})
);
}
}

userActivityLogger(`User updated advanced task definition '${id}'`, {
project: project,
project: task.project,
event: 'api:updateTaskDefinition',
payload: {
taskDef: id
Expand Down
6 changes: 6 additions & 0 deletions services/api/src/typeDefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ const typeDefs = gql`
type AdvancedTaskDefinitionArgument {
id: Int
name: String
displayName: String
type: String
range: [String]
advancedTaskDefinition: AdvancedTaskDefinition
Expand All @@ -138,6 +139,7 @@ const typeDefs = gql`
id: Int
name: String
description: String
confirmationText: String
type: AdvancedTaskDefinitionTypes
image: String
service: String
Expand All @@ -154,6 +156,7 @@ const typeDefs = gql`
id: Int
name: String
description: String
confirmationText: String
type: AdvancedTaskDefinitionTypes
service: String
command: String
Expand Down Expand Up @@ -1344,6 +1347,7 @@ const typeDefs = gql`
input AdvancedTaskDefinitionArgumentInput {
name: String
type: AdvancedTaskDefinitionArgumentTypes
displayName: String
}

input AdvancedTaskDefinitionArgumentValueInput {
Expand All @@ -1368,6 +1372,7 @@ const typeDefs = gql`
groupName: String
permission: TaskPermission
advancedTaskDefinitionArguments: [AdvancedTaskDefinitionArgumentInput]
confirmationText: String
}

input UpdateAdvancedTaskDefinitionInput {
Expand All @@ -1387,6 +1392,7 @@ const typeDefs = gql`
groupName: String
permission: TaskPermission
advancedTaskDefinitionArguments: [AdvancedTaskDefinitionArgumentInput]
confirmationText: String
}

input DeleteTaskInput {
Expand Down
1 change: 1 addition & 0 deletions services/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"react-dom": "^16.8.4",
"react-hexgrid": "^1.0.3",
"react-highlight-words": "^0.14.0",
"react-markdown": "^6.0.0",
"react-modal": "^3.8.1",
"react-nice-dates": "^1.0.2",
"react-select": "^3.0.0",
Expand Down
63 changes: 63 additions & 0 deletions services/ui/src/components/AddTask/components/CustomTaskConfirm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import Modal from 'components/Modal';
import Button from 'components/Button';
import { bp, color } from 'lib/variables';

import ReactMarkdown from 'react-markdown';

/**
* Confirm custom task
*/
export const CustomTaskConfirm = ({
taskText,
onProceed,
open,
openModal,
closeModal,
disabled,
}) => {
return (
<React.Fragment>
<div className="margins">
<Button disabled={disabled} action={openModal}>Confirm Task</Button>
</div>
<Modal
isOpen={open}
onRequestClose={closeModal}
contentLabel={`Confirm`}
>
<React.Fragment>
<ReactMarkdown>
{taskText}
</ReactMarkdown>
<div className="form-input">
<a href="#" className="hover-state margins" onClick={closeModal}>Cancel</a>
<Button action={onProceed}>Confirm</Button>
</div>
</React.Fragment>
</Modal>
<style jsx>{`
.margins {
margin-right: 10px;
}
input {
margin-right: 10px;
width: 100%;
}
.environment-name {
font-weight: bold;
color: ${color.lightBlue};
}
a.hover-state {
margin-right: 10px;
color: ${color.blue};
}
.form-input {
display: flex;
align-items: center;
justify-content: space-between;
}
`}</style>
</React.Fragment>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const DrushArchiveDump = ({ pageEnvironment, onCompleted, onError }) => (
required
/>
</div>
<Button action={taskDrushArchiveDump}>Add task</Button>
<Button action={taskDrushArchiveDump}>Run task</Button>
<style jsx>{`
.envSelect {
margin: 10px 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const DrushCacheClear = ({ pageEnvironment, onCompleted, onError }) => (
required
/>
</div>
<Button action={taskDrushCacheClear}>Add task</Button>
<Button action={taskDrushCacheClear}>Run task</Button>
<style jsx>{`
.envSelect {
margin: 10px 0;
Expand Down
2 changes: 1 addition & 1 deletion services/ui/src/components/AddTask/components/DrushCron.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const DrushCron = ({ pageEnvironment, onCompleted, onError }) => (
required
/>
</div>
<Button action={taskDrushCron}>Add task</Button>
<Button action={taskDrushCron}>Run task</Button>
<style jsx>{`
.envSelect {
margin: 10px 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const DrushRsyncFiles = ({
}
disabled={!selectedSourceEnv}
>
Add task
Run task
</Button>
<style jsx>{`
.warning {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const DrushSqlDump = ({ pageEnvironment, onCompleted, onError }) => (
required
/>
</div>
<Button action={taskDrushSqlDump}>Add task</Button>
<Button action={taskDrushSqlDump}>Run task</Button>
<style jsx>{`
.envSelect {
margin: 10px 0;
Expand Down
Loading