1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-05 13:55:21 +02:00

fix(container): fix various creating container issues EE-6287 (#10595)

* fix(container): show placeholder for image field EE-6287

* fix(container): correct query params for search button field EE-6287

* fix(container): use btoa to encode registry credential EE-6287

* fix(container): allow creating non-existing option EE-6287

* fix(ui/forms): typeahead component

* fix(container): select the default registry EE-6287

* fix(container): always enable deploy button when always pull is off EE-6287

* fix(container): reset command fields outside current event to avoid validation on broken values EE-6287

* fix(container): query registry with endpoint ID param EE-6287

---------

Co-authored-by: Chaim Lev-Ari <chaim.levi-ari@portainer.io>
This commit is contained in:
cmeng 2023-11-16 08:50:23 +13:00 committed by GitHub
parent e43d076269
commit d089dfbca0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 190 additions and 137 deletions

View file

@ -63,6 +63,7 @@ export function ComposePathField({
onChange={onChange}
placeholder={isCompose ? 'docker-compose.yml' : 'manifest.yml'}
model={model}
inputId="stack_repository_path"
/>
) : (
<Input
@ -71,6 +72,7 @@ export function ComposePathField({
updateInputValue(e.target.value);
}}
placeholder={isCompose ? 'docker-compose.yml' : 'manifest.yml'}
id="stack_repository_path"
/>
)}
</FormControl>

View file

@ -1,19 +0,0 @@
.root [data-reach-combobox-popover] {
border-radius: 5px;
border: 1px solid var(--border-form-control-color);
background-color: var(--bg-dropdown-menu-color);
color: var(--text-form-control-color);
z-index: 9999;
}
.root [data-reach-combobox-option]:hover {
background-color: var(--bg-dropdown-hover);
}
.root [data-suggested-value] {
font-weight: normal;
}
.root [data-user-value] {
font-weight: bold;
}

View file

@ -1,22 +1,10 @@
import { ChangeEvent } from 'react';
import {
Combobox,
ComboboxInput,
ComboboxList,
ComboboxOption,
ComboboxPopover,
} from '@reach/combobox';
import '@reach/combobox/styles.css';
import clsx from 'clsx';
import { useSearch } from '@/react/portainer/gitops/queries/useSearch';
import { useDebounce } from '@/react/hooks/useDebounce';
import { AutocompleteSelect } from '@@/form-components/AutocompleteSelect';
import { getAuthentication } from '../utils';
import { GitFormModel } from '../types';
import styles from './PathSelector.module.css';
export function PathSelector({
value,
onChange,
@ -24,6 +12,7 @@ export function PathSelector({
model,
dirOnly,
readOnly,
inputId,
}: {
value: string;
onChange(value: string): void;
@ -31,62 +20,33 @@ export function PathSelector({
model: GitFormModel;
dirOnly?: boolean;
readOnly?: boolean;
inputId: string;
}) {
const [searchTerm, setSearchTerm] = useDebounce(value, onChange);
const creds = getAuthentication(model);
const payload = {
repository: model.RepositoryURL,
keyword: searchTerm,
keyword: value,
reference: model.RepositoryReferenceName,
tlsSkipVerify: model.TLSSkipVerify,
dirOnly,
...creds,
};
const enabled = Boolean(
model.RepositoryURL && model.RepositoryURLValid && searchTerm
model.RepositoryURL && model.RepositoryURLValid && value
);
const { data: searchResults } = useSearch(payload, enabled);
return (
<Combobox
className={styles.root}
aria-label="compose"
onSelect={onSelect}
data-cy="component-gitComposeInput"
>
<ComboboxInput
value={searchTerm}
className="form-control"
onChange={handleChange}
placeholder={placeholder}
readOnly={readOnly}
/>
{searchResults && searchResults.length > 0 && (
<ComboboxPopover>
<ComboboxList>
{searchResults.map((result: string, index: number) => (
<ComboboxOption
key={index}
value={result}
className={clsx(
`[&[aria-selected="true"]]:th-highcontrast:!bg-black [&[aria-selected="true"]]:th-dark:!bg-black`,
`hover:th-highcontrast:!bg-black hover:th-dark:!bg-black`,
'th-highcontrast:bg-gray-10 th-dark:bg-gray-10 '
)}
/>
))}
</ComboboxList>
</ComboboxPopover>
)}
</Combobox>
<AutocompleteSelect
searchResults={searchResults?.map((result) => ({
value: result,
label: result,
}))}
value={value}
onChange={onChange}
placeholder={placeholder}
readOnly={readOnly}
inputId={inputId}
/>
);
function handleChange(e: ChangeEvent<HTMLInputElement>) {
setSearchTerm(e.target.value);
}
function onSelect(value: string) {
onChange(value);
}
}

View file

@ -16,14 +16,14 @@ interface Props {
value: RelativePathModel;
gitModel?: GitFormModel;
onChange?: (value: Partial<RelativePathModel>) => void;
readonly?: boolean;
isEditing?: boolean;
}
export function RelativePathFieldset({
value,
gitModel,
onChange,
readonly,
isEditing,
}: Props) {
const innerOnChange = useCallback(
(value: Partial<RelativePathModel>) => onChange && onChange(value),
@ -41,7 +41,7 @@ export function RelativePathFieldset({
label="Enable relative path volumes"
labelClass="col-sm-3 col-lg-2"
tooltip="Enabling this means you can specify relative path volumes in your Compose files, with Portainer pulling the content from your git repository to the environment the stack is deployed to."
disabled={readonly}
disabled={isEditing}
checked={value.SupportRelativePath}
onChange={(value) => innerOnChange({ SupportRelativePath: value })}
/>
@ -68,7 +68,7 @@ export function RelativePathFieldset({
<Input
name="FilesystemPath"
placeholder="/mnt"
disabled={readonly}
disabled={isEditing}
value={value.FilesystemPath}
onChange={(e) =>
innerOnChange({ FilesystemPath: e.target.value })
@ -94,7 +94,7 @@ export function RelativePathFieldset({
label="GitOps Edge configurations"
labelClass="col-sm-3 col-lg-2"
tooltip="By enabling the GitOps Edge Configurations feature, you gain the ability to define relative path volumes in your configuration files. Portainer will then automatically fetch the content from your git repository by matching the folder name or file name with the Portainer Edge ID, and apply it to the environment where the stack is deployed"
disabled={readonly}
disabled={isEditing}
checked={!!value.SupportPerDeviceConfigs}
onChange={(value) =>
innerOnChange({ SupportPerDeviceConfigs: value })
@ -120,6 +120,7 @@ export function RelativePathFieldset({
<FormControl
label="Directory"
errors={errors.PerDeviceConfigsPath}
inputId="per_device_configs_path_input"
>
<PathSelector
value={value.PerDeviceConfigsPath || ''}
@ -128,8 +129,9 @@ export function RelativePathFieldset({
}
placeholder="config"
model={gitModel || dummyGitForm}
readOnly={readonly}
readOnly={isEditing}
dirOnly
inputId="per_device_configs_path_input"
/>
</FormControl>
</div>
@ -174,7 +176,7 @@ export function RelativePathFieldset({
value: 'dir',
},
]}
disabled={readonly}
disabled={isEditing}
/>
</FormControl>
</div>
@ -205,7 +207,7 @@ export function RelativePathFieldset({
value: 'dir',
},
]}
disabled={readonly}
disabled={isEditing}
/>
</FormControl>
</div>

View file

@ -3,29 +3,18 @@ import angular from 'angular';
import { r2a } from '@/react-tools/react2angular';
import { withUIRouter } from '@/react-tools/withUIRouter';
import { withReactQuery } from '@/react-tools/withReactQuery';
import { PathSelector } from '@/react/portainer/gitops/ComposePathField/PathSelector';
import { RelativePathFieldset } from '@/react/portainer/gitops/RelativePathFieldset/RelativePathFieldset';
export const ngModule = angular
.module('portainer.app.react.gitops', [])
.component(
'pathSelector',
r2a(withUIRouter(withReactQuery(PathSelector)), [
'value',
'onChange',
'placeholder',
'model',
'dirOnly',
'readOnly',
])
)
.component(
'relativePathFieldset',
r2a(withUIRouter(withReactQuery(RelativePathFieldset)), [
'value',
'gitModel',
'onChange',
'readonly',
'isEditing',
])
);