Skip to content

Commit f0ae746

Browse files
Merge remote-tracking branch 'origin/share-filter' into share-filter
2 parents 9dd7abc + 31c6e2a commit f0ae746

File tree

18 files changed

+656
-325
lines changed

18 files changed

+656
-325
lines changed

.github/workflows/build-and-test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,8 @@ jobs:
130130
needs: checkout-install
131131
uses: ./.github/workflows/e2e-router.yml
132132
secrets: inherit
133+
134+
e2e-next-app-router:
135+
needs: checkout-install
136+
uses: ./.github/workflows/e2e-next-app-router.yml
137+
secrets: inherit
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: E2E Test for Next.js App Router
2+
3+
on:
4+
workflow_call:
5+
6+
permissions:
7+
contents: read
8+
9+
jobs:
10+
e2e-next-app-router:
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 30
13+
steps:
14+
- name: Checkout Repository
15+
uses: actions/checkout@v3
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Install Pnpm
20+
run: |
21+
corepack prepare pnpm@8.11.0 --activate
22+
corepack enable
23+
24+
- name: Setup Node.js 18
25+
uses: actions/setup-node@v3
26+
with:
27+
node-version: '18'
28+
cache: 'pnpm'
29+
30+
- name: Set Nx SHA
31+
uses: nrwl/nx-set-shas@v3
32+
33+
- name: Set SKIP_DEVTOOLS_POSTINSTALL environment variable
34+
run: echo "SKIP_DEVTOOLS_POSTINSTALL=true" >> $GITHUB_ENV
35+
36+
- name: Set local webpack
37+
run: echo "NEXT_PRIVATE_LOCAL_WEBPACK=true" >> $GITHUB_ENV
38+
39+
- name: Install Dependencies
40+
run: pnpm install
41+
42+
- name: Install Cypress
43+
run: npx cypress install
44+
45+
- name: Run Build for All
46+
run: npx nx run-many --targets=build --projects=tag:type:pkg
47+
48+
- name: Run condition check script
49+
id: check-ci
50+
run: node tools/scripts/ci-is-affected.mjs --appName=next-app-router-4000,next-app-router-4001
51+
52+
- name: E2E Test for Next.js App Router
53+
if: steps.check-ci.outcome == 'success'
54+
run: npx kill-port --port 4000,4001 || true && pnpm run app:next-router:dev & echo "done" && sleep 25 && npx nx run-many --target=e2e --projects=next-app-router-4000,next-app-router-4001 --parallel=1 && lsof -ti tcp:4000,4001 | xargs kill || true
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//@ts-check
2+
'use client';
3+
4+
import dynamic from 'next/dynamic';
5+
6+
// Dynamically import remote components
7+
const Button = dynamic(() => import('remote_4001/Button'), { ssr: true });
8+
const Header = dynamic(() => import('remote_4001/Header'), { ssr: true });
9+
const ProductCard = dynamic(() => import('remote_4001/ProductCard'), {
10+
ssr: true,
11+
});
12+
const TabGroup = dynamic(() => import('remote_4001/TabGroup'), { ssr: true });
13+
const TabNavItem = dynamic(() => import('remote_4001/TabNavItem'), {
14+
ssr: true,
15+
});
16+
const CountUp = dynamic(() => import('remote_4001/CountUp'), { ssr: true });
17+
const RenderingInfo = dynamic(() => import('remote_4001/RenderingInfo'), {
18+
ssr: true,
19+
});
20+
21+
export default function DemoPage() {
22+
return (
23+
<div className="p-4">
24+
<Header />
25+
26+
<main className="mx-auto mt-8 max-w-4xl">
27+
<h1 className="mb-6 text-2xl font-bold">Remote Components Demo</h1>
28+
29+
<section className="mb-8">
30+
<h2 className="mb-4 text-xl font-semibold">Basic UI Components</h2>
31+
<div className="space-x-4">
32+
<Button>Primary Button</Button>
33+
<Button>Secondary Button</Button>
34+
</div>
35+
</section>
36+
37+
<section className="mb-8">
38+
<h2 className="mb-4 text-xl font-semibold">Navigation Components</h2>
39+
<TabGroup>
40+
<TabNavItem href="/demo/tab1" isActive={true}>
41+
Tab 1
42+
</TabNavItem>
43+
<TabNavItem href="/demo/tab2" isActive={false}>
44+
Tab 2
45+
</TabNavItem>
46+
<TabNavItem href="/demo/tab3" isActive={false}>
47+
Tab 3
48+
</TabNavItem>
49+
</TabGroup>
50+
</section>
51+
52+
<section className="mb-8">
53+
<h2 className="mb-4 text-xl font-semibold">Product Components</h2>
54+
<div className="grid grid-cols-2 gap-4">
55+
<ProductCard
56+
product={{
57+
name: 'Demo Product',
58+
price: 99.99,
59+
description:
60+
'This is a demo product to showcase the ProductCard component',
61+
image: 'https://via.placeholder.com/300',
62+
rating: 4.5,
63+
}}
64+
/>
65+
<ProductCard
66+
product={{
67+
name: 'Another Product',
68+
price: 149.99,
69+
description: 'Another demo product with different details',
70+
image: 'https://via.placeholder.com/300',
71+
rating: 5,
72+
}}
73+
/>
74+
</div>
75+
</section>
76+
77+
<section className="mb-8">
78+
<h2 className="mb-4 text-xl font-semibold">Interactive Components</h2>
79+
<div className="space-y-4">
80+
<div className="rounded border p-4">
81+
<h3 className="mb-2 font-medium">Count Up Animation</h3>
82+
<CountUp start={0} end={1000} />
83+
</div>
84+
<div className="rounded border p-4">
85+
<h3 className="mb-2 font-medium">Rendering Information</h3>
86+
<RenderingInfo />
87+
</div>
88+
</div>
89+
</section>
90+
</main>
91+
</div>
92+
);
93+
}

main.py

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# To run this script you need Python setup and installed chardet and beautifulsoup dependencies through pip install
2+
3+
4+
import os
5+
import chardet
6+
from bs4 import BeautifulSoup
7+
8+
# This is basic config
9+
10+
INPUT_DIR = 'docs/index.html' # TypeDoc assinged docs dir,
11+
OUTPUT_NAV_ADOC = 'apps/docs/src/en/modules/ROOT/nav.adoc' # Your desired nav file to put pages nav
12+
OUTPUT_PAGES_DIR = 'apps/docs/src/en/modules/ROOT/pages' # Your desired location
13+
14+
def process_code_tag(tag):
15+
# Apply desired replacements to the HTML content
16+
cleaned_html = (
17+
tag.decode_contents()
18+
.replace(' ', '__')
19+
.replace('<br>', '\n')
20+
.replace('<br/>', '\n')
21+
.replace('<button>Copy</button>', '')
22+
)
23+
24+
# Convert the cleaned HTML to Beautiful Soup object
25+
cleaned_soup = BeautifulSoup(cleaned_html, "html.parser")
26+
27+
# Extract text content from the cleaned soup
28+
code_text = cleaned_soup.get_text()
29+
30+
return f"[source, javascript]\n----\n{code_text}\n----\n\n"
31+
32+
def process_div_or_p_tag(tag):
33+
# Apply desired replacements to the HTML content
34+
cleaned_html = (
35+
tag.decode_contents()
36+
.replace('<code>', '`')
37+
.replace('</code>', '`')
38+
.replace('<strong>', '*')
39+
.replace('</strong>', '*')
40+
)
41+
42+
for link in tag.find_all('a'):
43+
xref = link.get("href")
44+
link_text = link.get_text().strip()
45+
cleaned_html = cleaned_html.replace('<a ', f"{xref}[{link_text}] <a ")
46+
start = cleaned_html.index('<a ')
47+
end = cleaned_html.index('</a>') + 3
48+
if len(cleaned_html) > end:
49+
cleaned_html = cleaned_html[0: start:] + cleaned_html[end + 1::]
50+
51+
# Convert the cleaned HTML to Beautiful Soup object
52+
cleaned_soup = BeautifulSoup(cleaned_html, "html.parser")
53+
54+
# Extract text content from the cleaned soup
55+
content = cleaned_soup.get_text().strip()
56+
57+
return f"{content}\n\n"
58+
59+
def process_content_section(content_section, adoc_content):
60+
for tag in content_section.find_all():
61+
if tag.name in {"h1", "h2", "h3", "h4"}:
62+
heading_level = int(tag.name[1]) # Convert heading level to integer
63+
heading_text = tag.get_text().strip()
64+
adoc_content += f"{'=' * heading_level} {heading_text}\n\n"
65+
66+
elif tag.name == "pre":
67+
adoc_content += process_code_tag(tag).replace('__', ' ')
68+
69+
elif tag.name == "ul":
70+
for li in tag.find_all("li"):
71+
li_text = li.get_text().strip()
72+
adoc_content += f"* {li_text}\n"
73+
adoc_content += "\n"
74+
75+
elif tag.name == "div" or tag.name == "p":
76+
adoc_content += process_div_or_p_tag(tag)
77+
78+
return adoc_content
79+
80+
def update_nav_adoc(antora_links):
81+
# Find the position to replace '.Packages' section
82+
# Append antora_output.adoc to nav.adoc and replace '.Packages' section
83+
adoc_output_filename = OUTPUT_NAV_ADOC
84+
with open(adoc_output_filename, "r", encoding="utf-8") as test_adoc_file:
85+
nav_adoc_content = test_adoc_file.read()
86+
87+
# Find the position to replace '.Packages' section
88+
packages_start = nav_adoc_content.find(".Packages")
89+
if packages_start != -1:
90+
packages_end = nav_adoc_content.find("\n\n", packages_start) + 2
91+
if packages_end != -1:
92+
new_nav_adoc_content = (
93+
nav_adoc_content[:packages_start] +
94+
'.Packages\n' +
95+
"\n".join(antora_links) +
96+
"\n\n" +
97+
nav_adoc_content[packages_end:]
98+
)
99+
with open(adoc_output_filename, "w", encoding="utf-8") as new_nav_adoc_file:
100+
new_nav_adoc_file.write(new_nav_adoc_content)
101+
print(f"Updated {adoc_output_filename} with antora_output.adoc content.")
102+
else:
103+
print(".Packages end not found in nav.adoc.")
104+
else:
105+
print(".Packages section not found in nav.adoc.")
106+
# Append content of antora_output.adoc to nav.adoc
107+
with open(adoc_output_filename, "a", encoding="utf-8") as nav_adoc_file:
108+
nav_adoc_file.write('.Packages\n' + "\n".join(antora_links) + "\n\n")
109+
print(f"Appended content of antora_output.adoc to {adoc_output_filename}.")
110+
111+
def update_pages_directory():
112+
# Move generated .adoc files to pages dir
113+
output_directory = OUTPUT_PAGES_DIR
114+
for generated_filename in os.listdir():
115+
if generated_filename.endswith(".adoc"):
116+
generated_file_path = os.path.join(generated_filename)
117+
destination_path = os.path.join(output_directory, generated_filename)
118+
if os.path.exists(destination_path):
119+
os.remove(destination_path) # Remove existing file
120+
os.rename(generated_file_path, destination_path)
121+
print(f"Moved {generated_filename} to {output_directory}.")
122+
123+
def process_docs(ul_element):
124+
antora_links = []
125+
126+
# Iterate through <li> elements inside <ul>
127+
for li in ul_element.find_all("li"):
128+
link = li.find("a")
129+
if link:
130+
href = link.get("href")
131+
link_text = link.get_text().strip()
132+
133+
# Remove '_' at position 0 and replace remaining underscores with hyphens
134+
module_name = os.path.splitext(os.path.basename(href))[0]
135+
module_name = module_name[1:].replace("_", "-")
136+
137+
# Construct full path to the corresponding .html file
138+
html_path = os.path.join("docs", href)
139+
140+
# Check if the HTML file exists before reading and parsing
141+
if os.path.exists(html_path):
142+
# Read and parse the .html content
143+
with open(html_path, "rb") as html_file:
144+
html_content = html_file.read()
145+
146+
# Parse the .html content using Beautiful Soup
147+
html_soup = BeautifulSoup(html_content, "html.parser")
148+
149+
# Find the content section
150+
content_section = html_soup.find("section", class_="tsd-panel tsd-typography")
151+
152+
if content_section:
153+
# Convert <code> tags to Antora code blocks while preserving other text
154+
adoc_filename = f"{module_name}.adoc"
155+
adoc_content = f"= {link_text}\n\n"
156+
157+
adoc_content = process_content_section(content_section, adoc_content)
158+
159+
# Create the .adoc file with UTF-8 encoding
160+
with open(adoc_filename.replace("/", "-"), "w", encoding="utf-8") as adoc_file:
161+
adoc_file.write(adoc_content)
162+
163+
antora_link = f"* xref:{adoc_filename}[{link_text}]"
164+
antora_links.append(antora_link)
165+
else:
166+
print(f"HTML file '{html_path}' does not exist.")
167+
168+
return antora_links
169+
170+
171+
if __name__ == '__main__':
172+
# Read the HTML file in binary mode
173+
with open(INPUT_DIR, "rb") as file:
174+
html_content = file.read()
175+
176+
# Detect the encoding of the HTML content
177+
result = chardet.detect(html_content)
178+
encoding = result["encoding"]
179+
180+
# Parse the HTML content using Beautiful Soup
181+
soup = BeautifulSoup(html_content.decode(encoding), "html.parser")
182+
183+
# Find the <ul> element with the specified class
184+
ul_element = soup.find("ul", class_="tsd-small-nested-navigation")
185+
186+
if ul_element:
187+
# Lists to store Antora links and individual HTML files
188+
antora_links = process_docs(ul_element)
189+
190+
update_nav_adoc(antora_links)
191+
192+
update_pages_directory()
193+
194+
print("All tasks completed.")
195+
else:
196+
print("UL element not found in the HTML.")

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@
8888
"lodash.get": "4.4.2",
8989
"openai": "^4.72.0",
9090
"rambda": "7.5.0",
91+
"react": "18.3.1",
92+
"react-dom": "18.3.1",
9193
"react-router-dom": "6.26.2",
9294
"regenerator-runtime": "0.14.1",
9395
"sharp": "^0.33.4",
@@ -149,8 +151,6 @@
149151
"@swc/jest": "0.2.36",
150152
"@tailwindcss/forms": "0.5.9",
151153
"@testing-library/react": "16.1.0",
152-
"@types/react": "18.3.11",
153-
"@types/react-dom": "18.3.0",
154154
"@types/adm-zip": "0.5.5",
155155
"@types/chrome": "0.0.277",
156156
"@types/download": "8.0.5",
@@ -163,6 +163,8 @@
163163
"@types/node": "18.16.9",
164164
"@types/node-fetch": "2.6.11",
165165
"@types/pidusage": "2.0.5",
166+
"@types/react": "18.3.11",
167+
"@types/react-dom": "18.3.0",
166168
"@types/webpack-sources": "3.2.3",
167169
"@typescript-eslint/eslint-plugin": "7.18.0",
168170
"@typescript-eslint/parser": "7.18.0",
@@ -213,8 +215,6 @@
213215
"prettier-eslint": "16.3.0",
214216
"publint": "^0.2.12",
215217
"qwik-nx": "^3.1.1",
216-
"react": "18.3.1",
217-
"react-dom": "18.3.1",
218218
"react-refresh": "0.14.2",
219219
"rimraf": "^6.0.1",
220220
"rollup-plugin-copy": "3.5.0",

0 commit comments

Comments
 (0)