Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚧 [WIP][NEW SIGNUP] Improve functionality #7229

Open
wants to merge 35 commits into
base: new-signup
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
106e4e2
Refactor core elements usage
brionmario Dec 9, 2024
33621f0
Introduce flow actions
brionmario Dec 9, 2024
5bf8cc6
Update element properties
brionmario Dec 12, 2024
356af7b
Update schema
brionmario Dec 12, 2024
48e8f50
Add button types
brionmario Dec 13, 2024
01a93fc
Fix Attribute property selection issue
brionmario Dec 13, 2024
8cffdc3
Add `OTPInputAdapter`
brionmario Dec 13, 2024
7ef3fd6
Update `payload.json`
brionmario Dec 13, 2024
964a0e5
Add sub flow
brionmario Dec 13, 2024
5229fe7
Add button handles
brionmario Dec 16, 2024
47a9891
Update data
brionmario Dec 16, 2024
73b97eb
Implement initial transformer
brionmario Dec 16, 2024
0342ae2
Improve the transformer
brionmario Dec 16, 2024
14b56d3
Initial transform logic
brionmario Dec 17, 2024
305671c
Update transforming logic
brionmario Dec 17, 2024
1f95a34
Update transforming logic
brionmario Dec 17, 2024
f189dc0
Update transforming logic
brionmario Dec 17, 2024
83350dd
Update transforming logic
brionmario Dec 17, 2024
cc4cd89
Update transforming logic
brionmario Dec 17, 2024
b354fa1
Minor fixes
brionmario Dec 17, 2024
9351c24
Fix action issues
brionmario Dec 18, 2024
c98620c
Update transform logic
brionmario Dec 18, 2024
d7bc549
Add complete to last node
brionmario Dec 18, 2024
2f44f54
Introduce `onFlowSubmit`
brionmario Dec 18, 2024
8d4e26d
Add `config` POST api
brionmario Dec 18, 2024
15498ba
Update flow based on actions
brionmario Dec 18, 2024
5de72f3
Handle possible spreading issues
brionmario Dec 18, 2024
ff29892
Update transformer
brionmario Dec 18, 2024
3f607eb
Fix button type selected state
brionmario Dec 18, 2024
f1d06c2
Minor updates
brionmario Dec 18, 2024
9607b19
Add support to add edges from outside
brionmario Dec 18, 2024
7b9937a
Update adapter styles
brionmario Dec 20, 2024
e1eb44e
Fix ESLint issues
brionmario Dec 20, 2024
8679089
Fix ESLint issues
brionmario Dec 20, 2024
d8b6445
Fix TS issue
brionmario Dec 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { RequestErrorInterface, RequestResultInterface } from "@wso2is/admin.core.v1/hooks/use-request";
import actions from "../data/actions.json";
import { Actions } from "../models/actions";

/**
* Hook to get the actions supported by the flow builder.
*
* This function calls the GET method of the following endpoint to get the elements.
* - TODO: Fill this
* For more details, refer to the documentation:
* {@link https://TODO:<fillthis>)}
*
* @returns SWR response object containing the data, error, isLoading, isValidating, mutate.
*/
const useGetFlowBuilderCoreActions = <Data = Actions, Error = RequestErrorInterface>(
_shouldFetch: boolean = true
): RequestResultInterface<Data, Error> => {
return {
data: (actions as unknown) as Data,
error: null,
isLoading: false,
isValidating: false,
mutate: () => null
};
};

export default useGetFlowBuilderCoreActions;
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,17 @@ import { IdentifiableComponentInterface } from "@wso2is/core/models";
import { DnDProvider } from "@wso2is/dnd";
import { ReactFlowProvider } from "@xyflow/react";
import classNames from "classnames";
import React, { FunctionComponent, HTMLAttributes, ReactElement } from "react";
import React, { FunctionComponent, ReactElement } from "react";
import ElementPanel from "./element-panel/element-panel";
import ElementPropertiesPanel from "./element-property-panel/element-property-panel";
import VisualFlow from "./visual-flow";
import VisualFlow, { VisualFlowPropsInterface } from "./visual-flow";
import useAuthenticationFlowBuilderCore from "../hooks/use-authentication-flow-builder-core-context";
import { Elements } from "../models/elements";


/**
* Props interface of {@link DecoratedVisualFlow}
*/
export interface DecoratedVisualFlowPropsInterface
extends IdentifiableComponentInterface,
HTMLAttributes<HTMLDivElement> {
/**
* Flow elements.
*/
elements: Elements;
}
export type DecoratedVisualFlowPropsInterface = VisualFlowPropsInterface & IdentifiableComponentInterface;

/**
* Component to decorate the visual flow editor with the necessary providers.
Expand All @@ -56,13 +49,12 @@ const DecoratedVisualFlow: FunctionComponent<DecoratedVisualFlowPropsInterface>
<div
className={ classNames("decorated-visual-flow", "react-flow-container", "visual-editor") }
data-componentid={ componentId }
{ ...rest }
>
<ReactFlowProvider>
<DnDProvider>
<ElementPanel elements={ elements } open={ isElementPanelOpen }>
<ElementPropertiesPanel open={ isElementPropertiesPanelOpen }>
<VisualFlow />
<VisualFlow elements={ elements } { ...rest } />
</ElementPropertiesPanel>
</ElementPanel>
</DnDProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@ export interface CommonComponentPropertyFactoryPropsInterface extends Identifiab
/**
* The event handler for the property change.
* @param propertyKey - The key of the property.
* @param previousValue - The previous value of the property.
* @param newValue - The new value of the property.
* @param element - The element associated with the property.
*/
onChange: (propertyKey: string, previousValue: any, newValue: any, element: Element) => void;
onChange: (propertyKey: string, newValue: any, element: Element) => void;
}

/**
Expand All @@ -74,10 +73,10 @@ const CommonComponentPropertyFactory: FunctionComponent<CommonComponentPropertyF
if (typeof propertyValue === "boolean") {
return (
<FormControlLabel
control={ <Checkbox /> }
control={ <Checkbox defaultChecked={ propertyValue } /> }
label={ startCase(propertyKey) }
onChange={ (e: ChangeEvent<HTMLInputElement>) =>
onChange(propertyKey, propertyValue, e.target.checked, element)
onChange(`config.field.${propertyKey}`, e.target.checked, element)
}
data-componentid={ `${componentId}-${propertyKey}` }
/>
Expand All @@ -91,7 +90,7 @@ const CommonComponentPropertyFactory: FunctionComponent<CommonComponentPropertyF
label={ startCase(propertyKey) }
defaultValue={ propertyValue }
onChange={ (e: ChangeEvent<HTMLInputElement>) =>
onChange(propertyKey, propertyValue, e.target.value, element)
onChange(`config.field.${propertyKey}`, e.target.value, element)
}
data-componentid={ `${componentId}-${propertyKey}` }
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ export interface CommonWidgetPropertyFactoryPropsInterface extends IdentifiableC
/**
* The event handler for the property change.
* @param propertyKey - The key of the property.
* @param previousValue - The previous value of the property.
* @param newValue - The new value of the property.
* @param element - The element associated with the property.
*/
onChange: (propertyKey: string, previousValue: any, newValue: any, element: Element) => void;
onChange: (propertyKey: string, newValue: any, element: Element) => void;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,50 @@
* under the License.
*/

import FormControl from "@oxygen-ui/react/FormControl";
import MenuItem from "@oxygen-ui/react/MenuItem";
import Select from "@oxygen-ui/react/Select";
import Stack from "@oxygen-ui/react/Stack";
import Typography from "@oxygen-ui/react/Typography";
import { IdentifiableComponentInterface } from "@wso2is/core/models";
import { useReactFlow } from "@xyflow/react";
import capitalize from "lodash-es/capitalize";
import isEmpty from "lodash-es/isEmpty";
import React, { ChangeEvent, FunctionComponent, HTMLAttributes, ReactElement } from "react";
import merge from "lodash-es/merge";
import set from "lodash-es/set";
import React, { FunctionComponent, ReactElement } from "react";
import useAuthenticationFlowBuilderCore from "../../hooks/use-authentication-flow-builder-core-context";
import { Base } from "../../models/base";
import { Properties } from "../../models/base";
import { Component } from "../../models/component";
import { Element } from "../../models/elements";

/**
* Props interface of {@link ElementProperties}
*/
export type ElementPropertiesPropsInterface = IdentifiableComponentInterface & HTMLAttributes<HTMLDivElement>;
export type CommonElementPropertiesPropsInterface = IdentifiableComponentInterface & {
properties?: Properties;
/**
* The element associated with the property.
*/
element: Element;
/**
* The event handler for the property change.
* @param propertyKey - The key of the property.
* @param newValue - The new value of the property.
* @param element - The element associated with the property.
*/
onChange: (propertyKey: string, newValue: any, element: Element) => void;
/**
* The event handler for the variant change.
* @param variant - The variant of the element.
*/
onVariantChange?: (variant: string) => void;
};

/**
* Component to generate the properties panel for the selected element.
*
* @param props - Props injected to the component.
* @returns The ElementProperties component.
*/
const ElementProperties: FunctionComponent<ElementPropertiesPropsInterface> = ({
"data-componentid": componentId = "element-properties",
...rest
}: ElementPropertiesPropsInterface): ReactElement => {
const ElementProperties: FunctionComponent<Partial<CommonElementPropertiesPropsInterface>> = ({
"data-componentid": componentId = "element-properties"
}: Partial<CommonElementPropertiesPropsInterface>): ReactElement => {
const { updateNodeData } = useReactFlow();
const {
lastInteractedElement,
Expand All @@ -54,8 +68,6 @@ const ElementProperties: FunctionComponent<ElementPropertiesPropsInterface> = ({
lastInteractedNodeId
} = useAuthenticationFlowBuilderCore();

const hasVariants: boolean = !isEmpty(lastInteractedElement?.variants);

const changeSelectedVariant = (selected: string) => {
const selectedVariant: Component = lastInteractedElement?.variants?.find(
(element: Component) => element.variant === selected
Expand All @@ -64,31 +76,25 @@ const ElementProperties: FunctionComponent<ElementPropertiesPropsInterface> = ({
updateNodeData(lastInteractedNodeId, (node: any) => {
const components: Component = node?.data?.components?.map((component: any) => {
if (component.id === lastInteractedElement.id) {
return {
...component,
...selectedVariant
};
return merge(component, selectedVariant);
}

return component;
});

setLastInteractedElement({
...lastInteractedElement,
...selectedVariant
});
setLastInteractedElement(merge(lastInteractedElement, selectedVariant));

return {
components
};
});
};

const handlePropertyChange = (propertyKey: string, previousValue: any, newValue: any, element: Element) => {
const handlePropertyChange = (propertyKey: string, newValue: any, element: Element) => {
updateNodeData(lastInteractedNodeId, (node: any) => {
const components: Component = node?.data?.components?.map((component: any) => {
if (component.id === element.id) {
component.config.field[propertyKey] = newValue;
set(component, propertyKey, newValue);
}

return component;
Expand All @@ -101,33 +107,15 @@ const ElementProperties: FunctionComponent<ElementPropertiesPropsInterface> = ({
};

return (
<div className="flow-builder-element-properties" data-componentid={ componentId } { ...rest }>
<div className="flow-builder-element-properties" data-componentid={ componentId }>
{ lastInteractedElement ? (
<Stack gap={ 1 }>
{ hasVariants && (
<FormControl size="small" variant="outlined">
<Select
labelId={ `${lastInteractedElement?.variant}-variants` }
id={ `${lastInteractedElement?.variant}-variants` }
value={ lastInteractedElement?.variant }
label="variant"
onChange={ (e: ChangeEvent<HTMLInputElement>) =>
changeSelectedVariant(e.target.value as string)
}
>
{ lastInteractedElement?.variants?.map((element: Base) => (
<MenuItem key={ element?.variant } value={ element?.variant }>
{ capitalize(element?.display?.label) }
</MenuItem>
)) }
</Select>
</FormControl>
) }
{ lastInteractedElement && (
<ElementProperties
element={ lastInteractedElement }
properties={ lastInteractedElement?.config?.field }
onChange={ handlePropertyChange }
onVariantChange={ changeSelectedVariant }
/>
) }
</Stack>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

.social-button.oxygen-button {
background: var(--oxygen-palette-common-white);
color: var(--oxygen-palette-common-black);
width: 100%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 0 1px 0 rgba(0, 0, 0, .12), 0 1px 1px 0 rgba(0, 0, 0, .24);

&:hover {
color: rgba(0, 0, 0, .8);
}

.oxygen-sign-in-option-image {
height: 20px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

import Button, { ButtonProps } from "@oxygen-ui/react/Button";
import { IdentifiableComponentInterface } from "@wso2is/core/models";
import { Handle, Position } from "@xyflow/react";
import React, { FunctionComponent, ReactElement } from "react";
import ButtonAdapterConstants from "../../../../constants/button-adapter-constants";
import { ButtonVariants, Component } from "../../../../models/component";
import "./button-adapter.scss";

/**
* Props interface of {@link ButtonAdapter}
Expand Down Expand Up @@ -50,25 +53,47 @@ export const ButtonAdapter: FunctionComponent<ButtonAdapterPropsInterface> = ({
config = {
...config,
color: "primary",
fullWidth: true,
variant: "contained"
};
} else if (node.variant === ButtonVariants.Secondary) {
config = {
...config,
color: "secondary",
fullWidth: true,
variant: "contained"
};
} else if (node.variant === ButtonVariants.Text) {
config = {
...config,
fullWidth: true,
variant: "text"
};
} else if (node.variant === ButtonVariants.Social) {
config = {
...config,
className: "social-button",
fullWidth: true,
variant: "contained"
};
}

return (
<Button sx={ node?.variants?.[0]?.config.styles } { ...config }>
{ node?.variants?.[0]?.config?.field?.text }
</Button>
<div className="adapter button-adapter">
<Handle
id={ `${node?.id}${ButtonAdapterConstants.PREVIOUS_BUTTON_HANDLE_SUFFIX}` }
type="source"
position={ Position.Left }
/>
<Button startIcon={ <img src={ node?.display?.image } /> } sx={ node?.config.styles } { ...config }>
{ node?.variants?.[0]?.config?.field?.text }
</Button>
<Handle
id={ `${node?.id}${ButtonAdapterConstants.NEXT_BUTTON_HANDLE_SUFFIX}` }
type="source"
position={ Position.Right }
/>
</div>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ export const DefaultInputAdapter: FunctionComponent<DefaultInputAdapterPropsInte
multiline={ node.config?.field?.multiline }
placeholder={ node.config?.field?.placeholder || "" }
required={ node.config?.field?.required }
InputLabelProps={ {
required: node.config?.field?.required
} }
type={ node.config?.field?.type }
style={ node.config?.styles }
/>
Expand Down
Loading
Loading