Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
58 changes: 58 additions & 0 deletions .github/workflows/ui-v2-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: UI v2 CI

on:
pull_request:
branches:
- main
paths:
- "ui-v2/**"

jobs:
lint-format-test:
name: Lint, Format & Test
runs-on: ubuntu-latest
defaults:
run:
working-directory: ui-v2

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.32.0

- name: Get pnpm store directory
id: pnpm-cache
run: echo "store=$(pnpm store path)" >> $GITHUB_OUTPUT

- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.store }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('ui-v2/pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-pnpm-

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Prettier check
run: pnpm prettier:check

- name: Lint
run: pnpm lint

- name: Type check
run: pnpm typecheck

- name: Test
run: pnpm test

- name: Build
run: pnpm build
8 changes: 8 additions & 0 deletions ui-v2/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# OSS Conductor UI – defaults for local dev

# Backend API (Conductor server). Default: local server.
VITE_WF_SERVER=http://localhost:8080

# Optional
# VITE_PUBLIC_URL=/
# GENERATE_SOURCEMAP=false
23 changes: 23 additions & 0 deletions ui-v2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Dependencies
node_modules

# Local env (may contain secrets)
.env.local
.env.*.local

# Build output
dist
build
storybook-static

# Test / Playwright
/test-results/
/playwright-report/
/playwright/.cache/

# Turbo
.turbo

# IDE / OS
.DS_Store

9 changes: 9 additions & 0 deletions ui-v2/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
build
storybook-static
/test-results/
/playwright-report/
/playwright/.cache/
tests-examples
playwright
public/context.js
/dist/
1 change: 1 addition & 0 deletions ui-v2/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
105 changes: 105 additions & 0 deletions ui-v2/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import eslintReact from "@eslint-react/eslint-plugin";
import js from "@eslint/js";
import vitest from "@vitest/eslint-plugin";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import { globalIgnores } from "eslint/config";
import globals from "globals";
import tseslint from "typescript-eslint";

const commonRules = {
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
],
// TODO: Remove this and fix types properly
"@typescript-eslint/ban-ts-comment": "warn",
// Prevent direct imports from date-fns and date-fns-tz except in utils/date.ts
"no-restricted-imports": [
"error",
{
patterns: [
{
group: ["date-fns"],
message:
"Direct imports from 'date-fns' are not allowed. Please import from 'src/utils/date' instead.",
},
{
group: ["date-fns-tz"],
message:
"Direct imports from 'date-fns-tz' are not allowed. Please import from 'src/utils/date' instead.",
},
],
},
],
};

const baseConfig = {
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs["recommended-latest"],
reactRefresh.configs.vite,
eslintReact.configs.recommended,
],
languageOptions: {
ecmaVersion: 2020,
sourceType: "module",
globals: {
...globals.browser,
...globals.node,
},
},
rules: {
"no-undef": "error",
...commonRules,
},
};

export default tseslint.config([
globalIgnores(["dist", "node_modules"]),

// Test files (Vitest + testing globals)
{
files: [
"**/__tests__/**/*.{js,jsx,ts,tsx}",
"**/*.{test,spec}.{js,jsx,ts,tsx}",
],
...baseConfig,
plugins: { vitest, ...baseConfig.plugins },
rules: {
...vitest.configs.recommended.rules,
...commonRules,
},
},

// JSX files (allow PropTypes)
{
files: ["**/*.jsx"],
...baseConfig,
rules: {
...baseConfig.rules,
"react/prop-types": "off",
"@eslint-react/no-prop-types": "off",
},
},

// Non-test files (TS/TSX)
{
files: ["**/*.{js,ts,tsx}"],
ignores: [
"**/__tests__/**/*.{js,jsx,ts,tsx}",
"**/*.{test,spec}.{js,jsx,ts,tsx}",
],
...baseConfig,
},

// Allow date-fns and date-fns-tz imports in utils/date.ts
{
files: ["src/utils/date.ts"],
rules: {
"no-restricted-imports": "off",
},
},
]);
126 changes: 126 additions & 0 deletions ui-v2/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="/icons/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/icons/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/icons/favicon-16x16.png"
/>
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

<!-- HTML Meta Tags -->
<meta
name="description"
content="Conductor is a platform for orchestrating workflows and microservices. Design, execute, and monitor your workflows with ease."
/>
<meta property="og:url" content="/" />
<meta property="og:type" content="website" />
<meta property="og:title" content="Conductor" />
<meta
property="og:description"
content="Conductor is a platform for orchestrating workflows and microservices. Design, execute, and monitor your workflows with ease."
/>
<meta property="og:image" content="/icons/icon-512x512.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="512" />
<meta property="og:image:height" content="512" />
<meta property="og:image:alt" content="Conductor Logo" />
<meta property="og:locale" content="en_US" />

<!-- Twitter Meta Tags -->
<meta name="twitter:card" content="summary_large_image" />
<meta property="twitter:domain" content="/" />
<meta property="twitter:url" content="/" />
<meta name="twitter:title" content="Conductor" />
<meta
name="twitter:description"
content="Conductor is a platform for orchestrating workflows and microservices. Design, execute, and monitor your workflows with ease."
/>
<meta name="twitter:image" content="/icons/icon-512x512.png" />
<meta name="twitter:image:alt" content="Conductor Logo" />
<script nonce="tpsHAxwU5x0csoIuLNs2vg==">
(function () {
// Retrieve the nonce value from an existing CSP-protected script
// const nonceElement = document.querySelector("[nonce]");
// const nonceValue = nonceElement
// ? nonceElement.getAttribute("nonce")
// : null;
var nonceValue = "tpsHAxwU5x0csoIuLNs2vg==";
if (nonceValue) {
// Save the original createElement function
const originalCreateElement = document.createElement;

// Override document.createElement for <script> tags
document.createElement = function (tagName) {
const element = originalCreateElement.call(document, tagName);

// If the created element is a <script>, add the nonce
if (tagName.toLowerCase() === "script") {
element.setAttribute("nonce", nonceValue);
}
return element;
};

// Set up a MutationObserver to handle script tags added via DOM mutations
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
// If a <script> tag is added without a nonce, add the nonce
if (node.tagName === "SCRIPT" && !node.hasAttribute("nonce")) {
node.setAttribute("nonce", nonceValue);
}

// Handle <script> tags within added nodes (e.g., innerHTML)
if (node.nodeType === 1) {
const scripts = node.querySelectorAll("script:not([nonce])");
scripts.forEach((script) => {
script.setAttribute("nonce", nonceValue);
});
}
});
});
});

// Observe changes to the entire DOM tree
observer.observe(document.documentElement, {
childList: true, // Observe direct children being added
subtree: true, // Observe all descendants
});
}
})();
</script>
<script src="/context.js"></script>
<title>Conductor UI</title>
</head>

<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Loading
Loading