feat(microk8s): BE teasers in wizard [EE-4772] (#8449)

* feat(microk8s): separate existing/new envs EE-4772

update icons

fix be teaser box selector style

* match environment wizard box selectors

* revert title back

* updated kaas description in wizard

---------

Co-authored-by: testa113 <testa113>
Co-authored-by: Prabhat Khera <prabhat.khera@portainer.io>
pull/8591/head
Ali 2023-03-03 12:27:24 +13:00 committed by GitHub
parent d032119ebc
commit 769c8372fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 124 additions and 49 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB

4
app/assets/ico/vendor/kaas-icon.svg vendored Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -14,6 +14,7 @@ const BoxSelectorReact = react2angular(BoxSelector, [
'options',
'radioName',
'slim',
'hiddenSpacingCount',
]);
export const boxSelectorModule = angular

View File

@ -20,12 +20,14 @@ export type Props<T extends Value> = Union<T> & {
radioName: string;
options: ReadonlyArray<BoxSelectorOption<T>> | Array<BoxSelectorOption<T>>;
slim?: boolean;
hiddenSpacingCount?: number;
};
export function BoxSelector<T extends Value>({
radioName,
options,
slim = false,
hiddenSpacingCount,
...props
}: Props<T>) {
return (
@ -47,6 +49,10 @@ export function BoxSelector<T extends Value>({
slim={slim}
/>
))}
{hiddenSpacingCount &&
Array.from(Array(hiddenSpacingCount)).map((_, index) => (
<div key={index} className="flex-1" />
))}
</div>
</div>
</div>

View File

@ -8,19 +8,21 @@ import { useAnalytics } from '@/angulartics.matomo/analytics-services';
import { Button } from '@@/buttons';
import { PageHeader } from '@@/PageHeader';
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
import { FormSection } from '@@/form-components/FormSection';
import { useCreateEdgeDeviceParam } from '../hooks/useCreateEdgeDeviceParam';
import { EnvironmentSelector } from './EnvironmentSelector';
import {
EnvironmentSelector,
EnvironmentSelectorValue,
} from './EnvironmentSelector';
import { environmentTypes } from './environment-types';
EnvironmentOptionValue,
existingEnvironmentTypes,
newEnvironmentTypes,
} from './environment-types';
export function EnvironmentTypeSelectView() {
const createEdgeDevice = useCreateEdgeDeviceParam();
const [types, setTypes] = useState<EnvironmentSelectorValue[]>([]);
const [types, setTypes] = useState<EnvironmentOptionValue[]>([]);
const { trackEvent } = useAnalytics();
const router = useRouter();
@ -36,11 +38,34 @@ export function EnvironmentTypeSelectView() {
<Widget>
<WidgetTitle icon={Wand2} title="Environment Wizard" />
<WidgetBody>
<EnvironmentSelector
value={types}
onChange={setTypes}
createEdgeDevice={createEdgeDevice}
/>
<div className="form-horizontal">
<FormSection title="Select your environment(s)">
<p className="text-muted small">
You can onboard different types of environments, select all
that apply.
</p>
<p className="control-label !mb-2">
Connect to existing environments
</p>
<EnvironmentSelector
value={types}
onChange={setTypes}
createEdgeDevice={createEdgeDevice}
options={existingEnvironmentTypes}
/>
<p className="control-label !mb-2">Set up new environments</p>
<EnvironmentSelector
value={types}
onChange={setTypes}
createEdgeDevice={createEdgeDevice}
options={newEnvironmentTypes}
hiddenSpacingCount={
existingEnvironmentTypes.length -
newEnvironmentTypes.length
}
/>
</FormSection>
</div>
<Button
disabled={types.length === 0}
onClick={() => startWizard()}
@ -59,6 +84,11 @@ export function EnvironmentTypeSelectView() {
return;
}
const environmentTypes = [
...existingEnvironmentTypes,
...newEnvironmentTypes,
];
const steps = _.compact(
types.map((id) => environmentTypes.find((eType) => eType.id === id))
);

View File

@ -1,17 +1,16 @@
import { BoxSelector } from '@@/BoxSelector';
import { FormSection } from '@@/form-components/FormSection';
import { environmentTypes } from './environment-types';
export type EnvironmentSelectorValue = typeof environmentTypes[number]['id'];
import { EnvironmentOption, EnvironmentOptionValue } from './environment-types';
interface Props {
value: EnvironmentSelectorValue[];
onChange(value: EnvironmentSelectorValue[]): void;
value: EnvironmentOptionValue[];
onChange(value: EnvironmentOptionValue[]): void;
options: EnvironmentOption[];
createEdgeDevice?: boolean;
hiddenSpacingCount?: number;
}
const hasEdge: EnvironmentSelectorValue[] = [
const hasEdge: EnvironmentOptionValue[] = [
'dockerStandalone',
'dockerSwarm',
'kubernetes',
@ -21,31 +20,25 @@ export function EnvironmentSelector({
value,
onChange,
createEdgeDevice,
options,
hiddenSpacingCount,
}: Props) {
const options = filterEdgeDevicesIfNeed(environmentTypes, createEdgeDevice);
const filteredOptions = filterEdgeDevicesIfNeed(options, createEdgeDevice);
return (
<div className="form-horizontal">
<FormSection title="Select your environment(s)">
<p className="text-muted small">
You can onboard different types of environments, select all that
apply.
</p>
<BoxSelector
options={options}
isMulti
value={value}
onChange={onChange}
radioName="type-selector"
/>
</FormSection>
</div>
<BoxSelector
options={filteredOptions}
isMulti
value={value}
onChange={onChange}
radioName="type-selector"
hiddenSpacingCount={hiddenSpacingCount}
/>
);
}
function filterEdgeDevicesIfNeed(
types: typeof environmentTypes,
types: EnvironmentOption[],
createEdgeDevice?: boolean
) {
if (!createEdgeDevice) {

View File

@ -3,10 +3,27 @@ import Docker from '@/assets/ico/vendor/docker.svg?c';
import Kubernetes from '@/assets/ico/vendor/kubernetes.svg?c';
import Azure from '@/assets/ico/vendor/azure.svg?c';
import Nomad from '@/assets/ico/vendor/nomad.svg?c';
import KaaS from '@/assets/ico/vendor/kaas-icon.svg?c';
import InstallK8s from '@/assets/ico/vendor/install-kubernetes.svg?c';
import KaaSIcon from './kaas-icon.svg?c';
import { BoxSelectorOption } from '@@/BoxSelector';
export const environmentTypes = [
export type EnvironmentOptionValue =
| 'dockerStandalone'
| 'dockerSwarm'
| 'kubernetes'
| 'aci'
| 'nomad'
| 'kaas'
| 'k8sInstall';
export interface EnvironmentOption
extends BoxSelectorOption<EnvironmentOptionValue> {
id: EnvironmentOptionValue;
value: EnvironmentOptionValue;
}
export const existingEnvironmentTypes: EnvironmentOption[] = [
{
id: 'dockerStandalone',
value: 'dockerStandalone',
@ -49,23 +66,43 @@ export const environmentTypes = [
feature: FeatureId.NOMAD,
disabledWhenLimited: true,
},
];
export const newEnvironmentTypes: EnvironmentOption[] = [
{
id: 'kaas',
value: 'kaas',
label: 'KaaS',
description: 'Provision a Kubernetes environment with a cloud provider',
icon: KaaSIcon,
label: 'Provision KaaS Cluster',
description:
"Provision a Kubernetes cluster via a cloud provider's Kubernetes as a Service",
icon: KaaS,
iconType: 'logo',
feature: FeatureId.KAAS_PROVISIONING,
disabledWhenLimited: true,
},
] as const;
{
id: 'k8sInstall',
value: 'k8sInstall',
label: 'Create Kubernetes cluster',
description: 'Create a Kubernetes cluster on existing infrastructure',
icon: InstallK8s,
iconType: 'logo',
feature: FeatureId.K8SINSTALL,
disabledWhenLimited: true,
},
];
export const formTitles = {
export const environmentTypes = [
...existingEnvironmentTypes,
...newEnvironmentTypes,
];
export const formTitles: Record<EnvironmentOptionValue, string> = {
dockerStandalone: 'Connect to your Docker Standalone environment',
dockerSwarm: 'Connect to your Docker Swarm environment',
kubernetes: 'Connect to your Kubernetes environment',
aci: 'Connect to your ACI environment',
nomad: 'Connect to your Nomad environment',
kaas: 'Provision a KaaS environment',
k8sInstall: 'Create a Kubernetes cluster',
};

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -19,10 +19,10 @@ import { FormSection } from '@@/form-components/FormSection';
import { Icon } from '@@/Icon';
import {
EnvironmentOptionValue,
environmentTypes,
formTitles,
} from '../EnvironmentTypeSelectView/environment-types';
import { EnvironmentSelectorValue } from '../EnvironmentTypeSelectView/EnvironmentSelector';
import { WizardDocker } from './WizardDocker';
import { WizardAzure } from './WizardAzure';
@ -138,7 +138,7 @@ export function EnvironmentCreationView() {
}
}
function useParamEnvironmentTypes(): EnvironmentSelectorValue[] {
function useParamEnvironmentTypes(): EnvironmentOptionValue[] {
const {
params: { envType },
} = useCurrentStateAndParams();
@ -185,7 +185,7 @@ function useStepper(
setCurrentStepIndex(currentStepIndex - 1);
}
function getComponent(id: EnvironmentSelectorValue) {
function getComponent(id: EnvironmentOptionValue) {
switch (id) {
case 'dockerStandalone':
case 'dockerSwarm':

View File

@ -38,5 +38,6 @@ export enum FeatureId {
ENFORCE_DEPLOYMENT_OPTIONS = 'k8s-enforce-deployment-options',
K8S_ADM_ONLY_USR_INGRESS_DEPLY = 'k8s-admin-only-ingress-deploy',
K8S_ROLLING_RESTART = 'k8s-rolling-restart',
K8SINSTALL = 'k8s-install',
K8S_ANNOTATIONS = 'k8s-annotations',
}

View File

@ -19,6 +19,7 @@ export async function init(edition: Edition) {
[FeatureId.K8S_RESOURCE_POOL_STORAGE_QUOTA]: Edition.BE,
[FeatureId.K8S_CREATE_FROM_KUBECONFIG]: Edition.BE,
[FeatureId.KAAS_PROVISIONING]: Edition.BE,
[FeatureId.K8SINSTALL]: Edition.BE,
[FeatureId.NOMAD]: Edition.BE,
[FeatureId.ACTIVITY_AUDIT]: Edition.BE,
[FeatureId.EXTERNAL_AUTH_LDAP]: Edition.BE,