Skip to content

Commit

Permalink
Merge pull request #264 from os2display/feature/2321-checkbox-options
Browse files Browse the repository at this point in the history
Added checkbox options component for use in calendar modifiers
  • Loading branch information
tuj authored Nov 22, 2024
2 parents 7e794a0 + 5ee46c5 commit e1f2fa3
Show file tree
Hide file tree
Showing 39 changed files with 475 additions and 268 deletions.
5 changes: 5 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
"plugin:prettier/recommended"
],
"ignorePatterns": ["*.yml"],
"globals": {
"window": true,
"localStorage": true,
"document": true
},
"parser": "babel-eslint",
"parserOptions": {
"sourceType": "module",
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
run: |
docker network create frontend
docker compose run --rm node yarn install
docker compose run --rm node yarn check-coding-standards
docker compose run --rm node yarn check-coding-standards-actions
playwright-tests:
name: Playwright
Expand Down
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

- [#264](https://github.com/os2display/display-admin-client/pull/264)
- Added checkbox options component for use in calendar modifiers.
- Fixed multiselect when more than one feed source of the given type is installed.
- Fixed github action to fail on warnings.
- [#268](https://github.com/os2display/display-admin-client/pull/268)
- Added feed source UI.

Expand All @@ -23,8 +27,6 @@ All notable changes to this project will be documented in this file.
- Add validation checking if template is selected on slide before save
- [#260](https://github.com/os2display/display-admin-client/pull/260)
- Bug in multiselect, fixed by removing duplicates by key both `@id`and `id`
- [#265](https://github.com/os2display/display-admin-client/pull/265)
- Bug in multiselect, fixed by removing duplicates by key both `@id`and `id`
- [#259](https://github.com/os2display/display-admin-client/pull/259)
- Add saving of playlists/groups with screen (as opposed to _after_)
- Clean up `screen-manager.jsx`
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,14 @@
},
"scripts": {
"lint:js": "eslint --ext .js --ext .jsx ./src",
"lint-actions:js": "eslint --ext .js --ext .jsx ./src --max-warnings=0",
"lint:js:fix": "eslint --ext .js --ext .jsx --fix ./src",
"lint:scss": "stylelint \"./src/**/*.scss\"",
"lint-actions:scss": "stylelint \"./src/**/*.scss\" --max-warnings=0",
"lint:scss:fix": "stylelint --fix \"./src/**/*.scss\"",
"check-coding-standards": "yarn lint:js && yarn lint:scss",
"apply-coding-standards": "yarn lint:js:fix && yarn lint:scss:fix",
"check-coding-standards-actions": "yarn lint-actions:js && yarn lint-actions:scss",
"start": "vite --host 0.0.0.0",
"build": "vite build",
"preview": "vite preview"
Expand Down
54 changes: 33 additions & 21 deletions src/components/feed-sources/feed-source-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import FormSelect from "../util/forms/select";
import ContentBody from "../util/content-body/content-body";
import ContentFooter from "../util/content-footer/content-footer";
import FormInput from "../util/forms/form-input";
import CalendarFeedType from "./templates/calendar-feed-type.jsx";
import NotifiedFeedType from "./templates/notified-feed-type.jsx";
import EventDatabaseFeedType from "./templates/event-database-feed-type.jsx";
import CalendarApiFeedType from "./templates/calendar-api-feed-type";
import NotifiedFeedType from "./templates/notified-feed-type";
import EventDatabaseApiFeedType from "./templates/event-database-feed-type";

/**
* The feed-source form component.
Expand All @@ -22,13 +22,14 @@ import EventDatabaseFeedType from "./templates/event-database-feed-type.jsx";
* @param {Function} props.handleInput Handles form input.
* @param {Function} props.handleSubmit Handles form submit.
* @param {string} props.headerText Headline text.
* @param {boolean} [props.isLoading=false] Indicator of whether the form is
* loading. Default is `false`
* @param {string} [props.loadingMessage=""] The loading message for the
* spinner. Default is `""`
* @param {object} props.feedSource The feed source object
* @param {boolean} [props.isLoading] Indicator of whether the form is loading.
* Default is `false`
* @param {string} [props.loadingMessage] The loading message for the spinner.
* Default is `""`
* @param {object} props.feedSourceTypeOptions The options for feed source types
* @param {string} props.mode The mode
* @param {Function} props.onFeedTypeChange Callback on feed type change.
* @param {Function} props.handleSecretInput Callback on secret input change.
* @returns {object} The feed-source form.
*/
function FeedSourceForm({
Expand Down Expand Up @@ -81,15 +82,28 @@ function FeedSourceForm({
options={feedSourceTypeOptions}
/>

{feedSource?.feedType === "App\\Feed\\CalendarApiFeedType" &&
(<CalendarFeedType handleInput={handleSecretInput} formStateObject={feedSource.secrets} mode={mode} />)
}
{feedSource?.feedType === "App\\Feed\\NotifiedFeedType" &&
(<NotifiedFeedType handleInput={handleSecretInput} formStateObject={feedSource.secrets} mode={mode} />)
}
{feedSource?.feedType === "App\\Feed\\EventDatabaseApiFeedType" &&
(<EventDatabaseFeedType handleInput={handleSecretInput} formStateObject={feedSource.secrets} mode={mode} />)
}
{feedSource?.feedType === "App\\Feed\\CalendarApiFeedType" && (
<CalendarApiFeedType
handleInput={handleSecretInput}
formStateObject={feedSource.secrets}
mode={mode}
feedSourceId={feedSource["@id"]}
/>
)}
{feedSource?.feedType === "App\\Feed\\EventDatabaseApiFeedType" && (
<EventDatabaseApiFeedType
handleInput={handleSecretInput}
formStateObject={feedSource.secrets}
mode={mode}
/>
)}
{feedSource?.feedType === "App\\Feed\\NotifiedFeedType" && (
<NotifiedFeedType
handleInput={handleSecretInput}
formStateObject={feedSource.secrets}
mode={mode}
/>
)}
</ContentBody>
<ContentFooter>
<Button
Expand Down Expand Up @@ -126,13 +140,11 @@ FeedSourceForm.propTypes = {
}),
handleInput: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
handleSecretInput: PropTypes.func.isRequired,
onFeedTypeChange: PropTypes.func.isRequired,
headerText: PropTypes.string.isRequired,
isLoading: PropTypes.bool,
loadingMessage: PropTypes.string,
dynamicFormElement: PropTypes.oneOfType([
PropTypes.element,
PropTypes.arrayOf(PropTypes.element),
]),
feedSourceTypeOptions: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.string.isRequired,
Expand Down
45 changes: 21 additions & 24 deletions src/components/feed-sources/feed-source-manager.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { cloneElement, React, useEffect, useState } from "react";
import { React, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import PropTypes from "prop-types";
import { useNavigate } from "react-router-dom";
Expand All @@ -11,9 +11,6 @@ import {
displayError,
displaySuccess,
} from "../util/list/toast-component/display-toast";
import EventDatabaseFeedType from "./templates/event-database-feed-type.jsx";
import NotifiedFeedType from "./templates/notified-feed-type.jsx";
import CalendarFeedType from "./templates/calendar-feed-type.jsx";

/**
* The theme manager component.
Expand Down Expand Up @@ -48,7 +45,6 @@ function FeedSourceManager({
t("loading-messages.loading-feed-source")
);

const [dynamicFormElement, setDynamicFormElement] = useState();
const [submitting, setSubmitting] = useState(false);
const [formStateObject, setFormStateObject] = useState({});

Expand All @@ -68,23 +64,23 @@ function FeedSourceManager({
title: t("dynamic-fields.event-database-api-feed-type.title"),
key: "1",
secretsDefault: {
"host": ""
host: "",
},
},
{
value: "App\\Feed\\NotifiedFeedType",
title: t("dynamic-fields.notified-feed-type.title"),
key: "2",
secretsDefault: {
"token": "",
token: "",
},
},
{
value: "App\\Feed\\CalendarApiFeedType",
title: t("dynamic-fields.calendar-api-feed-type.title"),
key: "3",
key: "0",
secretsDefault: {
"resources": []
locations: [],
},
},
{
Expand All @@ -109,26 +105,29 @@ function FeedSourceManager({

/** Set loaded data into form state. */
useEffect(() => {
setFormStateObject({ ...initialState });
}, [initialState]);
const newState = { ...initialState };

const handleSecretInput = ({target}) => {
const localFormStateObject = { ...formStateObject };
if (!localFormStateObject.secrets) {
localFormStateObject.secrets = {};
if (newState.secrets instanceof Array) {
newState.secrets = {};
}
localFormStateObject.secrets[target.id] = target.value;
setFormStateObject(localFormStateObject);

setFormStateObject(newState);
}, [initialState]);

const handleSecretInput = ({ target }) => {
const secrets = { ...formStateObject.secrets };
secrets[target.id] = target.value;
setFormStateObject({ ...formStateObject, secrets });
};

const onFeedTypeChange = ({target}) => {
const value = target.value
const onFeedTypeChange = ({ target }) => {
const { value } = target;
const option = feedSourceTypeOptions.find((opt) => opt.value === value);
const newFormStateObject = {...formStateObject};
const newFormStateObject = { ...formStateObject };
newFormStateObject.feedType = value;
newFormStateObject.secrets = {...option.secretsDefault};
newFormStateObject.secrets = { ...option.secretsDefault };
setFormStateObject(newFormStateObject);
}
};

/** Save feed source. */
function saveFeedSource() {
Expand Down Expand Up @@ -193,7 +192,6 @@ function FeedSourceManager({
onFeedTypeChange={onFeedTypeChange}
handleSecretInput={handleSecretInput}
feedSourceTypeOptions={feedSourceTypeOptions}
dynamicFormElement={dynamicFormElement}
mode={saveMethod}
/>
)}
Expand Down Expand Up @@ -222,7 +220,6 @@ FeedSourceManager.propTypes = {
status: PropTypes.number,
}),
}),
mode: PropTypes.string,
};

export default FeedSourceManager;
7 changes: 3 additions & 4 deletions src/components/feed-sources/feed-sources-columns.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { React, useContext } from "react";
import { useTranslation } from "react-i18next";
import ColumnHoc from "../util/column-hoc";
import ListButton from "../util/list/list-button.jsx";
import SelectColumnHoc from "../util/select-column-hoc.jsx";
import UserContext from "../../context/user-context.jsx";
import ListButton from "../util/list/list-button";
import SelectColumnHoc from "../util/select-column-hoc";
import UserContext from "../../context/user-context";

/**
* Retrieves the columns for feed sources data based on API call response.
Expand All @@ -12,7 +12,6 @@ import UserContext from "../../context/user-context.jsx";
* @param {Function} props.apiCall - The API call function to retrieve feed sources data.
* @param {string} props.infoModalRedirect - The redirect URL for information modal.
* @param {string} props.infoModalTitle - The title for information modal.
* @param {string} props.dataKey - The key for data retrieval.
* @returns {object} Columns - An array of objects representing the columns for
* feed sources data.
*/
Expand Down
14 changes: 7 additions & 7 deletions src/components/feed-sources/feed-sources-list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import {
useDeleteV2FeedSourcesByIdMutation,
useGetV2FeedSourcesByIdSlidesQuery,
} from "../../redux/api/api.generated.ts";
import ListContext from "../../context/list-context.jsx";
import ContentBody from "../util/content-body/content-body.jsx";
import List from "../util/list/list.jsx";
import ListContext from "../../context/list-context";
import ContentBody from "../util/content-body/content-body";
import List from "../util/list/list";
import { FeedSourceColumns } from "./feed-sources-columns";
import {
displayError,
displaySuccess,
} from "../util/list/toast-component/display-toast.jsx";
import idFromUrl from "../util/helpers/id-from-url.jsx";
import UserContext from "../../context/user-context.jsx";
import useModal from "../../context/modal-context/modal-context-hook.jsx";
} from "../util/list/toast-component/display-toast";
import idFromUrl from "../util/helpers/id-from-url";
import UserContext from "../../context/user-context";
import useModal from "../../context/modal-context/modal-context-hook";

/**
* The feed sources list component.
Expand Down
55 changes: 55 additions & 0 deletions src/components/feed-sources/templates/calendar-api-feed-type.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
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";
import ConfigLoader from "../../../config-loader";

const CalendarApiFeedType = ({
feedSourceId,
handleInput,
formStateObject,
}) => {
const { t } = useTranslation("common", {
keyPrefix: "feed-source-manager.dynamic-fields.calendar-api-feed-type",
});

const [optionsEndpoint, setOptionsEndpoint] = useState(null);

useEffect(() => {
if (feedSourceId && feedSourceId !== "") {
ConfigLoader.loadConfig().then((config) => {
setOptionsEndpoint(`${config.api + feedSourceId}/config/locations`);
});
}
}, [feedSourceId]);

return (
<>
{!feedSourceId && (
<Alert className="mt-4" variant="warning">
{t("save-before-locations-can-be-set")}
</Alert>
)}
{optionsEndpoint && (
<MultiselectFromEndpoint
onChange={handleInput}
name="locations"
label={t("locations")}
value={formStateObject.locations ?? []}
optionsEndpoint={optionsEndpoint}
/>
)}
</>
);
};

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

export default CalendarApiFeedType;
37 changes: 0 additions & 37 deletions src/components/feed-sources/templates/calendar-feed-type.jsx

This file was deleted.

Loading

0 comments on commit e1f2fa3

Please sign in to comment.