Compare commits

...

4 Commits

Author SHA1 Message Date
Ruben Fiszel
a974e48988 all 2024-08-12 18:36:30 +02:00
Ruben Fiszel
e7d08359fc fix compile 2024-08-12 10:36:37 +02:00
Ruben Fiszel
22c2d248b2 Merge branch 'main' into rf/bundle 2024-08-12 09:55:50 +02:00
Ruben Fiszel
30b90e4951 all 2024-08-12 09:37:53 +02:00
50 changed files with 1543 additions and 427 deletions

View File

@@ -0,0 +1,8 @@
export default {
plugins: {
"postcss-import": {},
"tailwindcss/nesting": "postcss-nesting",
tailwindcss: {},
autoprefixer: {},
},
};

View File

@@ -0,0 +1,950 @@
/** @type {import('tailwindcss').Config} */
export default {
content: [],
theme: {
extend: {},
},
plugins: [],
};
const plugin = require("tailwindcss/plugin");
const lightTheme = {
surface: "#ffffff",
surfaceSecondary: "#f3f4f6",
surfaceHover: "#e5e7eb",
surfaceDisabled: "#f9fafb",
surfaceSelected: "#d1d5db",
textPrimary: "#2d3748",
textSecondary: "#4a5568",
textTertiary: "#505c70",
textDisabled: "#a0aec0",
border: "#ddd",
borderHover: "#ccc",
};
const lightThemeRgb = makeRgb(lightTheme);
const darkTheme = {
surface: "#2e3440",
surfaceSecondary: "#3b4252",
surfaceHover: "#454F64",
surfaceDisabled: "#212732",
surfaceSelected: "#434c5e",
textPrimary: "#EEEEEE",
textSecondary: "#C2C9D1",
textTertiary: "#A8AEB7",
textDisabled: "#989DA5",
border: "#3e4c60",
borderHover: "#3e4c60",
};
const darkThemeRgb = makeRgb(darkTheme);
function makeRgb(theme) {
return Object.fromEntries(
Object.entries(theme).map(([key, value]) => {
if (typeof value === "string" && value.startsWith("#")) {
return [key, hexToRgb(value)];
}
return [key, value];
})
);
}
function hexToRgb(hex) {
// Remove '#' symbol from the beginning of the hex value
hex = hex.replace("#", "");
// Convert the hex value to decimal
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
// Return the RGB string format
return `${r} ${g} ${b}`;
}
/** @type {import('tailwindcss').Config} */
const config = {
content: [
"./src/**/*.{html,js,svelte,ts}",
"./node_modules/windmill-components/**/*.{html,js,svelte,ts}",
],
safelist: [
"hljs",
"splitpanes__pane",
"splitpanes__splitter",
"wm-tab",
"autocomplete-list",
"autocomplete-list-item",
"autocomplete-list-item-create",
"selected",
"wm-tab-selected",
...(process.env.NODE_ENV === "production"
? [
{ pattern: /^m(\w?)-.*$/ },
{ pattern: /^p(\w?)-.*$/ },
{ pattern: /^rounded-.*$/ },
{ pattern: /^shadow-.*$/, variants: ["hover"] },
{ pattern: /^text-[^/]*$/, variants: ["hover", "active", "focus"] },
{ pattern: /^bg-[^/]*$/, variants: ["hover", "active", "focus"] },
{ pattern: /^border-[^/]*$/, variants: ["hover", "active", "focus"] },
{ pattern: /^ring-[^/]*$/, variants: ["hover", "active", "focus"] },
]
: []),
],
theme: {
colors: {
current: "currentcolor",
transparent: "transparent",
white: "#ffffff",
black: "#000000",
slate: {
50: "#f8fafc",
100: "#f1f5f9",
200: "#e2e8f0",
300: "#cbd5e1",
400: "#94a3b8",
500: "#64748b",
600: "#475569",
700: "#334155",
800: "#1e293b",
900: "#0f172a",
},
zinc: {
50: "#fafafa",
100: "#f4f4f5",
200: "#e4e4e7",
300: "#d4d4d8",
400: "#a1a1aa",
500: "#71717a",
600: "#52525b",
700: "#3f3f46",
800: "#27272a",
900: "#18181b",
},
neutral: {
50: "#fafafa",
100: "#f5f5f5",
200: "#e5e5e5",
300: "#d4d4d4",
400: "#a3a3a3",
500: "#737373",
600: "#525252",
700: "#404040",
800: "#262626",
900: "#171717",
},
stone: {
50: "#fafaf9",
100: "#f5f5f4",
200: "#e7e5e4",
300: "#d6d3d1",
400: "#a8a29e",
500: "#78716c",
600: "#57534e",
700: "#44403c",
800: "#292524",
900: "#1c1917",
},
orange: {
50: "#fff7ed",
100: "#ffedd5",
200: "#fed7aa",
300: "#fdba74",
400: "#fb923c",
500: "#f97316",
600: "#ea580c",
700: "#c2410c",
800: "#9a3412",
900: "#7c2d12",
},
amber: {
50: "#fffbeb",
100: "#fef3c7",
200: "#fde68a",
300: "#fcd34d",
400: "#fbbf24",
500: "#f59e0b",
600: "#d97706",
700: "#b45309",
800: "#92400e",
900: "#78350f",
},
lime: {
50: "#f7fee7",
100: "#ecfccb",
200: "#d9f99d",
300: "#bef264",
400: "#a3e635",
500: "#84cc16",
600: "#65a30d",
700: "#4d7c0f",
800: "#3f6212",
900: "#365314",
},
emerald: {
50: "#ecfdf5",
100: "#d1fae5",
200: "#a7f3d0",
300: "#6ee7b7",
400: "#34d399",
500: "#10b981",
600: "#059669",
700: "#047857",
800: "#065f46",
900: "#064e3b",
},
teal: {
50: "#f0fdfa",
100: "#ccfbf1",
200: "#99f6e4",
300: "#5eead4",
400: "#2dd4bf",
500: "#14b8a6",
600: "#0d9488",
700: "#0f766e",
800: "#115e59",
900: "#134e4a",
},
cyan: {
50: "#ecfeff",
100: "#cffafe",
200: "#a5f3fc",
300: "#67e8f9",
400: "#22d3ee",
500: "#06b6d4",
600: "#0891b2",
700: "#0e7490",
800: "#155e75",
900: "#164e63",
},
sky: {
50: "#f0f9ff",
100: "#e0f2fe",
200: "#bae6fd",
300: "#7dd3fc",
400: "#38bdf8",
500: "#0ea5e9",
600: "#0284c7",
700: "#0369a1",
800: "#075985",
900: "#0c4a6e",
},
violet: {
50: "#f5f3ff",
100: "#ede9fe",
200: "#ddd6fe",
300: "#c4b5fd",
400: "#a78bfa",
500: "#8b5cf6",
600: "#7c3aed",
700: "#6d28d9",
800: "#5b21b6",
900: "#4c1d95",
},
purple: {
50: "#faf5ff",
100: "#f3e8ff",
200: "#e9d5ff",
300: "#d8b4fe",
400: "#c084fc",
500: "#a855f7",
600: "#9333ea",
700: "#7e22ce",
800: "#6b21a8",
900: "#581c87",
},
fuchsia: {
50: "#fdf4ff",
100: "#fae8ff",
200: "#f5d0fe",
300: "#f0abfc",
400: "#e879f9",
500: "#d946ef",
600: "#c026d3",
700: "#a21caf",
800: "#86198f",
900: "#701a75",
},
pink: {
50: "#fdf2f8",
100: "#fce7f3",
200: "#fbcfe8",
300: "#f9a8d4",
400: "#f472b6",
500: "#ec4899",
600: "#db2777",
700: "#be185d",
800: "#9d174d",
900: "#831843",
},
rose: {
50: "#fff1f2",
100: "#ffe4e6",
200: "#fecdd3",
300: "#fda4af",
400: "#fb7185",
500: "#f43f5e",
600: "#e11d48",
700: "#be123c",
800: "#9f1239",
900: "#881337",
},
gray: {
50: "#f9fafb",
100: "#f3f4f6",
200: "#e5e7eb",
300: "#d1d5db",
400: "#9ca3af",
500: "#6b7280",
600: "#4b5563",
700: "#374151",
800: "#1f2937",
900: "#111827",
},
red: {
50: "#fef2f2",
100: "#fee2e2",
200: "#fecaca",
300: "#fca5a5",
400: "#f87171",
500: "#ef4444",
600: "#dc2626",
700: "#b91c1c",
800: "#991b1b",
900: "#7f1d1d",
},
orange: {
100: "#ffedd5",
200: "#ffedd5",
300: "#FDC089",
400: "#fb923c",
500: "#f97316",
600: "#ea580c",
700: "#c2410c",
800: "#c2410c",
},
yellow: {
50: "#fefce8",
100: "#fef9c3",
200: "#fef08a",
300: "#fde047",
400: "#facc15",
500: "#eab308",
600: "#ca8a04",
700: "#a16207",
800: "#854d0e",
900: "#713f12",
},
green: {
50: "#f0fdf4",
100: "#dcfce7",
200: "#bbf7d0",
300: "#86efac",
400: "#4ade80",
500: "#22c55e",
600: "#16a34a",
700: "#15803d",
800: "#166534",
900: "#14532d",
},
blue: {
50: "#eff6ff",
100: "#dbeafe",
200: "#bfdbfe",
300: "#93c5fd",
400: "#60a5fa",
500: "#3b82f6",
600: "#2563eb",
700: "#1d4ed8",
800: "#1e40af",
900: "#1e3a8a",
},
indigo: {
50: "#eef2ff",
100: "#e0e7ff",
200: "#c7d2fe",
300: "#a5b4fc",
400: "#818cf8",
500: "#6366f1",
600: "#4f46e5",
700: "#4338ca",
800: "#3730a3",
900: "#312e81",
},
frost: {
50: "#f5f7fa",
100: "#eaeef4",
200: "#cfd9e8",
300: "#a6bad3",
400: "#7594bb",
500: "#5e81ac",
600: "#415f88",
700: "#364d6e",
800: "#2f425d",
900: "#2b394f",
950: "#1d2534",
},
marine: {
50: "#E9E9F4",
100: "#859AC7",
200: "#586F9E",
300: "#4A5F8A",
400: "#394A6D",
500: "#323F5B",
},
surface: "rgb(var(--color-surface) / <alpha-value>)",
"surface-secondary":
"rgb(var(--color-surface-secondary) / <alpha-value>)",
"surface-hover": "rgb(var(--color-surface-hover) / <alpha-value>)",
"surface-disabled": "rgb(var(--color-surface-disabled) / <alpha-value>)",
"surface-selected": "rgb(var(--color-surface-selected) / <alpha-value>)",
primary: "rgb(var(--color-text-primary) / <alpha-value>)",
secondary: "rgb(var(--color-text-secondary) / <alpha-value>)",
tertiary: "rgb(var(--color-text-tertiary) / <alpha-value>)",
disabled: "rgb(var(--color-text-disabled) / <alpha-value>)",
"surface-inverse": "rgb(var(--color-surface-inverse) / <alpha-value>)",
"surface-secondary-inverse":
"rgb(var(--color-surface-secondary-inverse) / <alpha-value>)",
"surface-hover-inverse":
"rgb(var(--color-surface-hover-inverse) / <alpha-value>)",
"surface-disabled-inverse":
"rgb(var(--color-surface-disabled-inverse) / <alpha-value>)",
"surface-selected-inverse":
"rgb(var(--color-surface-selected-inverse) / <alpha-value>)",
"primary-inverse":
"rgb(var(--color-text-primary-inverse) / <alpha-value>)",
"secondary-inverse":
"rgb(var(--color-text-secondary-inverse) / <alpha-value>)",
"tertiary-inverse":
"rgb(var(--color-text-tertiary-inverse) / <alpha-value>)",
"disabled-inverse":
"rgb(var(--color-text-disabled-inverse) / <alpha-value>)",
},
fontFamily: {
// add double quotes if there is space in font name
main: ["Inter", "sans-serif"],
mono: [
"ui-monospace",
"SFMono-Regular",
"Menlo",
"Monaco",
"Consolas",
'"Liberation Mono"',
'"Courier New"',
"monospace",
],
},
extend: {
border: {
color: "red",
},
borderRadius: {
component: "0.250rem",
},
maxHeight: {
"1/2": "50vh",
"2/3": "66vh",
"3/4": "75vh",
},
minWidth: {
"1/4": "25%",
"1/3": "33%",
"1/2": "50%",
"2/3": "66%",
"3/4": "75%",
},
minHeight: {
"1/2": "50vh",
},
height: {
"2/3": "66vh",
},
transitionProperty: {
height: "height",
},
fontSize: {
"2xs": "0.7rem",
},
screens: {
fhd: "1900px",
qhd: "2500px",
"4k": "3800px",
},
animation: {
"spin-counter-clockwise": "spin-counter-clockwise 1s linear infinite",
},
keyframes: {
"spin-counter-clockwise": {
to: { transform: "rotate(-360deg)" },
},
},
},
},
plugins: [
require("@tailwindcss/forms"),
require("@tailwindcss/typography"),
// scopedPreflightStyles({
// isolationStrategy: isolateInsideOfContainer("#windmill-app"),
// }),
plugin(({ addBase, addComponents, addUtilities, theme }) => {
addBase({
fontFamily: theme("fontFamily.main"),
fontSize: theme("fontSize.base"),
fontWeight: theme("fontWeight.normal"),
backgroundColor: "rgb(var(--color-surface) / <alpha-value>)",
color: lightTheme.textPrimary,
"--color-surface": lightThemeRgb.surface,
"--color-surface-secondary": lightThemeRgb.surfaceSecondary,
"--color-surface-hover": lightThemeRgb.surfaceHover,
"--color-surface-disabled": lightThemeRgb.surfaceDisabled,
"--color-surface-selected": lightThemeRgb.surfaceSelected,
"--color-text-primary": lightThemeRgb.textPrimary,
"--color-text-secondary": lightThemeRgb.textSecondary,
"--color-text-tertiary": lightThemeRgb.textTertiary,
"--color-text-disabled": lightThemeRgb.textDisabled,
"--color-surface-inverse": darkThemeRgb.surface,
"--color-surface-secondary-inverse": darkThemeRgb.surfaceSecondary,
"--color-surface-hover-inverse": darkThemeRgb.surfaceHover,
"--color-surface-disabled-inverse": darkThemeRgb.surfaceDisabled,
"--color-surface-selected-inverse": darkThemeRgb.surfaceSelected,
"--color-text-primary-inverse": darkThemeRgb.textPrimary,
"--color-text-secondary-inverse": darkThemeRgb.textSecondary,
"--color-text-tertiary-inverse": darkThemeRgb.textTertiary,
"--color-text-disabled-inverse": darkThemeRgb.textDisabled,
"--color-border": lightThemeRgb.border,
"--color-border-hover": lightThemeRgb.borderHover,
"--vscode-editorSuggestWidget-background": "#f3f3f3",
"--vscode-editorHoverWidget-foreground": "#616161",
"--vscode-editorHoverWidget-border": "#c8c8c8",
"--vscode-editorHoverWidget-statusBarBackground": "#e7e7e7",
"--vscode-editorSuggestWidget-foreground": "#eeffff",
"--vscode-editorSuggestWidget-highlightForeground": "#80cbc4",
"--vscode-editorSuggestWidget-selectedBackground":
"rgba(0, 0, 0, 0.31)",
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: theme("fontSize.lg"),
},
"&.dark": {
backgroundColor: darkTheme.surface,
color: darkTheme.textPrimary,
"--color-surface": darkThemeRgb.surface,
"--color-surface-secondary": darkThemeRgb.surfaceSecondary,
"--color-surface-hover": darkThemeRgb.surfaceHover,
"--color-surface-disabled": darkThemeRgb.surfaceDisabled,
"--color-surface-selected": darkThemeRgb.surfaceSelected,
"--color-text-primary": darkThemeRgb.textPrimary,
"--color-text-secondary": darkThemeRgb.textSecondary,
"--color-text-tertiary": darkThemeRgb.textTertiary,
"--color-text-disabled": darkThemeRgb.textDisabled,
"--color-surface-inverse": lightThemeRgb.surface,
"--color-surface-secondary-inverse": lightThemeRgb.surfaceSecondary,
"--color-surface-hover-inverse": lightThemeRgb.surfaceHover,
"--color-surface-disabled-inverse": lightThemeRgb.surfaceDisabled,
"--color-surface-selected-inverse": lightThemeRgb.surfaceSelected,
"--color-text-primary-inverse": lightThemeRgb.textPrimary,
"--color-text-secondary-inverse": lightThemeRgb.textSecondary,
"--color-text-tertiary-inverse": lightThemeRgb.textTertiary,
"--color-text-disabled-inverse": lightThemeRgb.textDisabled,
"--color-border": darkThemeRgb.border,
"--color-border-hover": darkThemeRgb.borderHover,
"--vscode-editorSuggestWidget-background": "#252526",
"--vscode-editorHoverWidget-foreground": "#cccccc",
"--vscode-editorHoverWidget-border": "#454545",
"--vscode-editorHoverWidget-statusBarBackground": "#2c2c2d",
},
h1: {
fontSize: "24px",
fontWeight: theme("fontWeight.extrabold"),
lineHeight: "1.05",
[`@media (min-width: ${theme("screens.lg")})`]: {
fontSize: "26px",
},
[`@media (min-width: ${theme("screens.fhd")})`]: {
fontSize: "29px",
},
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: "34px",
},
},
h2: {
fontSize: "20px",
fontWeight: theme("fontWeight.extrabold"),
lineHeight: "1.1",
[`@media (min-width: ${theme("screens.fhd")})`]: {
fontSize: "22px",
},
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: "25px",
},
},
mark: {
backgroundColor: theme("colors.yellow.200"),
borderRadius: theme("borderRadius.sm"),
},
h3: {
fontSize: "18px",
fontWeight: theme("fontWeight.bold"),
lineHeight: "1.2",
[`@media (min-width: ${theme("screens.fhd")})`]: {
fontSize: "20px",
},
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: "22px",
},
},
h4: {
fontSize: "18px",
fontWeight: theme("fontWeight.semibold"),
lineHeight: "1.3",
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: "20px",
},
},
h5: {
fontSize: "16px",
fontWeight: theme("fontWeight.semibold"),
lineHeight: "1.5",
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: "18px",
},
},
h6: {
fontSize: "16px",
fontWeight: theme("fontWeight.medium"),
lineHeight: "1.5",
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: "18px",
},
},
button: {
fontWeight: theme("fontWeight.semibold"),
},
a: {
color: theme("colors.blue.500"),
},
".dark input::placeholder": {
color: theme("colors.gray.400"),
},
"[type='checkbox']:checked": {
backgroundImage: `url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='black' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");`,
},
".dark [type='checkbox']:checked": {
backgroundImage: `url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");`,
},
'input:not(.windmillapp),input[type="text"]:not(.windmillapp),input[type="email"]:not(.windmillapp),input[type="url"]:not(.windmillapp),input[type="password"]:not(.windmillapp),input[type="number"]:not(.windmillapp),input[type="date"]:not(.windmillapp),input[type="datetime-local"]:not(.windmillapp),input[type="month"]:not(.windmillapp),input[type="search"]:not(.windmillapp),input[type="tel"]:not(.windmillapp),input[type="time"]:not(.windmillapp),input[type="week"]:not(.windmillapp),textarea:not(.windmillapp):not(.monaco-mouse-cursor-text),select:not(.windmillapp)':
{
display: "block",
fontSize: theme("fontSize.sm"),
boxShadow: theme("boxShadow.sm"),
width: "100%",
padding: `${theme("spacing.1")} ${theme("spacing.2")}`,
border: `1px solid ${theme("colors.gray.300")}`,
borderRadius: theme("borderRadius.md"),
"&:focus": {
"--tw-ring-color": theme("colors.frost.100"),
"--tw-ring-offset-shadow":
"var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)",
"--tw-ring-shadow":
"var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)",
boxShadow:
"var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)",
},
"&:disabled,[disabled]": {
backgroundColor: theme("colors.gray.100") + " !important",
".dark &": {
backgroundColor: theme("colors.gray.700") + " !important",
},
},
},
'.dark input:not(.windmillapp),.dark input[type="text"]:not(.windmillapp),.dark input[type="email"]:not(.windmillapp),.dark input[type="url"]:not(.windmillapp),.dark input[type="password"]:not(.windmillapp),.dark input[type="number"]:not(.windmillapp),.dark input[type="date"]:not(.windmillapp),.dark input[type="datetime-local"]:not(.windmillapp),.dark input[type="month"]:not(.windmillapp),.dark input[type="search"]:not(.windmillapp),.dark input[type="tel"]:not(.windmillapp),.dark input[type="time"]:not(.windmillapp),.dark input[type="week"]:not(.windmillapp),.dark textarea:not(.windmillapp):not(.monaco-mouse-cursor-text),.dark select:not(.windmillapp)':
{
backgroundColor: theme("colors.gray.700"),
color: theme("colors.gray.200"),
borderColor: theme("colors.gray.600"),
"&:focus": {
"--tw-ring-color": theme("colors.frost.700"),
},
},
"button:disabled,button[disabled=true],a:disabled,a[disabled=true]": {
pointerEvents: "none",
cursor: "default",
opacity: "0.90",
},
"pre code.hljs": {
padding: "0px !important",
fontFamily: theme("fontFamily.mono"),
fontSize: theme("fontSize.xs") + " !important",
lineHeight: theme("lineHeight.4") + " !important",
},
".h1-textarea": {
fontSize: "24px !important",
fontWeight: `${theme("fontWeight.extrabold")} !important`,
lineHeight: "1.05 !important",
color: theme("!colors.gray.800"),
[`@media (min-width: ${theme("screens.lg")})`]: {
fontSize: "26px !important",
},
[`@media (min-width: ${theme("screens.fhd")})`]: {
fontSize: "29px !important",
},
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: "34px !important",
},
},
".h3-textarea": {
fontSize: "18px !important",
fontWeight: `${theme("fontWeight.bold")} !important`,
lineHeight: "1.2 !important",
color: theme("!colors.gray.600"),
[`@media (min-width: ${theme("screens.fhd")})`]: {
fontSize: "20px !important",
},
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: "22px !important",
},
},
".p-textarea": {
fontSize: "16px !important",
fontWeight: `${theme("fontWeight.normal")} !important`,
lineHeight: "1.5 !important",
color: theme("!colors.gray.600"),
[`@media (min-width: ${theme("screens.fhd")})`]: {
fontSize: "18px !important",
},
[`@media (min-width: ${theme("screens.qhd")})`]: {
fontSize: "20px !important",
},
},
input: {
backgroundColor: theme("colors.surface-secondary") + " !important",
},
textarea: {
backgroundColor: theme("colors.surface-secondary") + " !important",
},
});
addComponents({
".table-custom": {
"& th": {
paddingTop: theme("spacing.3"),
paddingRight: theme("spacing.1"),
paddingLeft: theme("spacing.1"),
paddingBottom: theme("spacing.3"),
fontSize: theme("fontSize.sm"),
textAlign: "left",
fontWeight: theme("fontWeight.semibold"),
color: theme("colors.gray.900"),
textTransform: "capitalize",
},
".dark & th": {
color: theme("colors.gray.200"),
},
"& td": {
paddingLeft: theme("spacing.1"),
paddingRight: theme("spacing.1"),
paddingTop: theme("spacing.2"),
paddingBottom: theme("spacing.2"),
fontSize: theme("fontSize.sm"),
color: theme("colors.gray.700"),
},
".dark & td ": {
color: theme("colors.gray.200"),
},
"& tbody > :not([hidden]) ~ :not([hidden])": {
borderTop: `1px solid ${theme("colors.gray.200")}`,
},
".dark & tbody > :not([hidden]) ~ :not([hidden])": {
borderTop: `1px solid ${theme("colors.gray.700")}`,
},
"& tbody > tr:hover": {
backgroundColor: theme("colors.gray.50"),
},
".dark & tbody > tr:hover": {
backgroundColor: theme("colors.gray.800"),
},
},
".commit-hash": {
fontSize: theme("fontSize.2xs"),
color: theme("colors.gray.500"),
backgroundColor: theme("colors.gray.200"),
fontFamily: theme("fontFamily.mono"),
},
".input-error": {
borderColor: `${theme("colors.red.500")} !important`,
},
".box": {
borderWidth: "1px",
borderRadius: theme("borderRadius.sm"),
boxShadow: theme("boxShadow.sm"),
padding: theme("spacing.4"),
},
".animate-skeleton": {
animation: theme("animation.pulse"),
backgroundColor: theme("colors.blue.100"),
borderRadius: theme("borderRadius.DEFAULT"),
},
".text-black-gradient": {
color: "transparent",
backgroundClip: "text",
backgroundImage: `linear-gradient(to right, ${theme(
"colors.black"
)}, ${theme("colors.gray.600")})`,
},
".splitpanes__pane": {
backgroundColor: lightTheme.surface + " !important",
overflow: "auto !important",
},
".dark .splitpanes__pane": {
backgroundColor: darkTheme.surface + " !important",
overflow: "auto !important",
},
".splitpanes__splitter": {
backgroundColor: lightTheme.border + " !important",
margin: "0 !important",
border: "none !important",
"&::after": {
backgroundColor: lightTheme.border + " !important",
margin: "0 !important",
transform: "none !important",
transition: "opacity 200ms !important",
opacity: "0",
"--splitter-hover-size": "5px",
"--splitter-hover-adjustment": "-2px",
},
"&:hover::after": {
opacity: "1",
zIndex: "1001 !important",
},
},
".dark .splitpanes__splitter": {
backgroundColor: darkTheme.border + " !important",
"&::after": {
backgroundColor: darkTheme.border + " !important",
},
},
".splitpanes--vertical>.splitpanes__splitter": {
width: "1px !important",
"&::before": {
left: "1px !important",
width: "0px !important",
marginLeft: "0 !important",
},
"&::after": {
top: "0 !important",
height: "100% !important",
left: "var(--splitter-hover-adjustment) !important",
width: "var(--splitter-hover-size) !important",
},
},
".splitpanes--horizontal>.splitpanes__splitter": {
height: "1px !important",
"&::before": {
top: "1px !important",
height: "0px !important",
marginTop: "0 !important",
},
"&::after": {
top: "var(--splitter-hover-adjustment) !important",
height: "var(--splitter-hover-size) !important",
left: "0 !important",
width: "100% !important",
},
},
// Windmill Tab classes
".wm-tab-active": {
borderColor: darkTheme.border,
color: lightTheme.textPrimary,
},
".dark .wm-tab-active": {
borderColor: lightTheme.border,
color: darkTheme.textPrimary,
},
});
addUtilities({
".separator": {
backgroundColor: `${lightTheme.border} !important`,
},
".dark .separator": {
backgroundColor: `${darkTheme.border} !important`,
},
".center-center": {
display: "flex",
justifyContent: "center",
alignItems: "center",
},
".inner-border": {
boxShadow: `inset 0 0 0 1px ${lightTheme.border}`,
},
".dark .inner-border": {
boxShadow: `inset 0 0 0 1px ${darkTheme.border}`,
},
".z5000": {
zIndex: "5000 !important",
},
".ellipsize": {
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
},
/** Set the '-webkit-line-clamp' property to the desired number of lines.
*
* Eg.: `class="ellipsize-multi-line [-webkit-line-clamp:3]"`
*/
".ellipsize-multi-line": {
display: "-webkit-box",
"-webkit-box-orient": "vertical",
overflow: "hidden",
},
".disabled": {
pointerEvents: "none",
cursor: "default",
filter: "grayscale(1)",
},
".scrollbar-hidden": {
"-ms-overflow-style": "none",
"scrollbar-width": "none",
"&::-webkit-scrollbar": {
display: "none",
width: "0px",
},
},
});
}),
],
darkMode: "class",
important: ".windmill-app",
};
module.exports = config;

243
backend/Cargo.lock generated
View File

@@ -459,7 +459,7 @@ dependencies = [
"proc-macro2",
"quote",
"swc_macros_common",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -542,7 +542,7 @@ checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c"
dependencies = [
"async-channel 2.3.1",
"async-executor",
"async-io 2.3.3",
"async-io 2.3.4",
"async-lock 3.4.0",
"blocking",
"futures-lite 2.3.0",
@@ -571,9 +571,9 @@ dependencies = [
[[package]]
name = "async-io"
version = "2.3.3"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964"
checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8"
dependencies = [
"async-lock 3.4.0",
"cfg-if",
@@ -581,11 +581,11 @@ dependencies = [
"futures-io",
"futures-lite 2.3.0",
"parking",
"polling 3.7.2",
"polling 3.7.3",
"rustix 0.38.34",
"slab",
"tracing",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -635,7 +635,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -683,7 +683,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -725,7 +725,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -779,9 +779,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "aws-config"
version = "1.5.4"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf6cfe2881cb1fcbba9ae946fb9a6480d3b7a714ca84c74925014a89ef3387a"
checksum = "4e95816a168520d72c0e7680c405a5a8c1fb6a035b4bc4b9d7b0de8e1a941697"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -799,7 +799,6 @@ dependencies = [
"fastrand 2.1.0",
"hex",
"http 0.2.12",
"hyper 0.14.30",
"ring 0.17.8",
"time",
"tokio",
@@ -822,9 +821,9 @@ dependencies = [
[[package]]
name = "aws-runtime"
version = "1.3.1"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87c5f920ffd1e0526ec9e70e50bf444db50b204395a0fa7016bbf9e31ea1698f"
checksum = "f42c2d4218de4dcd890a109461e2f799a1a2ba3bcd2cde9af88360f5df9266c6"
dependencies = [
"aws-credential-types",
"aws-sigv4",
@@ -837,6 +836,7 @@ dependencies = [
"fastrand 2.1.0",
"http 0.2.12",
"http-body 0.4.6",
"once_cell",
"percent-encoding",
"pin-project-lite",
"tracing",
@@ -845,9 +845,9 @@ dependencies = [
[[package]]
name = "aws-sdk-sso"
version = "1.36.0"
version = "1.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6acca681c53374bf1d9af0e317a41d12a44902ca0f2d1e10e5cb5bb98ed74f35"
checksum = "1074e818fbe4f9169242d78448b15be8916a79daa38ea1231f2e2e10d993fcd2"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -867,9 +867,9 @@ dependencies = [
[[package]]
name = "aws-sdk-ssooidc"
version = "1.37.0"
version = "1.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b79c6bdfe612503a526059c05c9ccccbf6bd9530b003673cb863e547fd7c0c9a"
checksum = "29755c51e33fa3f678598f64324a169cf4b7d3c4865d2709d4308f53366a92a4"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -889,9 +889,9 @@ dependencies = [
[[package]]
name = "aws-sdk-sts"
version = "1.36.0"
version = "1.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32e6ecdb2bd756f3b2383e6f0588dc10a4e65f5d551e70a56e0bfe0c884673ce"
checksum = "6e52dc3fd7dfa6c01a69cf3903e00aa467261639138a05b06cd92314d2c8fb07"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -1264,7 +1264,7 @@ dependencies = [
"regex",
"rustc-hash 1.1.0",
"shlex",
"syn 2.0.72",
"syn 2.0.74",
"which 4.4.2",
]
@@ -1409,7 +1409,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
"syn_derive",
]
@@ -1498,7 +1498,7 @@ checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -1613,9 +1613,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.1.8"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549"
checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292"
dependencies = [
"jobserver",
"libc",
@@ -1717,9 +1717,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.14"
version = "4.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c937d4061031a6d0c8da4b9a4f98a172fc2976dfb1c19213a9cf7d0d3c837e36"
checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc"
dependencies = [
"clap_builder",
"clap_derive",
@@ -1727,9 +1727,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.14"
version = "4.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85379ba512b21a328adf887e85f7742d12e96eb31f3ef077df4ffc26b506ffed"
checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
dependencies = [
"anstream",
"anstyle",
@@ -1746,7 +1746,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -1946,9 +1946,9 @@ dependencies = [
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "cpufeatures"
@@ -2132,7 +2132,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -2180,7 +2180,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim 0.11.1",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -2202,7 +2202,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core 0.20.10",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -2722,7 +2722,7 @@ dependencies = [
"quote",
"strum 0.25.0",
"strum_macros 0.25.3",
"syn 2.0.72",
"syn 2.0.74",
"thiserror",
]
@@ -2901,7 +2901,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version 0.4.0",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -2998,7 +2998,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -3154,7 +3154,7 @@ dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -3174,7 +3174,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -3285,14 +3285,14 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
[[package]]
name = "filetime"
version = "0.2.23"
version = "0.2.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550"
dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.4.1",
"windows-sys 0.52.0",
"libredox",
"windows-sys 0.59.0",
]
[[package]]
@@ -3377,7 +3377,7 @@ checksum = "32016f1242eb82af5474752d00fd8ebcd9004bd69b462b1c91de833972d08ed4"
dependencies = [
"proc-macro2",
"swc_macros_common",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -3405,7 +3405,7 @@ checksum = "b0fa992f1656e1707946bbba340ad244f0814009ef8c0118eb7b658395f19a2e"
dependencies = [
"frunk_proc_macro_helpers",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -3417,7 +3417,7 @@ dependencies = [
"frunk_core",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -3429,7 +3429,7 @@ dependencies = [
"frunk_core",
"frunk_proc_macro_helpers",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -3553,7 +3553,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -3806,7 +3806,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -4048,9 +4048,9 @@ dependencies = [
[[package]]
name = "hstr"
version = "0.2.11"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be89918d912f61134036c4fd49b8db2935b49cca4cbf45b3a6738abd2c6e9f77"
checksum = "dae404c0c5d4e95d4858876ab02eecd6a196bb8caa42050dfa809938833fc412"
dependencies = [
"hashbrown 0.14.5",
"new_debug_unreachable",
@@ -4450,7 +4450,7 @@ dependencies = [
"Inflector",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -4699,6 +4699,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.6.0",
"libc",
"redox_syscall 0.5.3",
]
[[package]]
@@ -5081,9 +5082,9 @@ dependencies = [
[[package]]
name = "mio"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
dependencies = [
"hermit-abi 0.3.9",
"libc",
@@ -5109,7 +5110,7 @@ checksum = "a7ce64b975ed4f123575d11afd9491f2e37bbd5813fbfbc0f09ae1fbddea74e0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -5148,7 +5149,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
"termcolor",
"thiserror",
]
@@ -5561,7 +5562,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -5879,7 +5880,7 @@ dependencies = [
"phf_shared",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -5920,7 +5921,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -5937,9 +5938,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "piper"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391"
checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
dependencies = [
"atomic-waker",
"fastrand 2.1.0",
@@ -6013,9 +6014,9 @@ dependencies = [
[[package]]
name = "polling"
version = "3.7.2"
version = "3.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b"
checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511"
dependencies = [
"cfg-if",
"concurrent-queue",
@@ -6023,7 +6024,7 @@ dependencies = [
"pin-project-lite",
"rustix 0.38.34",
"tracing",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -6118,7 +6119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e"
dependencies = [
"proc-macro2",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -6171,7 +6172,7 @@ checksum = "07c277e4e643ef00c1233393c673f655e3672cf7eb3ba08a00bdd0ea59139b5f"
dependencies = [
"proc-macro-rules-macros",
"proc-macro2",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -6183,7 +6184,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -6244,7 +6245,7 @@ dependencies = [
"schemars",
"serde",
"serde_json",
"syn 2.0.72",
"syn 2.0.74",
"thiserror",
"typify",
"unicode-ident",
@@ -6264,7 +6265,7 @@ dependencies = [
"serde_json",
"serde_tokenstream",
"serde_yaml",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -6307,7 +6308,7 @@ dependencies = [
"itertools 0.12.1",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -6987,7 +6988,7 @@ dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn 2.0.72",
"syn 2.0.74",
"walkdir",
]
@@ -7369,7 +7370,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -7469,9 +7470,9 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4"
[[package]]
name = "serde"
version = "1.0.205"
version = "1.0.206"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
checksum = "5b3e4cd94123dd520a128bcd11e34d9e9e423e7e3e50425cb1b4b1e3549d0284"
dependencies = [
"serde_derive",
]
@@ -7510,13 +7511,13 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.205"
version = "1.0.206"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
checksum = "fabfb6138d2383ea8208cf98ccf69cdfb1aff4088460681d84189aa259762f97"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -7527,14 +7528,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
name = "serde_json"
version = "1.0.122"
version = "1.0.124"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d"
dependencies = [
"indexmap 2.3.0",
"itoa",
@@ -7602,7 +7603,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -7657,7 +7658,7 @@ dependencies = [
"darling 0.20.10",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8007,7 +8008,7 @@ checksum = "01b2e185515564f15375f593fb966b5718bc624ba77fe49fa4616ad619690554"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8078,7 +8079,7 @@ dependencies = [
"quote",
"sqlx-core",
"sqlx-macros-core",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8101,7 +8102,7 @@ dependencies = [
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
"syn 2.0.72",
"syn 2.0.74",
"tempfile",
"tokio",
"url",
@@ -8253,7 +8254,7 @@ dependencies = [
"proc-macro2",
"quote",
"swc_macros_common",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8307,7 +8308,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8320,7 +8321,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8439,7 +8440,7 @@ dependencies = [
"proc-macro2",
"quote",
"swc_macros_common",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8505,7 +8506,7 @@ dependencies = [
"proc-macro2",
"quote",
"swc_macros_common",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8612,7 +8613,7 @@ dependencies = [
"proc-macro2",
"quote",
"swc_macros_common",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8731,7 +8732,7 @@ checksum = "695a1d8b461033d32429b5befbf0ad4d7a2c4d6ba9cd5ba4e0645c615839e8e4"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8742,7 +8743,7 @@ checksum = "91745f3561057493d2da768437c427c0e979dff7396507ae02f16c981c4a8466"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8765,7 +8766,7 @@ dependencies = [
"proc-macro2",
"quote",
"swc_macros_common",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8781,9 +8782,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.72"
version = "2.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7"
dependencies = [
"proc-macro2",
"quote",
@@ -8799,7 +8800,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -8822,7 +8823,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -9066,7 +9067,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -9272,7 +9273,7 @@ dependencies = [
"backtrace",
"bytes",
"libc",
"mio 1.0.1",
"mio 1.0.2",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
@@ -9290,7 +9291,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -9571,7 +9572,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -9789,7 +9790,7 @@ dependencies = [
"regress",
"schemars",
"serde_json",
"syn 2.0.72",
"syn 2.0.74",
"thiserror",
"unicode-ident",
]
@@ -9806,7 +9807,7 @@ dependencies = [
"serde",
"serde_json",
"serde_tokenstream",
"syn 2.0.72",
"syn 2.0.74",
"typify-impl",
]
@@ -10009,9 +10010,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "ureq"
version = "2.10.0"
version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72139d247e5f97a3eff96229a7ae85ead5328a39efe76f8bf5a06313d505b6ea"
checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a"
dependencies = [
"base64 0.22.1",
"flate2",
@@ -10199,7 +10200,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
"wasm-bindgen-shared",
]
@@ -10233,7 +10234,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -10266,7 +10267,7 @@ checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -10469,7 +10470,7 @@ dependencies = [
"hmac",
"http 1.1.0",
"hyper 1.4.1",
"itertools 0.13.0",
"itertools 0.10.5",
"jsonwebtoken",
"lazy_static",
"magic-crypt",
@@ -10571,7 +10572,7 @@ dependencies = [
"hmac",
"hyper 1.4.1",
"indexmap 2.3.0",
"itertools 0.13.0",
"itertools 0.10.5",
"lazy_static",
"magic-crypt",
"mail-send",
@@ -10655,7 +10656,7 @@ version = "1.377.1"
dependencies = [
"anyhow",
"gosyn",
"itertools 0.13.0",
"itertools 0.10.5",
"lazy_static",
"regex",
"windmill-parser",
@@ -10678,7 +10679,7 @@ version = "1.377.1"
dependencies = [
"anyhow",
"convert_case 0.6.0",
"itertools 0.13.0",
"itertools 0.10.5",
"lazy_static",
"php-parser-rs",
"regex",
@@ -10691,7 +10692,7 @@ name = "windmill-parser-py"
version = "1.377.1"
dependencies = [
"anyhow",
"itertools 0.13.0",
"itertools 0.10.5",
"rustpython-parser",
"serde_json",
"windmill-parser",
@@ -10703,7 +10704,7 @@ version = "1.377.1"
dependencies = [
"anyhow",
"async-recursion",
"itertools 0.13.0",
"itertools 0.10.5",
"lazy_static",
"phf",
"regex",
@@ -10777,7 +10778,7 @@ dependencies = [
"futures-core",
"hex",
"hmac",
"itertools 0.13.0",
"itertools 0.10.5",
"lazy_static",
"prometheus",
"regex",
@@ -10833,7 +10834,7 @@ dependencies = [
"gcp_auth",
"git-version",
"hex",
"itertools 0.13.0",
"itertools 0.10.5",
"jsonwebtoken",
"lazy_static",
"mappable-rc",
@@ -11141,7 +11142,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
"synstructure",
]
@@ -11163,7 +11164,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
]
[[package]]
@@ -11183,7 +11184,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
"syn 2.0.74",
"synstructure",
]

View File

@@ -29,6 +29,7 @@ use sha2::{Digest, Sha256};
use sql_builder::{bind::Bind, SqlBuilder};
use sqlx::{types::Uuid, FromRow};
use std::str;
use tower_http::cors::{Any, CorsLayer};
use windmill_audit::audit_ee::audit_log;
use windmill_audit::ActionKind;
use windmill_common::{
@@ -65,10 +66,24 @@ pub fn workspaced_service() -> Router {
}
pub fn unauthed_service() -> Router {
let cors = CorsLayer::new()
.allow_methods([http::Method::GET])
.allow_headers([http::header::CONTENT_TYPE, http::header::AUTHORIZATION])
.allow_origin(Any);
Router::new()
.route("/execute_component/*path", post(execute_component))
.route("/public_app/:secret", get(get_public_app_by_secret))
.route("/public_resource/*path", get(get_public_resource))
.route(
"/execute_component/*path",
post(execute_component).layer(cors.clone()),
)
.route(
"/public_app/:secret",
get(get_public_app_by_secret).layer(cors.clone()),
)
.route(
"/public_resource/*path",
get(get_public_resource).layer(cors.clone()),
)
}
pub fn global_service() -> Router {

View File

@@ -334,7 +334,7 @@ pub async fn run_server(
)
.nest(
"/w/:workspace_id/capture_u",
capture::global_service().layer(cors),
capture::global_service().layer(cors.clone()),
)
.nest(
"/auth",
@@ -346,7 +346,7 @@ pub async fn run_server(
)
.route("/version", get(git_v))
.route("/uptodate", get(is_up_to_date))
.route("/ee_license", get(ee_license))
.route("/ee_license", get(ee_license).layer(cors.clone()))
.route("/openapi.yaml", get(openapi))
.route("/openapi.json", get(openapi_json)),
)

View File

@@ -44,6 +44,7 @@ use time::OffsetDateTime;
#[cfg(feature = "enterprise")]
use tokio::sync::RwLock;
use tower_cookies::{Cookie, Cookies};
use tower_http::cors::{Any, CorsLayer};
use tracing::{Instrument, Span};
use windmill_audit::audit_ee::{audit_log, AuditAuthor};
use windmill_audit::ActionKind;
@@ -66,6 +67,11 @@ const COOKIE_NAME: &str = "token";
const COOKIE_PATH: &str = "/";
pub fn workspaced_service() -> Router {
let cors = CorsLayer::new()
.allow_methods([http::Method::GET])
.allow_headers([http::header::CONTENT_TYPE, http::header::AUTHORIZATION])
.allow_origin(Any);
Router::new()
.route("/list", get(list_users))
.route("/list_usage", get(list_user_usage))
@@ -76,16 +82,21 @@ pub fn workspaced_service() -> Router {
.route("/delete/:user", delete(delete_workspace_user))
.route("/is_owner/*path", get(is_owner_of_path))
.route("/whois/:username", get(whois))
.route("/whoami", get(whoami))
.route("/whoami", get(whoami).layer(cors))
.route("/leave", post(leave_workspace))
.route("/username_to_email/:username", get(username_to_email))
}
pub fn global_service() -> Router {
let cors = CorsLayer::new()
.allow_methods([http::Method::GET])
.allow_headers([http::header::CONTENT_TYPE, http::header::AUTHORIZATION])
.allow_origin(Any);
Router::new()
.route("/exists/:email", get(exists_email))
.route("/email", get(get_email))
.route("/whoami", get(global_whoami))
.route("/whoami", get(global_whoami).layer(cors))
.route("/list_invites", get(list_invites))
.route("/decline_invite", post(decline_invite))
.route("/accept_invite", post(accept_invite))
@@ -118,8 +129,13 @@ pub fn global_service() -> Router {
}
pub fn make_unauthed_service() -> Router {
let cors = CorsLayer::new()
.allow_methods([http::Method::POST])
.allow_headers([http::header::CONTENT_TYPE, http::header::AUTHORIZATION])
.allow_origin(Any);
Router::new()
.route("/login", post(login))
.route("/login", post(login).layer(cors))
.route("/logout", post(logout))
.route("/logout", get(logout))
}

View File

@@ -21,6 +21,8 @@ use crate::{
webhook_util::WebhookShared,
};
use tower_http::cors::{Any, CorsLayer};
use axum::{
extract::{Extension, Path, Query},
response::IntoResponse,
@@ -124,10 +126,15 @@ pub fn workspaced_service() -> Router {
router
}
pub fn global_service() -> Router {
let cors = CorsLayer::new()
.allow_methods([http::Method::GET])
.allow_headers([http::header::CONTENT_TYPE, http::header::AUTHORIZATION])
.allow_origin(Any);
Router::new()
.route("/list_as_superadmin", get(list_workspaces_as_super_admin))
.route("/list", get(list_workspaces))
.route("/users", get(user_workspaces))
.route("/users", get(user_workspaces).layer(cors.clone()))
.route("/create", post(create_workspace))
.route("/exists", post(exists_workspace))
.route("/exists_username", post(exists_username))
@@ -168,9 +175,9 @@ pub struct WorkspaceSettings {
pub error_handler: Option<String>,
pub error_handler_extra_args: Option<serde_json::Value>,
pub error_handler_muted_on_cancel: Option<bool>,
pub large_file_storage: Option<serde_json::Value>, // effectively: DatasetsStorage
pub git_sync: Option<serde_json::Value>, // effectively: WorkspaceGitSyncSettings
pub deploy_ui: Option<serde_json::Value>, // effectively: WorkspaceDeploymentUISettings
pub large_file_storage: Option<serde_json::Value>, // effectively: DatasetsStorage
pub git_sync: Option<serde_json::Value>, // effectively: WorkspaceGitSyncSettings
pub deploy_ui: Option<serde_json::Value>, // effectively: WorkspaceDeploymentUISettings
pub default_app: Option<String>,
pub automatic_billing: bool,
pub default_scripts: Option<serde_json::Value>,
@@ -1071,7 +1078,6 @@ async fn edit_deploy_ui_config(
));
}
#[cfg(feature = "enterprise")]
async fn edit_deploy_ui_config(
authed: ApiAuthed,
@@ -1097,8 +1103,9 @@ async fn edit_deploy_ui_config(
.await?;
if let Some(deploy_ui_settings) = new_config.deploy_ui_settings {
let serialized_config = serde_json::to_value::<WorkspaceDeploymentUISettings>(deploy_ui_settings)
.map_err(|err| Error::InternalErr(err.to_string()))?;
let serialized_config =
serde_json::to_value::<WorkspaceDeploymentUISettings>(deploy_ui_settings)
.map_err(|err| Error::InternalErr(err.to_string()))?;
sqlx::query!(
"UPDATE workspace_settings SET deploy_ui = $1 WHERE workspace_id = $2",
@@ -1120,8 +1127,6 @@ async fn edit_deploy_ui_config(
Ok(format!("Edit deployment UI config for workspace {}", &w_id))
}
#[derive(Deserialize)]
pub struct EditDefaultApp {
pub default_app_path: Option<String>,

View File

@@ -34,7 +34,11 @@ pub async fn schedule_key_renewal(_http_client: &reqwest::Client, _db: &crate::d
}
#[cfg(feature = "enterprise")]
pub async fn renew_license_key(_http_client: &reqwest::Client, _db: &crate::db::DB) -> String {
pub async fn renew_license_key(
_http_client: &reqwest::Client,
_db: &crate::db::DB,
_key: Option<String>,
) -> String {
// Implementation is not open source
"".to_string()
}
@@ -42,6 +46,7 @@ pub async fn renew_license_key(_http_client: &reqwest::Client, _db: &crate::db::
#[cfg(feature = "enterprise")]
pub async fn create_customer_portal_session(
_http_client: &reqwest::Client,
_key: Option<String>,
) -> error::Result<String> {
// Implementation is not open source
Ok("".to_string())

View File

@@ -1,12 +1,12 @@
{
"name": "windmill-components",
"version": "1.377.1",
"version": "1.377.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "windmill-components",
"version": "1.377.1",
"version": "1.377.3",
"license": "AGPL-3.0",
"dependencies": {
"@aws-crypto/sha256-js": "^4.0.0",
@@ -47,7 +47,6 @@
"svelte-chartjs": "^3.1.5",
"svelte-exmarkdown": "^3.0.5",
"svelte-infinite-loading": "^1.3.8",
"svelte-portal": "^2.2.1",
"svelte-tiny-virtual-list": "^2.0.5",
"tailwind-merge": "^1.13.2",
"vscode": "npm:@codingame/monaco-vscode-api@>=1.83.5 <1.84.0",
@@ -9837,11 +9836,6 @@
"svelte": ">=3"
}
},
"node_modules/svelte-portal": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/svelte-portal/-/svelte-portal-2.2.1.tgz",
"integrity": "sha512-uF7is5sM4aq5iN7QF/67XLnTUvQCf2iiG/B1BHTqLwYVY1dsVmTeXZ/LeEyU6dLjApOQdbEG9lkqHzxiQtOLEQ=="
},
"node_modules/svelte-preprocess": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.0.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "windmill-components",
"version": "1.377.1",
"version": "1.377.8",
"scripts": {
"dev": "vite dev",
"build": "vite build",
@@ -128,7 +128,6 @@
"svelte-chartjs": "^3.1.5",
"svelte-exmarkdown": "^3.0.5",
"svelte-infinite-loading": "^1.3.8",
"svelte-portal": "^2.2.1",
"svelte-tiny-virtual-list": "^2.0.5",
"tailwind-merge": "^1.13.2",
"vscode": "npm:@codingame/monaco-vscode-api@>=1.83.5 <1.84.0",
@@ -326,6 +325,11 @@
"types": "./package/components/DropdownV2.svelte.d.ts",
"svelte": "./package/components/DropdownV2.svelte",
"default": "./package/components/DropdownV2.svelte"
},
"./components/AppEmbed.svelte": {
"types": "./package/components/AppEmbed.svelte.d.ts",
"svelte": "./package/components/AppEmbed.svelte",
"default": "./package/components/AppEmbed.svelte"
}
},
"files": [
@@ -443,6 +447,9 @@
],
"components/DropdownV2.svelte": [
"./package/components/DropdownV2.svelte.d.ts"
],
"components/AppEmbed.svelte": [
"./package/components/AppEmbed.svelte.d.ts"
]
}
},

View File

@@ -0,0 +1,167 @@
<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="windmil-app relative h-full w-full">
<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}
</div>

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { createPopperActions, type PopperOptions } from 'svelte-popperjs'
import type { PopoverPlacement } from './Popover.model'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
export let placement: PopoverPlacement = 'bottom-end'
export let notClickable = false

View File

@@ -15,7 +15,7 @@
InfoIcon,
ArrowDownFromLine
} from 'lucide-svelte'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import ObjectViewer from './propertyPicker/ObjectViewer.svelte'
import S3FilePicker from './S3FilePicker.svelte'
import Alert from './common/alert/Alert.svelte'

View File

@@ -1,5 +1,4 @@
<script lang="ts">
import { goto } from '$lib/navigation'
import Github from '$lib/components/icons/brands/Github.svelte'
import Gitlab from '$lib/components/icons/brands/Gitlab.svelte'
import Google from '$lib/components/icons/brands/Google.svelte'
@@ -7,7 +6,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 +21,10 @@
export let password: string | undefined = undefined
export let error: string | undefined = undefined
export let popup: boolean = false
export let loginPasswordRequireEEOnPublicApps: boolean = false
export let gotoFn: ((path: string, opt?: Record<string, any> | undefined) => void) | undefined =
undefined
export let baseApiUrl: string | undefined = undefined
const providers = [
{
@@ -83,15 +86,19 @@
}
// Finally, we check whether the user is a superadmin
refreshSuperadmin()
redirectUser()
refreshSuperadmin(gotoFn)
if (gotoFn) {
redirectUser()
} else {
dispatch('login')
}
}
async function redirectUser() {
const firstTimeCookie =
document.cookie.match('(^|;)\\s*first_time\\s*=\\s*([^;]+)')?.pop() || '0'
if (Number(firstTimeCookie) > 0 && email === 'admin@windmill.dev') {
goto('/user/first-time')
gotoFn?.('/user/first-time')
return
}
@@ -100,12 +107,12 @@
return
}
if ($workspaceStore) {
goto(rd ?? '/')
gotoFn?.(rd ?? '/')
} else {
let workspaceTarget = parseQueryParams(rd ?? undefined)['workspace']
if (rd && workspaceTarget) {
$workspaceStore = workspaceTarget
goto(rd)
gotoFn?.(rd)
return
}
@@ -126,19 +133,19 @@
workspace: $workspaceStore!
})
if (!emptyString(defaultApp.default_app_path)) {
goto(`/apps/get/${defaultApp.default_app_path}`)
gotoFn?.(`/apps/get/${defaultApp.default_app_path}`)
} else {
goto(rd ?? '/')
gotoFn?.(rd ?? '/')
}
} else {
goto(rd ?? '/')
gotoFn?.(rd ?? '/')
}
} else if (rd?.startsWith('/user/workspaces')) {
goto(rd)
gotoFn?.(rd)
} else if (rd == '/#user-settings') {
goto(`/user/workspaces#user-settings`)
gotoFn?.(`/user/workspaces#user-settings`)
} else {
goto(`/user/workspaces${rd ? `?rd=${encodeURIComponent(rd)}` : ''}`)
gotoFn?.(`/user/workspaces${rd ? `?rd=${encodeURIComponent(rd)}` : ''}`)
}
}
}
@@ -262,68 +269,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>

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { createPopperActions } from 'svelte-popperjs'
import type { PopoverPlacement } from './Popover.model'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { fade } from 'svelte/transition'
import { twMerge } from 'tailwind-merge'

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { createPopperActions, type PopperOptions } from 'svelte-popperjs'
import type { PopoverPlacement } from './Popover.model'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { ExternalLink } from 'lucide-svelte'
export let placement: PopoverPlacement = 'bottom-end'

View File

@@ -0,0 +1,63 @@
<script context="module">
import { tick } from 'svelte'
/**
* Usage: <div use:portal={'css selector'}> or <div use:portal={document.body}>
*
* @param {HTMLElement} el
* @param {HTMLElement|string} target DOM Element or CSS Selector
*/
export function portal(el, target = 'body') {
let targetEl
async function update(newTarget) {
target = newTarget
if (typeof target === 'string') {
targetEl = document.querySelector(target)
if (targetEl === null) {
await tick()
targetEl = document.querySelector(target)
}
if (targetEl === null) {
throw new Error(`No element found matching css selector: "${target}"`)
}
} else if (target instanceof HTMLElement) {
targetEl = target
} else {
throw new TypeError(
`Unknown portal target type: ${
target === null ? 'null' : typeof target
}. Allowed types: string (CSS selector) or HTMLElement.`
)
}
targetEl.appendChild(el)
el.hidden = false
if (!el.classList.contains('windmill-app')) {
el.classList.add('windmill-app')
}
}
function destroy() {
if (el.parentNode) {
el.parentNode.removeChild(el)
}
}
update(target)
return {
update,
destroy
}
}
</script>
<script>
/**
* DOM Element or CSS Selector
* @type { HTMLElement|string}
*/
export let target = 'body'
</script>
<div use:portal={target} hidden>
<slot />
</div>

View File

@@ -20,7 +20,7 @@
import ResolveStyle from '../helpers/ResolveStyle.svelte'
import { initCss } from '../../utils'
import ConfirmationModal from '$lib/components/common/confirmationModal/ConfirmationModal.svelte'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
export let id: string
export let componentInput: AppInput | undefined

View File

@@ -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}

View File

@@ -25,7 +25,7 @@
import { Plus } from 'lucide-svelte'
import { Drawer, DrawerContent } from '$lib/components/common'
import InsertRow from './InsertRow.svelte'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { sendUserToast } from '$lib/toast'
import type { AppInput, StaticInput } from '$lib/components/apps/inputType'
import DbExplorerCount from './DbExplorerCount.svelte'

View File

@@ -9,7 +9,7 @@
import ResolveConfig from '../helpers/ResolveConfig.svelte'
// @ts-ignore
import MultiSelect from 'svelte-multiselect'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { createFloatingActions } from 'svelte-floating-ui'
import { extractCustomProperties } from '$lib/utils'
import { tick } from 'svelte'

View File

@@ -8,7 +8,7 @@
import { components } from '../../editor/component'
import ResolveConfig from '../helpers/ResolveConfig.svelte'
// @ts-ignore
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { createFloatingActions } from 'svelte-floating-ui'
import { extractCustomProperties } from '$lib/utils'
import { tick } from 'svelte'

View File

@@ -2,7 +2,7 @@
import { getContext } from 'svelte'
import SubGridEditor from '../../editor/SubGridEditor.svelte'
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { initCss } from '../../utils'
import { Button, Drawer, DrawerContent } from '$lib/components/common'
import { twMerge } from 'tailwind-merge'

View File

@@ -7,7 +7,7 @@
import { twMerge } from 'tailwind-merge'
import { initConfig, initOutput, maxHeight, ROW_GAP_Y, ROW_HEIGHT } from '../../editor/appUtils'
import InitializeComponent from '../helpers/InitializeComponent.svelte'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { clickOutside } from '$lib/utils'
import { X } from 'lucide-svelte'
import { components } from '../../editor/component'

View File

@@ -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}

View File

@@ -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>

View File

@@ -179,7 +179,7 @@
</Button>
</div>
</div>
<AppPreview noBackend app={selected.value} context={{}} />
<AppPreview author="" noBackend app={selected.value} />
{:else}
<Skeleton layout={[[40]]} />
{/if}

View File

@@ -30,7 +30,7 @@
import DeleteComponent from './settingsPanel/DeleteComponent.svelte'
import { secondaryMenuLeft } from './settingsPanel/secondaryMenu'
import { clickOutside } from '$lib/utils'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { twMerge } from 'tailwind-merge'
let contextMenuVisible = false

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { getContext } from 'svelte'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import type { AppViewerContext } from '../../types'
export let condition = false

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
export let condition = false
</script>

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

View File

@@ -3,7 +3,7 @@
import { ChevronDown } from 'lucide-svelte'
import { twMerge } from 'tailwind-merge'
import { createPopperActions, type PopperOptions } from 'svelte-popperjs'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
export let hasPadding: boolean = true
export let target: string | undefined = 'body'

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
export let condition = false
</script>

View File

@@ -73,7 +73,8 @@
on:close
>
<aside
class="drawer windmill-drawer {$$props.class ?? ''} {$$props.positionClass ?? ''}"
class="windmill-app drawer windmill-drawer {$$props.class ?? ''} {$$props.positionClass ??
''}"
class:open
class:close={!open && timeout}
style={`${style}; --zIndex: ${zIndex};`}

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { Menu, MenuButton, MenuItems, Transition } from '@rgossiaux/svelte-headlessui'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { offset, flip, shift } from 'svelte-floating-ui/dom'
import { createFloatingActions } from 'svelte-floating-ui'
import { twMerge } from 'tailwind-merge'

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { twMerge } from 'tailwind-merge'
import { clickOutside } from '$lib/utils'
import { X } from 'lucide-svelte'

View File

@@ -2,7 +2,7 @@
import { Menu, Transition, MenuButton, MenuItems } from '@rgossiaux/svelte-headlessui'
import { MoreVertical } from 'lucide-svelte'
import { createPopperActions, type PopperOptions } from 'svelte-popperjs'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import Button from '../common/button/Button.svelte'
const [popperRef, popperContent] = createPopperActions({ placement: 'auto' })

View File

@@ -20,7 +20,7 @@
import FlowErrorHandlerItem from './FlowErrorHandlerItem.svelte'
import { push } from '$lib/history'
import ConfirmationModal from '$lib/components/common/confirmationModal/ConfirmationModal.svelte'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { getDependentComponents } from '../flowExplorer'
import type { FlowCopilotContext } from '$lib/components/copilot/flow'
import { fade } from 'svelte/transition'

View File

@@ -1,6 +1,6 @@
<script lang="ts">
// @ts-ignore
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { createFloatingActions } from 'svelte-floating-ui'
import { tick } from 'svelte'
import { offset, flip, shift } from 'svelte-floating-ui/dom'

View File

@@ -6,7 +6,7 @@
import { computeKey } from './utils'
import WarningMessage from './WarningMessage.svelte'
import { NEVER_TESTED_THIS_FAR } from '../flows/models'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { Download, PanelRightOpen } from 'lucide-svelte'
import S3FilePicker from '../S3FilePicker.svelte'
import { workspaceStore } from '$lib/stores'

View File

@@ -22,7 +22,7 @@
import TimeAgo from '../TimeAgo.svelte'
import { forLater } from '$lib/forLater'
import { twMerge } from 'tailwind-merge'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import WaitTimeWarning from '../common/waitTimeWarning/WaitTimeWarning.svelte'
const dispatch = createEventDispatcher()

View File

@@ -27,7 +27,7 @@
SearchCode
} from 'lucide-svelte'
import JobPreview from '../runs/JobPreview.svelte'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { twMerge } from 'tailwind-merge'
import ContentSearchInner from '../ContentSearchInner.svelte'
import { goto } from '$app/navigation'
@@ -333,9 +333,8 @@
}
let mouseMoved: boolean = false
function handleMouseMove () {
function handleMouseMove() {
mouseMoved = true
}
onMount(() => {
@@ -531,7 +530,8 @@
<Popover notClickable placement="bottom-start">
<AlertTriangle size={16} class="text-yellow-500" />
<svelte:fragment slot="text">
Some of your search terms have been ignored because one or more parse errors:<br/><br/>
Some of your search terms have been ignored because one or more parse errors:<br
/><br />
<ul>
{#each queryParseErrors as msg}
<li>- {msg}</li>
@@ -545,7 +545,7 @@
{#if tab === 'default' || tab === 'switch-mode'}
{@const items = (itemMap[tab] ?? []).filter((e) => defaultMenuItems.includes(e))}
{#if items.length > 0}
<div class={tab === 'switch-mode' ? "p-2" : "p-2 border-b"}>
<div class={tab === 'switch-mode' ? 'p-2' : 'p-2 border-b'}>
{#each items as el}
<QuickMenuItem
on:select={el?.action}

View File

@@ -1,9 +1,10 @@
import { get } from 'svelte/store'
import { UserService } from '$lib/gen'
import { superadmin } from './stores.js'
import { goto } from '$lib/navigation'
export async function refreshSuperadmin(): Promise<void> {
export async function refreshSuperadmin(
gotoFn: ((path: string, opt?: Record<string, any> | undefined) => void) | undefined
): Promise<void> {
if (get(superadmin) == undefined) {
try {
const me = await UserService.globalWhoami()
@@ -14,7 +15,7 @@ export async function refreshSuperadmin(): Promise<void> {
}
} catch {
superadmin.set(false)
goto('/user/logout')
gotoFn?.('/user/logout')
}
}
}

View File

@@ -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)}

View File

@@ -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}

View File

@@ -76,7 +76,7 @@
import { forLater } from '$lib/forLater'
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
import PersistentScriptDrawer from '$lib/components/PersistentScriptDrawer.svelte'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import MemoryFootprintViewer from '$lib/components/MemoryFootprintViewer.svelte'
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
import { Highlight } from 'svelte-highlight'

View File

@@ -113,6 +113,6 @@
<div class="flex justify-end">
<DarkModeToggle forcedDarkMode={false} />
</div>
<Login {rd} {error} {password} {email} />
<Login gotoFn={(path, opt) => goto(path, opt)} {rd} {error} {password} {email} />
</div>
</div>

View File

@@ -44,7 +44,7 @@
import PremiumInfo from '$lib/components/settings/PremiumInfo.svelte'
import Toggle from '$lib/components/Toggle.svelte'
import TestOpenaiKey from '$lib/components/copilot/TestOpenaiKey.svelte'
import Portal from 'svelte-portal'
import Portal from '$lib/components/Portal.svelte'
import { fade } from 'svelte/transition'
import ChangeWorkspaceName from '$lib/components/settings/ChangeWorkspaceName.svelte'
import ChangeWorkspaceId from '$lib/components/settings/ChangeWorkspaceId.svelte'
@@ -494,7 +494,7 @@
apps: (settings.deploy_ui.include_type?.indexOf('app') ?? -1) >= 0,
resources: (settings.deploy_ui.include_type?.indexOf('resource') ?? -1) >= 0,
variables: (settings.deploy_ui.include_type?.indexOf('variable') ?? -1) >= 0,
secrets: (settings.deploy_ui.include_type?.indexOf('secret') ?? -1) >= 0,
secrets: (settings.deploy_ui.include_type?.indexOf('secret') ?? -1) >= 0
}
}
}
@@ -506,7 +506,7 @@
})
}
let deployUiSettings: {
let deployUiSettings: {
include_path: string[]
include_type: {
scripts: boolean

View File

@@ -32,7 +32,7 @@
async function loadUser() {
try {
await refreshSuperadmin()
await refreshSuperadmin((path, opt) => goto(path, opt))
if ($workspaceStore) {
if ($userStore) {

View File

@@ -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/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)}
/>