diff --git a/.github/workflows/node.working.js.yml b/.github/workflows/node.working.js.yml index e1fbef549..cd3029bf4 100644 --- a/.github/workflows/node.working.js.yml +++ b/.github/workflows/node.working.js.yml @@ -1,4 +1,4 @@ -name: OHRI CI - @esm and Docker Image +name: OHRI CI - @esm and Docker Image Working/QA on: push: @@ -11,8 +11,88 @@ on: types: [opened, synchronize] jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Cache dependencies + id: cache + uses: actions/cache@v3 + with: + path: '**/node_modules' + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + + - name: Install dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: yarn install --immutable + + - name: Run tests + run: yarn run test + + - name: Run build + run: yarn turbo run build --color --concurrency=5 --api="http://127.0.0.1:9080" --token="${{ secrets.TURBO_SERVER_TOKEN }}" --team="${{ github.repository_owner }}" + + - name: Upload build artifacts + uses: actions/upload-artifact@v3 + with: + name: packages + path: | + packages/**/dist + + qa: + runs-on: ubuntu-latest + needs: build + + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/working' }} + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + registry-url: 'https://registry.npmjs.org' + + - name: Cache dependencies + id: cache + uses: actions/cache@v3 + with: + path: '**/node_modules' + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: yarn install --immutable + + - name: Version + run: yarn workspaces foreach --worktree --topological --exclude @ohri/openmrs-esm-ohri version "$(node -e "console.log(require('semver').inc(require('./package.json').version, 'patch'))")-qa.${{ github.run_number }}" + + - name: Build + run: yarn turbo run build --color --concurrency=5 + + - name: qa + run: yarn config set npmAuthToken "${NODE_AUTH_TOKEN}" && yarn run ci:qa + env: + NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} + + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + with: + name: packages + path: | + packages/**/dist + docker_workingserver_frontend: runs-on: ubuntu-latest + needs: qa steps: - name: Wait for 5 min - Let @esms reflect on NPM registry @@ -37,7 +117,7 @@ jobs: file: ./frontend/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - tags: ${{ secrets.DOCKERHUB_USERNAME }}/ohri-working-frontend:next,${{ secrets.DOCKERHUB_USERNAME }}/ohri-working-frontend:ci_${{ github.run_number }} + tags: ${{ secrets.DOCKERHUB_USERNAME }}/ohri-working-frontend:qa,${{ secrets.DOCKERHUB_USERNAME }}/ohri-working-frontend:ci_${{ github.run_number }} cache-from: type=inline,ref=user/app:buildcache cache-to: type=inline,ref=user/app:buildcache,mode=max diff --git a/.yarnrc.yml b/.yarnrc.yml index 5ce885524..93a28075a 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -16,4 +16,7 @@ changesetBaseRefs: [ "dev", "origin/dev", "upstream/dev", + "working", + "origin/working", + "upstream/working", ] diff --git a/package.json b/package.json index 502f203aa..d062f3b0c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@ohri/openmrs-esm-ohri", "private": true, - "version": "2.3.1", + "version": "2.3.6", "description": "OHRI MicroFrontend for OpenMRS SPA", "workspaces": [ "packages/*" @@ -30,6 +30,7 @@ "verify": "turbo run lint && turbo run typescript && yarn test --coverage", "ci:prepublish": "yarn workspaces foreach --all --topological --exclude @ohri/openmrs-esm-ohri npm publish --access public --tag next", "ci:publish": "yarn workspaces foreach --all --topological --exclude @ohri/openmrs-esm-ohri npm publish --access public --tag latest", + "ci:qa": "yarn workspaces foreach --all --topological --exclude @ohri/openmrs-esm-ohri npm publish --access public --tag qa", "release": "yarn workspaces foreach --all --topological version", "coverage": "yarn test --coverage", "badges": "yarn coverage && yarn jest-coverage-badges --output './badges' ", diff --git a/packages/esm-cervical-cancer-app/package.json b/packages/esm-cervical-cancer-app/package.json index 22f6bea7d..39de913b1 100644 --- a/packages/esm-cervical-cancer-app/package.json +++ b/packages/esm-cervical-cancer-app/package.json @@ -1,6 +1,6 @@ { "name": "@ohri/openmrs-esm-ohri-cervical-cancer-app", - "version": "2.3.1", + "version": "2.3.6", "description": "Cervical cancer microfrontend for OpenMRS HIV Reference Implementation (OHRI)", "browser": "dist/openmrs-esm-ohri-cervical-cancer-app.js", "main": "src/index.ts", diff --git a/packages/esm-commons-lib/package.json b/packages/esm-commons-lib/package.json index 5f5377057..b2a77672e 100644 --- a/packages/esm-commons-lib/package.json +++ b/packages/esm-commons-lib/package.json @@ -1,6 +1,6 @@ { "name": "@ohri/openmrs-esm-ohri-commons-lib", - "version": "2.3.1", + "version": "2.3.6", "description": "Commons library microfrontend of shared assets for OpenMRS HIV Reference Implementation (OHRI)", "browser": "dist/ohri-commons-lib.js", "main": "src/index.ts", @@ -32,7 +32,7 @@ }, "dependencies": { "@carbon/react": "^1.13.0", - "@openmrs/openmrs-form-engine-lib": "2.0.0-pre.1029", + "@openmrs/openmrs-form-engine-lib": "2.0.0-pre.1260", "fuzzy": "^0.1.3", "lodash-es": "^4.17.15", "systemjs-webpack-interop": "^2.3.7", diff --git a/packages/esm-commons-lib/src/components/encounter-list/encounter-list.component.tsx b/packages/esm-commons-lib/src/components/encounter-list/encounter-list.component.tsx index f99d32550..b2e75d97c 100644 --- a/packages/esm-commons-lib/src/components/encounter-list/encounter-list.component.tsx +++ b/packages/esm-commons-lib/src/components/encounter-list/encounter-list.component.tsx @@ -20,7 +20,6 @@ import { useEncounterRows } from '../../hooks/useEncounterRows'; import { type OpenmrsEncounter } from '../../types'; import { useFormsJson } from '../../hooks/useFormsJson'; import { usePatientDeathStatus } from '../../hooks/usePatientDeathStatus'; -import { mutate } from 'swr'; import styles from './encounter-list.scss'; @@ -51,6 +50,7 @@ export interface EncounterListProps { workspaceWindowSize?: 'minimized' | 'maximized'; }; filter?: (encounter: any) => boolean; + afterFormSaveAction?: () => void; } export const EncounterList: React.FC = ({ @@ -62,6 +62,7 @@ export const EncounterList: React.FC = ({ formList, filter, launchOptions, + afterFormSaveAction, }) => { const { t } = useTranslation(); const [paginatedRows, setPaginatedRows] = useState([]); @@ -72,7 +73,12 @@ export const EncounterList: React.FC = ({ const { isDead } = usePatientDeathStatus(patientUuid); const formNames = useMemo(() => formList.map((form) => form.name), [formList]); const { formsJson, isLoading: isLoadingFormsJson } = useFormsJson(formNames); - const { encounters, isLoading, onFormSave } = useEncounterRows(patientUuid, encounterType, filter); + const { encounters, isLoading, onFormSave } = useEncounterRows( + patientUuid, + encounterType, + filter, + afterFormSaveAction, + ); const { moduleName, workspaceWindowSize, displayText, hideFormLauncher } = launchOptions; const defaultActions = useMemo( @@ -114,9 +120,7 @@ export const EncounterList: React.FC = ({ const abortController = new AbortController(); deleteEncounter(encounterUuid, abortController) .then(() => { - mutate((key) => typeof key === 'string' && key.startsWith('/ws/rest/v1/encounter'), undefined, { - revalidate: true, - }); + onFormSave(); showSnackbar({ isLowContrast: true, title: t('encounterDeleted', 'Encounter deleted'), @@ -132,6 +136,10 @@ export const EncounterList: React.FC = ({ kind: 'error', }); }); + + // Update encounters after deletion + const updatedEncounters = encounters.filter((enc) => enc.uuid !== encounterUuid); + constructPaginatedTableRows(updatedEncounters, currentPage, pageSize); close(); }, }); @@ -262,7 +270,7 @@ export const EncounterList: React.FC = ({ }); setPaginatedRows(rows); }, - [columns, defaultActions, forms, moduleName, workspaceWindowSize, patientUuid, onFormSave, handleDeleteEncounter], + [columns, defaultActions, forms, moduleName, onFormSave, workspaceWindowSize, patientUuid, handleDeleteEncounter], ); useEffect(() => { diff --git a/packages/esm-commons-lib/src/components/encounter-list/helpers.ts b/packages/esm-commons-lib/src/components/encounter-list/helpers.ts index 21692f005..812c2fa72 100644 --- a/packages/esm-commons-lib/src/components/encounter-list/helpers.ts +++ b/packages/esm-commons-lib/src/components/encounter-list/helpers.ts @@ -14,11 +14,10 @@ export function launchEncounterForm( intent: string = '*', workspaceWindowSize?: 'minimized' | 'maximized', patientUuid?: string, - mutateform?: () => void, ) { launchPatientWorkspace('patient-form-entry-workspace', { workspaceTitle: form.name, - mutateform: mutateform, + mutateForm: onFormSave, formInfo: { encounterUuid, formUuid: form.name, diff --git a/packages/esm-commons-lib/src/hooks/useEncounterRows.ts b/packages/esm-commons-lib/src/hooks/useEncounterRows.ts index 97e228f64..15576d277 100644 --- a/packages/esm-commons-lib/src/hooks/useEncounterRows.ts +++ b/packages/esm-commons-lib/src/hooks/useEncounterRows.ts @@ -1,10 +1,16 @@ -import { useCallback, useEffect, useState } from 'react'; -import useSWRImmutable, { mutate } from 'swr'; -import { type OpenmrsEncounter } from '../types'; +import useSWR from 'swr'; + +import { useCallback, useEffect, useMemo, useState } from 'react'; import { openmrsFetch } from '@openmrs/esm-framework'; import { encounterRepresentation } from '../constants'; +import { type OpenmrsEncounter } from '../types'; -export function useEncounterRows(patientUuid: string, encounterType: string, encounterFilter: (encounter) => boolean) { +export function useEncounterRows( + patientUuid: string, + encounterType: string, + encounterFilter: (encounter) => boolean, + afterFormSaveAction: () => void, +) { const [encounters, setEncounters] = useState([]); const url = `/ws/rest/v1/encounter?encounterType=${encounterType}&patient=${patientUuid}&v=${encounterRepresentation}`; @@ -12,7 +18,8 @@ export function useEncounterRows(patientUuid: string, encounterType: string, enc data: response, error, isLoading, - } = useSWRImmutable<{ data: { results: OpenmrsEncounter[] } }, Error>(url, openmrsFetch); + mutate, + } = useSWR<{ data: { results: OpenmrsEncounter[] } }, Error>(url, openmrsFetch); useEffect(() => { if (response) { @@ -30,8 +37,9 @@ export function useEncounterRows(patientUuid: string, encounterType: string, enc }, [encounterFilter, response]); const onFormSave = useCallback(() => { - mutate(url); - }, [url]); + mutate(); + afterFormSaveAction && afterFormSaveAction(); + }, [afterFormSaveAction, mutate]); return { encounters, diff --git a/packages/esm-covid-app/package.json b/packages/esm-covid-app/package.json index d5483b155..86a796ccc 100644 --- a/packages/esm-covid-app/package.json +++ b/packages/esm-covid-app/package.json @@ -1,6 +1,6 @@ { "name": "@ohri/openmrs-esm-ohri-covid-app", - "version": "2.3.1", + "version": "2.3.6", "description": "COVID Microfrontend for OpenMRS HIV Reference Implementation (OHRI)", "browser": "dist/openmrs-esm-ohri-covid-app.js", "main": "src/index.ts", diff --git a/packages/esm-form-render-app/package.json b/packages/esm-form-render-app/package.json index ead0e37c0..bc8a9eafa 100644 --- a/packages/esm-form-render-app/package.json +++ b/packages/esm-form-render-app/package.json @@ -1,6 +1,6 @@ { "name": "@ohri/openmrs-esm-ohri-form-render-app", - "version": "2.3.1", + "version": "2.3.6", "description": "A Forms Rendering microfrontend for OpenMRS HIV Reference Implementation (OHRI)", "browser": "dist/openmrs-esm-ohri-form-render-app.js", "main": "src/index.ts", @@ -39,7 +39,7 @@ }, "dependencies": { "@carbon/react": "^1.13.0", - "@openmrs/openmrs-form-engine-lib": "2.0.0-pre.1029", + "@openmrs/openmrs-form-engine-lib": "2.0.0-pre.1260", "ace-builds": "1.34.1", "react-ace": "^9.4.4" }, diff --git a/packages/esm-hiv-prevention-app/package.json b/packages/esm-hiv-prevention-app/package.json index 4a711aaf3..32fa91598 100644 --- a/packages/esm-hiv-prevention-app/package.json +++ b/packages/esm-hiv-prevention-app/package.json @@ -1,6 +1,6 @@ { "name": "@ohri/openmrs-esm-ohri-hiv-prevention-app", - "version": "2.3.1", + "version": "2.3.6", "description": "HIV Prevention microfrontend for OpenMRS HIV Reference Implementation (OHRI)", "browser": "dist/openmrs-esm-ohri-hiv-prevention-app.js", "main": "src/index.ts", diff --git a/packages/esm-ohri-core-app/package.json b/packages/esm-ohri-core-app/package.json index 13f83dc09..799d25dbd 100644 --- a/packages/esm-ohri-core-app/package.json +++ b/packages/esm-ohri-core-app/package.json @@ -1,6 +1,6 @@ { "name": "@ohri/openmrs-esm-ohri-core-app", - "version": "2.3.1", + "version": "2.3.6", "description": "A custom microfrontend for OpenMRS HIV Reference Implementation (OHRI)", "browser": "dist/ohri-core-app.js", "main": "src/index.ts", diff --git a/packages/esm-ohri-pmtct-app/package.json b/packages/esm-ohri-pmtct-app/package.json index 68510dd19..e30b1cd56 100644 --- a/packages/esm-ohri-pmtct-app/package.json +++ b/packages/esm-ohri-pmtct-app/package.json @@ -1,6 +1,6 @@ { "name": "@ohri/openmrs-esm-ohri-pmtct-app", - "version": "2.3.1", + "version": "2.3.6", "description": "PMTCT microfrontend for OpenMRS HIV Reference Implementation (OHRI)", "browser": "dist/ohri-pmtct-app.js", "main": "src/index.ts", diff --git a/packages/esm-opd-app/package.json b/packages/esm-opd-app/package.json index 22eee0422..615f33a57 100644 --- a/packages/esm-opd-app/package.json +++ b/packages/esm-opd-app/package.json @@ -1,6 +1,6 @@ { "name": "@ohri/openmrs-esm-ohri-opd-app", - "version": "2.3.1", + "version": "2.3.6", "description": "opd active visits", "browser": "dist/openmrs-esm-ohri-opd-app.js", "main": "src/index.ts", diff --git a/packages/esm-tb-app/package.json b/packages/esm-tb-app/package.json index bf75f732d..542371968 100644 --- a/packages/esm-tb-app/package.json +++ b/packages/esm-tb-app/package.json @@ -1,6 +1,6 @@ { "name": "@ohri/openmrs-esm-ohri-tb-app", - "version": "2.3.1", + "version": "2.3.6", "description": "Tuberclosis microfrontend for OpenMRS HIV Reference Implementation (OHRI)", "browser": "dist/openmrs-esm-ohri-tb-app.js", "main": "src/index.ts", diff --git a/packages/esm-tb-app/src/index.ts b/packages/esm-tb-app/src/index.ts index 993b6edcf..470496009 100644 --- a/packages/esm-tb-app/src/index.ts +++ b/packages/esm-tb-app/src/index.ts @@ -102,6 +102,7 @@ export const tbClinicalViewDashboardLink = getSyncLifecycle( createOHRIDashboardLink(tbClinicalViewDashboardMeta), options, ); + export const tbCasesDashboardLink = getSyncLifecycle(createOHRIGroupedLink(tbCasesDashboardMeta), options); export const tbCasesDashboard = getSyncLifecycle(rootComponent, options); diff --git a/packages/esm-tb-app/src/routes.json b/packages/esm-tb-app/src/routes.json index 4970eb4c2..563f183d6 100644 --- a/packages/esm-tb-app/src/routes.json +++ b/packages/esm-tb-app/src/routes.json @@ -107,6 +107,41 @@ "component": "tptProgramManagementDashboard" }, + + { + "name": "tpt-patient-summary", + "slot": "ohri-tpt-slot", + "component": "tptPatientSummaryDashboardLink", + "meta": { + "slot": "tpt-patient-summary-slot", + "columns": 1, + "path": "tpt-patient-summary", + "layoutMode": "anchored" + } + }, + { + "name": "tpt-patient-summary-ext", + "slot": "tpt-patient-summary-slot", + "component": "tptPatientSummaryDashboard" + }, + + { + "name": "tpt-program-management-summary", + "slot": "ohri-tpt-slot", + "component": "tptProgramManagementDashboardLink", + "meta": { + "slot": "tpt-program-management-summary-slot", + "columns": 1, + "path": "tpt-program-management", + "layoutMode": "anchored" + } + }, + { + "name": "tpt-program-management-summary-ext", + "slot": "tpt-program-management-summary-slot", + "component": "tptProgramManagementDashboard" + }, + { "name": "tb-treatment-follow-up-summary", "slot": "ohri-tb-slot", @@ -150,6 +185,37 @@ "title": "Tuberculosis" } }, + { + "name": "tb-prevention-dashboard-ext", + "slot": "tb-clinical-dashboard-slot", + "component": "tbPreventionDashboardLink", + "meta": { + "name": "tb-prevention", + "slot": "tb-prevention-dashboard-slot", + "config": { + "columns": 1, + "type": "grid", + "programme": "tpt", + "dashboardTitle": "TB Prevention" + }, + "title": "TB Prevention" + } + }, + { + "name": "tb-prevention-dashboard", + "slot": "tb-prevention-dashboard-slot", + "component": "tbPreventionDashboard", + "meta": { + "name": "tb-prevention", + "slot": "tb-prevention-dashboard-slot", + "config": { + "columns": 1, + "programme": "tpt", + "dashboardTitle": "TB Prevention" + }, + "title": "TB Prevention" + } + }, { "name": "tb-cases-dashboard-ext", "slot": "homepage-dashboard-slot", diff --git a/packages/esm-tb-app/src/views/tpt/program-management/tabs/tpt-treatment.component copy.tsx b/packages/esm-tb-app/src/views/tpt/program-management/tabs/tpt-treatment.component copy.tsx new file mode 100644 index 000000000..81612d276 --- /dev/null +++ b/packages/esm-tb-app/src/views/tpt/program-management/tabs/tpt-treatment.component copy.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { EmptyStateComingSoon } from '@ohri/openmrs-esm-ohri-commons-lib'; + +interface TptTreatmentListProps { + patientUuid: string; +} + +const TptTreatmentList: React.FC = ({ patientUuid }) => { + const { t } = useTranslation(); + + const headerTitle = t('tptTreatment', 'TPT Treatment'); + + return ( + <> + + + ); +}; + +export default TptTreatmentList;