1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-09 15:55:23 +02:00

refactor(settings): migrate hidden containers panel to react [EE-5507] (#9119)

This commit is contained in:
Chaim Lev-Ari 2023-07-10 03:39:11 +07:00 committed by GitHub
parent eefb4c4287
commit 8b11e1678e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 230 additions and 139 deletions

View file

@ -0,0 +1,70 @@
import { Formik, Form, Field } from 'formik';
import { Plus } from 'lucide-react';
import { SchemaOf, object, string } from 'yup';
import { useReducer } from 'react';
import { Button } from '@@/buttons';
import { FormControl } from '@@/form-components/FormControl';
import { Input } from '@@/form-components/Input';
export function AddLabelForm({
onSubmit,
isLoading,
}: {
onSubmit: (name: string, value: string) => void;
isLoading: boolean;
}) {
const [formKey, clearForm] = useReducer((state) => state + 1, 0);
const initialValues = {
name: '',
value: '',
};
return (
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={validation}
key={formKey}
>
{({ errors, isValid, dirty }) => (
<Form className="form-horizontal">
<div className="flex w-full items-start gap-4">
<FormControl label="Name" errors={errors.name} className="flex-1">
<Field
as={Input}
name="name"
placeholder="e.g. com.example.foo"
/>
</FormControl>
<FormControl label="Value" errors={errors.value} className="flex-1">
<Field as={Input} name="value" placeholder="e.g. bar" />
</FormControl>
<Button
type="submit"
icon={Plus}
disabled={!dirty || !isValid || isLoading}
>
Add filter
</Button>
</div>
</Form>
)}
</Formik>
);
function handleSubmit(values: typeof initialValues) {
clearForm();
onSubmit(values.name, values.value);
}
}
function validation(): SchemaOf<{ name: string; value: string }> {
return object({
name: string().required('Name is required'),
value: string().default(''),
});
}

View file

@ -0,0 +1,68 @@
import { Box } from 'lucide-react';
import { notifySuccess } from '@/portainer/services/notifications';
import { TextTip } from '@@/Tip/TextTip';
import { Widget } from '@@/Widget';
import { useSettings, useUpdateSettingsMutation } from '../../queries';
import { Pair } from '../../types';
import { AddLabelForm } from './AddLabelForm';
import { HiddenContainersTable } from './HiddenContainersTable';
export function HiddenContainersPanel() {
const settingsQuery = useSettings((settings) => settings.BlackListedLabels);
const mutation = useUpdateSettingsMutation();
if (!settingsQuery.data) {
return null;
}
const labels = settingsQuery.data;
return (
<div className="row">
<div className="col-sm-12">
<Widget>
<Widget.Title icon={Box} title="Hidden containers" />
<Widget.Body>
<div className="mb-3">
<TextTip color="blue">
You can hide containers with specific labels from Portainer UI.
You need to specify the label name and value.
</TextTip>
</div>
<AddLabelForm
isLoading={mutation.isLoading}
onSubmit={(name, value) =>
handleSubmit([...labels, { name, value }])
}
/>
<HiddenContainersTable
labels={labels}
isLoading={mutation.isLoading}
onDelete={(name) =>
handleSubmit(labels.filter((label) => label.name !== name))
}
/>
</Widget.Body>
</Widget>
</div>
</div>
);
function handleSubmit(labels: Pair[]) {
mutation.mutate(
{
BlackListedLabels: labels,
},
{
onSuccess: () => {
notifySuccess('Success', 'Hidden container settings updated');
},
}
);
}
}

View file

@ -0,0 +1,44 @@
import { Trash2 } from 'lucide-react';
import { DetailsTable } from '@@/DetailsTable';
import { Button } from '@@/buttons';
import { Pair } from '../../types';
export function HiddenContainersTable({
labels,
isLoading,
onDelete,
}: {
labels: Pair[];
isLoading: boolean;
onDelete: (name: string) => void;
}) {
return (
<DetailsTable
headers={['Name', 'Value', '']}
className="table-hover"
emptyMessage="No filter available."
>
{labels.map((label, index) => (
<DetailsTable.Row
key={index}
label={label.name}
columns={[
<Button
color="danger"
size="xsmall"
icon={Trash2}
onClick={() => onDelete(label.name)}
disabled={isLoading}
>
Remove
</Button>,
]}
>
{label.value}
</DetailsTable.Row>
))}
</DetailsTable>
);
}