Skip to content

Commit

Permalink
(chore) Various tooling tweaks (#93)
Browse files Browse the repository at this point in the history
* (chore) Various tooling tweaks

This commit includes the following changes to the tooling used in this project:

- Update ESLint config with `import` and `react-hooks` plugins
- Add turborepo for build caching and script parallelization
- Align TypeScript and Jest configs with OpenMRS standards
- Separate linting from formatting scripts so they can be run separately as described in [similar PRs](openmrs/openmrs-esm-patient-chart#1774) for other OpenMRS frontend modules
- Update Yarn to latest stable version
- Remove redundant Webpack `scriptRuleConfig` override

This aligns our tooling configuration with other OpenMRS frontend modules, improving consistency across the ecosystem.

* Prettier

* Fixup

* Review feedback
  • Loading branch information
denniskigen authored Dec 6, 2024
1 parent 91272a9 commit 16185d3
Show file tree
Hide file tree
Showing 89 changed files with 3,858 additions and 3,980 deletions.
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
**/*.d.tsx
**/*.d.ts
72 changes: 65 additions & 7 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,11 +1,69 @@
{
"env": {
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "import", "unused-imports"],
"rules": {
"unused-imports/no-unused-imports": "error",
"react-hooks/exhaustive-deps": 0,
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-unused-vars": "error"
"parserOptions": {
"project": true,
"tsconfigRootDir": "__dirname"
},
"extends": ["ts-react-important-stuff", "plugin:prettier/recommended"]
"plugins": ["@typescript-eslint", "import", "react-hooks"],
"root": true,
"rules": {
// The following rules need `noImplicitAny` to be set to `true` in our tsconfig. They are too restrictive for now, but should be reconsidered in future
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/unbound-method": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/consistent-type-exports": "error",
// Use `import type` instead of `import` for type imports
"@typescript-eslint/consistent-type-imports": [
"error",
{
"fixStyle": "inline-type-imports"
}
],
"import/no-duplicates": "error",
"no-console": ["error", { "allow": ["warn", "error"] }],
"no-restricted-imports": [
"error",
{
"paths": [
// These two rules ensure that we're importing lodash and lodash-es correctly. Not doing so can bloat our bundle size significantly.
{
"name": "lodash",
"message": "Import specific methods from `lodash`. e.g. `import map from 'lodash/map'`"
},
{
"name": "lodash-es",
"importNames": ["default"],
"message": "Import specific methods from `lodash-es`. e.g. `import { map } from 'lodash-es'`"
},
// These two rules ensure that we're importing Carbon components and icons from the correct packages (after v10). May be removed in the future.
{
"name": "carbon-components-react",
"message": "Import from `@carbon/react` directly. e.g. `import { Toggle } from '@carbon/react'`"
},
{
"name": "@carbon/icons-react",
"message": "Import from `@carbon/react/icons`. e.g. `import { ChevronUp } from '@carbon/react/icons'`"
}
]
}
],
"react-hooks/exhaustive-deps": "warn",
"react-hooks/rules-of-hooks": "error"
}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,5 @@ dist/
/playwright-report/
/playwright/.cache/
e2e/storageState.json

.turbo
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

set -e # die on error

npx pretty-quick --staged
npx lint-staged
2 changes: 0 additions & 2 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,5 @@ node_modules/
yarn.lock

# by file type
**/*.css
**/*.scss
**/*.md
**/*.json
894 changes: 0 additions & 894 deletions .yarn/releases/yarn-4.2.2.cjs

This file was deleted.

934 changes: 934 additions & 0 deletions .yarn/releases/yarn-4.5.3.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ enableGlobalCache: false

nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.2.2.cjs
yarnPath: .yarn/releases/yarn-4.5.3.cjs
4 changes: 3 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
module.exports = {
clearMocks: true,
transform: {
"^.+\\.tsx?$": "@swc/jest",
},
transformIgnorePatterns: ["/node_modules/(?!@openmrs)"],
moduleNameMapper: {
"\\.(s?css)$": "identity-obj-proxy",
"@openmrs/esm-framework": "@openmrs/esm-framework/mock",
"^dexie$": require.resolve("dexie"),
"^lodash-es/(.*)$": "lodash/$1",
"^lodash-es$": "lodash",
"^uuid$": "<rootDir>/node_modules/uuid/dist/index.js",
"^dexie$": require.resolve("dexie"),
},
setupFilesAfterEnv: ["<rootDir>/src/setup-tests.ts"],
testEnvironment: "jsdom",
Expand Down
35 changes: 19 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@openmrs/esm-cohort-builder-app",
"version": "4.0.0",
"license": "MPL-2.0",
"description": "A microfrontend for OpenMRS cohorts",
"description": "O3 frontend module for managing cohorts",
"browser": "dist/openmrs-esm-cohort-builder-app.js",
"main": "src/index.ts",
"source": true,
Expand All @@ -12,9 +12,10 @@
"build": "webpack --mode production",
"analyze": "webpack --mode=production --env.analyze=true",
"lint": "eslint src --ext js,jsx,ts,tsx",
"prettier": "prettier --write \"src/**/*.{ts,tsx}\"",
"prettier": "prettier --write \"src/**/*.{css,scss,ts,tsx}\"",
"typescript": "tsc",
"test": "jest --config jest.config.js --verbose",
"test:watch": "jest --config jest.config.js --watch",
"test-e2e": "playwright test",
"verify": "concurrently 'yarn:lint' 'yarn:test' 'yarn:typescript'",
"coverage": "yarn test -- --coverage",
Expand Down Expand Up @@ -53,6 +54,10 @@
"react-dom": "18.x",
"react-i18next": "11.x"
},
"dependencies": {
"classnames": "^2.3.2",
"dotenv": "^16.3.1"
},
"devDependencies": {
"@carbon/react": "1.21.0",
"@openmrs/esm-framework": "next",
Expand All @@ -70,36 +75,34 @@
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"@types/webpack-env": "^1.18.0",
"@typescript-eslint/eslint-plugin": "^5.51.0",
"@typescript-eslint/parser": "^5.51.0",
"@typescript-eslint/eslint-plugin": "^7.9.0",
"@typescript-eslint/parser": "^7.9.0",
"concurrently": "^7.6.0",
"css-loader": "^6.7.3",
"dayjs": "^1.11.7",
"eslint": "^8.33.0",
"eslint-config-prettier": "^8.6.0",
"eslint-config-ts-react-important-stuff": "^3.0.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-unused-imports": "^2.0.0",
"eslint": "^8.50.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-react-hooks": "^5.0.0",
"husky": "^8.0.3",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.4.2",
"jest-cli": "^29.4.2",
"jest-environment-jsdom": "^29.4.2",
"lint-staged": "^15.2.10",
"openmrs": "next",
"prettier": "^2.8.4",
"pretty-quick": "^3.1.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^12.1.5",
"swc-loader": "^0.2.3",
"turbo": "^2.3.3",
"typescript": "^4.9.5",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
},
"packageManager": "[email protected]",
"dependencies": {
"classnames": "^2.3.2",
"dotenv": "^16.3.1"
}
"lint-staged": {
"*.{ts,tsx}": "eslint --cache --fix --max-warnings 0",
"*.{css,scss,ts,tsx}": "prettier --write --list-different"
},
"packageManager": "[email protected]"
}
8 changes: 8 additions & 0 deletions prettier.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
bracketSpacing: true,
printWidth: 120,
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: 'all',
};
18 changes: 7 additions & 11 deletions src/cohort-builder-admin-link.component.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import React from "react";
import { useTranslation } from "react-i18next";
import { Layer, ClickableTile } from "@carbon/react";
import { ArrowRight } from "@carbon/react/icons";
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Layer, ClickableTile } from '@carbon/react';
import { ArrowRight } from '@carbon/react/icons';

const CohortBuilderAdminLink: React.FC = () => {
const { t } = useTranslation();
return (
<Layer>
<ClickableTile
href={`${window.spaBase}/cohort-builder`}
target="_blank"
rel="noopener noreferrer"
>
<ClickableTile href={`${window.spaBase}/cohort-builder`} target="_blank" rel="noopener noreferrer">
<div>
<div className="heading">{t("manageCohorts", "Manage Cohorts")}</div>
<div className="content">{t("cohortBuilder", "Cohort Builder")}</div>
<div className="heading">{t('manageCohorts', 'Manage Cohorts')}</div>
<div className="content">{t('cohortBuilder', 'Cohort Builder')}</div>
</div>
<div className="iconWrapper">
<ArrowRight size={16} />
Expand Down
35 changes: 12 additions & 23 deletions src/cohort-builder.resources.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import {
openmrsFetch,
FetchResponse,
restBaseUrl,
} from "@openmrs/esm-framework";
import useSWRImmutable from "swr/immutable";

import { Patient, SearchParams, DropdownValue, Response } from "./types";
import useSWRImmutable from 'swr/immutable';
import { openmrsFetch, restBaseUrl, type FetchResponse } from '@openmrs/esm-framework';
import type { Patient, SearchParams, DropdownValue, Response } from './types';

/**
* @param searchParams query details
Expand All @@ -19,10 +14,10 @@ export const search = async (searchParams: SearchParams) => {
const searchResults: FetchResponse<SearchResults> = await openmrsFetch(
`${restBaseUrl}/reportingrest/adhocquery?v=full`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: searchParams.query,
}
},
);
return searchResults;
};
Expand Down Expand Up @@ -52,12 +47,9 @@ export const useLocations = () => {
};

export const getDataSet = async (queryID: string) => {
const results: FetchResponse<SearchResults> = await openmrsFetch(
`${restBaseUrl}/reportingrest/dataSet/${queryID}`,
{
method: "GET",
}
);
const results: FetchResponse<SearchResults> = await openmrsFetch(`${restBaseUrl}/reportingrest/dataSet/${queryID}`, {
method: 'GET',
});

const dataset = results.data.rows.map((patient: Patient) => {
patient.id = patient.patientId.toString();
Expand All @@ -70,12 +62,9 @@ export const getDataSet = async (queryID: string) => {
};

export const getCohortMembers = async (cohortId: string) => {
const results: FetchResponse<SearchResults> = await openmrsFetch(
`${restBaseUrl}/cohort/${cohortId}/member?v=full`,
{
method: "GET",
}
);
const results: FetchResponse<SearchResults> = await openmrsFetch(`${restBaseUrl}/cohort/${cohortId}/member?v=full`, {
method: 'GET',
});

const dataset = results.data.rows.map((patient: Patient) => {
patient.id = patient.patientId.toString();
Expand Down
13 changes: 7 additions & 6 deletions src/cohort-builder.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
.heading {
@include type.type-style('productive-heading-02');
color: $text-02;
margin-bottom: spacing.$spacing-05;;
margin-bottom: spacing.$spacing-05;
}

.heading:after {
content: "";
content: '';
display: block;
width: 2rem;
padding-top: 0.188rem;
Expand Down Expand Up @@ -47,7 +47,7 @@
}

:global(.cds--inline-loading__text) {
color: white
color: white;
}

:global(.cds--tab--list) {
Expand Down Expand Up @@ -76,7 +76,8 @@
}

:global(.cds--tabs__nav-link) {
&:active, &:focus {
&:active,
&:focus {
outline: 0 !important;
outline-offset: 0 !important;
}
Expand Down Expand Up @@ -121,6 +122,6 @@
}

.text {
font-size: 0.9rem;
padding: 0.5rem;
font-size: 0.9rem;
padding: 0.5rem;
}
11 changes: 4 additions & 7 deletions src/cohort-builder.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import React from "react";
import React from 'react';
import { render } from '@testing-library/react';
import CohortBuilder from './cohort-builder';

import { render, cleanup } from "@testing-library/react";

import CohortBuilder from "./cohort-builder";

describe("Test the cohort builder", () => {
afterEach(cleanup);
describe('Test the cohort builder', () => {
it(`renders without dying`, () => {
render(<CohortBuilder />);
});
Expand Down
Loading

0 comments on commit 16185d3

Please sign in to comment.