Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ All notable changes to this project will be documented in this file.
* Updated PHP dependencies.
* Added Playwright github action.
* Changed how templates are imported.
* Removed propTypes.
* Upgraded redux-toolkit and how api slices are generated.
* Fixed redux-toolkit cache handling.

### NB! Prior to 3.x the project was split into separate repositories

Expand Down
37 changes: 34 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Development

```bash
docker compose pull
docker compose pull
docker compose up --detach
docker compose exec phpfpm composer install
docker compose run --rm node npm install
Expand All @@ -25,15 +25,46 @@ The fixtures have the image-text template, and two screen layouts: full screen a

TODO

## Documentation
## API specification and generated code

When the API is changed a new OpenAPI specification should be generated that reflects the changes to the API.

To generate the updated API specification, run the following command:

```shell
docker compose exec phpfpm composer update-api-spec
```

This will generate `public/api-spec-v2.json` and `public/api-spec-v2.yaml`.

This generated API specification is used to generate
[Redux Toolkit RTK Query](https://redux-toolkit.js.org/rtk-query/overview) code for interacting with the API.

To generate the Redux Toolkit RTK Query code, run the following command:

```shell
docker compose exec node npx @rtk-query/codegen-openapi /app/assets/shared/redux/openapi-config.js
```

This will generate `assets/shared/redux/generated-api.ts`. This generated code is enhanced by the custom file
`assets/shared/redux/enhanced-api.ts`.

### Important

If new endpoints are added to the API, `assets/shared/redux/enhanced-api.ts` should be modified to reflect changes in
Redux-Toolkit cache invalidation and new hooks should be added.

See
[https://redux-toolkit.js.org/rtk-query/usage/code-generation](https://redux-toolkit.js.org/rtk-query/usage/code-generation)
for information about the code generation.

## Tests

### API tests

TODO

### Admin / Client tests
### Admin and Client tests

To run tests, use the script:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import Form from "react-bootstrap/Form";
import { Button } from "react-bootstrap";
import { usePostV2UserActivationCodesActivateMutation } from "../../redux/api/api.generated.ts";
import { usePostV2UserActivationCodesActivateMutation } from "../../../shared/redux/enhanced-api.ts";
import {
displaySuccess,
displayError,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { React, useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { usePostV2UserActivationCodesMutation } from "../../redux/api/api.generated.ts";
import { usePostV2UserActivationCodesMutation } from "../../../shared/redux/enhanced-api.ts";
import ActivationCodeForm from "./activation-code-form";
import {
displaySuccess,
Expand Down Expand Up @@ -64,7 +64,7 @@ function ActivationCodeCreate() {
};

PostV2UserActivationCode({
userActivationCodeUserActivationCodeInput: JSON.stringify(saveData),
userActivationCodeUserActivationCodeInputJsonld: JSON.stringify(saveData),
});
};

Expand Down
13 changes: 0 additions & 13 deletions assets/admin/components/activation-code/activation-code-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { React } from "react";
import { useNavigate } from "react-router-dom";
import { Button, Col, Row } from "react-bootstrap";
import { useTranslation } from "react-i18next";
import PropTypes from "prop-types";
import Form from "react-bootstrap/Form";
import LoadingComponent from "../util/loading-component/loading-component";
import ContentBody from "../util/content-body/content-body";
Expand Down Expand Up @@ -107,16 +106,4 @@ function ActivationCodeForm({
);
}

ActivationCodeForm.propTypes = {
activationCode: PropTypes.shape({
displayName: PropTypes.string.isRequired,
role: PropTypes.string.isRequired,
}).isRequired,
handleInput: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
headerText: PropTypes.string.isRequired,
isLoading: PropTypes.bool,
loadingMessage: PropTypes.string,
};

export default ActivationCodeForm;
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {
displayError,
} from "../util/list/toast-component/display-toast";
import {
api,
enhancedApi,
useDeleteV2UserActivationCodesByIdMutation,
useGetV2UserActivationCodesQuery,
} from "../../redux/api/api.generated.ts";
} from "../../../shared/redux/enhanced-api.ts";

/**
* The Activation Code list component.
Expand Down Expand Up @@ -135,7 +135,7 @@ function ActivationCodeList() {
}

dispatch(
api.endpoints.postV2UserActivationCodesRefresh.initiate({
enhancedApi.endpoints.postV2UserActivationCodesRefresh.initiate({
userActivationCodeActivationCode: JSON.stringify({
activationCode: item[0].code,
}),
Expand Down
5 changes: 0 additions & 5 deletions assets/admin/components/auth-handler.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { React, useContext } from "react";
import PropTypes from "prop-types";
import Login from "./user/login";
import UserContext from "../context/user-context";

Expand All @@ -20,8 +19,4 @@ function AuthHandler({ children }) {
return children;
}

AuthHandler.propTypes = {
children: PropTypes.node.isRequired,
};

export default AuthHandler;
7 changes: 0 additions & 7 deletions assets/admin/components/error-boundary.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import "./error-boundary.scss";

class ErrorBoundary extends Component {
Expand Down Expand Up @@ -38,10 +37,4 @@ class ErrorBoundary extends Component {
}
}

ErrorBoundary.propTypes = {
children: PropTypes.node.isRequired,
errorText: PropTypes.string.isRequired,
errorHandler: PropTypes.func,
};

export default ErrorBoundary;
2 changes: 1 addition & 1 deletion assets/admin/components/feed-sources/feed-source-edit.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { React } from "react";
import { useParams } from "react-router-dom";
import { useGetV2FeedSourcesByIdQuery } from "../../redux/api/api.generated.ts";
import { useGetV2FeedSourcesByIdQuery } from "../../../shared/redux/enhanced-api.ts";
import FeedSourceManager from "./feed-source-manager";

/**
Expand Down
27 changes: 0 additions & 27 deletions assets/admin/components/feed-sources/feed-source-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { React } from "react";
import { Alert, Button, Row, Col } from "react-bootstrap";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import PropTypes from "prop-types";
import Form from "react-bootstrap/Form";
import LoadingComponent from "../util/loading-component/loading-component";
import FormInputArea from "../util/forms/form-input-area";
Expand Down Expand Up @@ -185,30 +184,4 @@ function FeedSourceForm({
);
}

FeedSourceForm.propTypes = {
feedSource: PropTypes.shape({
title: PropTypes.string,
description: PropTypes.string,
feedType: PropTypes.string,
supportedFeedOutputType: PropTypes.string,
}),
handleInput: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
handleSaveNoClose: PropTypes.func.isRequired,
handleSecretInput: PropTypes.func.isRequired,
onFeedTypeChange: PropTypes.func.isRequired,
headerText: PropTypes.string.isRequired,
isLoading: PropTypes.bool,
loadingMessage: PropTypes.string,
feedSourceTypeOptions: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.string.isRequired,
title: PropTypes.string,
key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
template: PropTypes.element,
})
).isRequired,
mode: PropTypes.string,
};

export default FeedSourceForm;
30 changes: 3 additions & 27 deletions assets/admin/components/feed-sources/feed-source-manager.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { React, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import PropTypes from "prop-types";
import { useNavigate } from "react-router-dom";
import FeedSourceForm from "./feed-source-form";
import {
usePostV2FeedSourcesMutation,
usePutV2FeedSourcesByIdMutation,
} from "../../redux/api/api.generated.ts";
} from "../../../shared/redux/enhanced-api.ts";
import {
displayError,
displaySuccess,
Expand Down Expand Up @@ -157,11 +156,11 @@ function FeedSourceManager({

if (saveMethod === "POST") {
postV2FeedSources({
feedSourceFeedSourceInput: JSON.stringify(formStateObject),
feedSourceFeedSourceInputJsonld: JSON.stringify(formStateObject),
});
} else if (saveMethod === "PUT") {
PutV2FeedSourcesById({
feedSourceFeedSourceInput: JSON.stringify(formStateObject),
feedSourceFeedSourceInputJsonld: JSON.stringify(formStateObject),
id,
});
}
Expand Down Expand Up @@ -236,27 +235,4 @@ function FeedSourceManager({
);
}

FeedSourceManager.propTypes = {
initialState: PropTypes.shape({
title: PropTypes.string,
description: PropTypes.string,
feedType: PropTypes.string,
feedSourceType: PropTypes.string,
host: PropTypes.string,
token: PropTypes.string,
baseUrl: PropTypes.string,
clientId: PropTypes.string,
clientSecret: PropTypes.string,
feedSources: PropTypes.string,
}),
saveMethod: PropTypes.string.isRequired,
id: PropTypes.string,
isLoading: PropTypes.bool,
loadingError: PropTypes.shape({
data: PropTypes.shape({
status: PropTypes.number,
}),
}),
};

export default FeedSourceManager;
2 changes: 1 addition & 1 deletion assets/admin/components/feed-sources/feed-sources-list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
useGetV2FeedSourcesQuery,
useDeleteV2FeedSourcesByIdMutation,
useGetV2FeedSourcesByIdSlidesQuery,
} from "../../redux/api/api.generated.ts";
} from "../../../shared/redux/enhanced-api.ts";
import ListContext from "../../context/list-context";
import ContentBody from "../util/content-body/content-body";
import List from "../util/list/list";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { React, useEffect, useState } from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import { Alert } from "react-bootstrap";
import MultiselectFromEndpoint from "../../slide/content/multiselect-from-endpoint";
Expand Down Expand Up @@ -43,12 +42,4 @@ const CalendarApiFeedType = ({
);
};

CalendarApiFeedType.propTypes = {
handleInput: PropTypes.func,
formStateObject: PropTypes.shape({
locations: PropTypes.arrayOf(PropTypes.string),
}),
feedSourceId: PropTypes.string,
};

export default CalendarApiFeedType;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { React, useEffect, useState } from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import { Alert } from "react-bootstrap";
import MultiselectFromEndpoint from "../../slide/content/multiselect-from-endpoint";
Expand Down Expand Up @@ -86,16 +85,4 @@ const ColiboFeedType = ({
);
};

ColiboFeedType.propTypes = {
handleInput: PropTypes.func,
formStateObject: PropTypes.shape({
api_base_uri: PropTypes.string,
client_id: PropTypes.string,
client_secret: PropTypes.string,
allowed_recipients: PropTypes.arrayOf(PropTypes.string),
}),
feedSourceId: PropTypes.string,
mode: PropTypes.string,
};

export default ColiboFeedType;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { React } from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import FormInput from "../../util/forms/form-input";

Expand All @@ -24,12 +23,4 @@ const EventDatabaseApiTemplate = ({ handleInput, formStateObject, mode }) => {
);
};

EventDatabaseApiTemplate.propTypes = {
handleInput: PropTypes.func,
formStateObject: PropTypes.shape({
host: PropTypes.string,
}),
mode: PropTypes.string,
};

export default EventDatabaseApiTemplate;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { React } from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import FormInput from "../../util/forms/form-input";

Expand Down Expand Up @@ -31,13 +30,4 @@ const EventDatabaseApiV2FeedType = ({ handleInput, formStateObject, mode }) => {
);
};

EventDatabaseApiV2FeedType.propTypes = {
handleInput: PropTypes.func,
formStateObject: PropTypes.shape({
host: PropTypes.string.isRequired,
apikey: PropTypes.string,
}),
mode: PropTypes.string,
};

export default EventDatabaseApiV2FeedType;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { React } from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import FormInput from "../../util/forms/form-input";

Expand All @@ -24,12 +23,4 @@ const NotifiedFeedType = ({ handleInput, formStateObject, mode }) => {
);
};

NotifiedFeedType.propTypes = {
handleInput: PropTypes.func,
formStateObject: PropTypes.shape({
token: PropTypes.string,
}),
mode: PropTypes.string,
};

export default NotifiedFeedType;
Loading