- Let's quickly build a smart queue that prints its messages and stores the latest one in a bucket.
+ Let's quickly learn about Winglang
- You'll interact with it in the embedded Wing Simulator, and then compile to AWS.
+ You'll create resources, explore the terraform output, interact with the Simulator and have fune
)
-}
\ No newline at end of file
+}
diff --git a/apps/tour/src/tutorials/01-tutorial.md b/apps/tour/src/tutorials/01-tutorial.md
index bd0cf72b..3cf3c3cb 100644
--- a/apps/tour/src/tutorials/01-tutorial.md
+++ b/apps/tour/src/tutorials/01-tutorial.md
@@ -1,7 +1,9 @@
-# Let's add the first cloud service to our app
+# Cloud.Queue resource
Below is an empty Wing source code file.
-The first line, "bring cloud", lets us access resources from the Wing standard library.
-1. **Uncomment line 3**. A **queue** will appear in the simulator to the right.
-2. Click **Next** to continue
+1. Uncomment line 3
+2. The code compiles into terraform, see generate SQS queue on the right
+3. Click **Next** to continue
+
+
diff --git a/apps/tour/src/tutorials/02-solution.w b/apps/tour/src/tutorials/02-solution.w
new file mode 100644
index 00000000..74f72a29
--- /dev/null
+++ b/apps/tour/src/tutorials/02-solution.w
@@ -0,0 +1,8 @@
+bring cloud;
+
+let q = new cloud.Queue();
+
+let handler = inflight (s: str) => {
+ log("inflight function was called with ${s}");
+ q.push(s);
+};
diff --git a/apps/tour/src/tutorials/02-tutorial.md b/apps/tour/src/tutorials/02-tutorial.md
index 438b7b6d..e58d275d 100644
--- a/apps/tour/src/tutorials/02-tutorial.md
+++ b/apps/tour/src/tutorials/02-tutorial.md
@@ -1,6 +1,14 @@
-# Push a message to the queue
+# Inflight function compiles to javascript code
-1. In the Wing Simulator, **click on the resource in the center named "cloud.Queue"**. An interaction panel will appear on the right hand side.
-2. Under **Push Message**, type in a message and click **Send**.
+inflight functions are functions that are going to run on the cloud
+
+1. Paste this inflight function in line 4:
+```ts
+let handler = inflight (s: str) => {
+ log("inflight function was called with ${s}");
+ // Type 'q.' to see the available methods
+};
+```
+2. The inflight code compiled into JS, Look for the code under assets
+3. Add code to push string s into `q` in line 7
-π Notice how the **Approx size** of the queue has changed.
diff --git a/apps/tour/src/tutorials/03-code.w b/apps/tour/src/tutorials/03-code.w
index 3b6b3503..74f72a29 100644
--- a/apps/tour/src/tutorials/03-code.w
+++ b/apps/tour/src/tutorials/03-code.w
@@ -1,3 +1,8 @@
bring cloud;
-let q = new cloud.Queue();
\ No newline at end of file
+let q = new cloud.Queue();
+
+let handler = inflight (s: str) => {
+ log("inflight function was called with ${s}");
+ q.push(s);
+};
diff --git a/apps/tour/src/tutorials/03-solution.w b/apps/tour/src/tutorials/03-solution.w
index 880477cf..68ed22f9 100644
--- a/apps/tour/src/tutorials/03-solution.w
+++ b/apps/tour/src/tutorials/03-solution.w
@@ -2,6 +2,9 @@ bring cloud;
let q = new cloud.Queue();
-new cloud.Function(inflight (s: str) => {
- log("Cloud Function was called with ${s}");
-});
\ No newline at end of file
+let handler = inflight (s: str) => {
+ log("inflight function was called with ${s}");
+ q.push(s);
+};
+
+new cloud.Function(handler);
diff --git a/apps/tour/src/tutorials/03-tutorial.md b/apps/tour/src/tutorials/03-tutorial.md
index ff5428ea..f738a30f 100644
--- a/apps/tour/src/tutorials/03-tutorial.md
+++ b/apps/tour/src/tutorials/03-tutorial.md
@@ -1,11 +1,12 @@
-# Invoke a function and explore the Logs Panel
+# Use cloud.Function for invoking the handler
-1. Paste this code in line 4:
+Let's wrap the inflight code with a cloud.Function
+
+1. Add a cloud.Function resource that will use the handler
```ts
-new cloud.Function(inflight (s: str) => {
- log("Cloud Function was called with ${s}");
-});
+new cloud.Function(handler);
```
-2. Find the **cloud.Function** in the simulator and **invoke** it with a payload.
+2. Notice that there are a lot of new resources, including IAM permissions
+3. In IAM policy, find the `sqs:SendMessage` permission generated for the cloud.Function
-π Notice the resulting log at the bottom of the simulator.
+Next, lets build this code for a different target, Wing Simulator
diff --git a/apps/tour/src/tutorials/04-code.w b/apps/tour/src/tutorials/04-code.w
index d91c1411..68ed22f9 100644
--- a/apps/tour/src/tutorials/04-code.w
+++ b/apps/tour/src/tutorials/04-code.w
@@ -2,16 +2,9 @@ bring cloud;
let q = new cloud.Queue();
-new cloud.Function(inflight (s: str) => {
- log("Cloud Function was called with ${s}");
- // Type 'q.' to see the available methods
-});
+let handler = inflight (s: str) => {
+ log("inflight function was called with ${s}");
+ q.push(s);
+};
-// Type 'q.' to see the available methods here.
-// Notice how they are different from the ones
-// suggested within the Cloud Function in line 7.
-// It's because even though it's the same queue,
-// lines 7 & 10 are in different execution phases.
-// preflight - for infrastructure definitions, executed at compile time.
-// inflight - for business logic, executed at runtime.
-// We'll learn more about these concepts in the next tutorial.
\ No newline at end of file
+new cloud.Function(handler);
diff --git a/apps/tour/src/tutorials/04-solution.w b/apps/tour/src/tutorials/04-solution.w
deleted file mode 100644
index 2b2cd586..00000000
--- a/apps/tour/src/tutorials/04-solution.w
+++ /dev/null
@@ -1,17 +0,0 @@
-bring cloud;
-
-let q = new cloud.Queue();
-
-new cloud.Function(inflight (s: str) => {
- log("Cloud Function was called with ${s}");
- q.push(s);
-});
-
-// Type 'q.' to see the available methods here.
-// Notice how they are different from the ones
-// suggested within the Cloud Function in line 7.
-// It's because even though it's the same queue,
-// lines 7 & 10 are in different execution phases.
-// preflight - for infrastructure definitions, executed at compile time.
-// inflight - for business logic, executed at runtime.
-// We'll learn more about these concepts in the next tutorial.
\ No newline at end of file
diff --git a/apps/tour/src/tutorials/04-tutorial.md b/apps/tour/src/tutorials/04-tutorial.md
index ed91e1ea..1264672e 100644
--- a/apps/tour/src/tutorials/04-tutorial.md
+++ b/apps/tour/src/tutorials/04-tutorial.md
@@ -1,7 +1,9 @@
-# Push a message to the queue programmatically
+# Wing Simulator
-1. Add code to push the function's payload to the queue in line 7. (Hint: look at how the payload is added to the log in line 6).
-2. Invoke the cloud.Function in the simulator (notice it's connected to the queue now).
-3. Explore what happens in the cloud.Queue in the simulator.
+
+1. In the Wing Simulator, click on the resource in the center named "cloud.Function".
+2. An interaction panel will appear on the right hand side.
+3. Under Invoke, type in a message and click Send.
+4. In the Wing Simulator, click on the resource in the center named "cloud.Queue"
+5. Notice how the **Approx size** increases every time you call it
-π **Bonus:** Look at the code comment in line 10.
\ No newline at end of file
diff --git a/apps/tour/src/tutorials/05-code.w b/apps/tour/src/tutorials/05-code.w
index 834be567..deb69a97 100644
--- a/apps/tour/src/tutorials/05-code.w
+++ b/apps/tour/src/tutorials/05-code.w
@@ -4,6 +4,6 @@ let q = new cloud.Queue();
// Paste here
new cloud.Function(inflight (s: str) => {
- log("Cloud Function was called with ${s}");
- q.push(s);
-});
\ No newline at end of file
+ log("inflight function was called with ${s}");
+ q.push(s);
+});
diff --git a/apps/tour/src/tutorials/05-solution.w b/apps/tour/src/tutorials/05-solution.w
index 5e839b82..b72627d5 100644
--- a/apps/tour/src/tutorials/05-solution.w
+++ b/apps/tour/src/tutorials/05-solution.w
@@ -4,10 +4,10 @@ let q = new cloud.Queue();
let b = new cloud.Bucket() as "Bucket: Last Message";
q.addConsumer(inflight (m: str) => {
- b.put("latest.txt", m);
+ b.put("latest.txt", m);
});
new cloud.Function(inflight (s: str) => {
- log("Cloud Function was called with ${s}");
- q.push(s);
-});
\ No newline at end of file
+ log("inflight function was called with ${s}");
+ q.push(s);
+});
diff --git a/apps/tour/src/tutorials/05-tutorial.md b/apps/tour/src/tutorials/05-tutorial.md
index 4a826332..97f57136 100644
--- a/apps/tour/src/tutorials/05-tutorial.md
+++ b/apps/tour/src/tutorials/05-tutorial.md
@@ -1,5 +1,7 @@
# Add a Bucket to store the latest message sent to our queue.
+To make things shorter we've inlined the inflight handler
+
1. Paste this code in line 4.
```ts
let b = new cloud.Bucket() as "Bucket: Last Message";
diff --git a/apps/tour/src/tutorials/06-code.w b/apps/tour/src/tutorials/06-code.w
index 5e839b82..3b83433c 100644
--- a/apps/tour/src/tutorials/06-code.w
+++ b/apps/tour/src/tutorials/06-code.w
@@ -4,10 +4,10 @@ let q = new cloud.Queue();
let b = new cloud.Bucket() as "Bucket: Last Message";
q.addConsumer(inflight (m: str) => {
- b.put("latest.txt", m);
+ b.put("latest.txt", m);
});
new cloud.Function(inflight (s: str) => {
- log("Cloud Function was called with ${s}");
- q.push(s);
-});
\ No newline at end of file
+ log("Cloud Function was called with ${s}");
+ q.push(s);
+});
diff --git a/apps/tour/src/tutorials/index.ts b/apps/tour/src/tutorials/index.ts
index 8b179e1c..3adf6d14 100644
--- a/apps/tour/src/tutorials/index.ts
+++ b/apps/tour/src/tutorials/index.ts
@@ -1,3 +1,4 @@
+import { Target } from "@wing-playground/shared/src/compiler/compiler";
import code01 from "./01-code.w?raw";
import solution01 from "./01-solution.w?raw";
import tutorial01 from "./01-tutorial.md?raw";
@@ -28,6 +29,7 @@ export interface Tutorial {
code: string;
solution?: string;
tutorial?: string
+ targets?: Target[];
}
export const tutorials = [
@@ -36,41 +38,46 @@ export const tutorials = [
name: "Create Queue",
code: code01,
solution: solution01,
- tutorial: tutorial01
+ tutorial: tutorial01,
+ targets: [Target.TFAWS],
},
{
id: "2",
- name: "Push Message",
+ name: "Inflight Code",
code: code02,
- // solution: solution02,
- tutorial: tutorial02
+ solution: solution02,
+ tutorial: tutorial02,
+ targets: [Target.TFAWS],
},
{
id: "3",
- name: "Logs",
+ name: "cloud.Function",
code: code03,
solution: solution03,
- tutorial: tutorial03
+ tutorial: tutorial03,
+ targets: [Target.TFAWS],
},
{
id: "4",
- name: "Push Programmatically",
+ name: "Simulator",
code: code04,
- solution: solution04,
- tutorial: tutorial04
+ tutorial: tutorial04,
+ targets: ["simulator", Target.TFAWS],
},
{
id: "5",
name: "Use Bucket",
code: code05,
solution: solution05,
- tutorial: tutorial05
+ tutorial: tutorial05,
+ targets: ["simulator", Target.TFAWS],
},
{
id: "6",
name: "Compile for AWS",
code: code06,
// solution: solution06,
- tutorial: tutorial06
+ tutorial: tutorial06,
+ targets: ["simulator", Target.TFAWS],
},
-]
\ No newline at end of file
+]
diff --git a/packages/shared/src/Tabs.tsx b/packages/shared/src/Tabs.tsx
new file mode 100644
index 00000000..f31634ed
--- /dev/null
+++ b/packages/shared/src/Tabs.tsx
@@ -0,0 +1,116 @@
+import classNames from "classnames";
+import { ReactNode, useEffect, useState } from "react";
+
+export interface Tab {
+ id: string;
+ name: string;
+ icon?: ReactNode;
+ panel?: ReactNode | (() => ReactNode);
+ count?: number;
+ tabClassName?: string;
+}
+
+export interface TabsProps {
+ tabs: Tab[];
+ currentTabId?: string;
+ onTabChange?: (tabId: string) => void;
+ renderActiveTabPanelOnly?: boolean;
+ tabsWithNotifications?: string[];
+ className?: string;
+}
+
+export const Tabs = (props: TabsProps) => {
+ const [currentTabId, setCurrentTabId] = useState(props.currentTabId);
+
+ useEffect(() => {
+ if (props.currentTabId) {
+ setCurrentTabId(props.currentTabId);
+ }
+ }, [props]);
+
+ useEffect(() => {
+ if (props.onTabChange && currentTabId) {
+ props.onTabChange(currentTabId);
+ }
+ }, [currentTabId]);
+
+ return (
+