Skip to content

Commit

Permalink
feat: use unique identifier for actions (#366)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpilch authored and alharris-at committed Feb 25, 2022
1 parent 9d978bf commit bbddbb5
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function CreateCustomerButton(
props: CreateCustomerButtonProps
): React.ReactElement {
const { overrides, ...rest } = props;
const action = useDataStoreCreateAction({
const createCustomerButtonClick = useDataStoreCreateAction({
model: Customer,
fields: { firstName: \\"Din\\", lastName: \\"Djarin\\" },
});
Expand All @@ -30,7 +30,7 @@ export default function CreateCustomerButton(
<Button
children=\\"Create\\"
onClick={() => {
action.run();
createCustomerButtonClick.run();
}}
{...rest}
{...getOverrideProps(overrides, \\"CreateCustomerButton\\")}
Expand Down Expand Up @@ -64,7 +64,7 @@ export default function DeleteCustomerButton(
props: DeleteCustomerButtonProps
): React.ReactElement {
const { overrides, ...rest } = props;
const action = useDataStoreDeleteAction({
const deleteCustomerButtonClick = useDataStoreDeleteAction({
model: Customer,
id: \\"d9887268-47dd-4899-9568-db5809218751\\",
});
Expand All @@ -73,7 +73,7 @@ export default function DeleteCustomerButton(
<Button
children=\\"Delete\\"
onClick={() => {
action.run();
deleteCustomerButtonClick.run();
}}
{...rest}
{...getOverrideProps(overrides, \\"DeleteCustomerButton\\")}
Expand Down Expand Up @@ -107,7 +107,7 @@ export default function UpdateCustomerButton(
props: UpdateCustomerButtonProps
): React.ReactElement {
const { overrides, ...rest } = props;
const action = useDataStoreUpdateAction({
const updateCustomerButtonClick = useDataStoreUpdateAction({
model: Customer,
id: \\"d9887268-47dd-4899-9568-db5809218751\\",
fields: { firstName: \\"Din\\", lastName: \\"Djarin\\" },
Expand All @@ -117,7 +117,7 @@ export default function UpdateCustomerButton(
<Button
children=\\"Update\\"
onClick={() => {
action.run();
updateCustomerButtonClick.run();
}}
{...rest}
{...getOverrideProps(overrides, \\"UpdateCustomerButton\\")}
Expand Down Expand Up @@ -150,13 +150,13 @@ export default function SignOutButton(
props: SignOutButtonProps
): React.ReactElement {
const { overrides, ...rest } = props;
const action = useAuthSignOutAction({ global: false });
const signOutButtonClick = useAuthSignOutAction({ global: false });
return (
/* @ts-ignore: TS2322 */
<Button
children=\\"Sign out\\"
onClick={() => {
action.run();
signOutButtonClick.run();
}}
{...rest}
{...getOverrideProps(overrides, \\"SignOutButton\\")}
Expand Down Expand Up @@ -189,15 +189,15 @@ export default function UpdateUserAttributeButton(
props: UpdateUserAttributeButtonProps
): React.ReactElement {
const { overrides, ...rest } = props;
const action = updateUserAttributesAction({
const updateUserAttributeButtonClick = updateUserAttributesAction({
attributes: { email: \\"newemail@domain.com\\", displayname: \\"newdisplayname\\" },
});
return (
/* @ts-ignore: TS2322 */
<Button
children=\\"Sign out\\"
onClick={() => {
action.run();
updateUserAttributeButtonClick.run();
}}
{...rest}
{...getOverrideProps(overrides, \\"UpdateUserAttributeButton\\")}
Expand Down Expand Up @@ -230,13 +230,16 @@ export default function NavigateButton(
props: NavigateButtonProps
): React.ReactElement {
const { overrides, ...rest } = props;
const action = useNavigateAction({ type: \\"anchor\\", about: \\"#about\\" });
const navigateButtonClick = useNavigateAction({
type: \\"anchor\\",
about: \\"#about\\",
});
return (
/* @ts-ignore: TS2322 */
<Button
children=\\"Go to About section\\"
onClick={() => {
action.run();
navigateButtonClick.run();
}}
{...rest}
{...getOverrideProps(overrides, \\"NavigateButton\\")}
Expand Down Expand Up @@ -269,7 +272,7 @@ export default function NavigateButton(
props: NavigateButtonProps
): React.ReactElement {
const { overrides, ...rest } = props;
const action = useNavigateAction({
const navigateButtonClick = useNavigateAction({
type: \\"url\\",
url: \\"https://www.amazon.com/\\",
});
Expand All @@ -278,7 +281,7 @@ export default function NavigateButton(
<Button
children=\\"Go to Amazon.com\\"
onClick={() => {
action.run();
navigateButtonClick.run();
}}
{...rest}
{...getOverrideProps(overrides, \\"NavigateButton\\")}
Expand Down Expand Up @@ -311,7 +314,7 @@ export default function NavigateButton(
props: NavigateButtonProps
): React.ReactElement {
const { overrides, ...rest } = props;
const action = useNavigateAction({
const navigateButtonClick = useNavigateAction({
type: \\"url\\",
url: \\"https://www.amazon.com/\\",
target: \\"newtab\\",
Expand All @@ -321,7 +324,7 @@ export default function NavigateButton(
<Button
children=\\"Go to Amazon.com (Open in new tab)\\"
onClick={() => {
action.run();
navigateButtonClick.run();
}}
{...rest}
{...getOverrideProps(overrides, \\"NavigateButton\\")}
Expand Down Expand Up @@ -354,13 +357,13 @@ export default function ReloadButton(
props: ReloadButtonProps
): React.ReactElement {
const { overrides, ...rest } = props;
const action = useNavigateAction({ type: \\"reload\\" });
const reloadButtonClick = useNavigateAction({ type: \\"reload\\" });
return (
/* @ts-ignore: TS2322 */
<Button
children=\\"Reload the page.\\"
onClick={() => {
action.run();
reloadButtonClick.run();
}}
{...rest}
{...getOverrideProps(overrides, \\"ReloadButton\\")}
Expand Down
64 changes: 0 additions & 64 deletions packages/codegen-ui-react/lib/react-component-render-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
StudioComponentAuthProperty,
StudioComponentChild,
StudioComponentProperty,
StudioGenericEvent,
StudioComponentEvent,
BoundStudioComponentEvent,
ActionStudioComponentEvent,
Expand Down Expand Up @@ -161,43 +160,6 @@ export function buildBindingAttrWithDefault(
);
}

export function buildBindingEvent(event: BoundStudioComponentEvent, eventName: string): JsxAttribute {
const expr = factory.createIdentifier(event.bindingEvent);
return factory.createJsxAttribute(factory.createIdentifier(eventName), factory.createJsxExpression(undefined, expr));
}

export function buildActionEvent(event: ActionStudioComponentEvent, eventName: string): JsxAttribute {
return factory.createJsxAttribute(
factory.createIdentifier(eventName),
factory.createJsxExpression(
undefined,
factory.createArrowFunction(
undefined,
undefined,
[],
undefined,
factory.createToken(SyntaxKind.EqualsGreaterThanToken),
factory.createBlock(
[
factory.createExpressionStatement(
factory.createCallExpression(
factory.createPropertyAccessExpression(
// TODO: use unique identifier
factory.createIdentifier('action'),
factory.createIdentifier('run'),
),
undefined,
[],
),
),
],
false,
),
),
),
);
}

export function buildFixedLiteralExpression(
prop: FixedStudioComponentProperty,
): ObjectLiteralExpression | StringLiteral | NumericLiteral | BooleanLiteral | NullLiteral | ArrayLiteralExpression {
Expand Down Expand Up @@ -537,32 +499,6 @@ export function buildOpeningElementProperties(prop: StudioComponentProperty, nam
return factory.createJsxAttribute(factory.createIdentifier(name), undefined);
}

export function buildOpeningElementEvents(event: StudioComponentEvent, name: string): JsxAttribute {
if (isBoundEvent(event)) {
return buildBindingEvent(event, name);
}
if (isActionEvent(event)) {
return buildActionEvent(event, name);
}

return factory.createJsxAttribute(factory.createIdentifier(name), undefined);
}

/*
* Tempory stub function to map from generic event name to React event name. Final implementation will be included in
* amplify-ui.
*/
export function mapGenericEventToReact(genericEventBinding: StudioGenericEvent): string {
switch (genericEventBinding) {
case StudioGenericEvent.click:
return 'onClick';
case StudioGenericEvent.change:
return 'onChange';
default:
throw new Error(`${genericEventBinding} is not a possible event.`);
}
}

export function addBindingPropertiesImports(
component: StudioComponent | StudioComponentChild,
importCollection: ImportCollection,
Expand Down
18 changes: 4 additions & 14 deletions packages/codegen-ui-react/lib/react-component-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
import {
ComponentRendererBase,
StudioNode,
StudioComponent,
StudioComponentChild,
StudioGenericEvent,
} from '@aws-amplify/codegen-ui';
import { ComponentRendererBase, StudioNode, StudioComponent, StudioComponentChild } from '@aws-amplify/codegen-ui';
import {
JsxAttributeLike,
JsxElement,
Expand All @@ -29,12 +23,8 @@ import {
SyntaxKind,
} from 'typescript';

import {
addBindingPropertiesImports,
buildOpeningElementProperties,
buildOpeningElementEvents,
mapGenericEventToReact,
} from './react-component-render-helper';
import { addBindingPropertiesImports, buildOpeningElementProperties } from './react-component-render-helper';
import { buildOpeningElementEvents } from './workflow';
import { ImportCollection, ImportSource, ImportValue } from './imports';

export class ReactComponentRenderer<TPropIn> extends ComponentRendererBase<
Expand Down Expand Up @@ -67,7 +57,7 @@ export class ReactComponentRenderer<TPropIn> extends ComponentRendererBase<
buildOpeningElementProperties(value, key),
);
const eventAttributes = Object.entries(this.component.events || {}).map(([key, value]) =>
buildOpeningElementEvents(value, mapGenericEventToReact(key as StudioGenericEvent)),
buildOpeningElementEvents(value, key, this.component.name),
);
const attributes = propertyAttributes.concat(eventAttributes);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@ import {
StudioNode,
StudioComponent,
StudioComponentChild,
StudioGenericEvent,
} from '@aws-amplify/codegen-ui';
import { JsxAttributeLike, JsxElement, JsxChild, JsxOpeningElement, SyntaxKind, Expression, factory } from 'typescript';
import { ImportCollection, ImportSource, ImportValue } from './imports';
import {
addBindingPropertiesImports,
buildOpeningElementProperties,
buildOpeningElementEvents,
mapGenericEventToReact,
} from './react-component-render-helper';
import { addBindingPropertiesImports, buildOpeningElementProperties } from './react-component-render-helper';
import { buildOpeningElementEvents } from './workflow';
import Primitive, { PrimitiveChildrenPropMapping } from './primitive';

export class ReactComponentWithChildrenRenderer<TPropIn> extends ComponentWithChildrenRendererBase<
Expand Down Expand Up @@ -64,7 +59,7 @@ export class ReactComponentWithChildrenRenderer<TPropIn> extends ComponentWithCh
buildOpeningElementProperties(value, key),
);
const eventAttributes = Object.entries(this.component.events || {}).map(([key, value]) =>
buildOpeningElementEvents(value, mapGenericEventToReact(key as StudioGenericEvent)),
buildOpeningElementEvents(value, key, this.component.name),
);
const attributes = propertyAttributes.concat(eventAttributes);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import Primitive, {
PrimitiveChildrenPropMapping,
} from './primitive';
import { RequiredKeys } from './utils/type-utils';
import { getComponentActions, buildUseActionStatement } from './action';
import { getComponentActions, buildUseActionStatement } from './workflow';

export abstract class ReactStudioTemplateRenderer extends StudioTemplateRenderer<
string,
Expand Down Expand Up @@ -1012,7 +1012,9 @@ export abstract class ReactStudioTemplateRenderer extends StudioTemplateRenderer
private buildUseActionStatements(component: StudioComponent): Statement[] {
const actions = getComponentActions(component);
if (actions) {
return actions.map((action) => buildUseActionStatement(action, this.importCollection));
return actions.map(({ action, identifier }) =>
buildUseActionStatement(action, identifier, this.importCollection),
);
}
return [];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ import {
buildConditionalExpression,
buildFixedLiteralExpression,
isActionEvent,
} from './react-component-render-helper';
import { ImportCollection, ImportSource } from './imports';
} from '../react-component-render-helper';
import { ImportCollection, ImportSource } from '../imports';

enum Action {
'Amplify.Navigate' = 'Amplify.Navigate',
Expand Down Expand Up @@ -68,20 +68,33 @@ export function getActionHookName(action: string): string {
return actionName;
}

export function getComponentActions(component: StudioComponent | StudioComponentChild): ActionStudioComponentEvent[] {
// TODO: add unique identifier to each action
export function getComponentActions(component: StudioComponent | StudioComponentChild): {
action: ActionStudioComponentEvent;
identifier: string;
}[] {
const actions = [];
if (component.events) {
actions.push(...Object.values(component.events).filter(isActionEvent));
actions.push(
...Object.entries(component.events)
// need 'action is ...' so that typescript will know all items after filter are ActionStudioComponentEvent type
.filter((action): action is [string, ActionStudioComponentEvent] => isActionEvent(action[1]))
.map(([event, action]) => ({ action, identifier: getActionIdentifier(component.name, event) })),
);
}
if (component.children) {
actions.push(...component.children.map(getComponentActions).flat());
}
return actions;
}

export function getActionIdentifier(componentName: string | undefined, event: string) {
const name = componentName || '';
return [name.charAt(0).toLowerCase() + name.slice(1), event.charAt(0).toUpperCase() + event.slice(1)].join('');
}

export function buildUseActionStatement(
action: ActionStudioComponentEvent,
identifier: string,
importCollection: ImportCollection,
): Statement {
const actionHookName = getActionHookName(action.action);
Expand All @@ -91,8 +104,7 @@ export function buildUseActionStatement(
factory.createVariableDeclarationList(
[
factory.createVariableDeclaration(
// TODO: update to unique name
factory.createIdentifier('action'),
factory.createIdentifier(identifier),
undefined,
undefined,
factory.createCallExpression(factory.createIdentifier(actionHookName), undefined, [
Expand Down
Loading

0 comments on commit bbddbb5

Please sign in to comment.