import { useState } from 'react';
import { FormikErrors } from 'formik';
import {
PathSelector,
PathSelectorGitModel,
} from '@/react/portainer/gitops/ComposePathField/PathSelector';
import { dummyGitForm } from '@/react/portainer/gitops/RelativePathFieldset/utils';
import { SwitchField } from '@@/form-components/SwitchField';
import { TextTip } from '@@/Tip/TextTip';
import { FormControl } from '@@/form-components/FormControl';
import { Input, Select } from '@@/form-components/Input';
import { useDocsUrl } from '@@/PageHeader/ContextHelp';
import { InsightsBox } from '@@/InsightsBox';
import { RelativePathModel, getPerDevConfigsFilterType } from './types';
interface Props {
values: RelativePathModel;
gitModel?: PathSelectorGitModel;
onChange: (value: RelativePathModel) => void;
isEditing?: boolean;
hideEdgeConfigs?: boolean;
errors?: FormikErrors;
}
export function RelativePathFieldset({
values: value,
gitModel,
onChange = () => {},
isEditing,
hideEdgeConfigs,
errors,
}: Props) {
const [relativePathManuallyEnabled, setRelativePathManuallyEnabled] =
useState(value.SupportRelativePath);
const [relativePathForcedEnabled, setRelativePathForcedEnabled] = useState(
value.SupportPerDeviceConfigs
);
const gitoptsEdgeConfigDocUrl = useDocsUrl(
'/user/edge/stacks/add#gitops-edge-configurations'
);
const pathTipSwarm =
'For relative path volumes use with Docker Swarm, you must have a network filesystem which all of your nodes can access.';
const pathTipGitopsActive =
'GitOps Edge configurations is active. When you set the ‘local filesystem path’, it will also be utilized for relative paths.';
return (
<>
{
setRelativePathManuallyEnabled(value);
handleChange({ SupportRelativePath: value });
}}
/>
{value.SupportRelativePath && (
<>
{relativePathForcedEnabled ? pathTipGitopsActive : pathTipSwarm}
{(!relativePathForcedEnabled || hideEdgeConfigs) && (
)}
>
)}
{!hideEdgeConfigs && (
<>
When enabled, corresponding Edge ID will be passed through as an
environment variable: PORTAINER_EDGE_ID.
{
setRelativePathForcedEnabled(v);
handleChange({
SupportPerDeviceConfigs: v,
SupportRelativePath: v ? true : relativePathManuallyEnabled,
});
}}
/>
{value.SupportPerDeviceConfigs && (
<>
Files named ${PORTAINER_EDGE_ID}.env{' '}
and/or ${PORTAINER_EDGE_GROUP}.env{' '}
contained by the config folder will be loaded for compose
file interpolation.
}
header="GitOps Edge Configurations"
insightCloseId="edge-config-interpolation-info"
className="mb-3"
/>
Specify the directory name where your configuration will be
located. This will allow you to manage device configuration
settings with a Git repo as your template.
handleChange({ PerDeviceConfigsPath: value })
}
placeholder="config"
model={gitModel || dummyGitForm}
readOnly={isEditing}
dirOnly
inputId="per_device_configs_path_input"
/>
Select which rule to use when matching configuration with
Portainer Edge ID either on a per-device basis or group-wide
with an Edge Group. Only configurations that match the
selected rule will be accessible through their corresponding
paths. Deployments that rely on accessing the configuration
may experience errors.
handleChange({
PerDeviceConfigsMatchType: getPerDevConfigsFilterType(
e.target.value
),
})
}
options={[
{
label: '',
value: '',
},
{
label: 'Match file name with Portainer Edge ID',
value: 'file',
},
{
label: 'Match folder name with Portainer Edge ID',
value: 'dir',
},
]}
disabled={isEditing}
/>
handleChange({
PerDeviceConfigsGroupMatchType:
getPerDevConfigsFilterType(e.target.value),
})
}
options={[
{
label: '',
value: '',
},
{
label: 'Match file name with Edge Group',
value: 'file',
},
{
label: 'Match folder name with Edge Group',
value: 'dir',
},
]}
disabled={isEditing}
/>
You can use it as an environment variable with an image:{' '}
myapp:${PORTAINER_EDGE_ID} or{' '}
myapp:${PORTAINER_EDGE_GROUP}. You
can also use it with the relative path for volumes:{' '}
./config/${PORTAINER_EDGE_ID}:/myapp/config
{' '}
or{' '}
./config/${PORTAINER_EDGE_GROUP}:/myapp/groupconfig
. More documentation can be found{' '}
here .
>
)}
>
)}
>
);
function handleChange(newValue: Partial) {
onChange({ ...value, ...newValue });
}
}