feat: orchestrator usage across MFs (#1)

This commit is contained in:
Ayo Ayco 2024-01-22 23:15:28 +01:00 committed by GitHub
parent fbcaac6ec1
commit df661089e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 112 additions and 57 deletions

View file

@ -1,71 +1,102 @@
// @ts-check
// import { broadcast } from 'utils/orchestrator'
import React, { useState } from "react";
const Cart = () => {
const [products, setProducts] = useState([
{
name: "Shoe A",
description: "It is a good shoe",
price: 100,
count: 2,
},
{
name: "Shoe B",
description: "It is a comfortable shoe",
price: 120,
count: 7,
},
]);
import { broadcast, listen } from "utils";
import React, { Component } from "react";
// listen to add-to-cart messages
// if item is already in cart, increment count
class Cart extends Component {
constructor(props) {
super(props);
this.state = {
products: [
{
name: "Shoe A",
description: "It is a good shoe",
price: 100,
count: 2,
},
{
name: "Shoe B",
description: "It is a comfortable shoe",
price: 120,
count: 7,
},
],
};
}
const getTotal = () => {
getTotalItems = () => {
const { products } = this.state;
return products.reduce((acc, product) => {
return acc + product.count;
}, 0);
};
getTotalPrice = () => {
const { products } = this.state;
return products.reduce((acc, product) => {
return acc + product.price * product.count;
}, 0);
};
const decreaseCount = (index) => {
// if in cart, decrease count
const updatedProducts = [...products];
if (updatedProducts[index].count > 1) {
updatedProducts[index].count--;
addProduct = (product) => {
const { products } = this.state;
const index = products.findIndex((p) => p.name === product.name);
if (index > -1) {
const updatedProducts = [...products];
updatedProducts[index].count++;
this.setState({ products: updatedProducts });
} else {
updatedProducts.splice(index, 1);
this.setState({ products: [...products, { ...product, count: 1 }] });
}
setProducts(updatedProducts);
};
const increaseCount = (index) => {
// if in cart, increase count
const updatedProducts = [...products];
updatedProducts[index].count++;
setProducts(updatedProducts);
removeProduct = (product) => {
const { products } = this.state;
const index = products.findIndex((p) => p.name === product.name);
if (index > -1) {
const updatedProducts = [...products];
updatedProducts[index].count--;
this.setState({ products: updatedProducts });
}
};
return (
<div>
<h2>🛒 Cart</h2>
<ul>
{products.map((product, index) => (
<li key={index}>
<span>({product.count}x) </span>
<span>{product.name}</span>
<span> - </span>
<strong>${product.price * product.count}</strong>
<span>
<button onClick={() => decreaseCount(index)}> - </button>
<button onClick={() => increaseCount(index)}> + </button>
</span>
</li>
))}
</ul>
componentDidMount() {
broadcast("update-count", this.getTotalItems());
listen("add-product", this.addProduct);
}
<span>Total: </span>
<strong>${getTotal()}</strong>
</div>
);
};
componentDidUpdate(prevProps, prevState) {
const { products } = this.state;
if (prevState.products !== products) {
broadcast("update-count", this.getTotalItems());
}
}
render() {
const { products } = this.state;
return (
<div>
<h2>🛒 Cart</h2>
<ul>
{products.map((product, index) => (
<li key={index}>
<span>({product.count}x) </span>
<span>{product.name}</span>
<span> - </span>
<strong>${product.price * product.count}</strong>
<span>
<button onClick={() => this.removeProduct(product)}> - </button>
<button onClick={() => this.addProduct(product)}> + </button>
</span>
</li>
))}
</ul>
<span>Total: </span>
<strong>${this.getTotalPrice()}</strong>
</div>
);
}
}
export default Cart;

View file

@ -1,4 +1,5 @@
import React from "react";
import { listen } from "utils";
import React, { useEffect } from "react";
import "./App.css";
const App = (props) => {
@ -6,6 +7,11 @@ const App = (props) => {
const [count, setCount] = React.useState(0);
// listen to add-to-cart messages
useEffect(() =>
listen("update-count", (count) => {
setCount(count);
})
);
return (
<section className="app-b">

View file

@ -1,3 +1,4 @@
import { broadcast } from "utils";
import styles from "./App.module.css";
function App() {
@ -25,8 +26,8 @@ function App() {
];
const addToCart = (product) => {
console.log(">>> add to cart", product);
// broadcast add product to cart
broadcast("add-product", product);
};
return (

View file

@ -0,0 +1 @@
export { broadcast, listen } from "./orchestrator.mjs";

View file

@ -1,3 +1,19 @@
// implement messaging system between MF's
const listeners = {};
// - broadcast message
// - listen to message & attach callback
export function broadcast(action, data) {
window.parent.postMessage({ action, data });
console.log("broadcast", { action, data });
}
// - listen to message & attach callback
export function listen(action, callback) {
window.parent.addEventListener("message", (event) => {
const { data } = event;
if (data.action === action) {
callback(data.data);
}
});
}