Skip to content

Commit 7c23e27

Browse files
authored
Merge pull request #11161 from marmelab/offline-example
Fix `<Edit>`, `<ReferenceField>` and `<List>` to better support offline mode
2 parents fdfae04 + 5acd057 commit 7c23e27

33 files changed

Lines changed: 1849 additions & 775 deletions

.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ jobs:
3030

3131
# Initializes the CodeQL tools for scanning.
3232
- name: Initialize CodeQL
33-
uses: github/codeql-action/init@v2
33+
uses: github/codeql-action/init@v3
3434
# Override language selection by uncommenting this and choosing your languages
3535
# with:
3636
# languages: go, javascript, csharp, python, cpp, java
3737

3838
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
3939
# If this step fails, then you should remove it and run the build manually (see below)
4040
- name: Autobuild
41-
uses: github/codeql-action/autobuild@v2
41+
uses: github/codeql-action/autobuild@v3
4242

4343
# ℹ️ Command-line programs to run using the OS shell.
4444
# 📚 https://git.io/JvXDl
@@ -52,4 +52,4 @@ jobs:
5252
# make release
5353

5454
- name: Perform CodeQL Analysis
55-
uses: github/codeql-action/analyze@v2
55+
uses: github/codeql-action/analyze@v3

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ run-crm: ## run the crm example
3939
build-crm: ## build the crm example
4040
@yarn build-crm
4141

42+
run-offline: ## run the offline example (dev mode)
43+
@yarn run-offline
44+
45+
build-offline: ## build the offline example
46+
@yarn build-offline
47+
48+
preview-offline: ## preview the offline example
49+
@yarn preview-offline
50+
4251
build-ra-core:
4352
@echo "Transpiling ra-core files...";
4453
@cd ./packages/ra-core && yarn build

examples/ra-offline/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

examples/ra-offline/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# ra-offline
2+
3+
Demo app showing the React-Admin offline-first capabilities.
4+
5+
It uses [vite-plugin-pwa](https://vite-pwa-org.netlify.app/) to make the app a Progressive Web App, and [configures the TanStack QueryClient](https://marmelab.com/react-admin/DataProviders.html#offline-support) to persist the query cache and pending mutations in the local storage.
6+
7+
## Installation
8+
9+
Install the application dependencies by running:
10+
11+
```sh
12+
npm install
13+
```
14+
15+
## Usage
16+
17+
The offline mode doesn't work in dev mode, that's a limitation of vite-pwa.
18+
19+
Build the application in production mode and serve it by running:
20+
21+
```sh
22+
npm run build
23+
npm run preview
24+
```
25+
26+
Use the Browser DevTools (or phone Airplane mode) to simulate Offline mode when needed. Using TanStack Query DevTools does not work.
27+
28+
## Limitations
29+
30+
This demo is hooked up to the [JSONPlaceholder](https://jsonplaceholder.typicode.com/) API, so the changes are not persisted for real. But the mutation should be visible in the Network tab and not trigger errors.
31+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
if ("serviceWorker" in navigator)
2+
navigator.serviceWorker.register("/dev-sw.js?dev-sw", {
3+
scope: "/",
4+
type: "module",
5+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import js from "@eslint/js";
2+
import { defineConfig, globalIgnores } from "eslint/config";
3+
import tseslint from "typescript-eslint";
4+
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
5+
import react from "eslint-plugin-react";
6+
import reactHooks from "eslint-plugin-react-hooks";
7+
import globals from "globals";
8+
9+
export default defineConfig([
10+
globalIgnores(["**/node_modules", "**/dist"]),
11+
{
12+
name: "eslint-js-recommended-rules",
13+
plugins: {
14+
js,
15+
},
16+
extends: ["js/recommended"],
17+
},
18+
tseslint.configs.recommended.map((conf) => ({
19+
...conf,
20+
files: ["**/*.ts", "**/*.tsx"],
21+
})),
22+
eslintPluginPrettierRecommended,
23+
{
24+
name: "react",
25+
...react.configs.flat.recommended,
26+
},
27+
reactHooks.configs["recommended-latest"],
28+
{
29+
languageOptions: {
30+
globals: {
31+
...globals.browser,
32+
...globals.node,
33+
},
34+
},
35+
rules: {
36+
"react/react-in-jsx-scope": "off",
37+
},
38+
settings: {
39+
react: {
40+
version: "detect",
41+
},
42+
},
43+
},
44+
]);

examples/ra-offline/index.html

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width,initial-scale=1" />
6+
<title>React-Admin Offline</title>
7+
<meta name="description" content="React-Admin Offline Demo" />
8+
<link rel="icon" href="/favicon.ico" />
9+
<link rel="apple-touch-icon" href="/apple-touch-icon-180x180.png" sizes="180x180" />
10+
<link rel="mask-icon" href="/maskable-icon-512x512.png" color="#FFFFFF" />
11+
<meta name="theme-color" content="#ffffff" />
12+
<link rel="preconnect" href="https://fonts.gstatic.com" />
13+
<link
14+
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"
15+
rel="stylesheet"
16+
/>
17+
</head>
18+
19+
<body>
20+
<noscript> You need to enable JavaScript to run this app. </noscript>
21+
<div id="root"></div>
22+
</body>
23+
<script type="module" src="/src/index.tsx"></script>
24+
</html>

examples/ra-offline/package.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"private": true,
3+
"type": "module",
4+
"scripts": {
5+
"dev": "vite",
6+
"build": "vite build",
7+
"preview": "vite preview",
8+
"type-check": "tsc --noEmit",
9+
"lint": "eslint --fix --ext .js,.jsx,.ts,.tsx ./src",
10+
"format": "prettier --write ./src"
11+
},
12+
"dependencies": {
13+
"@emotion/react": "^11.14.0",
14+
"@emotion/styled": "^11.14.0",
15+
"@mui/icons-material": "^7.0.1",
16+
"@mui/material": "^7.0.1",
17+
"@tanstack/query-async-storage-persister": "^5.90.22",
18+
"@tanstack/react-query": "^5.90.21",
19+
"@tanstack/react-query-devtools": "^5.90.22",
20+
"@tanstack/react-query-persist-client": "^5.90.22",
21+
"ra-data-json-server": "^5.14.1",
22+
"react": "^19.0.0",
23+
"react-admin": "^5.14.1",
24+
"react-dom": "^19.0.0"
25+
},
26+
"devDependencies": {
27+
"@eslint/js": "^9.23.0",
28+
"@types/node": "^20.10.7",
29+
"@types/react": "^18.3.3",
30+
"@types/react-dom": "^18.3.0",
31+
"@vitejs/plugin-react": "^4.3.4",
32+
"eslint": "^9.23.0",
33+
"eslint-config-prettier": "^10.1.1",
34+
"eslint-plugin-prettier": "^5.2.5",
35+
"eslint-plugin-react": "^7.37.4",
36+
"eslint-plugin-react-hooks": "^5.2.0",
37+
"globals": "^16.0.0",
38+
"prettier": "^3.3.3",
39+
"typescript": "^5.1.6",
40+
"typescript-eslint": "^8.28.0",
41+
"vite": "^6.2.6",
42+
"vite-plugin-pwa": "^1.2.0"
43+
},
44+
"name": "ra-offline"
45+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default {};
2.11 KB
Loading

0 commit comments

Comments
 (0)