Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
63ac645
5316: add poc how to make dynamic admin forms
Aug 29, 2025
7b31088
5316: return null instead of error
sinejespersen Sep 17, 2025
ac5bcd9
5316: add tests
sinejespersen Sep 22, 2025
bdd5cb5
5316: documentation, changed names make more sense, add example of ad…
sinejespersen Sep 22, 2025
4fa4025
5316: move dropdowns out of forms folder to ready the move of forms f…
sinejespersen Sep 22, 2025
af7d2e9
5316: move forms folder as the content is shared
sinejespersen Sep 22, 2025
203b7cd
5316: fix tests, renamed imports
sinejespersen Sep 23, 2025
9d2c007
5316: inject slides to logintest
sinejespersen Sep 24, 2025
2c6e45d
5316: try slidesListJson
sinejespersen Sep 24, 2025
36670b7
imma go with video now
sinejespersen Sep 24, 2025
0f383fd
move login
sinejespersen Sep 24, 2025
f83c291
5316: fix test, inject slides into logintest, fix *templates* routes
sinejespersen Sep 26, 2025
0a641eb
5316: fix failing test
sinejespersen Sep 26, 2025
9fa3690
5316: CI: true in GA
sinejespersen Sep 26, 2025
14ebc97
5316: disable instead of remove from interface, add help texts
sinejespersen Sep 26, 2025
246b13e
6501: Fixed merge
tuj Jan 19, 2026
ad5b6f5
6501: Fixed merge
tuj Jan 19, 2026
329c709
5316: Removed duplicate file
tuj Jan 19, 2026
8d2180f
6501: Cleanup
tuj Jan 19, 2026
d31961a
Merge branch 'release/3.0.0' into feature/5316-poc-admin-form
tuj Jan 19, 2026
874bc5e
5316: Added documentation
tuj Jan 19, 2026
957817b
6501: Added renderAdminForm to all templates
tuj Jan 19, 2026
b175321
6501: Changed check for exist
tuj Jan 19, 2026
e20ac92
6501: Applied coding standards
tuj Jan 19, 2026
2be9ad5
6501: Fixed merge
tuj Jan 19, 2026
b3ec396
6501: Fixed issues with tests
tuj Jan 20, 2026
48b70ab
6501: Applied coding standards
tuj Jan 20, 2026
76c6fb8
6501: Changed to fixed time
tuj Jan 20, 2026
05374d7
6501: Changed field order
tuj Jan 20, 2026
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
2 changes: 1 addition & 1 deletion .github/workflows/playwright.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:

- name: Run playwright
env:
CI: "true"
CI: true
run: |
docker compose run --rm playwright npx playwright install --with-deps
docker compose run --rm playwright npx playwright test
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ All notable changes to this project will be documented in this file.
- Replaced lodash functions with native ones.
- Aligned environment variable names.
- Aligned with v. 2.6.0.
- Added support for component based template admin forms.

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

Expand Down
190 changes: 109 additions & 81 deletions README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from "../util/list/toast-component/display-toast";
import LoadingComponent from "../util/loading-component/loading-component";
import ContentBody from "../util/content-body/content-body";
import FormInput from "../util/forms/form-input";
import FormInput from "../../../shared/forms/form-input.jsx";
import ContentFooter from "../util/content-footer/content-footer";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { useTranslation } from "react-i18next";
import Form from "react-bootstrap/Form";
import LoadingComponent from "../util/loading-component/loading-component";
import ContentBody from "../util/content-body/content-body";
import FormInput from "../util/forms/form-input";
import RadioButtons from "../util/forms/radio-buttons";
import FormInput from "../../../shared/forms/form-input";
import RadioButtons from "../../../shared/forms/radio-buttons";
import StickyFooter from "../util/sticky-footer";

/**
Expand Down
6 changes: 3 additions & 3 deletions assets/admin/components/feed-sources/feed-source-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import Form from "react-bootstrap/Form";
import LoadingComponent from "../util/loading-component/loading-component";
import FormInputArea from "../util/forms/form-input-area";
import FormSelect from "../util/forms/select";
import FormInputArea from "../../../shared/forms/form-input-area";
import FormSelect from "../../../shared/forms/select";
import ContentBody from "../util/content-body/content-body";
import FormInput from "../util/forms/form-input";
import FormInput from "../../../shared/forms/form-input";
import CalendarApiFeedType from "./templates/calendar-api-feed-type";
import NotifiedFeedType from "./templates/notified-feed-type";
import EventDatabaseApiFeedType from "./templates/event-database-feed-type";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { useTranslation } from "react-i18next";
import FormInput from "../../util/forms/form-input";
import FormInput from "../../../../shared/forms/form-input";

const BrndFeedType = ({ handleInput, formStateObject, mode }) => {
const { t } = useTranslation("common", {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Alert } from "react-bootstrap";
import MultiselectFromEndpoint from "../../slide/content/multiselect-from-endpoint";
import FormInput from "../../util/forms/form-input";
import FormInput from "../../../../shared/forms/form-input";

const ColiboFeedType = ({
feedSourceId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useTranslation } from "react-i18next";
import FormInput from "../../util/forms/form-input";
import FormInput from "../../../../shared/forms/form-input";

const EventDatabaseApiTemplate = ({ handleInput, formStateObject, mode }) => {
const { t } = useTranslation("common", {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useTranslation } from "react-i18next";
import FormInput from "../../util/forms/form-input";
import FormInput from "../../../../shared/forms/form-input";

const EventDatabaseApiV2FeedType = ({ handleInput, formStateObject, mode }) => {
const { t } = useTranslation("common", {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useTranslation } from "react-i18next";
import FormInput from "../../util/forms/form-input";
import FormInput from "../../../../shared/forms/form-input";

const NotifiedFeedType = ({ handleInput, formStateObject, mode }) => {
const { t } = useTranslation("common", {
Expand Down
2 changes: 1 addition & 1 deletion assets/admin/components/groups/group-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Form from "react-bootstrap/Form";
import LoadingComponent from "../util/loading-component/loading-component";
import ContentBody from "../util/content-body/content-body";
import ContentFooter from "../util/content-footer/content-footer";
import FormInput from "../util/forms/form-input";
import FormInput from "../../../shared/forms/form-input";

/**
* The group form component.
Expand Down
2 changes: 1 addition & 1 deletion assets/admin/components/media/media-list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
useGetV2MediaQuery,
useDeleteV2MediaByIdMutation,
} from "../../../shared/redux/enhanced-api.ts";
import FormCheckbox from "../util/forms/form-checkbox";
import FormCheckbox from "../../../shared/forms/form-checkbox";
import "./media-list.scss";

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { SelectPlaylistColumns } from "../playlist/playlists-columns";
import PlaylistsDropdown from "../util/forms/multiselect-dropdown/playlists/playlists-dropdown";
import PlaylistsDropdown from "../util/multiselect-dropdown/playlists/playlists-dropdown";
import DragAndDropTable from "../util/drag-and-drop-table/drag-and-drop-table";
import FormCheckbox from "../util/forms/form-checkbox";
import FormCheckbox from "../../../shared/forms/form-checkbox";
import {
useGetV2PlaylistsByIdSlidesQuery,
useGetV2PlaylistsQuery,
Expand Down
6 changes: 3 additions & 3 deletions assets/admin/components/playlist/playlist-campaign-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { useNavigate } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faExpand } from "@fortawesome/free-solid-svg-icons";
import ContentBody from "../util/content-body/content-body";
import FormInput from "../util/forms/form-input";
import FormInputArea from "../util/forms/form-input-area";
import FormInput from "../../../shared/forms/form-input";
import FormInputArea from "../../../shared/forms/form-input-area";
import SelectSlidesTable from "../util/multi-and-table/select-slides-table";
import LoadingComponent from "../util/loading-component/loading-component";
import Preview from "../preview/preview";
import idFromUrl from "../util/helpers/id-from-url";
import StickyFooter from "../util/sticky-footer";
import localStorageKeys from "../util/local-storage-keys";
import Select from "../util/forms/select";
import Select from "../../../shared/forms/select";
import userContext from "../../context/user-context";

/**
Expand Down
2 changes: 1 addition & 1 deletion assets/admin/components/playlist/playlist-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import UserContext from "../../context/user-context";
import Schedule from "../util/schedule/schedule";
import { useGetV2TenantsQuery } from "../../../shared/redux/enhanced-api.ts";
import ContentBody from "../util/content-body/content-body";
import TenantsDropdown from "../util/forms/multiselect-dropdown/tenants/tenants-dropdown";
import TenantsDropdown from "../util/multiselect-dropdown/tenants/tenants-dropdown";

/**
* The playlist form component.
Expand Down
2 changes: 1 addition & 1 deletion assets/admin/components/playlist/playlist-gantt-chart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import GanttChart from "../util/gantt-chart";
import localStorageKeys from "../util/local-storage-keys";
import FormCheckbox from "../util/forms/form-checkbox";
import FormCheckbox from "../../../shared/forms/form-checkbox";

/**
* @param {object} props The props.
Expand Down
10 changes: 5 additions & 5 deletions assets/admin/components/screen/screen-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import { useNavigate } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faExpand } from "@fortawesome/free-solid-svg-icons";
import ContentBody from "../util/content-body/content-body";
import FormInput from "../util/forms/form-input";
import FormInputArea from "../util/forms/form-input-area";
import FormInput from "../../../shared/forms/form-input";
import FormInputArea from "../../../shared/forms/form-input-area";
import SelectGroupsTable from "../util/multi-and-table/select-groups-table";
import GridGenerationAndSelect from "./util/grid-generation-and-select";
import MultiSelectComponent from "../util/forms/multiselect-dropdown/multi-dropdown";
import MultiSelectComponent from "../util/multiselect-dropdown/multi-dropdown";
import idFromUrl from "../util/helpers/id-from-url";
import {
useGetV2LayoutsQuery,
enhancedApi,
} from "../../../shared/redux/enhanced-api.ts";
import FormCheckbox from "../util/forms/form-checkbox";
import FormCheckbox from "../../../shared/forms/form-checkbox";
import Preview from "../preview/preview";
import StickyFooter from "../util/sticky-footer";
import Select from "../util/forms/select";
import Select from "../../../shared/forms/select";
import userContext from "../../context/user-context";
import ScreenStatus from "./screen-status";
import { displayError } from "../util/list/toast-component/display-toast";
Expand Down
2 changes: 1 addition & 1 deletion assets/admin/components/screen/screen-status.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useDispatch } from "react-redux";
import idFromUrl from "../util/helpers/id-from-url";
import { enhancedApi } from "../../../shared/redux/enhanced-api.ts";
import { displayError } from "../util/list/toast-component/display-toast";
import FormInput from "../util/forms/form-input";
import FormInput from "../../../shared/forms/form-input";
import AdminConfigLoader from "../util/admin-config-loader.js";

/**
Expand Down
2 changes: 1 addition & 1 deletion assets/admin/components/screen/util/screen-gantt-chart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { RRule } from "rrule";
import { useTranslation } from "react-i18next";
import GanttChart from "../../util/gantt-chart";
import localStorageKeys from "../../util/local-storage-keys";
import FormCheckbox from "../../util/forms/form-checkbox";
import FormCheckbox from "../../../../shared/forms/form-checkbox";
import UserContext from "../../../context/user-context";

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Col, Row } from "react-bootstrap";
import { useTranslation } from "react-i18next";
import FileSelector from "../file-selector";
import FormInput from "../../../util/forms/form-input";
import FormInput from "../../../../../shared/forms/form-input";

/**
* Contact form.
Expand Down
31 changes: 9 additions & 22 deletions assets/admin/components/slide/content/content-form.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import FormCheckbox from "../../util/forms/form-checkbox";
import FormInput from "../../util/forms/form-input";
import Select from "../../util/forms/select";
import FormCheckbox from "../../../../shared/forms/form-checkbox";
import FormInput from "../../../../shared/forms/form-input";
import Select from "../../../../shared/forms/select";
import Contacts from "./contacts/contacts";
import RichText from "../../util/forms/rich-text/rich-text";
import FormTable from "../../util/forms/form-table/form-table";
import RichText from "../../../../shared/forms/rich-text/rich-text";
import FormTable from "../../../../shared/forms/form-table/form-table";
import FileSelector from "./file-selector";
import StationSelector from "./station/station-selector";
import RadioButtons from "../../util/forms/radio-buttons";
import CheckboxOptions from "../../util/forms/checkbox-options";
import RadioButtons from "../../../../shared/forms/radio-buttons";
import CheckboxOptions from "../../../../shared/forms/checkbox-options";
import getInputFiles from "../../../../shared/utils/helper";

/**
* Render form elements for content form.
Expand All @@ -29,20 +30,6 @@ function ContentForm({
onChange = null,
mediaData = {},
}) {
const getInputFiles = (field) => {
const inputFiles = [];

if (Array.isArray(field)) {
field.forEach((mediaId) => {
if (Object.prototype.hasOwnProperty.call(mediaData, mediaId)) {
inputFiles.push(mediaData[mediaId]);
}
});
}

return inputFiles;
};

/**
* @param {object} formData - The data for form input.
* @returns {object | string} - Returns a rendered jsx object.
Expand Down Expand Up @@ -78,7 +65,7 @@ function ContentForm({
)}

<FileSelector
files={getInputFiles(formStateObject[formData.name])}
files={getInputFiles(formStateObject[formData.name], mediaData)}
multiple={formData.multipleImages}
onFilesChange={onFileChange}
name={formData.name}
Expand Down
4 changes: 2 additions & 2 deletions assets/admin/components/slide/content/feed-selector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
enhancedApi,
useGetV2FeedSourcesQuery,
} from "../../../../shared/redux/enhanced-api.ts";
import MultiSelectComponent from "../../util/forms/multiselect-dropdown/multi-dropdown";
import MultiSelectComponent from "../../util/multiselect-dropdown/multi-dropdown.jsx";
import idFromUrl from "../../util/helpers/id-from-url";
import ContentForm from "./content-form";
import MultiselectFromEndpoint from "./multiselect-from-endpoint";
Expand Down Expand Up @@ -167,7 +167,7 @@ function FeedSelector({
onChange={configurationChange}
name={element.name}
formStateObject={value?.configuration ?? {}}
onFileChange={() => {}}
onFileChange={() => {}} // Todo perhaps an error instead of an empty default
/>
);
};
Expand Down
2 changes: 1 addition & 1 deletion assets/admin/components/slide/content/file-dropzone.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function FileDropzone({ onFilesAdded, acceptedMimetypes = null }) {
<>
{/* TODO: Fix styling for dropzone: https://react-dropzone.js.org/#section-styling-dropzone */}
{/* eslint-disable react/jsx-props-no-spreading */}
<div {...getRootProps({ className: "dropzone drag-drop-area" })}>
<div {...getRootProps({ className: "dropzone drag-drop-area my-1" })}>
<input {...getInputProps()} />
<div>
<span>{t("file-dropzone.drag-and-drop-text")}</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Button, Row, Col } from "react-bootstrap";
import { useTranslation } from "react-i18next";
import FormInput from "../../util/forms/form-input";
import FormInput from "../../../../shared/forms/form-input";
import FilePreview from "./file-preview";

/**
Expand Down
22 changes: 12 additions & 10 deletions assets/admin/components/slide/content/file-selector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,21 @@ function FileSelector({
/>
{enableMediaLibrary && (
<>
<Button
disabled={!multiple && files.length > 0}
variant="success"
onClick={() => setShowMediaModal(true)}
>
{t("file-selector.open-media-library")}
</Button>
{/*
<div className="d-flex align-items-center mt-2">
<Button
disabled={!multiple && files.length > 0}
variant="success"
onClick={() => setShowMediaModal(true)}
>
{t("file-selector.open-media-library")}
</Button>
{/*
TODO: Make this configurable. It should always align with sizes in
https://github.com/os2display/display-api-service/blob/develop/src/Entity/Tenant/Media.php
*/}
<div className="small mt-3">
{t("file-selector.max-size")}: 200 MB
<div className="small mt-1 mx-2">
{t("file-selector.max-size")}: 200 MB
</div>
</div>
<MediaSelectorModal
selectedMedia={files}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import MultiSelectComponent from "../../util/forms/multiselect-dropdown/multi-dropdown";
import MultiSelectComponent from "../../util/multiselect-dropdown/multi-dropdown";
import localStorageKeys from "../../util/local-storage-keys";
import { displayError } from "../../util/list/toast-component/display-toast";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import AsyncSelect from "react-select/async";
import Col from "react-bootstrap/Col";
import dayjs from "dayjs";
import localeDa from "dayjs/locale/da";
import Select from "../../../util/forms/select";
import FormInput from "../../../util/forms/form-input";
import FormCheckbox from "../../../util/forms/form-checkbox";
import Select from "../../../../../shared/forms/select";
import FormInput from "../../../../../shared/forms/form-input";
import FormCheckbox from "../../../../../shared/forms/form-checkbox";
import localStorageKeys from "../../../util/local-storage-keys";

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useTranslation } from "react-i18next";
import FormInput from "../../../util/forms/form-input";
import FormCheckbox from "../../../util/forms/form-checkbox";
import FormInput from "../../../../../shared/forms/form-input";
import FormCheckbox from "../../../../../shared/forms/form-checkbox";

/**
* @param {object} props The props.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Col from "react-bootstrap/Col";
import { useTranslation } from "react-i18next";
import { MultiSelect } from "react-multi-select-component";
import Form from "react-bootstrap/Form";
import FormInput from "../../../util/forms/form-input";
import FormInput from "../../../../../shared/forms/form-input";
import { getHeaders, loadDropdownOptionsPromise } from "./poster-helper";

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState, useEffect, useContext } from "react";
import { useTranslation } from "react-i18next";
import MultiSelectComponent from "../../../util/forms/multiselect-dropdown/multi-dropdown";
import MultiSelectComponent from "../../../util/multiselect-dropdown/multi-dropdown";
import { displayError } from "../../../util/list/toast-component/display-toast";
import userContext from "../../../../context/user-context";

Expand Down
Loading
Loading