Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions app/hotreload.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
reload the browser without having to restart the Python app.
"""

import asyncio
from pathlib import Path

from watchfiles import Change, DefaultFilter, awatch
Expand All @@ -17,7 +18,7 @@


class WebFilter(DefaultFilter):
allowed_extensions = (".html", ".css", ".js", ".py", ".txt", ".env")
allowed_extensions = (".html", ".css", ".js", ".jsx", ".py", ".txt", ".env")

def __call__(self, change: Change, path: str) -> bool:
if not super().__call__(change, path):
Expand All @@ -27,8 +28,8 @@ def __call__(self, change: Change, path: str) -> bool:
if path.suffix not in self.allowed_extensions:
return False

# Allow HTML/CSS/JS files anywhere
if path.suffix in (".html", ".css", ".js"):
# Allow HTML/CSS/JS/JSX files anywhere
if path.suffix in (".html", ".css", ".js", ".jsx"):
return True

# xlwings Lite
Expand All @@ -44,6 +45,18 @@ async def watch_frontend_files(sio, directory):
directory,
watch_filter=WebFilter(),
):
is_jsx = False
for _, path in changes:
if Path(path).suffix == ".jsx":
is_jsx = True
break
if is_jsx:
frontend_dir = Path(directory) / "static" / "frontend"
proc = await asyncio.create_subprocess_shell(
"npm run build", cwd=frontend_dir
)
await proc.communicate()

await sio.emit("reload")


Expand Down
4 changes: 1 addition & 3 deletions app/routers/taskpane.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,4 @@
@router.get("/taskpane")
@router.get("/taskpane.html")
async def taskpane(request: Request):
return TemplateResponse(
request=request, name="examples/hello_world/taskpane_hello.html"
)
return TemplateResponse(request=request, name="react_taskpane.html")
24 changes: 24 additions & 0 deletions app/static/frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
16 changes: 16 additions & 0 deletions app/static/frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# React + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).

## Expanding the ESLint configuration

If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
29 changes: 29 additions & 0 deletions app/static/frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import { defineConfig, globalIgnores } from "eslint/config";

export default defineConfig([
globalIgnores(["dist"]),
{
files: ["**/*.{js,jsx}"],
extends: [
js.configs.recommended,
reactHooks.configs["recommended-latest"],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: "latest",
ecmaFeatures: { jsx: true },
sourceType: "module",
},
},
rules: {
"no-unused-vars": ["error", { varsIgnorePattern: "^[A-Z_]" }],
},
},
]);
13 changes: 13 additions & 0 deletions app/static/frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>frontend</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
Loading
Loading