Skip to content

Commit

Permalink
Update NewFileDrawerForm and TreeComponent
Browse files Browse the repository at this point in the history
Modified NewFileDrawerForm and TreeComponent to include ProFormTreeSelect and selective tree building based on file type. This allows the application to handle repositories and files in a hierarchical tree structure, providing a more intuitive user interface for navigating through directories and files. The commit also includes added useEffect to fetch playbook repositories on loading and a Select component for choosing file type.
  • Loading branch information
manu committed Jul 15, 2024
1 parent b2f9f5d commit ce09c22
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 74 deletions.
179 changes: 109 additions & 70 deletions client/src/pages/Playbooks/components/NewFileDrawerForm.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { buildTree } from '@/pages/Playbooks/components/TreeComponent';
import { getPlaybooksRepositories } from '@/services/rest/playbooks-repositories';
import { FileAddOutlined, FolderAddOutlined } from '@ant-design/icons';
import {
DrawerForm,
ProFormDependency,
ProFormSelect,
ProFormItem,
ProFormText,
ProFormRadio,
ProFormTreeSelect,
} from '@ant-design/pro-components';
import { Button } from 'antd';
import { Button, Card, Select, TreeSelectProps, Typography } from 'antd';
import { AddCircleOutline } from 'antd-mobile-icons';
import React from 'react';
import React, { useEffect } from 'react';
import { API } from 'ssm-shared-lib';

export type NewFileModalFormProps = {
Expand All @@ -20,12 +22,44 @@ export type NewFileModalFormProps = {
) => Promise<boolean>;
setSelectedNode: any;
};
const { Option } = Select;

const NewFileDrawerForm: React.FC<NewFileModalFormProps> = (props) => {
const [repositories, setRepositories] = React.useState<
API.PlaybooksRepository[] | undefined
>();
const [loading, setLoading] = React.useState(false);
const [fileType, setFileType] = React.useState('directory');
const [selectedPlaybook, setSelectedPlaybook] = React.useState<
API.PlaybooksRepository | undefined
>();

useEffect(() => {
setLoading(true);
void getPlaybooksRepositories()
.then((res) => {
setRepositories(res.data);
})
.finally(() => {
setLoading(false);
});
}, []);

const onSelect: TreeSelectProps['onSelect'] = (value, info) => {
setSelectedPlaybook(
repositories?.find((e) => info?.playbookRepository?.uuid === e.uuid),
);
};

const selectBefore = (
<Select
defaultValue="directory"
onSelect={(value: string) => setFileType(value)}
>
<Option value="directory">Directory</Option>
<Option value="playbook">Playbook</Option>
</Select>
);
return (
<DrawerForm<{ name: string; repository: string; type: string }>
title={`Create a new file`}
Expand Down Expand Up @@ -56,100 +90,105 @@ const NewFileDrawerForm: React.FC<NewFileModalFormProps> = (props) => {
setLoading(true);
await props
.submitNewFile(
values.repository,
selectedPlaybook?.uuid as string,
values.name,
`${
repositories?.find((e) => e.uuid === values.repository)?.path
}/${values.name}`,
values.type as 'playbook' | 'directory',
`${values.repository}/${values.name}`,
fileType as 'playbook' | 'directory',
)
.finally(() => {
setLoading(false);
});
return true;
}}
>
<ProFormSelect
placeholder={'For repository'}
<ProFormTreeSelect
label={`Repository path`}
style={{ width: '100%' }}
name={'repository'}
onChange={(e) => {
props.setSelectedNode(repositories?.find((f) => f.uuid === e)?.name);
}}
request={async () => {
return await getPlaybooksRepositories().then((e) => {
setRepositories(e?.data);
return e.data
? e.data.map((f) => {
return {
label: f.name,
value: f.uuid,
path: f.path,
};
})
: [];
});
rules={[
{
required: true,
message: `Please choose a path!`,
},
]}
fieldProps={{
onSelect: onSelect,
onDeselect: () => {
setSelectedPlaybook(undefined);
},
showSearch: true,
dropdownStyle: { maxHeight: 400, overflow: 'auto' },
fieldNames: {
label: '_name',
value: 'key',
},
treeDefaultExpandAll: true,
treeData: repositories?.map((e) => {
return {
...buildTree(e as API.PlaybooksRepository, true),
key: e.path,
};
}),
}}
placeholder="Please select"
allowClear
/>
<ProFormDependency name={['repository']}>
{({ repository }) => {
if (repository) {
return (
<>
<ProFormRadio.Group
label="Type"
radioType="button"
name={'type'}
colProps={{
span: 20,
}}
options={['directory', 'playbook']}
{' '}
<ProFormText
width={'xl'}
required={true}
name={'name'}
label={`File or directory name`}
tooltip={`Enter a name (the character '_' is not authorized)`}
placeholder={`name`}
fieldProps={{
addonBefore: selectBefore,
suffix: fileType === 'playbook' ? '.yml' : undefined,
}}
rules={[
{
required: true,
message: `Please select a type!`,
message: `Please input a name!`,
},
{
pattern: new RegExp('^[0-9a-zA-Z\\-]{0,100}$'),
message:
'Please enter a valid name (only alphanumerical and "-" authorized), max 100 chars',
},
]}
/>
<ProFormDependency name={['type']}>
{({ type }) => {
if (type) {
return (
<ProFormText
width={'xl'}
required={true}
name={'name'}
label={`File or directory name`}
tooltip={`Enter a name (the character '_' is not authorized)`}
placeholder={`name`}
fieldProps={{
prefix: `${
repositories?.find((e) => e.uuid === repository)
?.name
}/`,
suffix: type === 'playbook' ? '.yml' : undefined,
}}
rules={[
{
required: true,
message: `Please input a name!`,
},
{
pattern: new RegExp('^[0-9a-zA-Z\\-]{0,100}$'),
message:
'Please enter a valid name (only alphanumerical and "-" authorized), max 100 chars',
},
]}
/>
);
}
}}
</ProFormDependency>
</>
);
}
}}
</ProFormDependency>
<ProFormDependency name={['name', 'repository']}>
{({ name, repository }) => {
if (repository) {
return (
<ProFormItem>
{fileType === 'playbook' ? (
<FileAddOutlined />
) : (
<FolderAddOutlined />
)}
<Typography.Text code>
{repository?.replace(
selectedPlaybook?.path,
selectedPlaybook?.name,
)}
/{`${name}${fileType === 'playbook' ? '.yml' : ''}`}
</Typography.Text>
</ProFormItem>
);
}
}}
</ProFormDependency>
</DrawerForm>
);
};
Expand Down
12 changes: 8 additions & 4 deletions client/src/pages/Playbooks/components/TreeComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export type ClientPlaybooksTrees = {

export function buildTree(
rootNode: API.PlaybooksRepository,
onlyDirectories?: boolean,
): ClientPlaybooksTrees {
return {
_name: rootNode.name,
Expand All @@ -48,7 +49,7 @@ export function buildTree(
) : (
<SimpleIconsGit style={{ height: '1em', width: '1em', marginTop: 5 }} />
),
selectable: false,
selectable: !!onlyDirectories,
children: rootNode.children
? recursiveTreeTransform(
{
Expand All @@ -57,6 +58,7 @@ export function buildTree(
path: rootNode.name,
},
{ uuid: rootNode.uuid, name: rootNode.name, basePath: rootNode.path },
onlyDirectories,
)
: undefined,
};
Expand All @@ -65,6 +67,7 @@ export function buildTree(
export function recursiveTreeTransform(
tree: DirectoryTree.ExtendedTreeNode,
playbookRepository: { uuid: string; name: string; basePath: string },
onlyDirectories?: boolean,
depth = 0,
): ClientPlaybooksTrees[] {
const node = tree;
Expand Down Expand Up @@ -97,15 +100,16 @@ export function recursiveTreeTransform(
'/server/src/ansible/00000000-0000-0000-0000-000000000000/device',
),
depth: depth,
selectable: false,
selectable: !!onlyDirectories,
children: recursiveTreeTransform(
child,
playbookRepository,
onlyDirectories,
depth + 1,
),
});
} else {
if (child) {
if (child && !onlyDirectories) {
newTree.push({
key: child.path,
_name: child.name,
Expand All @@ -125,7 +129,7 @@ export function recursiveTreeTransform(
}
}
}
} else {
} else if (!onlyDirectories) {
newTree.push({
key: node.path,
_name: node.name,
Expand Down

0 comments on commit ce09c22

Please sign in to comment.