@openmrs/esm-cohort-builder-app 3.0.1-pre.87 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/package.json +48 -32
  2. package/src/cohort-builder-admin-link.component.tsx +27 -0
  3. package/src/cohort-builder.resources.ts +9 -5
  4. package/src/cohort-builder.tsx +12 -7
  5. package/src/components/empty-data/empty-data.component.tsx +9 -7
  6. package/src/components/empty-data/empty-data.style.scss +0 -1
  7. package/src/components/saved-cohorts/saved-cohorts.component.tsx +1 -1
  8. package/src/components/saved-cohorts/saved-cohorts.resources.ts +7 -3
  9. package/src/components/saved-queries/saved-queries.component.tsx +1 -1
  10. package/src/components/saved-queries/saved-queries.resources.ts +7 -3
  11. package/src/components/search-by-concepts/search-concept/search-concept.resource.ts +6 -2
  12. package/src/components/search-by-demographics/search-by-demographics.component.tsx +2 -2
  13. package/src/components/search-by-demographics/search-by-demographics.style.scss +2 -3
  14. package/src/components/search-by-drug-orders/search-by-drug-orders.resources.ts +3 -3
  15. package/src/components/search-by-encounters/search-by-encounters.resources.ts +3 -3
  16. package/src/components/search-by-enrollments/search-by-enrollments.resources.ts +2 -2
  17. package/src/components/search-by-person-attributes/search-by-person-attributes.resource.ts +2 -2
  18. package/src/components/search-history/search-history-options/search-history-options.resources.ts +7 -3
  19. package/src/components/search-history/search-history.component.tsx +1 -1
  20. package/src/components/search-history/search-history.test.tsx +1 -1
  21. package/src/components/search-results-table/search-results-table.component.tsx +1 -1
  22. package/src/index.ts +18 -27
  23. package/src/routes.json +26 -0
  24. package/.editorconfig +0 -12
  25. package/.eslintignore +0 -1
  26. package/.eslintrc +0 -28
  27. package/.github/workflows/codeql-analysis.yml +0 -72
  28. package/.github/workflows/node.js.yml +0 -95
  29. package/.husky/pre-commit +0 -6
  30. package/.husky/pre-push +0 -6
  31. package/.prettierignore +0 -14
  32. package/__mocks__/react-i18next.js +0 -57
  33. package/jest.config.json +0 -21
  34. package/translations/en.json +0 -119
  35. package/tsconfig.json +0 -23
  36. package/webpack.config.js +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-cohort-builder-app",
3
- "version": "3.0.1-pre.87",
3
+ "version": "4.0.0",
4
4
  "license": "MPL-2.0",
5
5
  "description": "A microfrontend for OpenMRS cohorts",
6
6
  "browser": "dist/openmrs-esm-cohort-builder-app.js",
@@ -14,11 +14,16 @@
14
14
  "lint": "eslint src --ext js,jsx,ts,tsx",
15
15
  "prettier": "prettier --write \"src/**/*.{ts,tsx}\"",
16
16
  "typescript": "tsc",
17
- "test": "jest --config jest.config.json --verbose",
17
+ "test": "jest --config jest.config.js --verbose",
18
+ "test-e2e": "playwright test",
18
19
  "verify": "concurrently 'yarn:lint' 'yarn:test' 'yarn:typescript'",
19
20
  "coverage": "yarn test -- --coverage",
20
21
  "prepare": "husky install"
21
22
  },
23
+ "files": [
24
+ "dist",
25
+ "src"
26
+ ],
22
27
  "husky": {
23
28
  "hooks": {
24
29
  "pre-commit": "pretty-quick --staged && yarn verify"
@@ -43,47 +48,58 @@
43
48
  "url": "https://github.com/openmrs/openmrs-esm-cohortbuilder/issues"
44
49
  },
45
50
  "peerDependencies": {
46
- "@carbon/react": "1.x",
47
- "@openmrs/esm-framework": "next",
48
- "dayjs": "^1.11.3",
51
+ "@openmrs/esm-framework": "*",
49
52
  "react": "18.x",
50
53
  "react-dom": "18.x",
51
54
  "react-i18next": "11.x"
52
55
  },
53
56
  "devDependencies": {
57
+ "@carbon/react": "1.21.0",
58
+ "@openmrs/esm-framework": "next",
54
59
  "@openmrs/esm-patient-common-lib": "next",
55
- "@swc/cli": "^0.1.57",
56
- "@swc/core": "^1.3.14",
57
- "@swc/jest": "^0.2.22",
58
- "@testing-library/dom": "^7.31.2",
59
- "@testing-library/jest-dom": "^5.13.0",
60
- "@testing-library/react": "^13.3.0",
60
+ "@openmrs/esm-styleguide": "next",
61
+ "@playwright/test": "1.44.0",
62
+ "@swc/cli": "^0.1.61",
63
+ "@swc/core": "^1.3.34",
64
+ "@swc/jest": "^0.2.24",
65
+ "@testing-library/dom": "^8.20.0",
66
+ "@testing-library/jest-dom": "^5.16.5",
67
+ "@testing-library/react": "^13.4.0",
61
68
  "@testing-library/user-event": "^14.4.3",
62
- "@types/jest": "^28.1.7",
63
- "@types/react-dom": "^16.9.14",
64
- "@types/webpack-env": "^1.16.0",
65
- "@typescript-eslint/eslint-plugin": "^5.29.0",
66
- "@typescript-eslint/parser": "^5.14.0",
67
- "concurrently": "^6.2.0",
68
- "css-loader": "^6.7.1",
69
- "eslint": "^8.18.0",
70
- "eslint-config-prettier": "^8.3.0",
69
+ "@types/jest": "^29.4.0",
70
+ "@types/react": "^18.0.27",
71
+ "@types/react-dom": "^18.0.10",
72
+ "@types/webpack-env": "^1.18.0",
73
+ "@typescript-eslint/eslint-plugin": "^5.51.0",
74
+ "@typescript-eslint/parser": "^5.51.0",
75
+ "concurrently": "^7.6.0",
76
+ "css-loader": "^6.7.3",
77
+ "dayjs": "^1.11.7",
78
+ "eslint": "^8.33.0",
79
+ "eslint-config-prettier": "^8.6.0",
71
80
  "eslint-config-ts-react-important-stuff": "^3.0.0",
72
- "eslint-plugin-import": "^2.26.0",
73
- "eslint-plugin-prettier": "^3.4.0",
81
+ "eslint-plugin-import": "^2.27.5",
82
+ "eslint-plugin-prettier": "^4.2.1",
74
83
  "eslint-plugin-unused-imports": "^2.0.0",
75
- "husky": "^6.0.0",
84
+ "husky": "^8.0.3",
76
85
  "identity-obj-proxy": "^3.0.0",
77
- "jest": "^28.1.3",
78
- "jest-cli": "^28.1.3",
79
- "jest-environment-jsdom": "^28.1.3",
86
+ "jest": "^29.4.2",
87
+ "jest-cli": "^29.4.2",
88
+ "jest-environment-jsdom": "^29.4.2",
80
89
  "openmrs": "next",
81
- "prettier": "^2.3.0",
82
- "pretty-quick": "^3.1.0",
90
+ "prettier": "^2.8.4",
91
+ "pretty-quick": "^3.1.3",
83
92
  "react": "^18.2.0",
84
93
  "react-dom": "^18.2.0",
85
- "react-i18next": "^11.18.4",
86
- "typescript": "^4.3.2"
94
+ "react-i18next": "^12.1.5",
95
+ "swc-loader": "^0.2.3",
96
+ "typescript": "^4.9.5",
97
+ "webpack": "^5.75.0",
98
+ "webpack-cli": "^5.0.1"
87
99
  },
88
- "dependencies": {}
89
- }
100
+ "packageManager": "yarn@4.2.2",
101
+ "dependencies": {
102
+ "classnames": "^2.3.2",
103
+ "dotenv": "^16.3.1"
104
+ }
105
+ }
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import { useTranslation } from "react-i18next";
3
+ import { Layer, ClickableTile } from "@carbon/react";
4
+ import { ArrowRight } from "@carbon/react/icons";
5
+
6
+ const CohortBuilderAdminLink: React.FC = () => {
7
+ const { t } = useTranslation();
8
+ return (
9
+ <Layer>
10
+ <ClickableTile
11
+ href={`${window.spaBase}/cohort-builder`}
12
+ target="_blank"
13
+ rel="noopener noreferrer"
14
+ >
15
+ <div>
16
+ <div className="heading">{t("manageCohorts", "Manage Cohorts")}</div>
17
+ <div className="content">{t("cohortBuilder", "Cohort Builder")}</div>
18
+ </div>
19
+ <div className="iconWrapper">
20
+ <ArrowRight size={16} />
21
+ </div>
22
+ </ClickableTile>
23
+ </Layer>
24
+ );
25
+ };
26
+
27
+ export default CohortBuilderAdminLink;
@@ -1,4 +1,8 @@
1
- import { openmrsFetch, FetchResponse } from "@openmrs/esm-framework";
1
+ import {
2
+ openmrsFetch,
3
+ FetchResponse,
4
+ restBaseUrl,
5
+ } from "@openmrs/esm-framework";
2
6
  import useSWRImmutable from "swr/immutable";
3
7
 
4
8
  import { Patient, SearchParams, DropdownValue, Response } from "./types";
@@ -13,7 +17,7 @@ interface SearchResults {
13
17
 
14
18
  export const search = async (searchParams: SearchParams) => {
15
19
  const searchResults: FetchResponse<SearchResults> = await openmrsFetch(
16
- "/ws/rest/v1/reportingrest/adhocquery?v=full",
20
+ `${restBaseUrl}/reportingrest/adhocquery?v=full`,
17
21
  {
18
22
  method: "POST",
19
23
  headers: { "Content-Type": "application/json" },
@@ -29,7 +33,7 @@ export const search = async (searchParams: SearchParams) => {
29
33
  export const useLocations = () => {
30
34
  const { data, error } = useSWRImmutable<{
31
35
  data: { results: Response[] };
32
- }>("/ws/rest/v1/location", openmrsFetch);
36
+ }>(`${restBaseUrl}/location`, openmrsFetch);
33
37
 
34
38
  const locations: DropdownValue[] = [];
35
39
  data?.data.results.map((location: Response, index: number) => {
@@ -49,7 +53,7 @@ export const useLocations = () => {
49
53
 
50
54
  export const getDataSet = async (queryID: string) => {
51
55
  const results: FetchResponse<SearchResults> = await openmrsFetch(
52
- `/ws/rest/v1/reportingrest/dataSet/${queryID}`,
56
+ `${restBaseUrl}/reportingrest/dataSet/${queryID}`,
53
57
  {
54
58
  method: "GET",
55
59
  }
@@ -67,7 +71,7 @@ export const getDataSet = async (queryID: string) => {
67
71
 
68
72
  export const getCohortMembers = async (cohortId: string) => {
69
73
  const results: FetchResponse<SearchResults> = await openmrsFetch(
70
- `/ws/rest/v1/cohort/${cohortId}/member?v=full`,
74
+ `${restBaseUrl}/cohort/${cohortId}/member?v=full`,
71
75
  {
72
76
  method: "GET",
73
77
  }
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from "react";
2
-
2
+ import classNames from "classnames";
3
3
  import { Tab, Tabs, TabList, TabPanels, TabPanel } from "@carbon/react";
4
4
  import { showToast, useLayoutType } from "@openmrs/esm-framework";
5
5
  import { useTranslation } from "react-i18next";
@@ -169,12 +169,16 @@ const CohortBuilder: React.FC = () => {
169
169
 
170
170
  return (
171
171
  <div
172
- className={`omrs-main-content ${styles.mainContainer} ${styles.cohortBuilder}`}
172
+ className={classNames(
173
+ "omrs-main-content",
174
+ styles.mainContainer,
175
+ styles.cohortBuilder
176
+ )}
173
177
  >
174
178
  <div
175
- className={
179
+ className={classNames(
176
180
  isLayoutTablet ? styles.tabletContainer : styles.desktopContainer
177
- }
181
+ )}
178
182
  >
179
183
  <p className={styles.title}>{t("cohortBuilder", "Cohort Builder")}</p>
180
184
  <div className={styles.tabContainer}>
@@ -183,9 +187,10 @@ const CohortBuilder: React.FC = () => {
183
187
  </p>
184
188
  <div className={styles.tab}>
185
189
  <Tabs
186
- className={`${styles.verticalTabs} ${
187
- isLayoutTablet ? styles.tabletTab : styles.desktopTab
188
- }`}
190
+ className={classNames(styles.verticalTabs, {
191
+ [styles.tabletTab]: isLayoutTablet,
192
+ [styles.desktopTab]: !isLayoutTablet,
193
+ })}
189
194
  >
190
195
  <TabList aria-label="navigation">
191
196
  {tabs.map((tab: TabItem, index: number) => (
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Tile } from "@carbon/react";
3
+ import { Layer, Tile } from "@carbon/react";
4
4
  import { EmptyDataIllustration } from "@openmrs/esm-patient-common-lib/src/empty-state/index";
5
5
 
6
6
  import styles from "./empty-data.style.scss";
@@ -11,12 +11,14 @@ export interface EmptyDataProps {
11
11
 
12
12
  const EmptyData: React.FC<EmptyDataProps> = (props) => {
13
13
  return (
14
- <Tile className={styles.tile}>
15
- <EmptyDataIllustration />
16
- <p className={styles.content}>
17
- There are no {props.displayText.toLowerCase()} to display
18
- </p>
19
- </Tile>
14
+ <Layer>
15
+ <Tile className={styles.tile}>
16
+ <EmptyDataIllustration />
17
+ <p className={styles.content}>
18
+ There are no {props.displayText.toLowerCase()} to display
19
+ </p>
20
+ </Tile>
21
+ </Layer>
20
22
  );
21
23
  };
22
24
 
@@ -1,5 +1,4 @@
1
1
  @use '@carbon/styles/scss/spacing';
2
- // @use '@carbon/colors';
3
2
  @use '@carbon/styles/scss/type';
4
3
  @import '~@openmrs/esm-styleguide/src/vars';
5
4
 
@@ -131,7 +131,7 @@ const SavedCohorts: React.FC<SavedCohortsProps> = ({ onViewCohort }) => {
131
131
  totalItems={cohorts.length}
132
132
  />
133
133
  )}
134
- {!cohorts.length && <EmptyData displayText="cohorts" />}
134
+ {!cohorts.length && <EmptyData displayText={t("cohorts", "cohorts")} />}
135
135
  </div>
136
136
  );
137
137
  };
@@ -1,4 +1,8 @@
1
- import { FetchResponse, openmrsFetch } from "@openmrs/esm-framework";
1
+ import {
2
+ FetchResponse,
3
+ openmrsFetch,
4
+ restBaseUrl,
5
+ } from "@openmrs/esm-framework";
2
6
 
3
7
  import { Cohort, DefinitionDataRow } from "../../types";
4
8
 
@@ -7,7 +11,7 @@ import { Cohort, DefinitionDataRow } from "../../types";
7
11
  */
8
12
  export async function getCohorts(): Promise<DefinitionDataRow[]> {
9
13
  const response: FetchResponse<{ results: Cohort[] }> = await openmrsFetch(
10
- "/ws/rest/v1/cohort?v=full",
14
+ `${restBaseUrl}/cohort?v=full`,
11
15
  {
12
16
  method: "GET",
13
17
  }
@@ -30,7 +34,7 @@ export async function getCohorts(): Promise<DefinitionDataRow[]> {
30
34
 
31
35
  export const onDeleteCohort = async (cohort: string) => {
32
36
  const result: FetchResponse = await openmrsFetch(
33
- `/ws/rest/v1/cohort/${cohort}`,
37
+ `${restBaseUrl}/cohort/${cohort}`,
34
38
  {
35
39
  method: "DELETE",
36
40
  }
@@ -131,7 +131,7 @@ const SavedQueries: React.FC<SavedQueriesProps> = ({ onViewQuery }) => {
131
131
  totalItems={queries.length}
132
132
  />
133
133
  )}
134
- {!queries.length && <EmptyData displayText="queries" />}
134
+ {!queries.length && <EmptyData displayText={t("queries", "queries")} />}
135
135
  </div>
136
136
  );
137
137
  };
@@ -1,4 +1,8 @@
1
- import { FetchResponse, openmrsFetch } from "@openmrs/esm-framework";
1
+ import {
2
+ FetchResponse,
3
+ openmrsFetch,
4
+ restBaseUrl,
5
+ } from "@openmrs/esm-framework";
2
6
 
3
7
  import { Response, DefinitionDataRow } from "../../types";
4
8
 
@@ -7,7 +11,7 @@ import { Response, DefinitionDataRow } from "../../types";
7
11
  */
8
12
  export async function getQueries(): Promise<DefinitionDataRow[]> {
9
13
  const response: FetchResponse<{ results: Response[] }> = await openmrsFetch(
10
- "/ws/rest/v1/reportingrest/dataSetDefinition?v=full",
14
+ `${restBaseUrl}/reportingrest/dataSetDefinition?v=full`,
11
15
  {
12
16
  method: "GET",
13
17
  }
@@ -30,7 +34,7 @@ export async function getQueries(): Promise<DefinitionDataRow[]> {
30
34
 
31
35
  export const deleteDataSet = async (queryID: string) => {
32
36
  const dataset: FetchResponse = await openmrsFetch(
33
- `/ws/rest/v1/reportingrest/adhocdataset/${queryID}?purge=true`,
37
+ `${restBaseUrl}/reportingrest/adhocdataset/${queryID}?purge=true`,
34
38
  {
35
39
  method: "DELETE",
36
40
  }
@@ -1,4 +1,8 @@
1
- import { FetchResponse, openmrsFetch } from "@openmrs/esm-framework";
1
+ import {
2
+ FetchResponse,
3
+ openmrsFetch,
4
+ restBaseUrl,
5
+ } from "@openmrs/esm-framework";
2
6
 
3
7
  import { Concept, DataType } from "../../../types";
4
8
 
@@ -22,7 +26,7 @@ interface Description {
22
26
  */
23
27
  export async function getConcepts(conceptName: String): Promise<Concept[]> {
24
28
  const searchResult: FetchResponse<{ results: ConceptResponse[] }> =
25
- await openmrsFetch(`/ws/rest/v1/concept?v=full&q=${conceptName}`, {
29
+ await openmrsFetch(`${restBaseUrl}/concept?v=full&q=${conceptName}`, {
26
30
  method: "GET",
27
31
  });
28
32
 
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from "react";
2
-
2
+ import classNames from "classnames";
3
3
  import {
4
4
  DatePicker,
5
5
  DatePickerInput,
@@ -84,7 +84,7 @@ const SearchByDemographics: React.FC<SearchByProps> = ({ onSubmit }) => {
84
84
  return (
85
85
  <>
86
86
  <Column>
87
- <p className={`${styles.text} ${styles.genderTitle}`}>
87
+ <p className={classNames(styles.text, styles.genderTitle)}>
88
88
  {t("gender", "Gender")}
89
89
  </p>
90
90
  <div className={styles.genderContainer}>
@@ -1,9 +1,8 @@
1
+ @use '@carbon/styles/scss/spacing';
1
2
  @import "~@openmrs/esm-styleguide/src/vars";
2
- @import "~carbon-components/src/globals/scss/vars";
3
- @import "~carbon-components/src/globals/scss/mixins";
4
3
 
5
4
  .contentSwitcher {
6
- height: $spacing-08;
5
+ height: spacing.$spacing-08;
7
6
  }
8
7
 
9
8
  .column {
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from "react";
2
2
 
3
- import { openmrsFetch } from "@openmrs/esm-framework";
3
+ import { openmrsFetch, restBaseUrl } from "@openmrs/esm-framework";
4
4
  import useSWRImmutable from "swr/immutable";
5
5
 
6
6
  import { DropdownValue, Response } from "../../types";
@@ -11,7 +11,7 @@ import { DropdownValue, Response } from "../../types";
11
11
  export function useDrugs() {
12
12
  const { data, error } = useSWRImmutable<{
13
13
  data: { results: Response[] };
14
- }>("/ws/rest/v1/drug", openmrsFetch);
14
+ }>(`${restBaseUrl}/drug`, openmrsFetch);
15
15
 
16
16
  const results = useMemo(() => {
17
17
  const drugs: DropdownValue[] = [];
@@ -38,7 +38,7 @@ export function useDrugs() {
38
38
  export function useCareSettings() {
39
39
  const { data, error } = useSWRImmutable<{
40
40
  data: { results: Response[] };
41
- }>("/ws/rest/v1/caresetting", openmrsFetch);
41
+ }>(`${restBaseUrl}/caresetting`, openmrsFetch);
42
42
 
43
43
  const results = useMemo(() => {
44
44
  const careSettings: DropdownValue[] = [];
@@ -1,4 +1,4 @@
1
- import { openmrsFetch } from "@openmrs/esm-framework";
1
+ import { openmrsFetch, restBaseUrl } from "@openmrs/esm-framework";
2
2
  import useSWRImmutable from "swr/immutable";
3
3
 
4
4
  import { DropdownValue, Response } from "../../types";
@@ -9,7 +9,7 @@ import { DropdownValue, Response } from "../../types";
9
9
  export const useForms = () => {
10
10
  const { data, error } = useSWRImmutable<{
11
11
  data: { results: Response[] };
12
- }>("/ws/rest/v1/form", openmrsFetch);
12
+ }>(`${restBaseUrl}/form`, openmrsFetch);
13
13
 
14
14
  const forms: DropdownValue[] = [];
15
15
  data?.data.results.map((form: Response, index: number) => {
@@ -33,7 +33,7 @@ export const useForms = () => {
33
33
  export const useEncounterTypes = () => {
34
34
  const { data, error } = useSWRImmutable<{
35
35
  data: { results: Response[] };
36
- }>("/ws/rest/v1/encountertype", openmrsFetch);
36
+ }>(`${restBaseUrl}/encountertype`, openmrsFetch);
37
37
 
38
38
  const encounterTypes: DropdownValue[] = [];
39
39
  data?.data.results.map((encounterType: Response, index: number) => {
@@ -1,4 +1,4 @@
1
- import { openmrsFetch } from "@openmrs/esm-framework";
1
+ import { openmrsFetch, restBaseUrl } from "@openmrs/esm-framework";
2
2
  import useSWRImmutable from "swr/immutable";
3
3
 
4
4
  import { DropdownValue, Response } from "../../types";
@@ -13,7 +13,7 @@ interface ProgramsResponse extends Response {
13
13
  export function usePrograms() {
14
14
  const { data, error } = useSWRImmutable<{
15
15
  data: { results: ProgramsResponse[] };
16
- }>("/ws/rest/v1/program", openmrsFetch);
16
+ }>(`${restBaseUrl}/program`, openmrsFetch);
17
17
 
18
18
  const programs: DropdownValue[] = [];
19
19
  data?.data.results.map((program: ProgramsResponse, index: number) => {
@@ -1,4 +1,4 @@
1
- import { openmrsFetch } from "@openmrs/esm-framework";
1
+ import { openmrsFetch, restBaseUrl } from "@openmrs/esm-framework";
2
2
  import useSWRImmutable from "swr/immutable";
3
3
 
4
4
  import { DropdownValue, Response } from "../../types";
@@ -9,7 +9,7 @@ import { DropdownValue, Response } from "../../types";
9
9
  export function usePersonAttributes() {
10
10
  const { data, error } = useSWRImmutable<{
11
11
  data: { results: Response[] };
12
- }>("/ws/rest/v1/personattributetype", openmrsFetch);
12
+ }>(`${restBaseUrl}/personattributetype`, openmrsFetch);
13
13
 
14
14
  const personAttributes: DropdownValue[] = [];
15
15
  data?.data.results.map((personAttribute: Response, index: number) => {
@@ -1,4 +1,8 @@
1
- import { FetchResponse, openmrsFetch } from "@openmrs/esm-framework";
1
+ import {
2
+ FetchResponse,
3
+ openmrsFetch,
4
+ restBaseUrl,
5
+ } from "@openmrs/esm-framework";
2
6
 
3
7
  import { Cohort, Query } from "../../../types";
4
8
 
@@ -9,7 +13,7 @@ import { Cohort, Query } from "../../../types";
9
13
  export async function createCohort(
10
14
  cohort: Cohort
11
15
  ): Promise<FetchResponse<Cohort>> {
12
- return await openmrsFetch("/ws/rest/v1/cohort", {
16
+ return await openmrsFetch(`${restBaseUrl}/cohort`, {
13
17
  method: "POST",
14
18
  headers: { "Content-Type": "application/json" },
15
19
  body: cohort,
@@ -21,7 +25,7 @@ export async function createCohort(
21
25
  * @param query
22
26
  */
23
27
  export async function createQuery(query: Query): Promise<FetchResponse<Query>> {
24
- return await openmrsFetch("/ws/rest/v1/reportingrest/adhocdataset", {
28
+ return await openmrsFetch(`${restBaseUrl}/reportingrest/adhocdataset`, {
25
29
  method: "POST",
26
30
  headers: { "Content-Type": "application/json" },
27
31
  body: query,
@@ -146,7 +146,7 @@ const SearchHistory: React.FC<SearchHistoryProps> = ({
146
146
  totalItems={searchResults.length}
147
147
  />
148
148
  )}
149
- {!searchResults.length && <EmptyData displayText="history" />}
149
+ {!searchResults.length && <EmptyData displayText={t("data", "data")} />}
150
150
  <ComposedModal
151
151
  size={"sm"}
152
152
  open={isClearHistoryModalVisible}
@@ -86,7 +86,7 @@ describe("Test the search history component", () => {
86
86
  );
87
87
 
88
88
  expect(
89
- screen.getByText("There are no history to display")
89
+ screen.getByText("There are no data to display")
90
90
  ).toBeInTheDocument();
91
91
  });
92
92
 
@@ -97,7 +97,7 @@ const SearchResultsTable: React.FC<SearchResultsTableProps> = ({
97
97
  totalItems={patients.length}
98
98
  />
99
99
  )}
100
- {!patients.length && <EmptyData displayText="data" />}
100
+ {!patients.length && <EmptyData displayText={t("data", "data")} />}
101
101
  </div>
102
102
  );
103
103
  };
package/src/index.ts CHANGED
@@ -1,36 +1,27 @@
1
- import { getAsyncLifecycle } from "@openmrs/esm-framework";
1
+ import { getSyncLifecycle } from "@openmrs/esm-framework";
2
2
 
3
- const importTranslation = require.context(
3
+ import cohortBuilderComponent from "./cohort-builder";
4
+ import cohortBuilderAdminPageCardLinkComponent from "./cohort-builder-admin-link.component";
5
+
6
+ const moduleName = "@openmrs/esm-cohort-builder";
7
+
8
+ const options = {
9
+ featureName: "cohort-builder",
10
+ moduleName,
11
+ };
12
+
13
+ export const importTranslation = require.context(
4
14
  "../translations",
5
15
  false,
6
16
  /.json$/,
7
17
  "lazy"
8
18
  );
9
19
 
10
- const backendDependencies = {
11
- fhir2: "^1.2.0",
12
- "webservices.rest": "^2.2.0",
13
- reportingrest: "^1.0.0",
14
- reporting: "^1.0.0",
15
- };
16
-
17
- function setupOpenMRS() {
18
- const moduleName = "@openmrs/esm-cohort-builder";
20
+ export function startupApp() {}
19
21
 
20
- const options = {
21
- featureName: "cohort-builder",
22
- moduleName,
23
- };
22
+ export const cohortBuilder = getSyncLifecycle(cohortBuilderComponent, options);
24
23
 
25
- return {
26
- pages: [
27
- {
28
- load: getAsyncLifecycle(() => import("./cohort-builder"), options),
29
- route: "cohort-builder",
30
- },
31
- ],
32
- extensions: [],
33
- };
34
- }
35
-
36
- export { backendDependencies, importTranslation, setupOpenMRS };
24
+ export const cohortBuilderAdminPageCardLink = getSyncLifecycle(
25
+ cohortBuilderAdminPageCardLinkComponent,
26
+ options
27
+ );
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "https://json.openmrs.org/routes.schema.json",
3
+ "backendDependencies": {
4
+ "fhir2": ">=1.2",
5
+ "webservices.rest": "^2.2.0",
6
+ "reportingrest": "^1.0.0",
7
+ "reporting": "^1.0.0"
8
+ },
9
+ "pages": [
10
+ {
11
+ "component": "cohortBuilder",
12
+ "route": "cohort-builder",
13
+ "online": true,
14
+ "offline": true
15
+ }
16
+ ],
17
+ "extensions": [
18
+ {
19
+ "name": "system-administration-cohort-builder-card-link",
20
+ "slot": "system-admin-page-card-link-slot",
21
+ "component": "cohortBuilderAdminPageCardLink",
22
+ "online": true,
23
+ "offline": true
24
+ }
25
+ ]
26
+ }
package/.editorconfig DELETED
@@ -1,12 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = space
5
- indent_size = 2
6
- charset = utf-8
7
- trim_trailing_whitespace = true
8
- insert_final_newline = true
9
- end_of_line = lf
10
-
11
- [*.md]
12
- trim_trailing_whitespace = false
package/.eslintignore DELETED
@@ -1 +0,0 @@
1
- **/*.d.tsx
package/.eslintrc DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "parser": "@typescript-eslint/parser",
3
- "plugins": ["@typescript-eslint", "import", "unused-imports"],
4
- "rules": {
5
- "unused-imports/no-unused-imports": "error",
6
- "react-hooks/exhaustive-deps": 0,
7
- "import/order":[
8
- "error",
9
- {
10
- "groups": ["builtin", "external", "internal"],
11
- "pathGroups":[{
12
- "pattern": "react",
13
- "group": "external",
14
- "position": "before"
15
- }],
16
- "pathGroupsExcludedImportTypes": ["react"],
17
- "newlines-between": "always",
18
- "alphabetize": {
19
- "order": "asc",
20
- "caseInsensitive":true
21
- }
22
- }
23
- ],
24
- "@typescript-eslint/no-explicit-any": "error",
25
- "@typescript-eslint/no-unused-vars": "error"
26
- },
27
- "extends": ["ts-react-important-stuff", "plugin:prettier/recommended"]
28
- }
@@ -1,72 +0,0 @@
1
- # For most projects, this workflow file will not need changing; you simply need
2
- # to commit it to your repository.
3
- #
4
- # You may wish to alter this file to override the set of languages analyzed,
5
- # or to provide custom queries or build logic.
6
- #
7
- # ******** NOTE ********
8
- # We have attempted to detect the languages in your repository. Please check
9
- # the `language` matrix defined below to confirm you have the correct set of
10
- # supported CodeQL languages.
11
- #
12
- name: "CodeQL"
13
-
14
- on:
15
- push:
16
- branches: [ "main" ]
17
- pull_request:
18
- # The branches below must be a subset of the branches above
19
- branches: [ "main" ]
20
- schedule:
21
- - cron: '17 9 * * 5'
22
-
23
- jobs:
24
- analyze:
25
- name: Analyze
26
- runs-on: ubuntu-latest
27
- permissions:
28
- actions: read
29
- contents: read
30
- security-events: write
31
-
32
- strategy:
33
- fail-fast: false
34
- matrix:
35
- language: [ 'javascript' ]
36
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37
- # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
38
-
39
- steps:
40
- - name: Checkout repository
41
- uses: actions/checkout@v3
42
-
43
- # Initializes the CodeQL tools for scanning.
44
- - name: Initialize CodeQL
45
- uses: github/codeql-action/init@v2
46
- with:
47
- languages: ${{ matrix.language }}
48
- # If you wish to specify custom queries, you can do so here or in a config file.
49
- # By default, queries listed here will override any specified in a config file.
50
- # Prefix the list here with "+" to use these queries and those in the config file.
51
-
52
- # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
53
- # queries: security-extended,security-and-quality
54
-
55
-
56
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
57
- # If this step fails, then you should remove it and run the build manually (see below)
58
- - name: Autobuild
59
- uses: github/codeql-action/autobuild@v2
60
-
61
- # ℹ️ Command-line programs to run using the OS shell.
62
- # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
63
-
64
- # If the Autobuild fails above, remove it and uncomment the following three lines.
65
- # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
66
-
67
- # - run: |
68
- # echo "Run, Build Application using script"
69
- # ./location_of_script_within_repo/buildscript.sh
70
-
71
- - name: Perform CodeQL Analysis
72
- uses: github/codeql-action/analyze@v2
@@ -1,95 +0,0 @@
1
- name: Node.js CI
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
- branches: [main]
8
- release:
9
- types:
10
- - created
11
-
12
- env:
13
- ESM_NAME: "@openmrs/esm-cohort-builder-app"
14
- JS_NAME: "openmrs-esm-cohort-builder-app.js"
15
-
16
- jobs:
17
- build:
18
- runs-on: ubuntu-latest
19
-
20
- steps:
21
- - uses: actions/checkout@v2
22
- - name: Use Node.js
23
- uses: actions/setup-node@v1
24
- with:
25
- node-version: "16.x"
26
- - run: yarn
27
- - run: yarn lint
28
- - run: yarn coverage
29
- - run: yarn typescript
30
- - run: yarn build
31
- - name: Upload Artifacts
32
- uses: actions/upload-artifact@v2
33
- with:
34
- name: dist
35
- path: |
36
- dist
37
-
38
- pre_release:
39
- runs-on: ubuntu-latest
40
-
41
- needs: build
42
-
43
- if: ${{ github.event_name == 'push' }}
44
-
45
- steps:
46
- - uses: actions/checkout@v2
47
- - name: Download Artifacts
48
- uses: actions/download-artifact@v2
49
- - name: Use Node.js
50
- uses: actions/setup-node@v1
51
- with:
52
- node-version: "18"
53
- registry-url: "https://registry.npmjs.org"
54
- - run: yarn install --immuatable
55
- - run: yarn version --new-version "$(node -e "console.log(require('semver').inc(require('./package.json').version, 'patch'))")-pre.${{ github.run_number }}" --no-git-tag-version
56
- - run: yarn build
57
- - run: yarn publish --access public --tag next
58
- env:
59
- NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
60
-
61
- release:
62
- runs-on: ubuntu-latest
63
-
64
- needs: build
65
-
66
- if: ${{ github.event_name == 'release' }}
67
-
68
- steps:
69
- - uses: actions/checkout@v2
70
- - name: Download Artifacts
71
- uses: actions/download-artifact@v2
72
- - name: Use Node.js
73
- uses: actions/setup-node@v1
74
- with:
75
- node-version: "16.x"
76
- registry-url: 'https://registry.npmjs.org'
77
- - run: yarn
78
- - run: yarn publish --access public
79
- env:
80
- NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
81
-
82
- deploy:
83
- runs-on: ubuntu-latest
84
-
85
- needs: pre_release
86
-
87
- if: ${{ github.event_name == 'push' }}
88
-
89
- steps:
90
- - name: Trigger RefApp Build
91
- uses: fjogeleit/http-request-action@master
92
- with:
93
- url: https://ci.openmrs.org/rest/api/latest/queue/REFAPP-D3X
94
- method: "POST"
95
- customHeaders: '{ "Authorization": "Bearer ${{ secrets.BAMBOO_TOKEN }}" }'
package/.husky/pre-commit DELETED
@@ -1,6 +0,0 @@
1
- #!/bin/sh
2
- . "$(dirname "$0")/_/husky.sh"
3
-
4
- set -e # die on error
5
-
6
- npx pretty-quick --staged
package/.husky/pre-push DELETED
@@ -1,6 +0,0 @@
1
- #!/bin/sh
2
- . "$(dirname "$0")/_/husky.sh"
3
-
4
- set -e # die on error
5
-
6
- yarn verify
package/.prettierignore DELETED
@@ -1,14 +0,0 @@
1
- # directories
2
- .husky/
3
- dist/
4
- node_modules/
5
-
6
- # dotfiles and generated
7
- .*
8
- yarn.lock
9
-
10
- # by file type
11
- **/*.css
12
- **/*.scss
13
- **/*.md
14
- **/*.json
@@ -1,57 +0,0 @@
1
- /** At present, this entire mock is boilerplate. */
2
-
3
- const React = require("react");
4
-
5
- const reactI18next = require("react-i18next");
6
-
7
- const hasChildren = (node) =>
8
- node && (node.children || (node.props && node.props.children));
9
-
10
- const getChildren = (node) =>
11
- node && node.children ? node.children : node.props && node.props.children;
12
-
13
- const renderNodes = (reactNodes) => {
14
- if (typeof reactNodes === "string") {
15
- return reactNodes;
16
- }
17
-
18
- return Object.keys(reactNodes).map((key, i) => {
19
- const child = reactNodes[key];
20
- const isElement = React.isValidElement(child);
21
-
22
- if (typeof child === "string") {
23
- return child;
24
- }
25
- if (hasChildren(child)) {
26
- const inner = renderNodes(getChildren(child));
27
- return React.cloneElement(child, { ...child.props, key: i }, inner);
28
- }
29
- if (typeof child === "object" && !isElement) {
30
- return Object.keys(child).reduce(
31
- (str, childKey) => `${str}${child[childKey]}`,
32
- ""
33
- );
34
- }
35
-
36
- return child;
37
- });
38
- };
39
-
40
- const useMock = [(k) => k, {}];
41
- useMock.t = (k, o) => (o && o.defaultValue) || (typeof o === "string" ? o : k);
42
- useMock.i18n = {};
43
-
44
- module.exports = {
45
- // this mock makes sure any components using the translate HoC receive the t function as a prop
46
- Trans: ({ children }) => renderNodes(children),
47
- Translation: ({ children }) => children((k) => k, { i18n: {} }),
48
- useTranslation: () => useMock,
49
-
50
- // mock if needed
51
- I18nextProvider: reactI18next.I18nextProvider,
52
- initReactI18next: reactI18next.initReactI18next,
53
- setDefaults: reactI18next.setDefaults,
54
- getDefaults: reactI18next.getDefaults,
55
- setI18n: reactI18next.setI18n,
56
- getI18n: reactI18next.getI18n,
57
- };
package/jest.config.json DELETED
@@ -1,21 +0,0 @@
1
-
2
-
3
- {
4
- "transform": {
5
- "^.+\\.tsx?$": "@swc/jest"
6
- },
7
- "transformIgnorePatterns": ["/node_modules/(?!@openmrs)"],
8
- "moduleNameMapper": {
9
- "\\.(s?css)$": "identity-obj-proxy",
10
- "@openmrs/esm-framework": "@openmrs/esm-framework/mock",
11
- "^lodash-es/(.*)$": "lodash/$1",
12
- "^uuid$": "<rootDir>/node_modules/uuid/dist/index.js"
13
- },
14
- "setupFilesAfterEnv": [
15
- "<rootDir>/src/setup-tests.ts"
16
- ],
17
- "testEnvironment": "jsdom",
18
- "testEnvironmentOptions": {
19
- "url": "http://localhost/"
20
- }
21
- }
@@ -1,119 +0,0 @@
1
- {
2
- "searchResults": "Search Results",
3
- "searchHistory": "Search History",
4
- "clearHistory": "Clear Search History",
5
- "concepts": "Concepts",
6
- "demographics": "Demographics",
7
- "encounters": "Encounters",
8
- "enrollments": "Enrollments",
9
- "drugOrder": "Drug Order",
10
- "composition": "Composition",
11
- "savedDefinitions": "Saved Definitions",
12
- "reset": "Reset",
13
- "search": "Search",
14
- "loading": "Loading",
15
- "dateRange": "Date Range",
16
- "searchByConcepts": "Search By Concepts",
17
- "whatObservations": "What observations",
18
- "whatValues": "What values",
19
- "lastDays": "and / or days",
20
- "previousPage": "Previous page",
21
- "nextPage": "Next page",
22
- "itemsPerPage:": "Items per page:",
23
- "clearSearch": "Clear search",
24
- "searchConcepts": "Search Concepts",
25
- "noSearchItems": "There are no search items",
26
- "whoseAnswer": "Patients with observations whose answer is ",
27
- "name": "Name",
28
- "age": "Age",
29
- "ageBetween": "Age between",
30
- "gender": "Gender",
31
- "openmrsId": "OpenMRS ID",
32
- "numberIsNotValid": "Number is not valid",
33
- "startDate": "Start date",
34
- "endDate": "End date",
35
- "query": "Query",
36
- "results": "Results",
37
- "haveObservations": "Patients who have these observations",
38
- "haveNoObservations": "Patients who do not have these observations",
39
- "any": "Any",
40
- "none": "None",
41
- "earliest": "Earliest",
42
- "recent": "Most Recent",
43
- "lowest": "Lowest",
44
- "highest": "Highest",
45
- "average": "Average",
46
- "withinTheLast": "Within the last",
47
- "valueIn": "Enter a value in ",
48
- "searchItemDeleteError": "Error deleting the search item",
49
- "cohortCreateSuccess": "Successfully created the cohort",
50
- "cohortCreateError": "Error creating the cohort",
51
- "delete": "Delete",
52
- "deleteFromHistory": "Delete from history",
53
- "save": "Save",
54
- "view": "View",
55
- "clear": "Clear",
56
- "cancel": "Cancel",
57
- "saveCohort": "Save Cohort",
58
- "saveQuery": "Save Query",
59
- "downloadResults": "Download Results",
60
- "saveName": "Enter a name",
61
- "saveDescription": "Enter a description",
62
- "clearHistoryMsg": "Are you sure you want to clear the search history?",
63
- "deleteHistoryItem": "Are you sure you want to delete {{searchItemName}} from the search history?",
64
- "searchIsCompleted": "Search is completed with {{numOfResults}} result(s)",
65
- "cohortBuilder": "Cohort Builder",
66
- "searchCriteria": "Search Criteria",
67
- "all": "All",
68
- "males": "Male",
69
- "females": "Female",
70
- "dead": "Dead",
71
- "alive": "Alive",
72
- "minAgeIsNotValid": "The age must be greater than 0",
73
- "maxAgeIsNotValid": "The age must be less than 200",
74
- "between": "Between",
75
- "and": "and",
76
- "birthDate": "Birth date",
77
- "selectedAttributeValues": "Enter Comma Delimited Values",
78
- "selectAttribute": "Select a person attribute",
79
- "location": "Location",
80
- "personAttributes": "Person Attributes",
81
- "selectEncounterTypes": "Select encounter types",
82
- "selectForms": "Select forms",
83
- "selectLocations": "Select locations",
84
- "atLeast": "at least many",
85
- "upto": "upto this many",
86
- "from": "From",
87
- "to": "to",
88
- "anyEncounter": "Any Encounter",
89
- "mostRecentEncounter": "Most Recent Encounter",
90
- "earliestEncounter": "Earliest Encounter",
91
- "selectMethod": "Select a method",
92
- "selectPrograms": "Select programs",
93
- "enrolledBetween": "Enrolled between",
94
- "completedBetween": "Completed between",
95
- "success": "Success",
96
- "cohortIsDeleted": "the cohort is deleted",
97
- "queryIsDeleted": "the query is deleted",
98
- "querySavingError": "Error saving the query",
99
- "cohortViewError": "Error viewing the cohort",
100
- "cohortDeleteError": "Error deleting the cohort",
101
- "queryDeleteError": "Error deleting the query",
102
- "deleteItem": "Are you sure you want to delete {{itemName}}?",
103
- "id": "id",
104
- "searchCohorts": "Search Cohorts",
105
- "searchCompleted": "Search is completed",
106
- "savedCohortDescription": "You can only search for Cohort Definitions that you have saved using a Name.",
107
- "savedQueryDescription": "You can only search for Query Definitions that you have saved using a Name.",
108
- "somethingWentWrong": "Something went wrong",
109
- "selectDrugs": "Select drugs",
110
- "selectCareSettings": "Select a care setting",
111
- "using": "Using between",
112
- "used": "Used between",
113
- "searchQueries": "Search Queries",
114
- "description": "Description",
115
- "compositionExplanationOne": "This query combines multiple cohorts using the logical operators:- AND,OR and NOT.",
116
- "compositionExplanationTwo": "To use this query you need to already have query results in your search history. Those existing query results can then be combined to yield the results of the composition query.",
117
- "compositionExplanationThree": "Example: if the search history #1 is a cohort of patients who are males, and if the search history #2 is a cohort of patients with ages between 23 and 35 years; then '1 AND 2' will result in a cohort of patients who are males with ages between 23 and 35 years.",
118
- "invalidComposition": "Composition is not valid"
119
- }
package/tsconfig.json DELETED
@@ -1,23 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "esModuleInterop": true,
4
- "module": "esnext",
5
- "allowSyntheticDefaultImports": true,
6
- "jsx": "react",
7
- "skipLibCheck": true,
8
- "moduleResolution": "node",
9
- "lib": [
10
- "dom",
11
- "es5",
12
- "scripthost",
13
- "es2015",
14
- "es2015.promise",
15
- "es2016.array.include",
16
- "es2018",
17
- "es2020"
18
- ],
19
- "resolveJsonModule": true,
20
- "noEmit": true,
21
- "target": "esnext"
22
- }
23
- }
package/webpack.config.js DELETED
@@ -1,4 +0,0 @@
1
- const config = (module.exports = require("openmrs/default-webpack-config"));
2
- config.scriptRuleConfig.exclude =
3
- /(node_modules(?![/\\]@openmrs\/esm-patient-common-lib))/;
4
- module.exports = config;