Skip to content

Feature/dental UI refactor and deploy#5959

Open
bitbossing wants to merge 17 commits into
OHIF:masterfrom
bitbossing:feature/dental-ui-refactor-and-deploy
Open

Feature/dental UI refactor and deploy#5959
bitbossing wants to merge 17 commits into
OHIF:masterfrom
bitbossing:feature/dental-ui-refactor-and-deploy

Conversation

@bitbossing
Copy link
Copy Markdown

@bitbossing bitbossing commented Apr 13, 2026

D.) Refactor, Deployment & Testing (Claude, Docker + Firebase)
📝 Create & clone a branch to work on Task D
📝 Create, Build and Deploy the Project using Docker to Firebase
📝 Full Scale Testing
📝 Fix Possible Bugs
📝 Update ReadMe File

Greptile Summary

This PR introduces a new 24x7-dental-ui OHIF extension and mode with dental-specific tools (PA Length, Canal Angle, Crown Width, Root Length), a 2×2 hanging protocol, a tooth selector, and Firebase Google Auth for deployment to Cloud Run + Firebase Hosting.

  • P1 — LoginPage.tsx: onSignIn() is not awaited and handleSignIn swallows all errors, so a failed sign-in (popup closed, network error) leaves the button permanently disabled showing "Redirecting…" with no way to retry without a page refresh.
  • P1 — WorkList.tsx: <FirebaseUserInfo /> is hardcoded unconditionally, bypassing the ohif.userInfo customization service used by ViewerHeader. This always bundles the Firebase SDK and silently ignores any other ohif.userInfo customization registered by downstream consumers.

Confidence Score: 4/5

Two P1 defects need fixes before merging: the permanently-stuck login button and the unconditional FirebaseUserInfo in WorkList.

The dental extension and mode code is well-structured and clean. However, the Firebase auth integration has two present defects that affect real users: a broken retry path on the login page and a customization bypass in WorkList. Both are straightforward to fix.

platform/app/src/routes/LoginPage.tsx and platform/app/src/routes/WorkList/WorkList.tsx need attention before merge.

Security Review

  • platform/app/.env tracked in git: Empty placeholder values are committed; because git rm --cached was not run, a developer who fills in real Firebase credentials locally could accidentally commit them in a future change.
  • Docker build args (Dockerfile + deploy.sh): Firebase credentials are passed via --build-arg, which records them in image layer history and are visible via docker history. Firebase web API keys are not high-sensitivity secrets, but the pattern should be noted.

Important Files Changed

Filename Overview
platform/app/src/routes/LoginPage.tsx New Firebase login page — onSignIn() not awaited causes the button to stay permanently disabled after a failed sign-in attempt
platform/app/src/routes/WorkList/WorkList.tsx Hardcodes <FirebaseUserInfo /> unconditionally, bypassing the ohif.userInfo customization mechanism used in ViewerHeader and always bundling the Firebase SDK
platform/app/src/utils/FirebaseAuthRoutes.tsx New Firebase auth wrapper — correctly gates app routes on auth state; errors in handleSignIn are swallowed (contributing to LoginPage P1)
platform/app/src/components/FirebaseUserInfo.tsx New user info dropdown with sign-out action; returns empty fragment when no user is present
platform/app/src/App.tsx Correctly gates Firebase auth routes and customization registration behind firebaseEnabled flag
Dockerfile Adds Firebase env var ARGs/ENVs; credentials passed as build args are recorded in image layer history
platform/app/.env Adds Firebase env var placeholders; file is tracked in git so real credentials could be accidentally committed despite the new .gitignore entry
deploy.sh New deploy script that sources .env, builds Docker image with Firebase build args, deploys to Cloud Run and Firebase Hosting
extensions/24x7-dental-ui/src/measurements/registerDentalMappings.ts Registers measurement mappings for four dental tools with singleton guard to prevent double-registration
modes/24x7-dental-ui/src/index.tsx Dental mode — extends basic mode with dental tools, custom toolbar sections, measurement auto-labeling, and subscription cleanup on exit
Prompt To Fix All With AI
This is a comment left during a code review.
Path: platform/app/src/routes/LoginPage.tsx
Line: 13-21

Comment:
**Sign-in button permanently stuck after a failed attempt**

`onSignIn()` is called without `await`, so errors from the async `handleSignIn` in `FirebaseAuthRoutes` (popup closed, network error, etc.) are silently swallowed and never reach the `catch` block here. When sign-in fails, `isSigningIn` remains `true` indefinitely — the button stays disabled showing "Redirecting…" and `setError` is never called. The user must refresh the page to retry.

```suggestion
  const handleGoogleSignIn = async () => {
    setIsSigningIn(true);
    setError(null);
    try {
      await onSignIn();
    } catch (err: any) {
      console.error('Google sign-in error:', err);
      setError(err.message || 'Sign-in failed. Please try again.');
      setIsSigningIn(false);
    }
  };
```

`handleSignIn` in `FirebaseAuthRoutes` should also re-throw errors instead of silently logging them, so callers can handle them.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: platform/app/src/routes/WorkList/WorkList.tsx
Line: 561

Comment:
**`FirebaseUserInfo` hardcoded, bypassing the customization system**

`<FirebaseUserInfo />` is always passed here regardless of whether Firebase is enabled, unlike `ViewerHeader.tsx` which reads `ohif.userInfo` from the `customizationService`. This means:

1. The Firebase SDK is always bundled and imported even in non-Firebase OHIF deployments.
2. Any other `ohif.userInfo` customization registered by a downstream consumer is silently ignored in the WorkList header.

The WorkList should mirror the `ViewerHeader` pattern — either read `customizationService.getCustomization('ohif.userInfo')` or gate on the same `firebaseEnabled` flag used in `App.tsx`.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: Dockerfile
Line: 74-85

Comment:
**Firebase credentials recorded in Docker image build history**

Values passed via `--build-arg` are permanently stored in each build layer and visible to anyone with access to the image via `docker history <image>`. While Firebase web API keys are not highly sensitive secrets (they're embedded in client JS), this pattern sets a precedent that could leak more sensitive values if the approach is reused. Consider writing a `.env`-style file at build time instead of using build args for credentials, or accept the trade-off explicitly in team policy.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: platform/app/.env
Line: 11-16

Comment:
**`.env` file with Firebase keys committed to the repository**

Although the values are empty placeholders here, the `.env` file itself is now tracked in git. The `.gitignore` addition in this PR (`# Environment variables / .env`) does not untrack a file that was already committed — `git rm --cached platform/app/.env` would be needed. A developer filling in real credentials locally won't be warned that the file is tracked and could accidentally commit them. Consider removing the file from tracking and replacing it with a `.env.example` or `.env.template` file containing only keys (no values).

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "📝 Update ReadMe File" | Re-trigger Greptile

Greptile also left 4 inline comments on this PR.

(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!

📝 Create a new mode [dental-ui] "Dental Mode" base on Longitudinal Mode and to refrain from editing original code
…o refrain from editing original code

📝 Add a button to toggle theme on the Header (change UI's color, font, icon)
○ Top-left: Current image
○ Top-right: Prior exam (Empty if none)
○ Bottom: Bitewing placeholders)
📝 Create new set of Measurement tool for Dental Mode which save its measurement on the new Dental Measurement Panel that automatically renames depending on tool name with auto increment.
○ PA Length : uses Periapical Length Tool
○ Canal Angle : uses Canal Angle Tool
○ Crown Width : uses Periapical Length Tool
○ Root Length : uses Periapical Length Tool
📝 Setup Firebase Project and Create a Login Page
📝 Create, Build and Deploy the Project using Docker to Firebase

📝 Full Scale Testing

📝 Fix Possible Bugs
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 13, 2026

Deploy Preview for ohif-dev ready!

Name Link
🔨 Latest commit e078eaa
🔍 Latest deploy log https://app.netlify.com/projects/ohif-dev/deploys/69dd11d8408f5000082d4065
😎 Deploy Preview https://deploy-preview-5959--ohif-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment on lines +13 to +21
setError(null);
try {
onSignIn();
} catch (err: any) {
console.error('Google sign-in error:', err);
setError(err.message || 'Sign-in failed. Please try again.');
setIsSigningIn(false);
}
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Sign-in button permanently stuck after a failed attempt

onSignIn() is called without await, so errors from the async handleSignIn in FirebaseAuthRoutes (popup closed, network error, etc.) are silently swallowed and never reach the catch block here. When sign-in fails, isSigningIn remains true indefinitely — the button stays disabled showing "Redirecting…" and setError is never called. The user must refresh the page to retry.

Suggested change
setError(null);
try {
onSignIn();
} catch (err: any) {
console.error('Google sign-in error:', err);
setError(err.message || 'Sign-in failed. Please try again.');
setIsSigningIn(false);
}
};
const handleGoogleSignIn = async () => {
setIsSigningIn(true);
setError(null);
try {
await onSignIn();
} catch (err: any) {
console.error('Google sign-in error:', err);
setError(err.message || 'Sign-in failed. Please try again.');
setIsSigningIn(false);
}
};

handleSignIn in FirebaseAuthRoutes should also re-throw errors instead of silently logging them, so callers can handle them.

Prompt To Fix With AI
This is a comment left during a code review.
Path: platform/app/src/routes/LoginPage.tsx
Line: 13-21

Comment:
**Sign-in button permanently stuck after a failed attempt**

`onSignIn()` is called without `await`, so errors from the async `handleSignIn` in `FirebaseAuthRoutes` (popup closed, network error, etc.) are silently swallowed and never reach the `catch` block here. When sign-in fails, `isSigningIn` remains `true` indefinitely — the button stays disabled showing "Redirecting…" and `setError` is never called. The user must refresh the page to retry.

```suggestion
  const handleGoogleSignIn = async () => {
    setIsSigningIn(true);
    setError(null);
    try {
      await onSignIn();
    } catch (err: any) {
      console.error('Google sign-in error:', err);
      setError(err.message || 'Sign-in failed. Please try again.');
      setIsSigningIn(false);
    }
  };
```

`handleSignIn` in `FirebaseAuthRoutes` should also re-throw errors instead of silently logging them, so callers can handle them.

How can I resolve this? If you propose a fix, please make it concise.

isReturnEnabled={false}
WhiteLabeling={appConfig.whiteLabeling}
showPatientInfo={PatientInfoVisibility.DISABLED}
UserInfo={<FirebaseUserInfo />}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 FirebaseUserInfo hardcoded, bypassing the customization system

<FirebaseUserInfo /> is always passed here regardless of whether Firebase is enabled, unlike ViewerHeader.tsx which reads ohif.userInfo from the customizationService. This means:

  1. The Firebase SDK is always bundled and imported even in non-Firebase OHIF deployments.
  2. Any other ohif.userInfo customization registered by a downstream consumer is silently ignored in the WorkList header.

The WorkList should mirror the ViewerHeader pattern — either read customizationService.getCustomization('ohif.userInfo') or gate on the same firebaseEnabled flag used in App.tsx.

Prompt To Fix With AI
This is a comment left during a code review.
Path: platform/app/src/routes/WorkList/WorkList.tsx
Line: 561

Comment:
**`FirebaseUserInfo` hardcoded, bypassing the customization system**

`<FirebaseUserInfo />` is always passed here regardless of whether Firebase is enabled, unlike `ViewerHeader.tsx` which reads `ohif.userInfo` from the `customizationService`. This means:

1. The Firebase SDK is always bundled and imported even in non-Firebase OHIF deployments.
2. Any other `ohif.userInfo` customization registered by a downstream consumer is silently ignored in the WorkList header.

The WorkList should mirror the `ViewerHeader` pattern — either read `customizationService.getCustomization('ohif.userInfo')` or gate on the same `firebaseEnabled` flag used in `App.tsx`.

How can I resolve this? If you propose a fix, please make it concise.

Comment thread Dockerfile
Comment on lines 74 to +85

# Firebase env vars — passed as --build-arg at docker build time
ARG REACT_APP_FIREBASE_API_KEY
ARG REACT_APP_FIREBASE_AUTH_DOMAIN
ARG REACT_APP_FIREBASE_PROJECT_ID
ARG REACT_APP_FIREBASE_STORAGE_BUCKET
ARG REACT_APP_FIREBASE_MESSAGING_SENDER_ID
ARG REACT_APP_FIREBASE_APP_ID
ENV REACT_APP_FIREBASE_API_KEY=${REACT_APP_FIREBASE_API_KEY}
ENV REACT_APP_FIREBASE_AUTH_DOMAIN=${REACT_APP_FIREBASE_AUTH_DOMAIN}
ENV REACT_APP_FIREBASE_PROJECT_ID=${REACT_APP_FIREBASE_PROJECT_ID}
ENV REACT_APP_FIREBASE_STORAGE_BUCKET=${REACT_APP_FIREBASE_STORAGE_BUCKET}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 security Firebase credentials recorded in Docker image build history

Values passed via --build-arg are permanently stored in each build layer and visible to anyone with access to the image via docker history <image>. While Firebase web API keys are not highly sensitive secrets (they're embedded in client JS), this pattern sets a precedent that could leak more sensitive values if the approach is reused. Consider writing a .env-style file at build time instead of using build args for credentials, or accept the trade-off explicitly in team policy.

Prompt To Fix With AI
This is a comment left during a code review.
Path: Dockerfile
Line: 74-85

Comment:
**Firebase credentials recorded in Docker image build history**

Values passed via `--build-arg` are permanently stored in each build layer and visible to anyone with access to the image via `docker history <image>`. While Firebase web API keys are not highly sensitive secrets (they're embedded in client JS), this pattern sets a precedent that could leak more sensitive values if the approach is reused. Consider writing a `.env`-style file at build time instead of using build args for credentials, or accept the trade-off explicitly in team policy.

How can I resolve this? If you propose a fix, please make it concise.

Comment thread platform/app/.env
Comment on lines 11 to +16
USE_HASH_ROUTER=false

REACT_APP_FIREBASE_API_KEY=
REACT_APP_FIREBASE_AUTH_DOMAIN=
REACT_APP_FIREBASE_PROJECT_ID=
REACT_APP_FIREBASE_STORAGE_BUCKET=
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 security .env file with Firebase keys committed to the repository

Although the values are empty placeholders here, the .env file itself is now tracked in git. The .gitignore addition in this PR (# Environment variables / .env) does not untrack a file that was already committed — git rm --cached platform/app/.env would be needed. A developer filling in real credentials locally won't be warned that the file is tracked and could accidentally commit them. Consider removing the file from tracking and replacing it with a .env.example or .env.template file containing only keys (no values).

Prompt To Fix With AI
This is a comment left during a code review.
Path: platform/app/.env
Line: 11-16

Comment:
**`.env` file with Firebase keys committed to the repository**

Although the values are empty placeholders here, the `.env` file itself is now tracked in git. The `.gitignore` addition in this PR (`# Environment variables / .env`) does not untrack a file that was already committed — `git rm --cached platform/app/.env` would be needed. A developer filling in real credentials locally won't be warned that the file is tracked and could accidentally commit them. Consider removing the file from tracking and replacing it with a `.env.example` or `.env.template` file containing only keys (no values).

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant