Skip to content

Commit

Permalink
Merge pull request #97 from bas-kirill/feature/openapi-countries
Browse files Browse the repository at this point in the history
feat(countries): use openapi for server side and client side
  • Loading branch information
bas-kirill authored Aug 22, 2024
2 parents cd9b332 + c9c0ddf commit 9ace0ff
Show file tree
Hide file tree
Showing 12 changed files with 180 additions and 58 deletions.
3 changes: 1 addition & 2 deletions client/src/domain/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Jwt } from "./model/jwt";
import { Role } from "./model/role";
import { InstrumentId } from "./model/instrument-id";
import type { Country, Countries } from "./model/country";
import type { Countries } from "./model/country";
import type { InstrumentName } from "./model/instrument-name";
import type {
ManufacturerName,
Expand All @@ -14,7 +14,6 @@ export {
Jwt,
Role,
InstrumentId,
Country,
Countries,
InstrumentName,
ManufacturerName,
Expand Down
3 changes: 3 additions & 0 deletions client/src/generated/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ api.ts
api/add-favorite-api.ts
api/basic-login-api.ts
api/delete-instrument-by-id-api.ts
api/get-countries-api.ts
api/get-instrument-basic-materials-api.ts
api/get-instrument-by-id-api.ts
api/get-instrument-types-api.ts
Expand All @@ -20,6 +21,8 @@ git_push.sh
index.ts
model/add-favorite-request-body.ts
model/client-error.ts
model/country.ts
model/get-countries-response.ts
model/get-instrument-basic-materials-response.ts
model/get-instrument-by-criteria-page-response.ts
model/get-instrument-criteria-request-body.ts
Expand Down
1 change: 1 addition & 0 deletions client/src/generated/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
export * from "./api/add-favorite-api";
export * from "./api/basic-login-api";
export * from "./api/delete-instrument-by-id-api";
export * from "./api/get-countries-api";
export * from "./api/get-instrument-basic-materials-api";
export * from "./api/get-instrument-by-id-api";
export * from "./api/get-instrument-types-api";
Expand Down
2 changes: 2 additions & 0 deletions client/src/generated/model/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export * from "./add-favorite-request-body";
export * from "./client-error";
export * from "./country";
export * from "./get-countries-response";
export * from "./get-instrument-basic-materials-response";
export * from "./get-instrument-by-criteria-page-response";
export * from "./get-instrument-criteria-request-body";
Expand Down
25 changes: 11 additions & 14 deletions client/src/pages/create-instrument/api/loader.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import { LoaderFunction } from "react-router-dom";
import { SERVER_URL } from "shared/config";
import { API_COUNTRIES, API_MANUFACTURERS } from "shared/config/backend";
import { API_MANUFACTURERS } from "shared/config/backend";
import axios from "axios";
import { Countries } from "domain/model/country";
import { ManufacturerNames } from "domain/model/manufacturer-name";
import { GetInstrumentTypesApi } from "generated/api/get-instrument-types-api";
import type { InstrumentBasicMaterial, InstrumentType } from "generated/model";
import type {
Country,
InstrumentBasicMaterial,
InstrumentType,
} from "generated/model";
import { GetInstrumentBasicMaterialsApi } from "generated/api/get-instrument-basic-materials-api";
import { GetCountriesApi } from "generated/api/get-countries-api";

const getInstrumentTypes = new GetInstrumentTypesApi();
const getInstrumentBasicMaterials = new GetInstrumentBasicMaterialsApi();
const getCountries = new GetCountriesApi();

export interface CreateInstrumentLoader {
instrumentTypes: InstrumentType[];
manufacturerNames: ManufacturerNames;
materials: InstrumentBasicMaterial[];
countries: Countries;
countries: Country[];
}

export const loader: LoaderFunction =
Expand All @@ -26,15 +31,7 @@ export const loader: LoaderFunction =
const instrumentBasicMaterialsRequest =
await getInstrumentBasicMaterials.getInstrumentBasicMaterials();

let countries: string[] = [];
await axios
.get<Countries>(`${SERVER_URL}${API_COUNTRIES}`)
.then((data) => {
countries = data.data;
})
.catch(() => {
throw new Error("Fail to retrieve countries");
});
const countriesRequest = await getCountries.getCountries();

let manufacturers: ManufacturerNames = [];
await axios
Expand All @@ -50,6 +47,6 @@ export const loader: LoaderFunction =
instrumentTypes: instrumentTypesRequest.data.content,
manufacturerNames: manufacturers,
materials: instrumentBasicMaterialsRequest.data.content,
countries: countries,
countries: countriesRequest.data.content,
};
};
20 changes: 7 additions & 13 deletions client/src/pages/edit-instrument/api/loader.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import { ManufacturerNames } from "domain/model/manufacturer-name";
import { Countries } from "domain/model/country";
import { LoaderFunction } from "react-router-dom";
import axios from "axios";
import { SERVER_URL } from "shared/config";
import { API_COUNTRIES, API_MANUFACTURERS } from "shared/config/backend";
import { API_MANUFACTURERS } from "shared/config/backend";
import { GetInstrumentByIdApi } from "generated/api/get-instrument-by-id-api";
import {
Country,
InstrumentBasicMaterial,
InstrumentDetail,
type InstrumentType,
} from "generated/model";
import { GetInstrumentTypesApi } from "generated/api/get-instrument-types-api";
import { GetInstrumentBasicMaterialsApi } from "generated/api/get-instrument-basic-materials-api";
import { GetCountriesApi } from "generated/api/get-countries-api";

const getInstrumentById = new GetInstrumentByIdApi();
const getInstrumentTypes = new GetInstrumentTypesApi();
const getInstrumentBasicMaterials = new GetInstrumentBasicMaterialsApi();
const getCountries = new GetCountriesApi();

export interface EditInstrumentLoader {
instrumentForEdit: InstrumentDetail;
instrumentTypes: InstrumentType[];
manufacturerNames: ManufacturerNames;
materials: InstrumentBasicMaterial[];
countries: Countries;
countries: Country[];
}

export const loader: LoaderFunction = async ({
Expand All @@ -37,15 +39,7 @@ export const loader: LoaderFunction = async ({
const instrumentBasicMaterialsRequest =
await getInstrumentBasicMaterials.getInstrumentBasicMaterials();

let countries: string[] = [];
await axios
.get<Countries>(`${SERVER_URL}${API_COUNTRIES}`)
.then((data) => {
countries = data.data;
})
.catch(() => {
throw new Error("Fail to retrieve countries");
});
const countriesRequest = await getCountries.getCountries();

let manufacturers: ManufacturerNames = [];
await axios
Expand All @@ -62,6 +56,6 @@ export const loader: LoaderFunction = async ({
instrumentTypes: instrumentTypesRequest.data.content,
manufacturerNames: manufacturers,
materials: instrumentBasicMaterialsRequest.data.content,
countries: countries,
countries: countriesRequest.data.content,
};
};
1 change: 0 additions & 1 deletion client/src/shared/config/backend.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export const SERVER_URL = "http://localhost:8080";

export const API = "/api";
export const API_COUNTRIES = `${API}/countries`;
export const API_CREATE_INSTRUMENT = `${API}/instrument/create`;
export const API_MANUFACTURERS = `${API}/manufacturers`;
14 changes: 8 additions & 6 deletions client/src/shared/model/parseInstrumentDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import { InstrumentName } from "domain/model/instrument-name";
import { ManufacturerName } from "domain/model/manufacturer-name";
import { ManufactureDate } from "domain/model/manufacture-date";
import { ReleaseDate } from "domain/model/release-date";
import { Country } from "domain/model/country";
import { InstrumentId } from "domain/model/instrument-id";
import { InstrumentType } from "generated/model/instrument-type";
import { InstrumentBasicMaterial } from "generated/model";
import { Country, InstrumentBasicMaterial } from "generated/model";

export const parseInstrumentDetails = (data: FormData) => {
const errors = [];
Expand Down Expand Up @@ -67,11 +66,14 @@ export const parseInstrumentDetails = (data: FormData) => {
errors.push("Release date must be after manufacture date");
}

const country = data.get("country");
const country = {
country: data.get("country"),
} as Country;

if (
country === null ||
typeof country !== "string" ||
manufactureDate === ""
country.country === null ||
typeof country.country !== "string" ||
country.country === ""
) {
errors.push("Type country");
}
Expand Down
29 changes: 13 additions & 16 deletions client/src/widgets/catalogue-filter/ui/CountryFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import React, { useEffect, useState } from "react";
import { ManufacturerNames } from "domain/model/manufacturer-name";
import axios from "axios";
import { SERVER_URL } from "shared/config";
import { API_COUNTRIES } from "shared/config/backend";
import { Countries } from "domain/model/country";
import { GetCountriesApi } from "generated/api/get-countries-api";
import { Country } from "generated/model";

interface Props {
onValueChange: (names: ManufacturerNames) => void;
}

const getCountries = new GetCountriesApi();

export const CountryFilter = ({ onValueChange }: Props) => {
const [countries, setCountries] = useState<Countries>([]);
const [countries, setCountries] = useState<Country[]>([]);

useEffect(() => {
axios
.get<Countries>(`${SERVER_URL}${API_COUNTRIES}`)
.then((r) => {
setCountries(r.data);
})
.catch((e) => {
throw new Error(`Failed to extract countries: '${e}'`);
});
const fetchCountries = async () => {
const response = await getCountries.getCountries();
setCountries(response.data.content);
};
fetchCountries();
}, []);

function onChange() {
Expand All @@ -39,15 +36,15 @@ export const CountryFilter = ({ onValueChange }: Props) => {
<div id="country-filter">
<legend>Country:</legend>
{countries.map((country) => (
<div key={country}>
<div key={country.country}>
<input
type="checkbox"
name={country}
name={country.country}
onChange={onChange}
className="country-filter-checkbox"
defaultChecked={true}
/>
<label htmlFor={country}>{country}</label>
<label htmlFor={country.country}>{country.country}</label>
</div>
))}
</div>
Expand Down
48 changes: 48 additions & 0 deletions openapi/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ servers:
basePath:
default: api
tags:
- name: getCountries
description: Get Countries
x-displayName: getCountries
- name: addFavorite
description: Add Favorite
x-displayName: addFavorite
Expand Down Expand Up @@ -55,6 +58,32 @@ tags:
description: User Registration
x-displayName: userRegistration
paths:
/countries:
get:
description: Get Countries
summary: Get Countries
operationId: getCountries
tags:
- getCountries
responses:
'200':
description: Country
content:
application/json:
schema:
$ref: '#/components/schemas/GetCountriesResponse'
'400':
description: Client Error
content:
application/json:
schema:
$ref: '#/components/schemas/ClientError'
default:
description: Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ServerError'
/favorite/add:
post:
description: Add Favorite
Expand Down Expand Up @@ -468,6 +497,22 @@ components:
description: A description of the error.
example:
message: Internal Server Error. Please try again later.
Country:
type: object
required:
- country
properties:
country:
type: string
GetCountriesResponse:
type: object
required:
- content
properties:
content:
type: array
items:
$ref: '#/components/schemas/Country'
AddFavoriteRequestBody:
type: object
required:
Expand Down Expand Up @@ -659,6 +704,9 @@ components:
password:
type: string
x-tagGroups:
- name: Get Countries
tags:
- getCountries
- name: Add Favorite
tags:
- addFavorite
Expand Down
Loading

0 comments on commit 9ace0ff

Please sign in to comment.