Skip to content
Closed
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
75 changes: 75 additions & 0 deletions ichub-frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#################################################################################
# Eclipse Tractus-X - Industry Core Hub Frontend
#
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the
# License for the specific language govern in permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
#################################################################################

# Stage 1: Build the React app
FROM node:23-alpine AS builder

# Set the working directory
WORKDIR /app

# Install necessary dependencies
RUN apk add --no-cache python3 make g++ jq

Check warning on line 30 in ichub-frontend/Dockerfile

View workflow job for this annotation

GitHub Actions / Analyze

[MEDIUM] Unpinned Package Version in Apk Add

Package version pinning reduces the range of versions that can be installed, reducing the chances of failure due to unanticipated changes

Check warning

Code scanning / KICS

Unpinned Package Version in Apk Add Warning

RUN instruction apk add --no-cache python3 make g++ jq does not use package pinning form

# Copy package files and install dependencies
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Copy the rest of the source code
COPY . .

# Build the application
RUN yarn build


# Stage 2: Serve the app with Nginx
FROM nginxinc/nginx-unprivileged:alpine

Check warning on line 44 in ichub-frontend/Dockerfile

View workflow job for this annotation

GitHub Actions / Analyze

[LOW] Healthcheck Instruction Missing

Ensure that HEALTHCHECK is being used. The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working

Check notice

Code scanning / KICS

Healthcheck Instruction Missing Note

Dockerfile doesn't contain instruction 'HEALTHCHECK'

# Copy custom Nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf

# Copy built files from the builder stage
COPY --from=builder /app/dist /usr/share/nginx/html

# Change to root user
USER root

# Rename index.html to index.html.reference, to be used by env variables inject script
RUN mv /usr/share/nginx/html/index.html /usr/share/nginx/html/index.html.reference

# Create symlink for tmp for index.html to enable readOnlyRootFilesystem
RUN ln -s /tmp/index.html /usr/share/nginx/html/index.html

# Add env variables inject script and mark as executable
COPY ./scripts/inject-dynamic-env.sh /docker-entrypoint.d/00-inject-dynamic-env.sh
RUN chmod +x /docker-entrypoint.d/00-inject-dynamic-env.sh

# Make nginx owner of /usr/share/nginx/html/ and change to nginx user
RUN chown -R 101:101 /usr/share/nginx/html/

# Change to nginx user
USER 101

# Expose port 80
EXPOSE 80

# Start Nginx
CMD ["nginx", "-g", "daemon off;"]
8 changes: 8 additions & 0 deletions ichub-frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
</head>
<body>
<div id="root"></div>
<script>
// Do NOT change ENV attributes without changing them in scripts/inject-dynamic-env.sh as well
const ENV = {
REQUIRE_HTTPS_URL_PATTERN: "true",
ICHUB_ASSETS_URL: "http://localhost:3000/assets",
ICHUB_BACKEND_URL: "https://portal-backend.example.org"
}
</script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
42 changes: 42 additions & 0 deletions ichub-frontend/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#################################################################################
# Eclipse Tractus-X - Industry Core Hub Frontend
#
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the
# License for the specific language govern in permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
#################################################################################

server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/index.html /index.html;
}

error_page 404 /index.html;

# Here we should specify the backend service
# location /api/ {
# proxy_pass http://backend:5000/;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# }
}
4 changes: 3 additions & 1 deletion ichub-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
"preview": "vite preview",
"build:docker": "IMAGE=ichub-frontend && docker build -t $IMAGE -f Dockerfile .",
"start:docker": "IMAGE=ichub-frontend && docker run --rm -d -p 8080:80 --name ichub-frontend $IMAGE"
},
"dependencies": {
"@catena-x/portal-shared-components": "^3.7.6",
Expand Down
40 changes: 40 additions & 0 deletions ichub-frontend/scripts/inject-dynamic-env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/sh

#################################################################################
# Eclipse Tractus-X - Industry Core Hub Frontend
#
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the
# License for the specific language govern in permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
#################################################################################

source_file=/usr/share/nginx/html/index.html.reference
target_file=/tmp/index.html

# List of environment variables to be replaced
# (They should be set and match the ones in index.html)
# Sequence is irrelevant
vars=" \
REQUIRE_HTTPS_URL_PATTERN \
ICHUB_ASSETS_URL \
ICHUB_BACKEND_URL \
"

# Execute envsubst with the defined variables
envsubst "$(printf '${%s} ' $vars)" < "$source_file" > "$target_file"

echo "Variables injected correctly in $target_file"
2 changes: 1 addition & 1 deletion ichub-frontend/src/components/general/CardChip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const CardChip = ({ status, statusText }: CardChipProps) => {
border: theme.palette.chip[border],
height: '28px',
}}
icon={statusKey==StatusVariants.shared?<PersonIcon sx={{color: '#000000', fontSize: '18px'}}/>:null}
icon={statusKey==StatusVariants.shared?<PersonIcon sx={{color: '#000000', fontSize: '18px'}}/>:undefined}
/>
)
}
4 changes: 2 additions & 2 deletions ichub-frontend/src/components/general/JsonViewerDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import { JsonViewerDialogProps } from '../../types/jsonViewer';

const JsonViewerDialog = ({ open, onClose, carJsonData }: JsonViewerDialogProps) => {
const [copied, setCopied] = useState(false);
const title = carJsonData?.Name ? `${carJsonData.Name} JSON data` : "DCM JSON Data";
const description = carJsonData?.Description ? `${carJsonData.Description}` : "";
const title = carJsonData?.name ? `${carJsonData.name} JSON data` : "DCM JSON Data";
const description = carJsonData?.description ? `${carJsonData.description}` : "";

const handleCopy = () => {
const json_string = JSON.stringify(carJsonData, null, 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const ShareDropdown = ({ handleCopy, handleDownload, handleShare }: ShareDropdow
'font-size': '14px',
}}
buttonText="Share"
startIcon={<Icon fontSize="16" iconName="IosShare" />}
>
<Grid2 container direction="column">
<Button className="dropdown-button share-dropdown-btn" color="secondary" size="small" onClick={handleCopy} startIcon={<Icon fontSize="16" iconName="ContentCopy" />}>
Expand Down
2 changes: 1 addition & 1 deletion ichub-frontend/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { SharedThemeProvider } from '@catena-x/portal-shared-components'
import { theme } from './theme'
import { theme } from './theme/theme.ts'
import { ThemeProvider } from '@mui/material/styles';

import App from './App.tsx'
Expand Down
4 changes: 2 additions & 2 deletions ichub-frontend/src/pages/ProductsDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ const ProductsDetails = () => {
case PRODUCT_STATUS.REGISTERED:
return <StatusTag color="confirmed" label="Registered" variant="outlined" />;
case PRODUCT_STATUS.DRAFT:
return <StatusTag color="info" label="Draft" variant="outline" />;
return <StatusTag color="label" label="Draft" variant="outlined" />;
case PRODUCT_STATUS.SHARED:
return <StatusTag color="warning" label="Shared" variant="filled" />;
return <StatusTag color="pending" label="Shared" variant="filled" />;
default:
return null;
}
Expand Down
21 changes: 19 additions & 2 deletions ichub-frontend/src/pages/ProductsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,35 @@ import carPartsData from "../tests/payloads/sample-data.json";
import { ProductCard } from "../components/general/ProductCard";
import { PartInstance } from "../types/product";
import { Grid2 } from "@mui/material";
import { StatusVariants } from "../components/general/CardChip";

const ProductsList = () => {
const [carParts, setCarParts] = useState<PartInstance[]>([]);

const navigate = useNavigate();

useEffect(() => {
setCarParts(carPartsData);
const mappedCarParts = carPartsData.map((part) => ({
...part,
status: part.status as StatusVariants,
}));
setCarParts(mappedCarParts);
}, []);

const handleButtonClick = (itemId: string) => {
navigate(`/product/${itemId}`); // Navigate to the details page
};

const handleShare = (itemId: string) => {
console.log('Sharing item with id:', itemId);
// Share logic
};

const handleMore = (itemId: string) => {
console.log('More options for item with id:', itemId);
// More options logic
};

return (
<Grid2 className="product-catalog" container spacing={1} direction="row">
<Grid2 className="title flex flex-content-center">
Expand All @@ -50,11 +65,13 @@ const ProductsList = () => {
<Grid2 className="flex flex-content-center">
<ProductCard
onClick={(itemId: any) => handleButtonClick(itemId)}
onShare={handleShare}
onMore={handleMore}
items={carParts.map((part) => ({
uuid: part.uuid,
name: part.name,
class: part.class,
status: part.status,
status: part.status as StatusVariants,
}))}
/>
</Grid2>
Expand Down
Loading
Loading