From b947d573012c7b8d8a08cc4f1347e68a2b76085a Mon Sep 17 00:00:00 2001 From: Jose Francisco Date: Thu, 23 Nov 2023 16:36:52 +0000 Subject: [PATCH 1/7] (feat) POC - Offline ready jobs and component --- .../offline-ready-modal.component.tsx | 112 ++++++++++++++++++ .../apps/esm-offline-tools-app/src/index.ts | 6 + .../offline-actions-mode-button.component.tsx | 93 +++++++++++---- .../offline-actions-mode-button.scss | 14 +++ .../esm-offline-tools-app/src/routes.json | 6 + .../translations/en.json | 11 +- .../translations/es.json | 21 ++-- .../translations/fr.json | 25 ++-- packages/framework/esm-globals/src/types.ts | 4 +- packages/shell/esm-app-shell/src/apps.ts | 30 +++++ packages/shell/esm-app-shell/src/run.ts | 4 +- 11 files changed, 283 insertions(+), 43 deletions(-) create mode 100644 packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx diff --git a/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx new file mode 100644 index 000000000..363b83eab --- /dev/null +++ b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx @@ -0,0 +1,112 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { + ModalBody, + ModalFooter, + ModalHeader, + Button, + ProgressBar, +} from "@carbon/react"; +import { useTranslation } from "react-i18next"; +import { showToast } from "@openmrs/esm-framework"; + +export interface OfflineActionsProgressModalProps { + items?: Array; + closeModal: (active: boolean) => void; +} + +const OfflineReadyModal: React.FC = ({ + closeModal, + items, +}) => { + const { t } = useTranslation(); + const [progress, setProgress] = useState(0); + const [abortController, setAbortController] = useState( + () => new AbortController() + ); + + async function runAsyncFunctionsInParallel(asyncFunctions) { + const totalFunctions = asyncFunctions.length; + + if (totalFunctions === 0) { + console.warn("No tasks to run."); + setProgress(100); + return; + } + + let completedFunctions = 0; + + const promises = asyncFunctions.map(async (asyncFunction) => { + await asyncFunction(abortController); + completedFunctions++; + const progress = (completedFunctions / totalFunctions) * 100; + setProgress(progress); + }); + + await Promise.all(promises); + + console.warn("All tasks completed!"); + } + + useEffect(() => { + runAsyncFunctionsInParallel(items || []); + }, [abortController, items]); + + const handleClose = useCallback(() => { + if (progress < 100) { + abortController.abort(); + + showToast({ + critical: true, + kind: "warning", + description: t( + "unavailableOfflineFeatures", + "Some features may not be available offline." + ), + title: t("offlinePreparationCanceled", "Offline preparation canceled"), + }); + closeModal(false); + } else { + showToast({ + critical: true, + kind: "success", + description: t("offlineModeIsReady", "Offline mode is ready"), + title: t("offline", "Offline"), + }); + closeModal(true); + } + }, [abortController, closeModal, progress, t]); + + return ( + <> + + + + + + + + + + ); +}; + +export default OfflineReadyModal; diff --git a/packages/apps/esm-offline-tools-app/src/index.ts b/packages/apps/esm-offline-tools-app/src/index.ts index a95c30c9d..face214c8 100644 --- a/packages/apps/esm-offline-tools-app/src/index.ts +++ b/packages/apps/esm-offline-tools-app/src/index.ts @@ -12,6 +12,7 @@ import offlineToolsComponent from "./root.component"; import offlineToolsLinkComponent from "./offline-tools-app-menu-link.component"; import offlineToolsNavItemsComponent from "./nav/offline-tools-nav-menu.component"; import offlineToolsConfirmationModalComponent from "./components/confirmation-modal.component"; +import offlineToolsOfflineReadyModalComponent from "./components/offline-ready-modal.component"; import offlineToolsPatientsCardComponent from "./offline-patients/patients-overview-card.component"; import offlineToolsActionsCardComponent from "./offline-actions/offline-actions-overview-card.component"; import offlineToolsActionsComponent from "./offline-actions/offline-actions.component"; @@ -54,6 +55,11 @@ export const offlineToolsConfirmationModal = getSyncLifecycle( options ); +export const offlineToolsOfflineReadyModal = getSyncLifecycle( + offlineToolsOfflineReadyModalComponent, + options +); + export const offlineToolsPatientsCard = getSyncLifecycle( offlineToolsPatientsCardComponent, options diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx index 151263e78..2471a3386 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx @@ -1,10 +1,10 @@ -import React from "react"; +import React, { useState, useCallback, useEffect } from "react"; import { useTranslation } from "react-i18next"; -import { Toggle } from "@carbon/react"; +import { Toggle, Button, DefinitionTooltip } from "@carbon/react"; import { Network_3 } from "@carbon/react/icons"; import { getCurrentOfflineMode, - setCurrentOfflineMode, + showModal, } from "@openmrs/esm-framework/src/internal"; import styles from "./offline-actions-mode-button.scss"; @@ -14,30 +14,77 @@ function doNotCloseMenu(ev: React.SyntheticEvent) { const OfflineActionsModeButton: React.FC = () => { const { t } = useTranslation(); - const [active, setActive] = React.useState( - () => getCurrentOfflineMode().active + + //TODO: USE FRAMEWORK FUNCTIONS (getCurrentOfflineMode...) + const [lastRun, setLastRun] = useState(() => + localStorage.getItem("openmrs3:offline-last-run") + ); + const [active, setActive] = useState( + () => localStorage.getItem("openmrs3:offline-mode") === "active" ); - const toggle = React.useCallback(() => { - setActive((value) => { - const active = !value; - setCurrentOfflineMode(active ? "on" : "off"); - return active; - }); - }, []); + + const toggle = useCallback(() => { + if (window.installedModules && window.installedModules.length > 0) { + const dispose = showModal("offline-tools-offline-ready-modal", { + items: window.installedModules + .filter((app) => app.length >= 3) + .map((app) => app[2]), + closeModal: (result) => { + setActive(result); + + const lastRunTimestamp = new Date().toLocaleString(); + + if (result) { + setLastRun(lastRunTimestamp); + } + + //TODO: USE FRAMEWORK FUNCTIONS (getCurrentOfflineMode...) + localStorage.setItem( + "openmrs3:offline-mode", + result ? "active" : "disabled" + ); + + localStorage.setItem( + "openmrs3:offline-last-run", + result ? lastRunTimestamp : "" + ); + + dispose(); + }, + }); + } else { + console.warn("No installed modules found."); + } + }, [setActive]); + + const handleRefresh = useCallback(() => { + toggle(); + }, [toggle]); return ( -
- -
- {t("offlineReady", "Offline Ready")} - + <> +
+ +
+ + {t("offlineReady", "Offline Ready")} + + {active ? ( + + ) : ( + + )} +
-
+ ); }; diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss index 6f01f8052..e1aa35493 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss @@ -24,6 +24,10 @@ color: $ui-02; } + :global(.cds--definition-term) { + color: $ui-02; + } + svg { margin: 0rem 0.75rem; fill: $field-01; @@ -35,4 +39,14 @@ width: fit-content; align-items: center; } + + button, + button:hover { + color: $inverse-link; + } + + button :hover { + @include brand-03(background-color); + color: $inverse-link; + } } diff --git a/packages/apps/esm-offline-tools-app/src/routes.json b/packages/apps/esm-offline-tools-app/src/routes.json index c6f314480..a4b4f3586 100644 --- a/packages/apps/esm-offline-tools-app/src/routes.json +++ b/packages/apps/esm-offline-tools-app/src/routes.json @@ -31,6 +31,12 @@ "online": true, "offline": true }, + { + "name": "offline-tools-offline-ready-modal", + "component": "offlineToolsOfflineReadyModal", + "online": true, + "offline": true + }, { "name": "offline-tools-dashboard-patients-card", "slot": "offline-tools-dashboard-cards", diff --git a/packages/apps/esm-offline-tools-app/translations/en.json b/packages/apps/esm-offline-tools-app/translations/en.json index 304df0615..ed1f9158d 100644 --- a/packages/apps/esm-offline-tools-app/translations/en.json +++ b/packages/apps/esm-offline-tools-app/translations/en.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "There are no {{displayText}} to display", "home": "Home", "homeHeader": "Offline home", @@ -9,6 +11,8 @@ "homeOverviewCardPatientsHeader": "Patients", "homeOverviewCardPatientsNewlyRegistered": "Newly registered", "homeOverviewCardView": "View", + "lastRun": "Last Run", + "never": "Never", "offlineActions": "Offline Actions", "offlineActionsDeleteConfirmationModalCancel": "Cancel", "offlineActionsDeleteConfirmationModalConfirm": "Delete forever", @@ -26,8 +30,8 @@ "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Update offline patients", "offlinePatients": "Offline patients", - "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "Offline patients", + "offlinePatients_lower": "offline patients", "offlinePatientsTableDeleteConfirmationModalCancel": "Cancel", "offlinePatientsTableDeleteConfirmationModalConfirm": "Remove patients", "offlinePatientsTableDeleteConfirmationModalContent": "Are you sure that you want to remove all selected patients from the offline list? Their charts will no longer be available in offline mode and any newly registered patient will be permanently deleted.", @@ -53,5 +57,8 @@ "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", "offlineReady": "Offline Ready", - "offlineToolsAppMenuLink": "Offline tools" + "offlineToolsAppMenuLink": "Offline tools", + "preparingOfflineMode": "Preparing for offline mode", + "progressBarLabel": "{{progress}}% Complete", + "refresh": "Refresh" } diff --git a/packages/apps/esm-offline-tools-app/translations/es.json b/packages/apps/esm-offline-tools-app/translations/es.json index 6cc1961b4..0c757d2fc 100644 --- a/packages/apps/esm-offline-tools-app/translations/es.json +++ b/packages/apps/esm-offline-tools-app/translations/es.json @@ -1,4 +1,6 @@ { + "cancel": "Cancelar", + "confirm": "Confirmar", "emptyStateText": "No hay {{displayText}} para mostrar", "home": "Inicio", "homeHeader": "Inicio offline", @@ -9,6 +11,8 @@ "homeOverviewCardPatientsHeader": "Pacientes", "homeOverviewCardPatientsNewlyRegistered": "Recién registrados", "homeOverviewCardView": "Ver", + "lastRun": "Última carrera", + "never": "Nunca", "offlineActions": "Acciones offline", "offlineActionsDeleteConfirmationModalCancel": "Cancelar", "offlineActionsDeleteConfirmationModalConfirm": "Eliminar para siempre", @@ -20,15 +24,19 @@ "offlineActionsNoActionsEmptyStateTitle": "No hay acciones pendientes de carga", "offlineActionsTableAction": "Acción", "offlineActionsTableCreatedOn": "Fecha y Hora", - "offlineActionsTableDeleteActions_one": "Eliminar acción", "offlineActionsTableDeleteActions_many": "Eliminar {{count}} acciones", + "offlineActionsTableDeleteActions_one": "Eliminar acción", "offlineActionsTableDeleteActions_other": "Eliminar {{count}} acciones", "offlineActionsTableError": "Error", "offlineActionsTablePatient": "Paciente", "offlineActionsUpdateOfflinePatients": "Actualizar pacientes offline", + "offlinePatientSyncDetailsDownloadedHeader": "Descargado en este dispositivo", + "offlinePatientSyncDetailsFailedHeader": "Hubo un error al descargar los siguientes elementos", + "offlinePatientSyncDetailsFallbackErrorMessage": "Error desconocido.", + "offlinePatientSyncDetailsHeader": "Detalles de pacientes offline", "offlinePatients": "Pacientes offline", - "offlinePatients_lower": "pacientes offline", "offlinePatientsHeader": "Pacientes offline", + "offlinePatients_lower": "pacientes offline", "offlinePatientsTableDeleteConfirmationModalCancel": "Cancelar", "offlinePatientsTableDeleteConfirmationModalConfirm": "Eliminar pacientes", "offlinePatientsTableDeleteConfirmationModalContent": "¿Estás seguro de que deseas eliminar todos los pacientes seleccionados de la lista offline? Sus registros ya no estarán disponibles en modo offline y cualquier paciente recién registrado se eliminará permanentemente.", @@ -49,10 +57,9 @@ "offlinePatientsTableTitle": "Pacientes offline", "offlinePatientsTableUpdatePatient": "Actualizar paciente", "offlinePatientsTableUpdatePatients": "Actualizar pacientes", - "offlinePatientSyncDetailsDownloadedHeader": "Descargado en este dispositivo", - "offlinePatientSyncDetailsFailedHeader": "Hubo un error al descargar los siguientes elementos", - "offlinePatientSyncDetailsFallbackErrorMessage": "Error desconocido.", - "offlinePatientSyncDetailsHeader": "Detalles de pacientes offline", "offlineReady": "Listo offline", - "offlineToolsAppMenuLink": "Herramientas offline" + "offlineToolsAppMenuLink": "Herramientas offline", + "preparingOfflineMode": "Preparando modo sin conexión", + "progressBarLabel": "{{progress}}% Completo", + "refresh": "Actualizar" } diff --git a/packages/apps/esm-offline-tools-app/translations/fr.json b/packages/apps/esm-offline-tools-app/translations/fr.json index 6d3bad255..958b24981 100644 --- a/packages/apps/esm-offline-tools-app/translations/fr.json +++ b/packages/apps/esm-offline-tools-app/translations/fr.json @@ -1,4 +1,6 @@ { + "cancel": "Annuler", + "confirm": "Confirmer", "emptyStateText": "There are no {{displayText}} to display", "home": "Accueil", "homeHeader": "Accueil hors ligne", @@ -9,8 +11,10 @@ "homeOverviewCardPatientsHeader": "Patients", "homeOverviewCardPatientsNewlyRegistered": "Nouvellement enregistré", "homeOverviewCardView": "Voir", + "lastRun": "Dernière course", + "never": "Jamais", "offlineActions": "Actions hors ligne", - "offlineActionsDeleteConfirmationModalCancel": "Annuller", + "offlineActionsDeleteConfirmationModalCancel": "Annuler", "offlineActionsDeleteConfirmationModalConfirm": "Supprimer pour toujours", "offlineActionsDeleteConfirmationModalContent": "Êtes-vous sûr de vouloir supprimer toutes les actions hors ligne sélectionnées? Il ne sera pas possible de revenir en arrière.", "offlineActionsDeleteConfirmationModalTitle": "Supprimer les actions hors ligne", @@ -20,16 +24,20 @@ "offlineActionsNoActionsEmptyStateTitle": "Aucune actions en attente de téléchargement", "offlineActionsTableAction": "Action", "offlineActionsTableCreatedOn": "Date & Heure", - "offlineActionsTableDeleteActions_one": "Supprimer l'action", "offlineActionsTableDeleteActions_many": "Supprimer les {{count}} actions", + "offlineActionsTableDeleteActions_one": "Supprimer l'action", "offlineActionsTableDeleteActions_other": "Supprimer les {{count}} actions", "offlineActionsTableError": "Erreur", "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Mettre à jour les patients hors ligne", + "offlinePatientSyncDetailsDownloadedHeader": "Téléchargé sur cet appareil", + "offlinePatientSyncDetailsFailedHeader": "Une erreur est survenue en téléchargeant les éléments suivants", + "offlinePatientSyncDetailsFallbackErrorMessage": "Erreur inconnue.", + "offlinePatientSyncDetailsHeader": "Détails des patients hors ligne", "offlinePatients": "Offline patients", - "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "Patients hors ligne", - "offlinePatientsTableDeleteConfirmationModalCancel": "Annuller", + "offlinePatients_lower": "offline patients", + "offlinePatientsTableDeleteConfirmationModalCancel": "Annuler", "offlinePatientsTableDeleteConfirmationModalConfirm": "Enlever les patients", "offlinePatientsTableDeleteConfirmationModalContent": "Êtes-vous sûr que de vouloir supprimer tous les patients sélectionnés de la liste hors ligne? Leurs graphiques ne seront plus disponibles en mode hors ligne et tout patient nouvellement enregistré sera supprimé pour toujours.", "offlinePatientsTableDeleteConfirmationModalTitle": "Enlever les patients hors ligne", @@ -49,10 +57,9 @@ "offlinePatientsTableTitle": "Patients hors ligne", "offlinePatientsTableUpdatePatient": "Mettre à jour le patient", "offlinePatientsTableUpdatePatients": "Mettre à jour les patients", - "offlinePatientSyncDetailsDownloadedHeader": "Téléchargé sur cet appareil", - "offlinePatientSyncDetailsFailedHeader": "Une erreur est survenue en téléchargeant les éléments suivants", - "offlinePatientSyncDetailsFallbackErrorMessage": "Erreur inconnue.", - "offlinePatientSyncDetailsHeader": "Détails des patients hors ligne", "offlineReady": "Prêt pour être hors ligne", - "offlineToolsAppMenuLink": "Outils hors ligne" + "offlineToolsAppMenuLink": "Outils hors ligne", + "preparingOfflineMode": "Préparation du mode hors ligne", + "progressBarLabel": "{{progress}}% Complet", + "refresh": "rafraîchir" } diff --git a/packages/framework/esm-globals/src/types.ts b/packages/framework/esm-globals/src/types.ts index 1c5d616a1..5831aa18a 100644 --- a/packages/framework/esm-globals/src/types.ts +++ b/packages/framework/esm-globals/src/types.ts @@ -54,7 +54,7 @@ declare global { /** * Gets the installed modules, which are tuples consisting of the module's name and exports. */ - installedModules: Array<[string, OpenmrsAppRoutes]>; + installedModules: Array<[string, OpenmrsAppRoutes, OfflineReadyFunction]>; /** * The i18next instance for the app. */ @@ -62,6 +62,8 @@ declare global { } } +export type OfflineReadyFunction = (abortController: AbortController) => void; + export type SpaEnvironment = "production" | "development" | "test"; export interface ImportMap { diff --git a/packages/shell/esm-app-shell/src/apps.ts b/packages/shell/esm-app-shell/src/apps.ts index 8d65ab5fd..2b3d26268 100644 --- a/packages/shell/esm-app-shell/src/apps.ts +++ b/packages/shell/esm-app-shell/src/apps.ts @@ -147,6 +147,36 @@ function getLoader( }; } +//TODO: MOCK asyncTask +const OFFLINE_READY_FUNCTION = "offlineReady"; + +const asyncTask = async (abortController) => { + return new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => { + console.warn("Task completed"); + resolve("Task completed"); + }, Math.floor(Math.random() * (7000 - 1000 + 1)) + 1000); + abortController.signal.addEventListener("abort", () => { + clearTimeout(timeoutId); + console.warn("Operation aborted"); + reject("Operation aborted"); + }); + }); +}; + +/** + * This function creates a loader function suitable for use in either a single-spa + * application or parcel. + * + * This function returns a function responsible for executing the actions required + * to prepare the module for offline mode. + */ + +export function getOfflineReadyLoader(appName: string) { + //TODO dynamic import + return asyncTask; +} + /** * This is the main entry-point for registering an app with the app shell. * Each app has a name and should have a `routes.json` file that defines it's diff --git a/packages/shell/esm-app-shell/src/run.ts b/packages/shell/esm-app-shell/src/run.ts index a5a742632..ee4427517 100644 --- a/packages/shell/esm-app-shell/src/run.ts +++ b/packages/shell/esm-app-shell/src/run.ts @@ -36,6 +36,7 @@ import { finishRegisteringAllApps, registerApp, tryRegisterExtension, + getOfflineReadyLoader, } from "./apps"; import { setupI18n } from "./locale"; import { appName, getCoreExtensions } from "./ui"; @@ -91,7 +92,8 @@ async function setupApps() { const modules: typeof window.installedModules = []; const registrationPromises = Object.entries(routes).map( async ([module, routes]) => { - modules.push([module, routes]); + const offlineLoader = getOfflineReadyLoader(module); + modules.push([module, routes, offlineLoader]); registerApp(module, routes); } ); From 0a23d82dc3efdfe6576d12a2b713b21923545cf2 Mon Sep 17 00:00:00 2001 From: Jose Francisco Date: Thu, 23 Nov 2023 16:56:28 +0000 Subject: [PATCH 2/7] (chore) fix lint for i18n files --- .../esm-offline-tools-app/translations/am.json | 13 ++++++++++++- .../esm-offline-tools-app/translations/ar.json | 13 ++++++++++++- .../esm-offline-tools-app/translations/en.json | 8 ++++++-- .../esm-offline-tools-app/translations/es.json | 18 +++++++++++------- .../esm-offline-tools-app/translations/fr.json | 18 +++++++++++------- .../esm-offline-tools-app/translations/he.json | 13 ++++++++++++- .../esm-offline-tools-app/translations/km.json | 13 ++++++++++++- 7 files changed, 76 insertions(+), 20 deletions(-) diff --git a/packages/apps/esm-offline-tools-app/translations/am.json b/packages/apps/esm-offline-tools-app/translations/am.json index 91d1d6103..bb4b55415 100644 --- a/packages/apps/esm-offline-tools-app/translations/am.json +++ b/packages/apps/esm-offline-tools-app/translations/am.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "There are no {{displayText}} to display", "home": "Home", "homeHeader": "Offline home", @@ -9,6 +11,9 @@ "homeOverviewCardPatientsHeader": "Patients", "homeOverviewCardPatientsNewlyRegistered": "Newly registered", "homeOverviewCardView": "View", + "lastRun": "Last Run", + "never": "Never", + "offline": "Offline", "offlineActions": "Offline actions", "offlineActionsDeleteConfirmationModalCancel": "Cancel", "offlineActionsDeleteConfirmationModalConfirm": "Delete forever", @@ -25,6 +30,7 @@ "offlineActionsTableError": "Error", "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Update offline patients", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "Offline patients", @@ -52,6 +58,11 @@ "offlinePatientSyncDetailsFailedHeader": "There was an error downloading the following items", "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Offline Ready", - "offlineToolsAppMenuLink": "Offline tools" + "offlineToolsAppMenuLink": "Offline tools", + "preparingOfflineMode": "Preparing for offline mode", + "progressBarLabel": "{progress}% Complete", + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/ar.json b/packages/apps/esm-offline-tools-app/translations/ar.json index 84da5f58e..871638e36 100644 --- a/packages/apps/esm-offline-tools-app/translations/ar.json +++ b/packages/apps/esm-offline-tools-app/translations/ar.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "لا يوجد {{displayText}} لعرضه", "home": "الرئيسية", "homeHeader": "الصفحة الرئيسية بدون اتصال", @@ -9,6 +11,9 @@ "homeOverviewCardPatientsHeader": "المرضى", "homeOverviewCardPatientsNewlyRegistered": "مُسجل حديثًا", "homeOverviewCardView": "عرض", + "lastRun": "Last Run", + "never": "Never", + "offline": "Offline", "offlineActions": "الأنشطة بدون اتصال", "offlineActionsDeleteConfirmationModalCancel": "إلغاء", "offlineActionsDeleteConfirmationModalConfirm": "حذف نهائي", @@ -29,6 +34,7 @@ "offlineActionsTableError": "خطأ", "offlineActionsTablePatient": "المريض", "offlineActionsUpdateOfflinePatients": "تحديث المرضى بدون اتصال", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "المرضى بدون اتصال", "offlinePatients_lower": "المرضى بدون اتصال", "offlinePatientsHeader": "المرضى بدون اتصال", @@ -56,6 +62,11 @@ "offlinePatientSyncDetailsFailedHeader": "حدث خطأ أثناء تحميل العناصر التالية", "offlinePatientSyncDetailsFallbackErrorMessage": "خطأ غير معروف.", "offlinePatientSyncDetailsHeader": "تفاصيل المريض بدون اتصال", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "جاهز للعمل بدون اتصال", - "offlineToolsAppMenuLink": "أدوات العمل بدون اتصال" + "offlineToolsAppMenuLink": "أدوات العمل بدون اتصال", + "preparingOfflineMode": "Preparing for offline mode", + "progressBarLabel": "{progress}% Complete", + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/en.json b/packages/apps/esm-offline-tools-app/translations/en.json index ed1f9158d..81e7a723a 100644 --- a/packages/apps/esm-offline-tools-app/translations/en.json +++ b/packages/apps/esm-offline-tools-app/translations/en.json @@ -13,6 +13,7 @@ "homeOverviewCardView": "View", "lastRun": "Last Run", "never": "Never", + "offline": "Offline", "offlineActions": "Offline Actions", "offlineActionsDeleteConfirmationModalCancel": "Cancel", "offlineActionsDeleteConfirmationModalConfirm": "Delete forever", @@ -29,9 +30,10 @@ "offlineActionsTableError": "Error", "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Update offline patients", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", - "offlinePatientsHeader": "Offline patients", "offlinePatients_lower": "offline patients", + "offlinePatientsHeader": "Offline patients", "offlinePatientsTableDeleteConfirmationModalCancel": "Cancel", "offlinePatientsTableDeleteConfirmationModalConfirm": "Remove patients", "offlinePatientsTableDeleteConfirmationModalContent": "Are you sure that you want to remove all selected patients from the offline list? Their charts will no longer be available in offline mode and any newly registered patient will be permanently deleted.", @@ -56,9 +58,11 @@ "offlinePatientSyncDetailsFailedHeader": "There was an error downloading the following items", "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Offline Ready", "offlineToolsAppMenuLink": "Offline tools", "preparingOfflineMode": "Preparing for offline mode", "progressBarLabel": "{{progress}}% Complete", - "refresh": "Refresh" + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/es.json b/packages/apps/esm-offline-tools-app/translations/es.json index 0c757d2fc..b2617d95b 100644 --- a/packages/apps/esm-offline-tools-app/translations/es.json +++ b/packages/apps/esm-offline-tools-app/translations/es.json @@ -13,6 +13,7 @@ "homeOverviewCardView": "Ver", "lastRun": "Última carrera", "never": "Nunca", + "offline": "Offline", "offlineActions": "Acciones offline", "offlineActionsDeleteConfirmationModalCancel": "Cancelar", "offlineActionsDeleteConfirmationModalConfirm": "Eliminar para siempre", @@ -24,19 +25,16 @@ "offlineActionsNoActionsEmptyStateTitle": "No hay acciones pendientes de carga", "offlineActionsTableAction": "Acción", "offlineActionsTableCreatedOn": "Fecha y Hora", - "offlineActionsTableDeleteActions_many": "Eliminar {{count}} acciones", "offlineActionsTableDeleteActions_one": "Eliminar acción", + "offlineActionsTableDeleteActions_many": "Eliminar {{count}} acciones", "offlineActionsTableDeleteActions_other": "Eliminar {{count}} acciones", "offlineActionsTableError": "Error", "offlineActionsTablePatient": "Paciente", "offlineActionsUpdateOfflinePatients": "Actualizar pacientes offline", - "offlinePatientSyncDetailsDownloadedHeader": "Descargado en este dispositivo", - "offlinePatientSyncDetailsFailedHeader": "Hubo un error al descargar los siguientes elementos", - "offlinePatientSyncDetailsFallbackErrorMessage": "Error desconocido.", - "offlinePatientSyncDetailsHeader": "Detalles de pacientes offline", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Pacientes offline", - "offlinePatientsHeader": "Pacientes offline", "offlinePatients_lower": "pacientes offline", + "offlinePatientsHeader": "Pacientes offline", "offlinePatientsTableDeleteConfirmationModalCancel": "Cancelar", "offlinePatientsTableDeleteConfirmationModalConfirm": "Eliminar pacientes", "offlinePatientsTableDeleteConfirmationModalContent": "¿Estás seguro de que deseas eliminar todos los pacientes seleccionados de la lista offline? Sus registros ya no estarán disponibles en modo offline y cualquier paciente recién registrado se eliminará permanentemente.", @@ -57,9 +55,15 @@ "offlinePatientsTableTitle": "Pacientes offline", "offlinePatientsTableUpdatePatient": "Actualizar paciente", "offlinePatientsTableUpdatePatients": "Actualizar pacientes", + "offlinePatientSyncDetailsDownloadedHeader": "Descargado en este dispositivo", + "offlinePatientSyncDetailsFailedHeader": "Hubo un error al descargar los siguientes elementos", + "offlinePatientSyncDetailsFallbackErrorMessage": "Error desconocido.", + "offlinePatientSyncDetailsHeader": "Detalles de pacientes offline", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Listo offline", "offlineToolsAppMenuLink": "Herramientas offline", "preparingOfflineMode": "Preparando modo sin conexión", "progressBarLabel": "{{progress}}% Completo", - "refresh": "Actualizar" + "refresh": "Actualizar", + "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/fr.json b/packages/apps/esm-offline-tools-app/translations/fr.json index 958b24981..ec2d4f6b3 100644 --- a/packages/apps/esm-offline-tools-app/translations/fr.json +++ b/packages/apps/esm-offline-tools-app/translations/fr.json @@ -13,6 +13,7 @@ "homeOverviewCardView": "Voir", "lastRun": "Dernière course", "never": "Jamais", + "offline": "Offline", "offlineActions": "Actions hors ligne", "offlineActionsDeleteConfirmationModalCancel": "Annuler", "offlineActionsDeleteConfirmationModalConfirm": "Supprimer pour toujours", @@ -24,19 +25,16 @@ "offlineActionsNoActionsEmptyStateTitle": "Aucune actions en attente de téléchargement", "offlineActionsTableAction": "Action", "offlineActionsTableCreatedOn": "Date & Heure", - "offlineActionsTableDeleteActions_many": "Supprimer les {{count}} actions", "offlineActionsTableDeleteActions_one": "Supprimer l'action", + "offlineActionsTableDeleteActions_many": "Supprimer les {{count}} actions", "offlineActionsTableDeleteActions_other": "Supprimer les {{count}} actions", "offlineActionsTableError": "Erreur", "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Mettre à jour les patients hors ligne", - "offlinePatientSyncDetailsDownloadedHeader": "Téléchargé sur cet appareil", - "offlinePatientSyncDetailsFailedHeader": "Une erreur est survenue en téléchargeant les éléments suivants", - "offlinePatientSyncDetailsFallbackErrorMessage": "Erreur inconnue.", - "offlinePatientSyncDetailsHeader": "Détails des patients hors ligne", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", - "offlinePatientsHeader": "Patients hors ligne", "offlinePatients_lower": "offline patients", + "offlinePatientsHeader": "Patients hors ligne", "offlinePatientsTableDeleteConfirmationModalCancel": "Annuler", "offlinePatientsTableDeleteConfirmationModalConfirm": "Enlever les patients", "offlinePatientsTableDeleteConfirmationModalContent": "Êtes-vous sûr que de vouloir supprimer tous les patients sélectionnés de la liste hors ligne? Leurs graphiques ne seront plus disponibles en mode hors ligne et tout patient nouvellement enregistré sera supprimé pour toujours.", @@ -57,9 +55,15 @@ "offlinePatientsTableTitle": "Patients hors ligne", "offlinePatientsTableUpdatePatient": "Mettre à jour le patient", "offlinePatientsTableUpdatePatients": "Mettre à jour les patients", + "offlinePatientSyncDetailsDownloadedHeader": "Téléchargé sur cet appareil", + "offlinePatientSyncDetailsFailedHeader": "Une erreur est survenue en téléchargeant les éléments suivants", + "offlinePatientSyncDetailsFallbackErrorMessage": "Erreur inconnue.", + "offlinePatientSyncDetailsHeader": "Détails des patients hors ligne", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Prêt pour être hors ligne", "offlineToolsAppMenuLink": "Outils hors ligne", "preparingOfflineMode": "Préparation du mode hors ligne", "progressBarLabel": "{{progress}}% Complet", - "refresh": "rafraîchir" + "refresh": "rafraîchir", + "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/he.json b/packages/apps/esm-offline-tools-app/translations/he.json index 1df128305..3b5f1f2f2 100644 --- a/packages/apps/esm-offline-tools-app/translations/he.json +++ b/packages/apps/esm-offline-tools-app/translations/he.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "There are no {{displayText}} to display", "home": "דף הבית", "homeHeader": "דף הבית במצב לא מקוון", @@ -9,6 +11,9 @@ "homeOverviewCardPatientsHeader": "מטופלים", "homeOverviewCardPatientsNewlyRegistered": "רשומים חדשים", "homeOverviewCardView": "צפה", + "lastRun": "Last Run", + "never": "Never", + "offline": "Offline", "offlineActions": "פעולות לא מקוונות", "offlineActionsDeleteConfirmationModalCancel": "ביטול", "offlineActionsDeleteConfirmationModalConfirm": "מחיקה לצמיתות", @@ -27,6 +32,7 @@ "offlineActionsTableError": "שגיאה", "offlineActionsTablePatient": "מטופל", "offlineActionsUpdateOfflinePatients": "עדכן מטופלים לא מקוונים", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "מטופלים לא מקוונים", @@ -54,6 +60,11 @@ "offlinePatientSyncDetailsFailedHeader": "אירעה שגיאה בהורדת הפריטים הבאים", "offlinePatientSyncDetailsFallbackErrorMessage": "שגיאה לא ידועה.", "offlinePatientSyncDetailsHeader": "פרטי מטופל לא מקוון", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "מצב לא מקוון מוכן", - "offlineToolsAppMenuLink": "כלי לא מקוונים" + "offlineToolsAppMenuLink": "כלי לא מקוונים", + "preparingOfflineMode": "Preparing for offline mode", + "progressBarLabel": "{progress}% Complete", + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/km.json b/packages/apps/esm-offline-tools-app/translations/km.json index 4b2781b68..4b985163b 100644 --- a/packages/apps/esm-offline-tools-app/translations/km.json +++ b/packages/apps/esm-offline-tools-app/translations/km.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "There are no {{displayText}} to display", "home": "ផ្ទះ", "homeHeader": "Offline home", @@ -9,6 +11,9 @@ "homeOverviewCardPatientsHeader": "Patients", "homeOverviewCardPatientsNewlyRegistered": "Newly registered", "homeOverviewCardView": "View", + "lastRun": "Last Run", + "never": "Never", + "offline": "Offline", "offlineActions": "សកម្មភាពក្រៅបណ្តាញ", "offlineActionsDeleteConfirmationModalCancel": "Cancel", "offlineActionsDeleteConfirmationModalConfirm": "Delete forever", @@ -24,6 +29,7 @@ "offlineActionsTableError": "Error", "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Update offline patients", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "Offline patients", @@ -51,6 +57,11 @@ "offlinePatientSyncDetailsFailedHeader": "There was an error downloading the following items", "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Offline Ready", - "offlineToolsAppMenuLink": "Offline tools" + "offlineToolsAppMenuLink": "Offline tools", + "preparingOfflineMode": "Preparing for offline mode", + "progressBarLabel": "{progress}% Complete", + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline." } From cfaabd752a5ce27c36ca9cb7f59a5ade3332c982 Mon Sep 17 00:00:00 2001 From: Jose Francisco Date: Tue, 28 Nov 2023 15:58:21 +0000 Subject: [PATCH 3/7] (feat) use framework functions to handle offline jobs --- .../offline-actions-mode-button.component.tsx | 38 +++++-------------- packages/framework/esm-offline/src/mode.ts | 6 ++- 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx index 2471a3386..18512d464 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx @@ -1,10 +1,12 @@ -import React, { useState, useCallback, useEffect } from "react"; +import React, { useState, useCallback } from "react"; import { useTranslation } from "react-i18next"; import { Toggle, Button, DefinitionTooltip } from "@carbon/react"; import { Network_3 } from "@carbon/react/icons"; import { getCurrentOfflineMode, + setCurrentOfflineMode, showModal, + useConnectivity, } from "@openmrs/esm-framework/src/internal"; import styles from "./offline-actions-mode-button.scss"; @@ -14,14 +16,11 @@ function doNotCloseMenu(ev: React.SyntheticEvent) { const OfflineActionsModeButton: React.FC = () => { const { t } = useTranslation(); - - //TODO: USE FRAMEWORK FUNCTIONS (getCurrentOfflineMode...) - const [lastRun, setLastRun] = useState(() => - localStorage.getItem("openmrs3:offline-last-run") - ); - const [active, setActive] = useState( - () => localStorage.getItem("openmrs3:offline-mode") === "active" + const isOnline = useConnectivity(); + const [lastRun, setLastRun] = useState( + () => getCurrentOfflineMode().lastRun ); + const [active, setActive] = useState(() => getCurrentOfflineMode().active); const toggle = useCallback(() => { if (window.installedModules && window.installedModules.length > 0) { @@ -31,24 +30,7 @@ const OfflineActionsModeButton: React.FC = () => { .map((app) => app[2]), closeModal: (result) => { setActive(result); - - const lastRunTimestamp = new Date().toLocaleString(); - - if (result) { - setLastRun(lastRunTimestamp); - } - - //TODO: USE FRAMEWORK FUNCTIONS (getCurrentOfflineMode...) - localStorage.setItem( - "openmrs3:offline-mode", - result ? "active" : "disabled" - ); - - localStorage.setItem( - "openmrs3:offline-last-run", - result ? lastRunTimestamp : "" - ); - + setCurrentOfflineMode(result ? "on" : "off"); dispose(); }, }); @@ -62,7 +44,7 @@ const OfflineActionsModeButton: React.FC = () => { }, [toggle]); return ( - <> + isOnline && (
@@ -84,7 +66,7 @@ const OfflineActionsModeButton: React.FC = () => { )}
- + ) ); }; diff --git a/packages/framework/esm-offline/src/mode.ts b/packages/framework/esm-offline/src/mode.ts index 8839af46a..6f821c7ed 100644 --- a/packages/framework/esm-offline/src/mode.ts +++ b/packages/framework/esm-offline/src/mode.ts @@ -41,16 +41,19 @@ export interface OfflineModeResult { current: OfflineMode; notAvailable: boolean; active: boolean; + lastRun: string; } -const offlineModeStorageKey = "openmrs3:offline-mode"; +const offlineModeStorageKey = "openmrs:offline-mode"; let offlineMode: OfflineMode = "unavailable"; +let lastRun: string = ""; export function getCurrentOfflineMode(): OfflineModeResult { return { current: offlineMode, notAvailable: offlineMode === "unavailable", active: offlineMode === "on", + lastRun: lastRun, }; } @@ -60,6 +63,7 @@ export function setCurrentOfflineMode(mode: OfflineMode) { offlineModeStorageKey, mode === "on" ? "active" : "disabled" ); + lastRun = new Date().toLocaleString(); offlineMode = mode; } } From cd6c8ae8e3a1e7e9f71fb160af7c97c5c635f7a3 Mon Sep 17 00:00:00 2001 From: Jose Francisco Date: Thu, 7 Dec 2023 20:08:41 +0000 Subject: [PATCH 4/7] (chore) Change offline setup to event based part-1 --- .../offline-ready-modal.component.tsx | 64 +++++++------------ .../apps/esm-offline-tools-app/src/index.ts | 2 + .../offline-actions-mode-button.component.tsx | 64 +++++++++++-------- packages/framework/esm-globals/src/types.ts | 4 +- packages/framework/esm-offline/src/mode.ts | 9 +++ packages/framework/esm-offline/src/public.ts | 1 + packages/shell/esm-app-shell/src/apps.ts | 30 --------- packages/shell/esm-app-shell/src/run.ts | 4 +- 8 files changed, 74 insertions(+), 104 deletions(-) diff --git a/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx index 363b83eab..ada179593 100644 --- a/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx @@ -4,10 +4,10 @@ import { ModalFooter, ModalHeader, Button, - ProgressBar, + InlineLoading, } from "@carbon/react"; import { useTranslation } from "react-i18next"; -import { showToast } from "@openmrs/esm-framework"; +import { getCurrentOfflineMode, showToast } from "@openmrs/esm-framework"; export interface OfflineActionsProgressModalProps { items?: Array; @@ -19,40 +19,29 @@ const OfflineReadyModal: React.FC = ({ items, }) => { const { t } = useTranslation(); - const [progress, setProgress] = useState(0); + const [isRunning, setIsRunning] = useState(true); const [abortController, setAbortController] = useState( () => new AbortController() ); - async function runAsyncFunctionsInParallel(asyncFunctions) { - const totalFunctions = asyncFunctions.length; + async function dispatchOfflineEvent() { + //TODO CHANGE MODE + let mode = getCurrentOfflineMode().active; + window.dispatchEvent( + new CustomEvent(`openmrs:offline-${mode ? "enabled" : "disabled"}`, { + detail: getCurrentOfflineMode(), + }) + ); - if (totalFunctions === 0) { - console.warn("No tasks to run."); - setProgress(100); - return; - } - - let completedFunctions = 0; - - const promises = asyncFunctions.map(async (asyncFunction) => { - await asyncFunction(abortController); - completedFunctions++; - const progress = (completedFunctions / totalFunctions) * 100; - setProgress(progress); - }); - - await Promise.all(promises); - - console.warn("All tasks completed!"); + setIsRunning(false); } useEffect(() => { - runAsyncFunctionsInParallel(items || []); + dispatchOfflineEvent(); }, [abortController, items]); const handleClose = useCallback(() => { - if (progress < 100) { + if (isRunning) { abortController.abort(); showToast({ @@ -74,7 +63,7 @@ const OfflineReadyModal: React.FC = ({ }); closeModal(true); } - }, [abortController, closeModal, progress, t]); + }, [abortController, closeModal, isRunning, t]); return ( <> @@ -83,25 +72,18 @@ const OfflineReadyModal: React.FC = ({ closeModal={handleClose} /> - + {isRunning && ( + + )} - - diff --git a/packages/apps/esm-offline-tools-app/src/index.ts b/packages/apps/esm-offline-tools-app/src/index.ts index face214c8..bd696e78c 100644 --- a/packages/apps/esm-offline-tools-app/src/index.ts +++ b/packages/apps/esm-offline-tools-app/src/index.ts @@ -133,6 +133,8 @@ export function startupApp() { setupOffline(); setupSynchronizingOfflineActionsNotifications(); + // registerOfflineHandler(setupOffline); + registerBreadcrumbs([ { path: `${window.spaBase}/${routes.offlineTools}`, diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx index 6f275e88b..c9a88aeea 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx @@ -23,20 +23,13 @@ const OfflineActionsModeButton: React.FC = () => { const [active, setActive] = useState(() => getCurrentOfflineMode().active); const toggle = useCallback(() => { - if (window.installedModules && window.installedModules.length > 0) { - const dispose = showModal("offline-tools-offline-ready-modal", { - items: window.installedModules - .filter((app) => app.length >= 3) - .map((app) => app[2]), - closeModal: (result) => { - setActive(result); - setCurrentOfflineMode(result ? "on" : "off"); - dispose(); - }, - }); - } else { - console.warn("No installed modules found."); - } + const dispose = showModal("offline-tools-offline-ready-modal", { + closeModal: (result) => { + setActive(result); + setCurrentOfflineMode(result ? "on" : "off"); + dispose(); + }, + }); }, [setActive]); const handleRefresh = useCallback(() => { @@ -44,20 +37,37 @@ const OfflineActionsModeButton: React.FC = () => { }, [toggle]); return ( -
-
- - - {t("offlineReady", "Offline Ready")} - + isOnline && ( +
+
+ + + {t("offlineReady", "Offline Ready")} + +
+ + {active && ( + + )} + + {!active && ( + + )}
- -
+ ) ); }; diff --git a/packages/framework/esm-globals/src/types.ts b/packages/framework/esm-globals/src/types.ts index 5831aa18a..1c5d616a1 100644 --- a/packages/framework/esm-globals/src/types.ts +++ b/packages/framework/esm-globals/src/types.ts @@ -54,7 +54,7 @@ declare global { /** * Gets the installed modules, which are tuples consisting of the module's name and exports. */ - installedModules: Array<[string, OpenmrsAppRoutes, OfflineReadyFunction]>; + installedModules: Array<[string, OpenmrsAppRoutes]>; /** * The i18next instance for the app. */ @@ -62,8 +62,6 @@ declare global { } } -export type OfflineReadyFunction = (abortController: AbortController) => void; - export type SpaEnvironment = "production" | "development" | "test"; export interface ImportMap { diff --git a/packages/framework/esm-offline/src/mode.ts b/packages/framework/esm-offline/src/mode.ts index 6f821c7ed..2109b35a2 100644 --- a/packages/framework/esm-offline/src/mode.ts +++ b/packages/framework/esm-offline/src/mode.ts @@ -36,6 +36,7 @@ async function isPrivateBrowsing() { } export type OfflineMode = "on" | "off" | "unavailable"; +export type OfflineHandler = () => void | Promise; export interface OfflineModeResult { current: OfflineMode; @@ -68,6 +69,14 @@ export function setCurrentOfflineMode(mode: OfflineMode) { } } +export function registerOfflineHandler(setupOffline: OfflineHandler) { + window.addEventListener("openmrs:offline-enabled", setupOffline); + const offlineMode = getCurrentOfflineMode(); + if (offlineMode.active) { + setupOffline(); + } +} + export async function activateOfflineCapability() { const isPrivate = await isPrivateBrowsing(); diff --git a/packages/framework/esm-offline/src/public.ts b/packages/framework/esm-offline/src/public.ts index c161daad2..28fe3d542 100644 --- a/packages/framework/esm-offline/src/public.ts +++ b/packages/framework/esm-offline/src/public.ts @@ -2,6 +2,7 @@ export { type OfflineMode, type OfflineModeResult, getCurrentOfflineMode, + registerOfflineHandler, } from "./mode"; export * from "./offline-patient-data"; export * from "./service-worker-messaging"; diff --git a/packages/shell/esm-app-shell/src/apps.ts b/packages/shell/esm-app-shell/src/apps.ts index 2b3d26268..8d65ab5fd 100644 --- a/packages/shell/esm-app-shell/src/apps.ts +++ b/packages/shell/esm-app-shell/src/apps.ts @@ -147,36 +147,6 @@ function getLoader( }; } -//TODO: MOCK asyncTask -const OFFLINE_READY_FUNCTION = "offlineReady"; - -const asyncTask = async (abortController) => { - return new Promise((resolve, reject) => { - const timeoutId = setTimeout(() => { - console.warn("Task completed"); - resolve("Task completed"); - }, Math.floor(Math.random() * (7000 - 1000 + 1)) + 1000); - abortController.signal.addEventListener("abort", () => { - clearTimeout(timeoutId); - console.warn("Operation aborted"); - reject("Operation aborted"); - }); - }); -}; - -/** - * This function creates a loader function suitable for use in either a single-spa - * application or parcel. - * - * This function returns a function responsible for executing the actions required - * to prepare the module for offline mode. - */ - -export function getOfflineReadyLoader(appName: string) { - //TODO dynamic import - return asyncTask; -} - /** * This is the main entry-point for registering an app with the app shell. * Each app has a name and should have a `routes.json` file that defines it's diff --git a/packages/shell/esm-app-shell/src/run.ts b/packages/shell/esm-app-shell/src/run.ts index ee4427517..a5a742632 100644 --- a/packages/shell/esm-app-shell/src/run.ts +++ b/packages/shell/esm-app-shell/src/run.ts @@ -36,7 +36,6 @@ import { finishRegisteringAllApps, registerApp, tryRegisterExtension, - getOfflineReadyLoader, } from "./apps"; import { setupI18n } from "./locale"; import { appName, getCoreExtensions } from "./ui"; @@ -92,8 +91,7 @@ async function setupApps() { const modules: typeof window.installedModules = []; const registrationPromises = Object.entries(routes).map( async ([module, routes]) => { - const offlineLoader = getOfflineReadyLoader(module); - modules.push([module, routes, offlineLoader]); + modules.push([module, routes]); registerApp(module, routes); } ); From 63768afb656b0c6c7f6f10f1169d67af130d0174 Mon Sep 17 00:00:00 2001 From: Jose Francisco Date: Mon, 18 Dec 2023 10:08:02 +0000 Subject: [PATCH 5/7] (chore) lint --- .../offline-ready-modal.component.tsx | 53 +++++++------------ .../apps/esm-offline-tools-app/src/index.ts | 12 ++--- .../offline-actions-mode-button.component.tsx | 37 +++++-------- .../translations/am.json | 2 +- .../translations/ar.json | 2 +- .../translations/en.json | 2 +- .../translations/es.json | 2 +- .../translations/fr.json | 2 +- .../translations/he.json | 2 +- .../translations/km.json | 2 +- packages/framework/esm-offline/src/mode.ts | 14 ++--- packages/framework/esm-offline/src/public.ts | 15 ++---- 12 files changed, 53 insertions(+), 92 deletions(-) diff --git a/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx index ada179593..46d323c23 100644 --- a/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx @@ -1,36 +1,25 @@ -import React, { useCallback, useEffect, useState } from "react"; -import { - ModalBody, - ModalFooter, - ModalHeader, - Button, - InlineLoading, -} from "@carbon/react"; -import { useTranslation } from "react-i18next"; -import { getCurrentOfflineMode, showToast } from "@openmrs/esm-framework"; +import React, { useCallback, useEffect, useState } from 'react'; +import { ModalBody, ModalFooter, ModalHeader, Button, InlineLoading } from '@carbon/react'; +import { useTranslation } from 'react-i18next'; +import { getCurrentOfflineMode, showToast } from '@openmrs/esm-framework'; export interface OfflineActionsProgressModalProps { items?: Array; closeModal: (active: boolean) => void; } -const OfflineReadyModal: React.FC = ({ - closeModal, - items, -}) => { +const OfflineReadyModal: React.FC = ({ closeModal, items }) => { const { t } = useTranslation(); const [isRunning, setIsRunning] = useState(true); - const [abortController, setAbortController] = useState( - () => new AbortController() - ); + const [abortController, setAbortController] = useState(() => new AbortController()); async function dispatchOfflineEvent() { //TODO CHANGE MODE let mode = getCurrentOfflineMode().active; window.dispatchEvent( - new CustomEvent(`openmrs:offline-${mode ? "enabled" : "disabled"}`, { + new CustomEvent(`openmrs:offline-${mode ? 'enabled' : 'disabled'}`, { detail: getCurrentOfflineMode(), - }) + }), ); setIsRunning(false); @@ -46,20 +35,17 @@ const OfflineReadyModal: React.FC = ({ showToast({ critical: true, - kind: "warning", - description: t( - "unavailableOfflineFeatures", - "Some features may not be available offline." - ), - title: t("offlinePreparationCanceled", "Offline preparation canceled"), + kind: 'warning', + description: t('unavailableOfflineFeatures', 'Some features may not be available offline.'), + title: t('offlinePreparationCanceled', 'Offline preparation canceled'), }); closeModal(false); } else { showToast({ critical: true, - kind: "success", - description: t("offlineModeIsReady", "Offline mode is ready"), - title: t("offline", "Offline"), + kind: 'success', + description: t('offlineModeIsReady', 'Offline mode is ready'), + title: t('offline', 'Offline'), }); closeModal(true); } @@ -67,24 +53,21 @@ const OfflineReadyModal: React.FC = ({ return ( <> - + {isRunning && ( )} diff --git a/packages/apps/esm-offline-tools-app/src/index.ts b/packages/apps/esm-offline-tools-app/src/index.ts index 6e7507b1c..eb361ef61 100644 --- a/packages/apps/esm-offline-tools-app/src/index.ts +++ b/packages/apps/esm-offline-tools-app/src/index.ts @@ -8,7 +8,7 @@ import offlineToolsComponent from './root.component'; import offlineToolsLinkComponent from './offline-tools-app-menu-link.component'; import offlineToolsNavItemsComponent from './nav/offline-tools-nav-menu.component'; import offlineToolsConfirmationModalComponent from './components/confirmation-modal.component'; -import offlineToolsOfflineReadyModalComponent from "./components/offline-ready-modal.component"; +import offlineToolsOfflineReadyModalComponent from './components/offline-ready-modal.component'; import offlineToolsPatientsCardComponent from './offline-patients/patients-overview-card.component'; import offlineToolsActionsCardComponent from './offline-actions/offline-actions-overview-card.component'; import offlineToolsActionsComponent from './offline-actions/offline-actions.component'; @@ -37,15 +37,9 @@ export const offlineToolsNavItems = getSyncLifecycle(offlineToolsNavItemsCompone export const offlineToolsConfirmationModal = getSyncLifecycle(offlineToolsConfirmationModalComponent, options); -export const offlineToolsOfflineReadyModal = getSyncLifecycle( - offlineToolsOfflineReadyModalComponent, - options -); +export const offlineToolsOfflineReadyModal = getSyncLifecycle(offlineToolsOfflineReadyModalComponent, options); -export const offlineToolsPatientsCard = getSyncLifecycle( - offlineToolsPatientsCardComponent, - options -); +export const offlineToolsPatientsCard = getSyncLifecycle(offlineToolsPatientsCardComponent, options); export const offlineToolsActionsCard = getSyncLifecycle(offlineToolsActionsCardComponent, options); diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx index c9a88aeea..f19758893 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx @@ -1,14 +1,14 @@ -import React, { useState, useCallback } from "react"; -import { useTranslation } from "react-i18next"; -import { Toggle, Button, DefinitionTooltip } from "@carbon/react"; -import { Network_3 } from "@carbon/react/icons"; +import React, { useState, useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Toggle, Button, DefinitionTooltip } from '@carbon/react'; +import { Network_3 } from '@carbon/react/icons'; import { getCurrentOfflineMode, setCurrentOfflineMode, showModal, useConnectivity, -} from "@openmrs/esm-framework/src/internal"; -import styles from "./offline-actions-mode-button.scss"; +} from '@openmrs/esm-framework/src/internal'; +import styles from './offline-actions-mode-button.scss'; function doNotCloseMenu(ev: React.SyntheticEvent) { ev.stopPropagation(); @@ -17,16 +17,14 @@ function doNotCloseMenu(ev: React.SyntheticEvent) { const OfflineActionsModeButton: React.FC = () => { const { t } = useTranslation(); const isOnline = useConnectivity(); - const [lastRun, setLastRun] = useState( - () => getCurrentOfflineMode().lastRun - ); + const [lastRun, setLastRun] = useState(() => getCurrentOfflineMode().lastRun); const [active, setActive] = useState(() => getCurrentOfflineMode().active); const toggle = useCallback(() => { - const dispose = showModal("offline-tools-offline-ready-modal", { + const dispose = showModal('offline-tools-offline-ready-modal', { closeModal: (result) => { setActive(result); - setCurrentOfflineMode(result ? "on" : "off"); + setCurrentOfflineMode(result ? 'on' : 'off'); dispose(); }, }); @@ -42,30 +40,21 @@ const OfflineActionsModeButton: React.FC = () => {
- {t("offlineReady", "Offline Ready")} + {t('offlineReady', 'Offline Ready')}
{active && ( )} - {!active && ( - - )} + {!active && }
) ); diff --git a/packages/apps/esm-offline-tools-app/translations/am.json b/packages/apps/esm-offline-tools-app/translations/am.json index bb4b55415..7d2508e0d 100644 --- a/packages/apps/esm-offline-tools-app/translations/am.json +++ b/packages/apps/esm-offline-tools-app/translations/am.json @@ -12,6 +12,7 @@ "homeOverviewCardPatientsNewlyRegistered": "Newly registered", "homeOverviewCardView": "View", "lastRun": "Last Run", + "loading": "Loading", "never": "Never", "offline": "Offline", "offlineActions": "Offline actions", @@ -62,7 +63,6 @@ "offlineReady": "Offline Ready", "offlineToolsAppMenuLink": "Offline tools", "preparingOfflineMode": "Preparing for offline mode", - "progressBarLabel": "{progress}% Complete", "refresh": "Refresh", "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/ar.json b/packages/apps/esm-offline-tools-app/translations/ar.json index 871638e36..c14448bb3 100644 --- a/packages/apps/esm-offline-tools-app/translations/ar.json +++ b/packages/apps/esm-offline-tools-app/translations/ar.json @@ -12,6 +12,7 @@ "homeOverviewCardPatientsNewlyRegistered": "مُسجل حديثًا", "homeOverviewCardView": "عرض", "lastRun": "Last Run", + "loading": "Loading", "never": "Never", "offline": "Offline", "offlineActions": "الأنشطة بدون اتصال", @@ -66,7 +67,6 @@ "offlineReady": "جاهز للعمل بدون اتصال", "offlineToolsAppMenuLink": "أدوات العمل بدون اتصال", "preparingOfflineMode": "Preparing for offline mode", - "progressBarLabel": "{progress}% Complete", "refresh": "Refresh", "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/en.json b/packages/apps/esm-offline-tools-app/translations/en.json index 81e7a723a..f57eaae45 100644 --- a/packages/apps/esm-offline-tools-app/translations/en.json +++ b/packages/apps/esm-offline-tools-app/translations/en.json @@ -12,6 +12,7 @@ "homeOverviewCardPatientsNewlyRegistered": "Newly registered", "homeOverviewCardView": "View", "lastRun": "Last Run", + "loading": "Loading", "never": "Never", "offline": "Offline", "offlineActions": "Offline Actions", @@ -62,7 +63,6 @@ "offlineReady": "Offline Ready", "offlineToolsAppMenuLink": "Offline tools", "preparingOfflineMode": "Preparing for offline mode", - "progressBarLabel": "{{progress}}% Complete", "refresh": "Refresh", "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/es.json b/packages/apps/esm-offline-tools-app/translations/es.json index b2617d95b..bf49641b3 100644 --- a/packages/apps/esm-offline-tools-app/translations/es.json +++ b/packages/apps/esm-offline-tools-app/translations/es.json @@ -12,6 +12,7 @@ "homeOverviewCardPatientsNewlyRegistered": "Recién registrados", "homeOverviewCardView": "Ver", "lastRun": "Última carrera", + "loading": "Loading", "never": "Nunca", "offline": "Offline", "offlineActions": "Acciones offline", @@ -63,7 +64,6 @@ "offlineReady": "Listo offline", "offlineToolsAppMenuLink": "Herramientas offline", "preparingOfflineMode": "Preparando modo sin conexión", - "progressBarLabel": "{{progress}}% Completo", "refresh": "Actualizar", "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/fr.json b/packages/apps/esm-offline-tools-app/translations/fr.json index ec2d4f6b3..28c09a014 100644 --- a/packages/apps/esm-offline-tools-app/translations/fr.json +++ b/packages/apps/esm-offline-tools-app/translations/fr.json @@ -12,6 +12,7 @@ "homeOverviewCardPatientsNewlyRegistered": "Nouvellement enregistré", "homeOverviewCardView": "Voir", "lastRun": "Dernière course", + "loading": "Loading", "never": "Jamais", "offline": "Offline", "offlineActions": "Actions hors ligne", @@ -63,7 +64,6 @@ "offlineReady": "Prêt pour être hors ligne", "offlineToolsAppMenuLink": "Outils hors ligne", "preparingOfflineMode": "Préparation du mode hors ligne", - "progressBarLabel": "{{progress}}% Complet", "refresh": "rafraîchir", "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/he.json b/packages/apps/esm-offline-tools-app/translations/he.json index 3b5f1f2f2..3f21d8b38 100644 --- a/packages/apps/esm-offline-tools-app/translations/he.json +++ b/packages/apps/esm-offline-tools-app/translations/he.json @@ -12,6 +12,7 @@ "homeOverviewCardPatientsNewlyRegistered": "רשומים חדשים", "homeOverviewCardView": "צפה", "lastRun": "Last Run", + "loading": "Loading", "never": "Never", "offline": "Offline", "offlineActions": "פעולות לא מקוונות", @@ -64,7 +65,6 @@ "offlineReady": "מצב לא מקוון מוכן", "offlineToolsAppMenuLink": "כלי לא מקוונים", "preparingOfflineMode": "Preparing for offline mode", - "progressBarLabel": "{progress}% Complete", "refresh": "Refresh", "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/apps/esm-offline-tools-app/translations/km.json b/packages/apps/esm-offline-tools-app/translations/km.json index 4b985163b..1254de9b8 100644 --- a/packages/apps/esm-offline-tools-app/translations/km.json +++ b/packages/apps/esm-offline-tools-app/translations/km.json @@ -12,6 +12,7 @@ "homeOverviewCardPatientsNewlyRegistered": "Newly registered", "homeOverviewCardView": "View", "lastRun": "Last Run", + "loading": "Loading", "never": "Never", "offline": "Offline", "offlineActions": "សកម្មភាពក្រៅបណ្តាញ", @@ -61,7 +62,6 @@ "offlineReady": "Offline Ready", "offlineToolsAppMenuLink": "Offline tools", "preparingOfflineMode": "Preparing for offline mode", - "progressBarLabel": "{progress}% Complete", "refresh": "Refresh", "unavailableOfflineFeatures": "Some features may not be available offline." } diff --git a/packages/framework/esm-offline/src/mode.ts b/packages/framework/esm-offline/src/mode.ts index ecbeb87a4..bccb1adb1 100644 --- a/packages/framework/esm-offline/src/mode.ts +++ b/packages/framework/esm-offline/src/mode.ts @@ -31,7 +31,7 @@ async function isPrivateBrowsing() { return (await isFirefoxPrivateBrowsing()) || (await isEdgePrivateBrowsing()) || (await isSafariPrivateBrowsing()); } -export type OfflineMode = "on" | "off" | "unavailable"; +export type OfflineMode = 'on' | 'off' | 'unavailable'; export type OfflineHandler = () => void | Promise; export interface OfflineModeResult { @@ -41,15 +41,15 @@ export interface OfflineModeResult { lastRun: string; } -const offlineModeStorageKey = "openmrs:offline-mode"; -let offlineMode: OfflineMode = "unavailable"; -let lastRun: string = ""; +const offlineModeStorageKey = 'openmrs:offline-mode'; +let offlineMode: OfflineMode = 'unavailable'; +let lastRun: string = ''; export function getCurrentOfflineMode(): OfflineModeResult { return { current: offlineMode, - notAvailable: offlineMode === "unavailable", - active: offlineMode === "on", + notAvailable: offlineMode === 'unavailable', + active: offlineMode === 'on', lastRun: lastRun, }; } @@ -62,7 +62,7 @@ export function setCurrentOfflineMode(mode: OfflineMode) { } export function registerOfflineHandler(setupOffline: OfflineHandler) { - window.addEventListener("openmrs:offline-enabled", setupOffline); + window.addEventListener('openmrs:offline-enabled', setupOffline); const offlineMode = getCurrentOfflineMode(); if (offlineMode.active) { setupOffline(); diff --git a/packages/framework/esm-offline/src/public.ts b/packages/framework/esm-offline/src/public.ts index 2e0bee08f..7a16dcf7a 100644 --- a/packages/framework/esm-offline/src/public.ts +++ b/packages/framework/esm-offline/src/public.ts @@ -1,13 +1,8 @@ -export { - type OfflineMode, - type OfflineModeResult, - getCurrentOfflineMode, - registerOfflineHandler, -} from "./mode"; -export * from "./offline-patient-data"; -export * from "./service-worker-messaging"; -export * from "./service-worker-http-headers"; -export * from "./uuid"; +export { type OfflineMode, type OfflineModeResult, getCurrentOfflineMode, registerOfflineHandler } from './mode'; +export * from './offline-patient-data'; +export * from './service-worker-messaging'; +export * from './service-worker-http-headers'; +export * from './uuid'; export { type QueueItemDescriptor, type SyncItem, From 01a286ef7914e121c10b3f0bc7d04830d2ca4926 Mon Sep 17 00:00:00 2001 From: Jose Francisco Date: Tue, 19 Dec 2023 12:40:52 +0000 Subject: [PATCH 6/7] (chore) register Offline Handler --- .../src/components/offline-ready-modal.component.tsx | 4 +--- packages/apps/esm-offline-tools-app/src/index.ts | 6 ++---- .../src/offline-actions/synchronizing-notification.tsx | 2 +- packages/framework/esm-offline/src/mode.ts | 5 +---- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx index 46d323c23..46f3f75dd 100644 --- a/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx @@ -14,10 +14,8 @@ const OfflineReadyModal: React.FC = ({ closeMo const [abortController, setAbortController] = useState(() => new AbortController()); async function dispatchOfflineEvent() { - //TODO CHANGE MODE - let mode = getCurrentOfflineMode().active; window.dispatchEvent( - new CustomEvent(`openmrs:offline-${mode ? 'enabled' : 'disabled'}`, { + new CustomEvent(`openmrs:offline-enabled`, { detail: getCurrentOfflineMode(), }), ); diff --git a/packages/apps/esm-offline-tools-app/src/index.ts b/packages/apps/esm-offline-tools-app/src/index.ts index eb361ef61..1b2f04736 100644 --- a/packages/apps/esm-offline-tools-app/src/index.ts +++ b/packages/apps/esm-offline-tools-app/src/index.ts @@ -1,4 +1,4 @@ -import { defineConfigSchema, getSyncLifecycle, registerBreadcrumbs } from '@openmrs/esm-framework'; +import { defineConfigSchema, getSyncLifecycle, registerBreadcrumbs, registerOfflineHandler } from '@openmrs/esm-framework'; import { routes } from './constants'; import { createDashboardLink } from './createDashboardLink'; import { dashboardMeta } from './dashboard.meta'; @@ -88,11 +88,9 @@ export const offlineToolsOptInButton = getSyncLifecycle(offlineToolsOptInButtonC export function startupApp() { defineConfigSchema(moduleName, {}); - setupOffline(); + registerOfflineHandler(setupOffline); setupSynchronizingOfflineActionsNotifications(); - // registerOfflineHandler(setupOffline); - registerBreadcrumbs([ { path: `${window.spaBase}/${routes.offlineTools}`, diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx index 2d1df0774..32b295198 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx @@ -51,7 +51,7 @@ function SynchronizingNotification({ mySynchronizationIndex }) {
{isCanceled ? t('offlineActionsSynchronizationNotificationCanceling', 'Canceling...') - : t('offlineActionsSynchronizationNotificationStatus', '{current} / {total} actions', { + : t('offlineActionsSynchronizationNotificationStatus', '{{current}} / {{total}} actions', { current: synchronization.totalCount - synchronization.pendingCount, total: synchronization.totalCount, })} diff --git a/packages/framework/esm-offline/src/mode.ts b/packages/framework/esm-offline/src/mode.ts index bccb1adb1..0412605d3 100644 --- a/packages/framework/esm-offline/src/mode.ts +++ b/packages/framework/esm-offline/src/mode.ts @@ -59,14 +59,11 @@ export function setCurrentOfflineMode(mode: OfflineMode) { localStorage.setItem(offlineModeStorageKey, mode === 'on' ? 'active' : 'disabled'); offlineMode = mode; } + lastRun = new Date().toLocaleString(); } export function registerOfflineHandler(setupOffline: OfflineHandler) { window.addEventListener('openmrs:offline-enabled', setupOffline); - const offlineMode = getCurrentOfflineMode(); - if (offlineMode.active) { - setupOffline(); - } } export async function activateOfflineCapability() { From f1db15500ebc7ff8d2852939539182da3a7f9f9d Mon Sep 17 00:00:00 2001 From: Jose Francisco Date: Wed, 17 Jan 2024 10:28:06 +0000 Subject: [PATCH 7/7] (chore) Replaced toggle with switcher item for menu consistency --- .../apps/esm-offline-tools-app/src/index.ts | 7 +++- .../offline-actions-mode-button.extension.tsx | 32 ++++++-------- .../offline-actions-mode-button.scss | 42 +------------------ 3 files changed, 20 insertions(+), 61 deletions(-) diff --git a/packages/apps/esm-offline-tools-app/src/index.ts b/packages/apps/esm-offline-tools-app/src/index.ts index 2f8a51349..370d167e9 100644 --- a/packages/apps/esm-offline-tools-app/src/index.ts +++ b/packages/apps/esm-offline-tools-app/src/index.ts @@ -1,4 +1,9 @@ -import { defineConfigSchema, getSyncLifecycle, registerBreadcrumbs, registerOfflineHandler } from '@openmrs/esm-framework'; +import { + defineConfigSchema, + getSyncLifecycle, + registerBreadcrumbs, + registerOfflineHandler, +} from '@openmrs/esm-framework'; import { routes } from './constants'; import { createDashboardLink } from './createDashboardLink'; import { dashboardMeta } from './dashboard.meta'; diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx index d98b70fea..cc5f217ba 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx @@ -1,6 +1,6 @@ import React, { useState, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { Toggle, Button, DefinitionTooltip } from '@carbon/react'; +import { Button } from '@carbon/react'; import { Network_3 } from '@carbon/react/icons'; import { getCurrentOfflineMode, @@ -18,7 +18,6 @@ function doNotCloseMenu(ev: React.SyntheticEvent) { const OfflineActionsModeButton: React.FC = () => { const { t } = useTranslation(); const isOnline = useConnectivity(); - const [lastRun, setLastRun] = useState(() => getCurrentOfflineMode().lastRun); const [active, setActive] = useState(() => getCurrentOfflineMode().active); const toggle = useCallback(() => { @@ -37,26 +36,21 @@ const OfflineActionsModeButton: React.FC = () => { return ( isOnline && ( -
+
- - {t('offlineReady', 'Offline Ready')} - +

{t('offlineReady', 'Offline Ready')}

- - {active && ( - - )} - - {!active && } -
+ {active ? ( + + ) : ( + + )} + ) ); }; diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss index 538096c47..565871148 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss @@ -3,48 +3,8 @@ .panelItemContainer a { display: flex; - justify-content: space-between; align-items: center; - - :global(.cds--toggle-input__label .cds--toggle__switch) { - margin-top: 0 !important; - } - - :global(.cds--toggle) { - /* setting the width prevents the toggle from changing size when the text changes */ - width: 76px; - margin: 0 1rem; - } - - :global(.cds--toggle__text) { - color: $ui-02; - } - - :global(.cds--definition-term) { - color: $ui-02; - } - - svg { - margin: 0rem 0.75rem; - fill: $field-01; - } - - & > div { - display: flex; - flex-direction: row; - width: fit-content; - align-items: center; - } - - button, - button:hover { - color: $inverse-link; - } - - button :hover { - @include brand-03(background-color); - color: $inverse-link; - } + justify-content: space-between; } .panelItemContainer div {