Skip to content

Commit

Permalink
[jk] Add pipeline description (mage-ai#2203)
Browse files Browse the repository at this point in the history
* [jk] Add description to pipeline model

* [jk] Add description column

* [jk] Edit description

* [jk] Use textarea for description editing

* [jk] Allow updating to empty description

* [jk] Update unit tests

* [jk] Fix bug
  • Loading branch information
johnson-mage authored Mar 15, 2023
1 parent 3e96a87 commit fbf8c14
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 22 deletions.
1 change: 1 addition & 0 deletions mage_ai/api/presenters/PipelinePresenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class PipelinePresenter(BasePresenter):
default_attributes = [
'blocks',
'data_integration',
'description',
'name',
'type',
'uuid',
Expand Down
7 changes: 7 additions & 0 deletions mage_ai/data_preparation/models/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def __init__(self, uuid, repo_path=None, config=None, repo_config=None, catalog=
self.block_configs = []
self.blocks_by_uuid = {}
self.data_integration = None
self.description = None
self.extensions = {}
self.name = None
self.repo_path = repo_path or get_repo_path()
Expand Down Expand Up @@ -376,6 +377,7 @@ def load_config(self, config, catalog=None):
else:
self.data_integration = catalog
self.name = config.get('name')
self.description = config.get('description')
self.type = config.get('type') or self.type

self.block_configs = config.get('blocks') or []
Expand Down Expand Up @@ -458,6 +460,7 @@ def __initialize_blocks_by_uuid(
def to_dict_base(self, exclude_data_integration=False) -> Dict:
base = dict(
data_integration=self.data_integration if not exclude_data_integration else None,
description=self.description,
name=self.name,
type=self.type.value if type(self.type) is not str else self.type,
uuid=self.uuid,
Expand Down Expand Up @@ -619,6 +622,10 @@ async def update(self, data, update_content=False):

should_save = False

if 'description' in data and data['description'] != self.description:
self.description = data['description']
should_save = True

if 'type' in data and data['type'] != self.type:
"""
Update kernel
Expand Down
1 change: 1 addition & 0 deletions mage_ai/frontend/interfaces/PipelineType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export default interface PipelineType {
data_integration?: {
catalog: CatalogType;
};
description?: string;
extensions?: PipelineExtensionsType;
id?: number;
metadata?: PipelineMetadataType;
Expand Down
12 changes: 10 additions & 2 deletions mage_ai/frontend/oracle/elements/Inputs/InputModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import KeyboardShortcutButton from '@oracle/elements/Button/KeyboardShortcutButt
import Panel from '@oracle/components/Panel';
import Spacing from '@oracle/elements/Spacing';
import Text from '@oracle/elements/Text';
import TextArea from '@oracle/elements/Inputs/TextArea';
import TextInput from '@oracle/elements/Inputs/TextInput';

type InputModalProps = {
description?: string;
isLoading?: boolean;
maxWidth?: number;
minWidth?: number;
noEmptyValue?: boolean;
onClose: () => void;
onSave: (value: string) => void;
textArea?: boolean;
title: string;
value: string;
};
Expand All @@ -24,13 +27,16 @@ function InputModal({
isLoading,
maxWidth,
minWidth,
noEmptyValue,
onClose,
onSave,
textArea,
title,
value,
}: InputModalProps) {
const refTextInput = useRef(null);
const [inputValue, setInputValue] = useState<string>(value);
const TextEl = textArea ? TextArea : TextInput;

useEffect(() => {
refTextInput?.current?.focus();
Expand All @@ -46,10 +52,12 @@ function InputModal({
</Text>

<Spacing mt={1}>
<TextInput
<TextEl
monospace
onChange={e => setInputValue(e.target.value)}
ref={refTextInput}
// @ts-ignore
rows={textArea ? 7 : null}
value={inputValue}
/>
</Spacing>
Expand All @@ -69,7 +77,7 @@ function InputModal({
inline
loading={isLoading}
onClick={() => {
if (inputValue === value || !inputValue) {
if (inputValue === value || (noEmptyValue && !inputValue)) {
onClose();
return;
}
Expand Down
16 changes: 7 additions & 9 deletions mage_ai/frontend/oracle/elements/Inputs/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@ const TextInputStyle = styled.textarea<TextAreaProps>`
${SHARED_INPUT_STYLES}
`;

const TextInput = ({ rows = 3, ...props }: TextAreaProps, ref) => {
return (
<InputWrapper
{...props}
input={<TextInputStyle rows={rows} {...props} />}
ref={ref}
/>
);
};
const TextInput = ({ rows = 3, ...props }: TextAreaProps, ref) => (
<InputWrapper
{...props}
input={<TextInputStyle rows={rows} {...props} />}
ref={ref}
/>
);

export default React.forwardRef(TextInput);
52 changes: 42 additions & 10 deletions mage_ai/frontend/pages/pipelines/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ function PipelineListPage() {
}));
fetchPipelines();
hideInputModal?.();
setSelectedPipeline(null);
},
onErrorCallback: (response, errors) => {
const pipelineUUID = response?.url_parameters?.pk;
Expand Down Expand Up @@ -140,28 +141,42 @@ function PipelineListPage() {
);

const [showInputModal, hideInputModal] = useModal(({
pipelineDescription,
pipelineName,
}: {
pipelineName: string;
pipelineDescription?: string;
pipelineName?: string;
}) => (
<InputModal
isLoading={isLoadingUpdate}
minWidth={UNIT * 55}
noEmptyValue={!!pipelineName}
onClose={hideInputModal}
onSave={(name: string) => {
onSave={(value: string) => {
if (selectedPipeline) {
const selectedPipelineUUID = selectedPipeline.uuid;
const pipelineUpdateRequestBody: PipelineType = {
uuid: selectedPipelineUUID,
};
if (pipelineName) {
pipelineUpdateRequestBody.name = value;
} else {
pipelineUpdateRequestBody.description = value;
}

setPipelinesEditing(prev => ({
...prev,
[selectedPipelineUUID]: true,
}));
updatePipeline({
name,
uuid: selectedPipelineUUID,
});
updatePipeline(pipelineUpdateRequestBody);
}
}}
title="Rename pipeline"
value={pipelineName}
textArea={!pipelineName}
title={pipelineName
? 'Rename pipeline'
: 'Edit description'
}
value={pipelineName ? pipelineName : pipelineDescription}
/>
), {} , [
isLoadingUpdate,
Expand Down Expand Up @@ -228,7 +243,12 @@ function PipelineListPage() {
{
label: () => 'Rename pipeline',
onClick: () => showInputModal({ pipelineName: selectedPipeline?.name }),
uuid: 'Pipelines/MoreActionsMenu/rename',
uuid: 'Pipelines/MoreActionsMenu/Rename',
},
{
label: () => 'Edit description',
onClick: () => showInputModal({ pipelineDescription: selectedPipeline?.description }),
uuid: 'Pipelines/MoreActionsMenu/EditDescription',
},
]}
query={query}
Expand Down Expand Up @@ -266,7 +286,7 @@ function PipelineListPage() {
</Spacing>
): (
<Table
columnFlex={[null, 1, 7, 1, 1, 1, null]}
columnFlex={[null, 1, 3, 4, 1, 1, 1, null]}
columns={[
{
label: () => '',
Expand All @@ -278,6 +298,9 @@ function PipelineListPage() {
{
uuid: 'Name',
},
{
uuid: 'Description',
},
{
uuid: 'Type',
},
Expand Down Expand Up @@ -307,6 +330,7 @@ function PipelineListPage() {
rows={pipelines.map((pipeline, idx) => {
const {
blocks,
description,
name,
schedules,
type,
Expand Down Expand Up @@ -368,6 +392,14 @@ function PipelineListPage() {
{uuid}
</Link>
</NextLink>,
<Text
default
key={`pipeline_description_${idx}`}
title={description}
width={UNIT * 90}
>
{description}
</Text>,
<Text
key={`pipeline_type_${idx}`}
>
Expand Down
6 changes: 5 additions & 1 deletion mage_ai/tests/data_preparation/models/test_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def test_add_block(self):

self.assertEqual(pipeline.to_dict(), dict(
data_integration=None,
description=None,
name='test pipeline 2',
uuid='test_pipeline_2',
type='python',
Expand Down Expand Up @@ -153,6 +154,7 @@ def test_delete_block(self):
pipeline = Pipeline('test_pipeline_3', self.repo_path)
self.assertEqual(pipeline.to_dict(), dict(
data_integration=None,
description=None,
name='test pipeline 3',
uuid='test_pipeline_3',
type='python',
Expand Down Expand Up @@ -222,6 +224,7 @@ def test_execute(self):
pipeline.execute_sync()
self.assertEqual(pipeline.to_dict(), dict(
data_integration=None,
description=None,
name='test pipeline 4',
uuid='test_pipeline_4',
type='python',
Expand Down Expand Up @@ -312,6 +315,7 @@ def test_execute_multiple_paths(self):
pipeline.execute_sync()
self.assertEqual(pipeline.to_dict(), dict(
data_integration=None,
description=None,
name='test pipeline 5',
uuid='test_pipeline_5',
type='python',
Expand Down Expand Up @@ -523,11 +527,11 @@ def test_save_and_get_data_integration_catalog(self):
self.assertTrue(os.path.exists(pipeline.config_path))
with open(pipeline.config_path) as f:
config_json = yaml.full_load(f)
print('WTFFFFFFFFFFF', config_json)
self.assertEqual(
config_json,
{
"data_integration": None,
"description": None,
"extensions": {},
"name": "test_pipeline_9",
"type": "integration",
Expand Down

0 comments on commit fbf8c14

Please sign in to comment.