This commit is contained in:
Ruben Fiszel
2024-08-12 09:37:53 +02:00
parent c288d73c13
commit 30b90e4951
31 changed files with 10978 additions and 230 deletions
+24
View File
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
+245
View File
@@ -0,0 +1,245 @@
// this file is generated — do not edit it
/// <reference types="@sveltejs/kit" />
/**
* Environment variables [loaded by Vite](https://vitejs.dev/guide/env-and-mode.html#env-files) from `.env` files and `process.env`. Like [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private), this module cannot be imported into client-side code. This module only includes variables that _do not_ begin with [`config.kit.env.publicPrefix`](https://kit.svelte.dev/docs/configuration#env) _and do_ start with [`config.kit.env.privatePrefix`](https://kit.svelte.dev/docs/configuration#env) (if configured).
*
* _Unlike_ [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private), the values exported from this module are statically injected into your bundle at build time, enabling optimisations like dead code elimination.
*
* ```ts
* import { API_KEY } from '$env/static/private';
* ```
*
* Note that all environment variables referenced in your code should be declared (for example in an `.env` file), even if they don't have a value until the app is deployed:
*
* ```
* MY_FEATURE_FLAG=""
* ```
*
* You can override `.env` values from the command line like so:
*
* ```bash
* MY_FEATURE_FLAG="enabled" npm run dev
* ```
*/
declare module '$env/static/private' {
export const SHELL: string;
export const npm_command: string;
export const LSCOLORS: string;
export const npm_config_userconfig: string;
export const COLORTERM: string;
export const GTK_THEME: string;
export const GDK_DPI_SCALE: string;
export const npm_config_cache: string;
export const npm_package_dev_optional: string;
export const LESS: string;
export const npm_package_integrity: string;
export const I3SOCK: string;
export const NODE: string;
export const CREDENTIALS_DIRECTORY: string;
export const MEMORY_PRESSURE_WRITE: string;
export const AWS_CLI_AUTO_PROMPT: string;
export const COLOR: string;
export const npm_config_local_prefix: string;
export const GREP_COLORS: string;
export const npm_config_globalconfig: string;
export const XCURSOR_SIZE: string;
export const EDITOR: string;
export const XDG_SEAT: string;
export const PWD: string;
export const LOGNAME: string;
export const XDG_SESSION_TYPE: string;
export const GOOGLE_APPLICATION_CREDENTIALS: string;
export const npm_package_dev: string;
export const npm_config_init_module: string;
export const SYSTEMD_EXEC_PID: string;
export const _: string;
export const MOTD_SHOWN: string;
export const HOME: string;
export const npm_package_peer: string;
export const LANG: string;
export const LS_COLORS: string;
export const XDG_CURRENT_DESKTOP: string;
export const npm_package_version: string;
export const MEMORY_PRESSURE_WATCH: string;
export const SWAYSOCK: string;
export const WAYLAND_DISPLAY: string;
export const npm_package_resolved: string;
export const INVOCATION_ID: string;
export const INIT_CWD: string;
export const npm_lifecycle_script: string;
export const npm_package_optional: string;
export const npm_config_npm_version: string;
export const XDG_SESSION_CLASS: string;
export const TERM: string;
export const npm_package_name: string;
export const npm_config_prefix: string;
export const USER: string;
export const NOMAD_ADDR: string;
export const DISPLAY: string;
export const npm_lifecycle_event: string;
export const SHLVL: string;
export const MOZ_ENABLE_WAYLAND: string;
export const PAGER: string;
export const XDG_VTNR: string;
export const XDG_SESSION_ID: string;
export const npm_config_user_agent: string;
export const npm_execpath: string;
export const UPDATE_ZSH_DAYS: string;
export const XDG_RUNTIME_DIR: string;
export const DEBUGINFOD_URLS: string;
export const npm_package_json: string;
export const BUN_INSTALL: string;
export const WLR_DRM_NO_MODIFIERS: string;
export const npm_config_legacy_peer_deps: string;
export const npm_config_noproxy: string;
export const PATH: string;
export const GDK_SCALE: string;
export const npm_config_node_gyp: string;
export const DBUS_SESSION_BUS_ADDRESS: string;
export const CARGO_INCREMENTAL: string;
export const npm_config_global_prefix: string;
export const MAIL: string;
export const npm_node_execpath: string;
export const OLDPWD: string;
export const GOPATH: string;
export const npm_package_engines_node: string;
export const CONSUL_HTTP_ADDR: string;
}
/**
* Similar to [`$env/static/private`](https://kit.svelte.dev/docs/modules#$env-static-private), except that it only includes environment variables that begin with [`config.kit.env.publicPrefix`](https://kit.svelte.dev/docs/configuration#env) (which defaults to `PUBLIC_`), and can therefore safely be exposed to client-side code.
*
* Values are replaced statically at build time.
*
* ```ts
* import { PUBLIC_BASE_URL } from '$env/static/public';
* ```
*/
declare module '$env/static/public' {
}
/**
* This module provides access to runtime environment variables, as defined by the platform you're running on. For example if you're using [`adapter-node`](https://github.com/sveltejs/kit/tree/main/packages/adapter-node) (or running [`vite preview`](https://kit.svelte.dev/docs/cli)), this is equivalent to `process.env`. This module only includes variables that _do not_ begin with [`config.kit.env.publicPrefix`](https://kit.svelte.dev/docs/configuration#env) _and do_ start with [`config.kit.env.privatePrefix`](https://kit.svelte.dev/docs/configuration#env) (if configured).
*
* This module cannot be imported into client-side code.
*
* Dynamic environment variables cannot be used during prerendering.
*
* ```ts
* import { env } from '$env/dynamic/private';
* console.log(env.DEPLOYMENT_SPECIFIC_VARIABLE);
* ```
*
* > In `dev`, `$env/dynamic` always includes environment variables from `.env`. In `prod`, this behavior will depend on your adapter.
*/
declare module '$env/dynamic/private' {
export const env: {
SHELL: string;
npm_command: string;
LSCOLORS: string;
npm_config_userconfig: string;
COLORTERM: string;
GTK_THEME: string;
GDK_DPI_SCALE: string;
npm_config_cache: string;
npm_package_dev_optional: string;
LESS: string;
npm_package_integrity: string;
I3SOCK: string;
NODE: string;
CREDENTIALS_DIRECTORY: string;
MEMORY_PRESSURE_WRITE: string;
AWS_CLI_AUTO_PROMPT: string;
COLOR: string;
npm_config_local_prefix: string;
GREP_COLORS: string;
npm_config_globalconfig: string;
XCURSOR_SIZE: string;
EDITOR: string;
XDG_SEAT: string;
PWD: string;
LOGNAME: string;
XDG_SESSION_TYPE: string;
GOOGLE_APPLICATION_CREDENTIALS: string;
npm_package_dev: string;
npm_config_init_module: string;
SYSTEMD_EXEC_PID: string;
_: string;
MOTD_SHOWN: string;
HOME: string;
npm_package_peer: string;
LANG: string;
LS_COLORS: string;
XDG_CURRENT_DESKTOP: string;
npm_package_version: string;
MEMORY_PRESSURE_WATCH: string;
SWAYSOCK: string;
WAYLAND_DISPLAY: string;
npm_package_resolved: string;
INVOCATION_ID: string;
INIT_CWD: string;
npm_lifecycle_script: string;
npm_package_optional: string;
npm_config_npm_version: string;
XDG_SESSION_CLASS: string;
TERM: string;
npm_package_name: string;
npm_config_prefix: string;
USER: string;
NOMAD_ADDR: string;
DISPLAY: string;
npm_lifecycle_event: string;
SHLVL: string;
MOZ_ENABLE_WAYLAND: string;
PAGER: string;
XDG_VTNR: string;
XDG_SESSION_ID: string;
npm_config_user_agent: string;
npm_execpath: string;
UPDATE_ZSH_DAYS: string;
XDG_RUNTIME_DIR: string;
DEBUGINFOD_URLS: string;
npm_package_json: string;
BUN_INSTALL: string;
WLR_DRM_NO_MODIFIERS: string;
npm_config_legacy_peer_deps: string;
npm_config_noproxy: string;
PATH: string;
GDK_SCALE: string;
npm_config_node_gyp: string;
DBUS_SESSION_BUS_ADDRESS: string;
CARGO_INCREMENTAL: string;
npm_config_global_prefix: string;
MAIL: string;
npm_node_execpath: string;
OLDPWD: string;
GOPATH: string;
npm_package_engines_node: string;
CONSUL_HTTP_ADDR: string;
[key: `PUBLIC_${string}`]: undefined;
[key: `${string}`]: string | undefined;
}
}
/**
* Similar to [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private), but only includes variables that begin with [`config.kit.env.publicPrefix`](https://kit.svelte.dev/docs/configuration#env) (which defaults to `PUBLIC_`), and can therefore safely be exposed to client-side code.
*
* Note that public dynamic environment variables must all be sent from the server to the client, causing larger network requests — when possible, use `$env/static/public` instead.
*
* Dynamic environment variables cannot be used during prerendering.
*
* ```ts
* import { env } from '$env/dynamic/public';
* console.log(env.PUBLIC_DEPLOYMENT_SPECIFIC_VARIABLE);
* ```
*/
declare module '$env/dynamic/public' {
export const env: {
[key: `PUBLIC_${string}`]: string | undefined;
}
}
@@ -0,0 +1,20 @@
export { matchers } from './matchers.js';
export const nodes = [
() => import('./nodes/0'),
() => import('./nodes/1')
];
export const server_loads = [];
export const dictionary = {
};
export const hooks = {
handleError: (({ error }) => { console.error(error) }),
reroute: (() => {})
};
export { default as root } from '../root.svelte';
@@ -0,0 +1 @@
export const matchers = {};
@@ -0,0 +1 @@
export { default as component } from "../../../../node_modules/@sveltejs/kit/src/runtime/components/layout.svelte";
@@ -0,0 +1 @@
export { default as component } from "../../../../node_modules/@sveltejs/kit/src/runtime/components/error.svelte";
+25
View File
@@ -0,0 +1,25 @@
// this file is generated — do not edit it
declare module "svelte/elements" {
export interface HTMLAttributes<T> {
'data-sveltekit-keepfocus'?: true | '' | 'off' | undefined | null;
'data-sveltekit-noscroll'?: true | '' | 'off' | undefined | null;
'data-sveltekit-preload-code'?:
| true
| ''
| 'eager'
| 'viewport'
| 'hover'
| 'tap'
| 'off'
| undefined
| null;
'data-sveltekit-preload-data'?: true | '' | 'hover' | 'tap' | 'off' | undefined | null;
'data-sveltekit-reload'?: true | '' | 'off' | undefined | null;
'data-sveltekit-replacestate'?: true | '' | 'off' | undefined | null;
}
}
export {};
@@ -0,0 +1,39 @@
{
"compilerOptions": {
"paths": {},
"rootDirs": [
"..",
"./types"
],
"verbatimModuleSyntax": true,
"isolatedModules": true,
"lib": [
"esnext",
"DOM",
"DOM.Iterable"
],
"moduleResolution": "bundler",
"module": "esnext",
"noEmit": true,
"target": "esnext"
},
"include": [
"ambient.d.ts",
"non-ambient.d.ts",
"./types/**/$types.d.ts",
"../vite.config.js",
"../vite.config.ts",
"../src/**/*.js",
"../src/**/*.ts",
"../src/**/*.svelte",
"../tests/**/*.js",
"../tests/**/*.ts",
"../tests/**/*.svelte"
],
"exclude": [
"../node_modules/**",
"../src/service-worker.js",
"../src/service-worker.ts",
"../src/service-worker.d.ts"
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"recommendations": ["svelte.svelte-vscode"]
}
+47
View File
@@ -0,0 +1,47 @@
# Svelte + Vite
This template should help get you started developing with Svelte in Vite.
## Recommended IDE Setup
[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
## Need an official Svelte framework?
Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
## Technical considerations
**Why use this over SvelteKit?**
- It brings its own routing solution which might not be preferable for some users.
- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
This template contains as little as possible to get started with Vite + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate.
**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information.
**Why include `.vscode/extensions.json`?**
Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project.
**Why enable `checkJs` in the JS template?**
It is likely that most cases of changing variable types in runtime are likely to be accidental, rather than deliberate. This provides advanced typechecking out of the box. Should you like to take advantage of the dynamically-typed nature of JavaScript, it is trivial to change the configuration.
**Why is HMR not preserving my local component state?**
HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/sveltejs/svelte-hmr/tree/master/packages/svelte-hmr#preservation-of-local-state).
If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR.
```js
// store.js
// An extremely simple external store
import { writable } from 'svelte/store'
export default writable(0)
```
+13
View File
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
+32
View File
@@ -0,0 +1,32 @@
{
"compilerOptions": {
"moduleResolution": "bundler",
"target": "ESNext",
"module": "ESNext",
/**
* svelte-preprocess cannot figure out whether you have
* a value or a type, so tell TypeScript to enforce using
* `import type` instead of `import` for Types.
*/
"verbatimModuleSyntax": true,
"isolatedModules": true,
"resolveJsonModule": true,
/**
* To have warnings / errors of the Svelte compiler at the
* correct position, enable source maps by default.
*/
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable this if you'd like to use dynamic types.
*/
"checkJs": true
},
/**
* Use global.d.ts instead of compilerOptions.types
* to avoid limiting type declarations.
*/
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
}
+9979
View File
File diff suppressed because it is too large Load Diff
+63
View File
@@ -0,0 +1,63 @@
{
"name": "app-viewer-bundle",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"@floating-ui/core": "^1.3.1",
"@hey-api/openapi-ts": "^0.43.0",
"@playwright/test": "^1.34.3",
"@rgossiaux/svelte-headlessui": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/typography": "^0.5.8",
"@types/d3": "^7.4.0",
"@types/d3-zoom": "^3.0.3",
"@types/lodash": "^4.14.195",
"@types/node": "^20.3.3",
"@types/vscode": "^1.83.5",
"@typescript-eslint/eslint-plugin": "^5.59.8",
"@typescript-eslint/parser": "^5.60.0",
"@zerodevx/svelte-toast": "^0.9.5",
"autoprefixer": "^10.4.13",
"cssnano": "^6.0.1",
"d3-dag": "^0.11.5",
"eslint": "^8.47.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-svelte": "^2.33.1",
"path-browserify": "^1.0.1",
"postcss": "^8.4.24",
"postcss-load-config": "^4.0.1",
"prettier": "^2.8.8",
"prettier-plugin-svelte": "^2.10.1",
"simple-svelte-autocomplete": "^2.5.1",
"style-to-object": "^0.4.1",
"stylelint-config-recommended": "^13.0.0",
"svelte": "^4.0.0",
"svelte-awesome-color-picker": "^3.0.4",
"svelte-check": "^3.4.3",
"svelte-floating-ui": "^1.5.8",
"svelte-highlight": "^7.6.0",
"svelte-multiselect": "^10.0.0",
"svelte-popperjs": "^1.3.2",
"svelte-preprocess": "^5.0.1",
"svelte-range-slider-pips": "^2.3.1",
"svelte-splitpanes": "0.8.0",
"tailwindcss": "^3.4.1",
"tslib": "^2.6.1",
"typescript": "^5.1.3",
"vite": "^5",
"vite-plugin-circular-dependency": "^0.2.1",
"vite-plugin-mkcert": "^1.17.5",
"yootils": "^0.3.1"
},
"dependencies": {
"vite-plugin-css-injected-by-js": "^3.5.1",
"windmill-components": "^1.377.2"
}
}
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+165
View File
@@ -0,0 +1,165 @@
import AppPreview from "windmill-components/components/apps/editor/AppPreview.svelte";
// import "./app.css";
globalThis.render = (workspace) => {
new AppPreview({
target: document.getElementById("app"),
props: {
app: {
grid: [
{
3: {
fixed: true,
x: 0,
y: 0,
fullHeight: false,
w: 6,
h: 2,
},
12: {
fixed: true,
x: 0,
y: 0,
fullHeight: false,
w: 12,
h: 2,
},
data: {
type: "containercomponent",
configuration: {},
customCss: {
container: {
class: "!p-0",
style: "",
},
},
actions: [],
numberOfSubgrids: 1,
id: "topbar",
},
id: "topbar",
},
{
3: {
fixed: false,
x: 0,
y: 2,
fullHeight: false,
w: 3,
h: 10,
},
12: {
fixed: false,
x: 0,
y: 2,
fullHeight: false,
w: 6,
h: 10,
},
data: {
type: "aggridcomponent",
configuration: {
columnDefs: {
type: "static",
value: [
{
field: "id",
flex: 1,
},
{
field: "name",
editable: true,
flex: 1,
},
{
field: "age",
flex: 1,
},
],
},
flex: {
type: "static",
value: true,
},
allEditable: {
type: "static",
value: false,
},
multipleSelectable: {
type: "static",
value: false,
},
rowMultiselectWithClick: {
type: "static",
value: true,
},
pagination: {
type: "static",
value: false,
},
selectFirstRowByDefault: {
type: "static",
value: true,
},
extraConfig: {
type: "static",
value: {},
},
compactness: {
type: "static",
value: "normal",
},
wrapActions: {
type: "static",
value: false,
},
footer: {
type: "static",
value: true,
},
customActionsHeader: {
type: "static",
},
},
componentInput: {
type: "static",
fieldType: "array",
subFieldType: "object",
value: [
{
id: 1,
name: "A cell with a long name",
age: 42,
},
{
id: 2,
name: "A briefer cell",
age: 84,
},
],
},
customCss: {
container: {
class: "",
style: "",
},
},
actions: [],
id: "a",
},
id: "a",
},
],
fullscreen: false,
unusedInlineScripts: [],
hiddenInlineScripts: [],
theme: undefined,
},
author: "",
},
});
};
if (import.meta.env.DEV) {
globalThis.render("foo");
}
+2
View File
@@ -0,0 +1,2 @@
/// <reference types="svelte" />
/// <reference types="vite/client" />
+7
View File
@@ -0,0 +1,7 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
export default {
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
// for more information about preprocessors
preprocess: vitePreprocess(),
}
+14
View File
@@ -0,0 +1,14 @@
import { defineConfig } from "vite";
import { svelte } from "@sveltejs/vite-plugin-svelte";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [svelte()],
build: {
lib: { entry: "src/main.js", formats: ["iife"], name: "app" },
},
define: {
"process.env.NODE_ENV": '"production"',
__pkg__: '"0.42.0"'
},
});
@@ -0,0 +1,16 @@
// vite.config.js
import { defineConfig } from "file:///git/windmill/app-viewer-bundle/node_modules/vite/dist/node/index.js";
import { svelte } from "file:///git/windmill/app-viewer-bundle/node_modules/@sveltejs/vite-plugin-svelte/src/index.js";
var vite_config_default = defineConfig({
plugins: [svelte()],
build: {
lib: { entry: "src/main.js", formats: ["iife"], name: "app" }
},
define: {
"process.env.NODE_ENV": '"production"'
}
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvZ2l0L3dpbmRtaWxsL2FwcC12aWV3ZXItYnVuZGxlXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvZ2l0L3dpbmRtaWxsL2FwcC12aWV3ZXItYnVuZGxlL3ZpdGUuY29uZmlnLmpzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9naXQvd2luZG1pbGwvYXBwLXZpZXdlci1idW5kbGUvdml0ZS5jb25maWcuanNcIjtpbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHsgc3ZlbHRlIH0gZnJvbSBcIkBzdmVsdGVqcy92aXRlLXBsdWdpbi1zdmVsdGVcIjtcblxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XG4gIHBsdWdpbnM6IFtzdmVsdGUoKV0sXG4gIGJ1aWxkOiB7XG4gICAgbGliOiB7IGVudHJ5OiBcInNyYy9tYWluLmpzXCIsIGZvcm1hdHM6IFtcImlpZmVcIl0sIG5hbWU6IFwiYXBwXCIgfSxcbiAgfSxcbiAgZGVmaW5lOiB7XG4gICAgXCJwcm9jZXNzLmVudi5OT0RFX0VOVlwiOiAnXCJwcm9kdWN0aW9uXCInLFxuICB9LFxufSk7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQStRLFNBQVMsb0JBQW9CO0FBQzVTLFNBQVMsY0FBYztBQUd2QixJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMxQixTQUFTLENBQUMsT0FBTyxDQUFDO0FBQUEsRUFDbEIsT0FBTztBQUFBLElBQ0wsS0FBSyxFQUFFLE9BQU8sZUFBZSxTQUFTLENBQUMsTUFBTSxHQUFHLE1BQU0sTUFBTTtBQUFBLEVBQzlEO0FBQUEsRUFDQSxRQUFRO0FBQUEsSUFDTix3QkFBd0I7QUFBQSxFQUMxQjtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
+9 -1
View File
@@ -1,6 +1,6 @@
{
"name": "windmill-components",
"version": "1.377.1",
"version": "1.377.3",
"scripts": {
"dev": "vite dev",
"build": "vite build",
@@ -326,6 +326,11 @@
"types": "./package/components/DropdownV2.svelte.d.ts",
"svelte": "./package/components/DropdownV2.svelte",
"default": "./package/components/DropdownV2.svelte"
},
"./components/AppEmbed.svelte": {
"types": "./package/components/apps/AppEmbed.svelte.d.ts",
"svelte": "./package/components/apps/AppEmbed.svelte",
"default": "./package/components/apps/AppEmbed.svelte"
}
},
"files": [
@@ -443,6 +448,9 @@
],
"components/DropdownV2.svelte": [
"./package/components/DropdownV2.svelte.d.ts"
],
"components/AppEmbed.svelte": [
"./package/components/AppEmbed.svelte.d.ts"
]
}
},
+62 -55
View File
@@ -7,7 +7,7 @@
import Okta from '$lib/components/icons/brands/Okta.svelte'
import { OauthService, UserService, WorkspaceService } from '$lib/gen'
import { usersWorkspaceStore, workspaceStore, userStore } from '$lib/stores'
import { usersWorkspaceStore, workspaceStore, userStore, enterpriseLicense } from '$lib/stores'
import { classNames, emptyString, parseQueryParams } from '$lib/utils'
import { base } from '$lib/base'
import { getUserExt } from '$lib/user'
@@ -22,6 +22,7 @@
export let password: string | undefined = undefined
export let error: string | undefined = undefined
export let popup: boolean = false
export let loginPasswordRequireEEOnPublicApps: boolean = false
const providers = [
{
@@ -262,68 +263,74 @@
{/if}
{#if showPassword}
<div>
<div class="space-y-6">
{#if isCloudHosted()}
<p class="text-xs text-tertiary italic pb-6">
To get credentials without the OAuth providers above, send an email at
contact@windmill.dev
</p>
{/if}
<div>
<label for="email" class="block text-sm font-medium leading-6 text-primary">
Email
</label>
{#if loginPasswordRequireEEOnPublicApps && !$enterpriseLicense}
<p class="text-xs text-red-400 italic p-6">
To log in with email and password on a public app, Windmill requires an enterprise license
</p>
{:else}
<div>
<div class="space-y-6">
{#if isCloudHosted()}
<p class="text-xs text-tertiary italic pb-6">
To get credentials without the OAuth providers above, send an email at
contact@windmill.dev
</p>
{/if}
<div>
<input
type="email"
bind:value={email}
id="email"
autocomplete="email"
class="block w-full rounded-md border-0 py-1.5 text-primary shadow-sm ring-1 ring-inset placeholder:text-secondary focus:ring-2 focus:ring-inset focus:ring-frost-600 sm:text-sm sm:leading-6"
/>
<label for="email" class="block text-sm font-medium leading-6 text-primary">
Email
</label>
<div>
<input
type="email"
bind:value={email}
id="email"
autocomplete="email"
class="block w-full rounded-md border-0 py-1.5 text-primary shadow-sm ring-1 ring-inset placeholder:text-secondary focus:ring-2 focus:ring-inset focus:ring-frost-600 sm:text-sm sm:leading-6"
/>
</div>
</div>
</div>
<div>
<label for="password" class="block text-sm font-medium leading-6 text-primary">
Password
</label>
<div>
<input
on:keyup={handleKeyUp}
bind:value={password}
id="password"
type="password"
autocomplete="current-password"
class="block w-full rounded-md border-0 py-1.5 text-shadow shadow-sm ring-1 ring-inset placeholder:text-secondary focus:ring-2 focus:ring-inset focus:ring-frost-600 sm:text-sm sm:leading-6"
/>
<label for="password" class="block text-sm font-medium leading-6 text-primary">
Password
</label>
<div>
<input
on:keyup={handleKeyUp}
bind:value={password}
id="password"
type="password"
autocomplete="current-password"
class="block w-full rounded-md border-0 py-1.5 text-shadow shadow-sm ring-1 ring-inset placeholder:text-secondary focus:ring-2 focus:ring-inset focus:ring-frost-600 sm:text-sm sm:leading-6"
/>
</div>
</div>
</div>
<div class="pt-2">
<button
on:click={login}
disabled={!email || !password}
class="flex w-full justify-center rounded-md bg-frost-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-frost-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-frost-600"
>
Sign in
</button>
<div class="pt-2">
<button
on:click={login}
disabled={!email || !password}
class="flex w-full justify-center rounded-md bg-frost-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-frost-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-frost-600"
>
Sign in
</button>
</div>
</div>
</div>
{/if}
{/if}
{#if isCloudHosted()}
<p class="text-2xs text-tertiary italic mt-10 text-center">
By logging in, you agree to our
<a href="https://windmill.dev/terms_of_service" target="_blank" rel="noreferrer">
Terms of Service
</a>
and
<a href="https://windmill.dev/privacy_policy" target="_blank" rel="noreferrer">
Privacy Policy
</a>
</p>
{/if}
</div>
{#if isCloudHosted()}
<p class="text-2xs text-tertiary italic mt-10 text-center">
By logging in, you agree to our
<a href="https://windmill.dev/terms_of_service" target="_blank" rel="noreferrer">
Terms of Service
</a>
and
<a href="https://windmill.dev/privacy_policy" target="_blank" rel="noreferrer">
Privacy Policy
</a>
</p>
{/if}
</div>
@@ -21,7 +21,7 @@
export let render: boolean
export let horizontalAlignment: 'left' | 'center' | 'right' | undefined = undefined
const { app, worldStore, policy } = getContext<AppViewerContext>('AppViewerContext')
const { app, worldStore } = getContext<AppViewerContext>('AppViewerContext')
let resolvedConfig = initConfig(
components['recomputeallcomponent'].initialData.configuration,
@@ -59,7 +59,7 @@
<InitializeComponent {id} />
<AlignWrapper {horizontalAlignment}>
{#if render && policy}
{#if render}
<RecomputeAllWrapper
containerClass={css?.container?.class}
containerStyle={css?.container?.style}
@@ -119,8 +119,8 @@
email: $userStore?.email,
groups: $userStore?.groups,
username: $userStore?.username,
query: Object.fromEntries($page.url.searchParams.entries()),
hash: $page.url.hash,
query: Object.fromEntries(new URLSearchParams(window.location.search).entries()),
hash: window.location.hash,
workspace: $workspaceStore,
mode: 'editor',
summary: $summaryStore,
@@ -168,7 +168,6 @@
previewTheme,
debuggingComponents: writable({}),
replaceStateFn: (path) => replaceState(path, $page.state),
policy: policy,
recomputeAllContext: writable({
loading: false,
componentNumber: 0,
@@ -218,6 +217,10 @@
function hashchange(e: HashChangeEvent) {
context.hash = e.newURL.split('#')[1]
context = context
worldStore.update((x) => {
x.outputsById?.['ctx']?.['hash'].set(context.hash, true)
return x
})
}
$: context.mode = $mode == 'dnd' ? 'editor' : 'viewer'
@@ -570,7 +573,7 @@
app={$appStore}
appPath={path}
{breakpoint}
{policy}
author={policy.on_behalf_of_email ?? ''}
isEditor
{context}
noBackend={false}
@@ -0,0 +1,165 @@
<script lang="ts">
import { BROWSER } from 'esm-env'
import { base } from '$lib/base'
import AppPreview from '$lib/components/apps/editor/AppPreview.svelte'
import { IS_APP_PUBLIC_CONTEXT_KEY, type EditorBreakpoint } from '$lib/components/apps/types'
import { Alert, Skeleton } from '$lib/components/common'
import { WindmillIcon } from '$lib/components/icons'
import { AppService, type AppWithLastVersion } from '$lib/gen'
import { enterpriseLicense, userStore } from '$lib/stores'
import { twMerge } from 'tailwind-merge'
import { setContext } from 'svelte'
import { writable } from 'svelte/store'
import { setLicense } from '$lib/enterpriseUtils'
import { isCloudHosted } from '$lib/cloud'
import Login from '$lib/components/Login.svelte'
import { getUserExt } from '$lib/user'
import { User, UserRoundX } from 'lucide-svelte'
export let workspace: string
export let secret: string | undefined = undefined
export let path: string | undefined = undefined
export let replaceStateFn: (path: string) => void = (path: string) =>
window.history.replaceState(null, '', path)
export let gotoFn: (path: string, opt?: Record<string, any> | undefined) => void = (
path: string,
opt?: Record<string, any>
) => window.history.pushState(null, '', path)
export let hideUser = false
let app: (AppWithLastVersion & { value: any }) | undefined = undefined
let notExists = false
let noPermission = false
let neitherSecretNorPath = !secret && !path
setContext(IS_APP_PUBLIC_CONTEXT_KEY, true)
async function loadApp() {
try {
neitherSecretNorPath = !secret && !path
if (neitherSecretNorPath) {
throw new Error('No secret or path provided')
}
app = secret
? await AppService.getPublicAppBySecret({
workspace: workspace,
path: secret
})
: await AppService.getAppByPath({
workspace: workspace,
path: path!
})
noPermission = false
notExists = false
} catch (e) {
if (e.status == 401) {
noPermission = true
} else {
notExists = true
}
}
}
if (BROWSER) {
setLicense()
loadUser().then(() => {
loadApp()
})
}
async function loadUser() {
try {
userStore.set(await getUserExt(workspace))
} catch (e) {
console.warn('Anonymous user')
}
}
const breakpoint = writable<EditorBreakpoint>('lg')
const darkMode =
window.localStorage.getItem('dark-mode') ??
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
if (darkMode === 'dark') {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
</script>
<div
class="z-50 text-xs fixed bottom-1 right-2 {$enterpriseLicense && !isCloudHosted()
? 'transition-opacity delay-1000 duration-1000 opacity-20 hover:delay-0 hover:opacity-100'
: ''}"
>
<a href="https://windmill.dev" class="whitespace-nowrap text-tertiary inline-flex items-center"
>Powered by &nbsp;<WindmillIcon />&nbsp;Windmill</a
>
</div>
{#if !hideUser}
<div class="z-50 text-2xs text-tertiary absolute top-3 left-2"
>{#if $userStore}
<div class="flex gap-1 items-center"><User size={14} />{$userStore.username}</div>
{:else}<UserRoundX size={14} />{/if}
</div>
{/if}
{#if notExists}
<div class="px-4 mt-20"
><Alert type="error" title="Not found"
>There was an error loading the app, is the url correct? <a href={base}>Go to Windmill</a>
</Alert></div
>
{:else if noPermission}
<div class="px-4 mt-20 w-full text-center font-bold text-xl"
>{#if $userStore}You are logged in but have no read access for this app{:else}You must be logged
in and have read access for this app{/if}</div
>
<div class="px-2 mx-auto mt-20 max-w-xl w-full">
<Login
loginPasswordRequireEEOnPublicApps
on:login={() => {
// window.location.reload()
loadUser().then(() => {
loadApp()
})
app = app
}}
popup
rd={window.location.href}
/>
</div>
{:else if app}
{#key app}
<div
class={twMerge(
'min-h-screen h-full w-full',
app?.value?.['css']?.['app']?.['viewer']?.class,
'wm-app-viewer'
)}
style={app?.value?.['css']?.['app']?.['viewer']?.style}
>
<AppPreview
noBackend={false}
username={$userStore?.username ?? 'anonymous'}
email={$userStore?.email ?? 'anonymous'}
groups={$userStore?.groups ?? []}
{workspace}
summary={app.summary}
app={app.value}
appPath={app.path}
{breakpoint}
author={app.policy.on_behalf_of_email ?? ''}
isEditor={false}
{replaceStateFn}
{gotoFn}
/>
</div>
{/key}
{:else}
<Skeleton layout={[[4], 0.5, [50]]} />
{/if}
@@ -9,7 +9,6 @@
EditorBreakpoint,
EditorMode
} from '../types'
import type { Policy } from '$lib/gen'
import Button from '../../common/button/Button.svelte'
import { Unlock } from 'lucide-svelte'
import GridViewer from './GridViewer.svelte'
@@ -19,7 +18,7 @@
import { deepEqual } from 'fast-equals'
import { dfs, maxHeight } from './appUtils'
import { BG_PREFIX, migrateApp } from '../utils'
import { workspaceStore, enterpriseLicense } from '$lib/stores'
import { workspaceStore, enterpriseLicense, userStore } from '$lib/stores'
import DarkModeObserver from '$lib/components/DarkModeObserver.svelte'
import { getTheme } from './componentsPanel/themeUtils'
import HiddenComponent from '../components/helpers/HiddenComponent.svelte'
@@ -28,11 +27,11 @@
export let app: App
export let appPath: string = ''
export let breakpoint: Writable<EditorBreakpoint> = writable('lg')
export let policy: Policy = {}
export let author: string
export let summary: string = ''
export let workspace: string = $workspaceStore!
export let isEditor: boolean = false
export let context: Record<string, any>
export let noBackend: boolean = false
export let isLocked = false
export let hideRefreshBar = false
@@ -46,6 +45,10 @@
migrateApp(app)
let email: string = $userStore?.email ?? 'anonymous'
let groups: string[] = $userStore?.groups ?? []
let username: string = $userStore?.username ?? 'anonymous'
const appStore = writable<App>(app)
const selectedComponent = writable<string[] | undefined>(undefined)
const mode = writable<EditorMode>('preview')
@@ -59,11 +62,15 @@
const allIdsInPath = writable<string[]>([])
let ncontext: any = {
...context,
email,
groups,
username,
query: Object.fromEntries(new URLSearchParams(window.location.search).entries()),
hash: window.location.hash,
workspace,
mode: 'viewer',
summary: summary,
author: policy.on_behalf_of_email
author
}
function resizeWindow() {
@@ -80,7 +87,15 @@
let parentContext = getContext<AppViewerContext>('AppViewerContext')
let worldStore = buildWorld(ncontext)
$: onContextChange(context)
$: onContextChange({
email,
groups,
username,
workspace,
summary: summary,
author
})
function onContextChange(context: any) {
Object.assign(ncontext, context)
@@ -136,7 +151,6 @@
debuggingComponents: writable({}),
replaceStateFn,
gotoFn,
policy,
recomputeAllContext: writable({
loading: false,
componentNumber: 0,
@@ -239,7 +253,7 @@
<h2 class="truncate">{summary}</h2>
<RecomputeAllComponents />
<div class="text-2xs text-secondary">
{policy.on_behalf_of ? `on behalf of ${policy.on_behalf_of_email}` : ''}
{author != '' ? `on behalf of ${author}` : ''}
</div>
</div>
</div>
@@ -179,7 +179,7 @@
</Button>
</div>
</div>
<AppPreview noBackend app={selected.value} context={{}} />
<AppPreview author="" noBackend app={selected.value} />
{:else}
<Skeleton layout={[[40]]} />
{/if}
+1 -2
View File
@@ -1,5 +1,5 @@
import type { Schema } from '$lib/common'
import type { Policy, Preview } from '$lib/gen'
import type { Preview } from '$lib/gen'
import type { History } from '$lib/history'
import type { Writable } from 'svelte/store'
@@ -274,7 +274,6 @@ export type AppViewerContext = {
debuggingComponents: Writable<Record<string, number>>
replaceStateFn?: ((url: string) => void) | undefined
gotoFn?: ((url: string, opt?: Record<string, any> | undefined) => void) | undefined
policy: Policy
recomputeAllContext: Writable<{
onClick?: () => void
@@ -189,14 +189,9 @@
app={appViewerApp?.app?.value}
appPath="''"
{breakpoint}
policy={{}}
author=""
workspace="hub"
isEditor={false}
context={{
username: $userStore?.username ?? 'anonymous',
email: $userStore?.email ?? 'anonymous',
groups: $userStore?.groups ?? []
}}
summary={appViewerApp?.app.summary ?? ''}
noBackend
replaceStateFn={(path) => replaceState(path, $page.state)}
@@ -46,19 +46,12 @@
style={app?.value.css?.['app']?.['viewer']?.style}
>
<AppPreview
context={{
email: $userStore?.email,
username: $userStore?.username,
groups: $userStore?.groups,
query: Object.fromEntries($page.url.searchParams.entries()),
hash: $page.url.hash
}}
workspace={$workspaceStore ?? ''}
summary={app.summary}
app={app.value}
appPath={app.path}
{breakpoint}
policy={app.policy}
author={app.policy.on_behalf_of_email ?? ''}
isEditor={false}
noBackend={false}
{hideRefreshBar}
@@ -1,146 +1,12 @@
<script lang="ts">
import { BROWSER } from 'esm-env'
import { page } from '$app/stores'
import { base } from '$lib/base'
import AppPreview from '$lib/components/apps/editor/AppPreview.svelte'
import { IS_APP_PUBLIC_CONTEXT_KEY, type EditorBreakpoint } from '$lib/components/apps/types'
import { Alert, Skeleton } from '$lib/components/common'
import { WindmillIcon } from '$lib/components/icons'
import { AppService, type AppWithLastVersion } from '$lib/gen'
import { enterpriseLicense, userStore } from '$lib/stores'
import { twMerge } from 'tailwind-merge'
import { setContext } from 'svelte'
import { writable } from 'svelte/store'
import { setLicense } from '$lib/enterpriseUtils'
import { isCloudHosted } from '$lib/cloud'
import Login from '$lib/components/Login.svelte'
import { getUserExt } from '$lib/user'
import { User, UserRoundX } from 'lucide-svelte'
import { goto, replaceState } from '$app/navigation'
let app: (AppWithLastVersion & { value: any }) | undefined = undefined
let notExists = false
let noPermission = false
setContext(IS_APP_PUBLIC_CONTEXT_KEY, true)
async function loadApp() {
try {
app = await AppService.getPublicAppBySecret({
workspace: $page.params.workspace,
path: $page.params.secret
})
noPermission = false
notExists = false
} catch (e) {
if (e.status == 401) {
noPermission = true
} else {
notExists = true
}
}
}
if (BROWSER) {
setLicense()
loadUser().then(() => {
loadApp()
})
}
async function loadUser() {
try {
userStore.set(await getUserExt($page.params.workspace))
} catch (e) {
console.warn('Anonymous user')
}
}
const breakpoint = writable<EditorBreakpoint>('lg')
const darkMode =
window.localStorage.getItem('dark-mode') ??
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
if (darkMode === 'dark') {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
import { page } from '$app/stores'
import AppEmbed from '$lib/components/apps/editor/AppEmbed.svelte'
</script>
<div
class="z-50 text-xs fixed bottom-1 right-2 {$enterpriseLicense && !isCloudHosted()
? 'transition-opacity delay-1000 duration-1000 opacity-20 hover:delay-0 hover:opacity-100'
: ''}"
>
<a href="https://windmill.dev" class="whitespace-nowrap text-tertiary inline-flex items-center"
>Powered by &nbsp;<WindmillIcon />&nbsp;Windmill</a
>
</div>
<div class="z-50 text-2xs text-tertiary absolute top-3 left-2"
>{#if $userStore}
<div class="flex gap-1 items-center"><User size={14} />{$userStore.username}</div>
{:else}<UserRoundX size={14} />{/if}
</div>
{#if notExists}
<div class="px-4 mt-20"
><Alert type="error" title="Not found"
>There was an error loading the app, is the url correct? <a href={base}>Go to Windmill</a>
</Alert></div
>
{:else if noPermission}
<div class="px-4 mt-20 w-full text-center font-bold text-xl"
>{#if $userStore}You are logged in but have no read access for this app{:else}You must be logged
in and have read access for this app{/if}</div
>
<div class="px-2 mx-auto mt-20 max-w-xl w-full">
<Login
on:login={() => {
// window.location.reload()
loadUser().then(() => {
loadApp()
})
app = app
}}
popup
rd={$page.url.toString()}
/>
</div>
{:else if app}
{#key app}
<div
class={twMerge(
'min-h-screen h-full w-full',
app?.value?.['css']?.['app']?.['viewer']?.class,
'wm-app-viewer'
)}
style={app?.value?.['css']?.['app']?.['viewer']?.style}
>
<AppPreview
noBackend={false}
context={{
email: $userStore?.email,
groups: $userStore?.groups,
username: $userStore?.username,
query: Object.fromEntries($page.url.searchParams.entries()),
hash: $page.url.hash
}}
workspace={$page.params.workspace}
summary={app.summary}
app={app.value}
appPath={app.path}
{breakpoint}
policy={app.policy}
isEditor={false}
replaceStateFn={(path) => replaceState(path, $page.state)}
gotoFn={(path, opt) => goto(path, opt)}
/>
</div>
{/key}
{:else}
<Skeleton layout={[[4], 0.5, [50]]} />
{/if}
<AppEmbed
workspace={$page.params.workspace}
secret={$page.params.secret}
replaceStateFn={(path) => replaceState(path, $page.state)}
gotoFn={(path, opt) => goto(path, opt)}
/>