Skip to content

Commit

Permalink
Update query handling and improve form components
Browse files Browse the repository at this point in the history
Removed default values for pagination parameters, conditionally paginated data only if parameters exist. Enhanced component naming and added new functionality for network and image selection in forms, using unique origin tags for better clarity.
  • Loading branch information
SquirrelDevelopper committed Oct 10, 2024
1 parent a8d2dbf commit d16c6ee
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { ContextSelect } from '@/components/ComposeEditor/ViewBuilderElements/SmartFields';
import {
SmartSelect,
SmartSelectSingle,
} from '@/components/ComposeEditor/ViewBuilderElements/SmartFields';
import { PlusOutlined } from '@ant-design/icons';
import { ProFormInstance } from '@ant-design/pro-components';
import {
Expand Down Expand Up @@ -63,7 +66,7 @@ export const renderField = (
case 'service-networks':
return (
<>
<ContextSelect
<SmartSelect
id={field.id}
name={[...namePath, field.id as string]}
index={index}
Expand All @@ -73,6 +76,17 @@ export const renderField = (
/>
</>
);
case 'image':
return (
<SmartSelectSingle
id={field.id}
name={[...namePath, field.id as string]}
index={index}
initialValue={field.value}
form={form}
labelWithIcon={labelWithIcon}
/>
);
}
switch (field.fieldType) {
case 'text':
Expand Down
146 changes: 126 additions & 20 deletions client/src/components/ComposeEditor/ViewBuilderElements/SmartFields.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { ProFormInstance } from '@ant-design/pro-components';
import { getImages, getNetworks } from '@/services/rest/services';
import {
ProForm,
ProFormInstance,
ProFormItem,
} from '@ant-design/pro-components';
import { ProFormSelect } from '@ant-design/pro-form';
import { AutoComplete, Space, Tag } from 'antd';
import React, { ReactNode, useCallback, useEffect, useState } from 'react';

type SmartFieldsProps = {
Expand All @@ -11,50 +17,73 @@ type SmartFieldsProps = {
labelWithIcon: ReactNode;
};

export const ContextSelect: React.FC<SmartFieldsProps> = ({
export const SmartSelect: React.FC<SmartFieldsProps> = ({
id,
name,
index,
initialValue,
form,
labelWithIcon,
}) => {
const [contextNames, setContextNames] = useState<string[]>([]);
const [contextNames, setContextNames] = useState<
{ origin: string; value: string }[]
>([]);

const extractContextNames = useCallback(() => {
const extractContextNames = useCallback(async () => {
const values = form.getFieldsValue();
switch (id) {
case 'depends_on':
if (values && values.services) {
const names = Object.values(values.services).map(
(service: any) => service.name,
);
const names = Object.values(values.services).map((service: any) => {
return { origin: 'This stack', value: service.name };
});
setContextNames(names);
}
return;
case 'service-configs':
if (values && values.configs) {
const names = Object.values(values.configs).map(
(config: any) => config.name,
);
const names = Object.values(values.configs).map((config: any) => {
return { origin: 'This stack', value: config.name };
});
setContextNames(names);
}
return;
case 'service-networks':
if (values && values.networks) {
const names = Object.values(values.networks).map(
(network: any) => network.name,
);
setContextNames(names);
}
return;
const names =
values.networks && values.networks
? Object.values(values.networks).map((network: any) => {
return { origin: 'This stack', value: network.name };
})
: [];
const networksData = await getNetworks();
const uniqueNamesMap: Map<
string,
{ origin: string; value: string | undefined }
> = new Map();
networksData?.data?.forEach((e) => {
if (!uniqueNamesMap.has(e.name)) {
const nameObject = {
origin: e.device?.ip || 'unknown',
value: e.name,
};
uniqueNamesMap.set(e.name, nameObject);
} else {
const nameObject = {
origin: 'On multiple devices',
value: e.name,
};
uniqueNamesMap.set(e.name, nameObject);
}
});
names.push(...Array.from(uniqueNamesMap.values()));
setContextNames(names);
}

return [];
}, [form]);

useEffect(() => {
extractContextNames(); // Extract names on mount
void extractContextNames(); // Extract names on mount
}, [form, extractContextNames]);

return (
Expand All @@ -65,14 +94,91 @@ export const ContextSelect: React.FC<SmartFieldsProps> = ({
key={index}
name={name}
options={contextNames.map((contextName) => ({
label: contextName,
value: contextName,
label: contextName.value,
value: contextName.value,
origin: contextName.origin,
}))}
fieldProps={{
optionRender: (option) => (
<Space>
<span role="img" aria-label={option.data.label as string}>
<Tag>{option.data.origin}</Tag>
</span>
{option.data.label}
</Space>
),
onClick: () => extractContextNames(),
}}
initialValue={initialValue}
/>
</>
);
};

export const SmartSelectSingle: React.FC<SmartFieldsProps> = ({
id,
name,
index,
initialValue,
form,
labelWithIcon,
}) => {
const [contextNames, setContextNames] = useState<
{ origin: string; value: string }[]
>([]);

const extractContextNames = useCallback(async () => {
const values = form.getFieldsValue();
switch (id) {
case 'image':
const imagesData = await getImages();
const uniqueNamesMap: Map<string, { origin: string; value: string }> =
new Map();
imagesData?.data?.forEach((e) => {
e.repoTags?.forEach((f) => {
if (!uniqueNamesMap.has(f)) {
const nameObject = {
origin: e.device?.ip || 'unknown',
value: f,
};
uniqueNamesMap.set(f, nameObject);
} else {
const nameObject = {
origin: 'On multiple devices',
value: f,
};
uniqueNamesMap.set(f, nameObject);
}
});
});
setContextNames(Array.from(uniqueNamesMap.values()));
}

return [];
}, [form]);

useEffect(() => {
void extractContextNames(); // Extract names on mount
}, [form, extractContextNames]);

return (
<ProFormItem name={name} label={labelWithIcon}>
<AutoComplete
key={index}
options={contextNames.map((contextName) => ({
label: (
<Space>
<span role="img" aria-label={contextName.value as string}>
<Tag>{contextName.origin}</Tag>
</span>
{contextName.value}
</Space>
),
value: contextName.value,
}))}
onClick={() => extractContextNames()}
defaultValue={initialValue}
/>
</ProFormItem>
);
};
7 changes: 4 additions & 3 deletions server/src/controllers/rest/containers/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { SuccessResponse } from '../../../middlewares/api/ApiResponse';

export const getImages = async (req, res) => {
const realUrl = req.url;
const { current = 1, pageSize = 10 } = req.query;
const { current, pageSize } = req.query;
const params = parse(realUrl, true).query as unknown as API.PageParams &
API.ContainerVolume & {
sorter: any;
Expand All @@ -24,8 +24,9 @@ export const getImages = async (req, res) => {
['id', 'parentId', 'deviceUuid'],
);
const totalBeforePaginate = dataSource?.length || 0;
dataSource = paginate(dataSource, current as number, pageSize as number);

if (current && pageSize) {
dataSource = paginate(dataSource, current as number, pageSize as number);
}
new SuccessResponse('Got Images', dataSource, {
total: totalBeforePaginate,
success: true,
Expand Down
7 changes: 4 additions & 3 deletions server/src/controllers/rest/containers/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import PlaybookUseCases from '../../../services/PlaybookUseCases';

export const getNetworks = async (req, res) => {
const realUrl = req.url;
const { current = 1, pageSize = 10 } = req.query;
const { current, pageSize } = req.query;
const params = parse(realUrl, true).query as unknown as API.PageParams &
API.ContainerNetwork & {
sorter: any;
Expand All @@ -27,8 +27,9 @@ export const getNetworks = async (req, res) => {
['attachable', 'name', 'scope', 'driver', 'deviceUuid'],
);
const totalBeforePaginate = dataSource?.length || 0;
dataSource = paginate(dataSource, current as number, pageSize as number);

if (current && pageSize) {
dataSource = paginate(dataSource, current as number, pageSize as number);
}
new SuccessResponse('Got networks', dataSource, {
total: totalBeforePaginate,
success: true,
Expand Down
7 changes: 4 additions & 3 deletions server/src/controllers/rest/containers/volumes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import PlaybookUseCases from '../../../services/PlaybookUseCases';

export const getVolumes = async (req, res) => {
const realUrl = req.url;
const { current = 1, pageSize = 10 } = req.query;
const { current, pageSize } = req.query;
const params = parse(realUrl, true).query as unknown as API.PageParams &
API.ContainerVolume & {
sorter: any;
Expand All @@ -27,8 +27,9 @@ export const getVolumes = async (req, res) => {
['name', 'scope', 'driver', 'deviceUuid'],
);
const totalBeforePaginate = dataSource?.length || 0;
dataSource = paginate(dataSource, current as number, pageSize as number);

if (current && pageSize) {
dataSource = paginate(dataSource, current as number, pageSize as number);
}
new SuccessResponse('Got volumes', dataSource, {
total: totalBeforePaginate,
success: true,
Expand Down

0 comments on commit d16c6ee

Please sign in to comment.