diff --git a/README.md b/README.md index 9cb846d60b..7307d7ddea 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Windmill Labs offers commercial licenses, an enterprise edition, local hub mirro Disclaimer: Windmill is in BETA. It is secure to run in production but we are still improving the product fast.

+![Windmill Screenshot](./imgs/windmill-flow.png) ![Windmill Screenshot](./imgs/windmill.png) Windmill is fully open-sourced (AGPLv3): @@ -80,31 +81,21 @@ Windmill is fully open-sourced (AGPLv3): 1. Define a minimal and generic script in Python, Typescript, Go or Bash that solves a specific task. Here sending an email with SMTP. The code can be defined in the provided Web IDE or synchronized with your own github repo: - ![Step 1](./imgs/python-script.png) + ![Step 1](./imgs/windmill-editor.png) -2. Your scripts parameters are automatically parsed and generate a frontend. You - can narrow down the types during task definition to specify regex for string, - an enum or a specific format for objects. Each script correspond to an app by - itself: ![Step 2](./imgs/arguments.png) +2. Your scripts parameters are automatically parsed and generate a frontend. + ![Step 2](./imgs/windmill-run.png) + ![Step 3](./imgs/windmill-result.png) 3. Make it flow! You can chain your scripts or scripts made by the community - shared on [WindmillHub](https://hub.windmill.dev). There is tight integration - between Windmill and the hub to make it easy to build flows from a soon-to-be - exhaustive library of generic modules. In flows, one can pipe output to input - using rich expressions that are just plain Javascript underneath. Flows - support for-loops, branching, approval steps. As such and coupled with - inputs being able to refer to any step's output, they are actual DAG rather - than just linear sequences. They are backed by an open JSON spec we call - [OpenFlow](https://docs.windmill.dev/docs/openflow) + shared on [WindmillHub](https://hub.windmill.dev). + ![Step 4](./imgs/windmill-flow.png) -Both scripts and flows are not restricted to be triggered by the UI. They can be -triggered by a schedule, watch for changes (using -[internal states](https://docs.windmill.dev/docs/reference#internal-state)) or -triggered through API with either an async or sync webhook. The latter kind of -endpoints make Windmill akin to a self-hostable AWS Lambda. Windmill can be the -central place to host, build and run all of your integrations, automation and -internal apps. We include credentials management and OAuth integration, groups -and much more! +4. (Coming soon) Build complex UI on top of your scripts and flows. + +Scripts and flows can also be triggered by a cron schedule '*/5 * * * *' or through webhooks. + +You can build your entire infra on top of Windmill! ## CLI diff --git a/backend/windmill-api/src/apps.rs b/backend/windmill-api/src/apps.rs index a071ae1f98..f67ea630a4 100644 --- a/backend/windmill-api/src/apps.rs +++ b/backend/windmill-api/src/apps.rs @@ -127,8 +127,8 @@ async fn list_apps( let sqlb = SqlBuilder::select_from("app") .fields(&[ "id", - "workspace_id", - "path", + "app.workspace_id", + "app.path", "summary", "versions[array_upper(versions, 1)] as version", "policy->>'execution_mode' as execution_mode", @@ -138,7 +138,7 @@ async fn list_apps( .left() .join("favorite") .on( - "favorite.favorite_kind = 'app' AND favorite.workspace_id = o.workspace_id AND favorite.path = o.path AND favorite.usr = ?" + "favorite.favorite_kind = 'app' AND favorite.workspace_id = app.workspace_id AND favorite.path = app.path AND favorite.usr = ?" .bind(&authed.username), ) .order_desc("favorite.path IS NOT NULL") diff --git a/frontend/src/lib/components/flows/map/FlowBranchAllMap.svelte b/frontend/src/lib/components/flows/map/FlowBranchAllMap.svelte index d6edf1b3a8..3540cfbee6 100644 --- a/frontend/src/lib/components/flows/map/FlowBranchAllMap.svelte +++ b/frontend/src/lib/components/flows/map/FlowBranchAllMap.svelte @@ -64,7 +64,7 @@ : '' )} > - + diff --git a/frontend/src/lib/components/flows/map/FlowBranchOneMap.svelte b/frontend/src/lib/components/flows/map/FlowBranchOneMap.svelte index 4c9ec37217..e8ff1349c0 100644 --- a/frontend/src/lib/components/flows/map/FlowBranchOneMap.svelte +++ b/frontend/src/lib/components/flows/map/FlowBranchOneMap.svelte @@ -61,7 +61,7 @@ : '' )} > - + @@ -87,7 +87,7 @@ : '' )} > - + diff --git a/frontend/src/lib/components/flows/map/MapItem.svelte b/frontend/src/lib/components/flows/map/MapItem.svelte index f2cb1e09a5..4070e677ba 100644 --- a/frontend/src/lib/components/flows/map/MapItem.svelte +++ b/frontend/src/lib/components/flows/map/MapItem.svelte @@ -8,6 +8,7 @@ import FlowBranchOneMap from './FlowBranchOneMap.svelte' import FlowBranchAllMap from './FlowBranchAllMap.svelte' import { + faArrowRotateForward, faBuilding, faCode, faCodeBranch, @@ -16,6 +17,7 @@ } from '@fortawesome/free-solid-svg-icons' import Icon from 'svelte-awesome' import IconedResourceType from '$lib/components/IconedResourceType.svelte' + import LanguageIcon from '$lib/components/common/languageIcons/LanguageIcon.svelte' export let mod: FlowModule @@ -51,7 +53,7 @@ {...itemProps} >
- +
@@ -74,7 +76,7 @@ label={mod.summary || 'Run one branch'} >
- +
@@ -90,7 +92,7 @@ label={mod.summary || 'Run all branches'} >
- +
@@ -109,14 +111,16 @@ >
{#if mod.value.type === 'rawscript'} - + {:else if mod.value.type === 'identity'} - + {:else if mod.value.type === 'script'} {#if mod.value.path.startsWith('hub/')} - +
+ +
{:else} - + {/if} {/if}
diff --git a/frontend/src/lib/components/sidebar/MenuLink.svelte b/frontend/src/lib/components/sidebar/MenuLink.svelte index f78e0e98e8..43540002bb 100644 --- a/frontend/src/lib/components/sidebar/MenuLink.svelte +++ b/frontend/src/lib/components/sidebar/MenuLink.svelte @@ -46,7 +46,7 @@ {#if !isCollapsed} diff --git a/frontend/src/lib/components/sidebar/SidebarContent.svelte b/frontend/src/lib/components/sidebar/SidebarContent.svelte index a4ebf05407..d9ec05121e 100644 --- a/frontend/src/lib/components/sidebar/SidebarContent.svelte +++ b/frontend/src/lib/components/sidebar/SidebarContent.svelte @@ -59,10 +59,12 @@ {/each}
-
- {#each favoriteLinks as menuLink (menuLink.href)} - - {/each} +
+
+ {#each favoriteLinks as menuLink (menuLink.href)} + + {/each} +
diff --git a/imgs/python-script.png b/imgs/python-script.png index 1a300b4e7a..40bec7d8f9 100644 Binary files a/imgs/python-script.png and b/imgs/python-script.png differ diff --git a/imgs/windmill-editor.png b/imgs/windmill-editor.png new file mode 100644 index 0000000000..fe794655d8 Binary files /dev/null and b/imgs/windmill-editor.png differ diff --git a/imgs/windmill-flow.png b/imgs/windmill-flow.png new file mode 100644 index 0000000000..dd121ecd5f Binary files /dev/null and b/imgs/windmill-flow.png differ diff --git a/imgs/windmill-result.png b/imgs/windmill-result.png new file mode 100644 index 0000000000..ac09fcc113 Binary files /dev/null and b/imgs/windmill-result.png differ diff --git a/imgs/windmill-run.png b/imgs/windmill-run.png new file mode 100644 index 0000000000..71fc1e4801 Binary files /dev/null and b/imgs/windmill-run.png differ diff --git a/imgs/windmill.png b/imgs/windmill.png index dfef2d3cca..1ba4ce09b8 100644 Binary files a/imgs/windmill.png and b/imgs/windmill.png differ