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
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/repos
# Ignore custom templates folder.
/assets/shared/custom-templates/*

/public/admin
/public/client
# Ignore release json file.
/public/release.json

###> symfony/framework-bundle ###
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
* Cleaned up Github Actions workflows.
* Updated PHP dependencies.
* Added Playwright github action.
* Changed how templates are imported.

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

Expand Down
6 changes: 3 additions & 3 deletions assets/admin/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import localStorageKeys from "./components/util/local-storage-keys";
import RestrictedRoute from "./restricted-route";
import RestrictedRoute from "./components/restricted-route";
import Topbar from "./components/navigation/topbar/top-bar";
import SideBar from "./components/navigation/sidebar/sidebar";
import ScreenList from "./components/screen/screen-list";
Expand All @@ -32,14 +32,14 @@ import UserContext from "./context/user-context";
import ListContext from "./context/list-context";
import SharedPlaylists from "./components/playlist/shared-playlists";
import Logout from "./components/user/logout";
import AuthHandler from "./auth-handler";
import AuthHandler from "./components/auth-handler";
import LoadingComponent from "./components/util/loading-component/loading-component";
import ModalProvider from "./context/modal-context/modal-provider";
import UsersList from "./components/users/users-list";
import ActivationCodeList from "./components/activation-code/activation-code-list";
import ActivationCodeCreate from "./components/activation-code/activation-code-create";
import ActivationCodeActivate from "./components/activation-code/activation-code-activate";
import AdminConfigLoader from "./admin-config-loader.js";
import AdminConfigLoader from "./components/util/admin-config-loader.js";
import "react-toastify/dist/ReactToastify.css";
import "./app.scss";
import FeedSourcesList from "./components/feed-sources/feed-sources-list";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { React, useContext } from "react";
import PropTypes from "prop-types";
import Login from "./components/user/login";
import UserContext from "./context/user-context";
import Login from "./user/login";
import UserContext from "../context/user-context";

/**
* The auth handler wrapper.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { React, useContext } from "react";
import PropTypes from "prop-types";
import UserContext from "./context/user-context";
import NoAccess from "./components/no-access/no-access";
import UserContext from "../context/user-context";
import NoAccess from "./no-access/no-access";

/**
* The restricted route wrapper.
Expand Down
2 changes: 1 addition & 1 deletion assets/admin/components/screen/screen-list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
displayError,
} from "../util/list/toast-component/display-toast";
import "./screen-list.scss";
import AdminConfigLoader from "../../admin-config-loader.js";
import AdminConfigLoader from "../util/admin-config-loader.js";

/**
* The screen list component.
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 @@ -18,7 +18,7 @@ import idFromUrl from "../util/helpers/id-from-url";
import { api } from "../../redux/api/api.generated.ts";
import { displayError } from "../util/list/toast-component/display-toast";
import FormInput from "../util/forms/form-input";
import AdminConfigLoader from "../../admin-config-loader.js";
import AdminConfigLoader from "../util/admin-config-loader.js";

/**
* Displays screen status.
Expand Down
10 changes: 4 additions & 6 deletions assets/admin/components/slide/preview/slide-preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ import { React, useEffect, useState } from "react";
import { Button } from "react-bootstrap";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import ErrorBoundary from "../../../error-boundary";
import ErrorBoundary from "../../error-boundary";
import "./slide-preview.scss";
import renderSlide from "../../../../shared/template/slide.jsx";
import { renderSlide } from "../../../../shared/slide-utils/templates";

/**
* A remote component wrapper
* Slide live preview.
*
* @param {object} props Props.
* @param {object} props.slide The slide.
* @param {boolean} props.url The url for the remote component.
* @param {object} props.mediaData Object of loaded media.
* @param {object} props.themeData Object of theme data.
* @param {string} props.orientation Display orientation or horizontal.
Expand All @@ -23,7 +22,7 @@ import renderSlide from "../../../../shared/template/slide.jsx";
*/
function SlidePreview({
slide,
templateData,
templateData,
showPreview,
orientation = "",
closeButton = false,
Expand Down Expand Up @@ -147,7 +146,6 @@ function SlidePreview({
SlidePreview.propTypes = {
slide: PropTypes.shape({ content: PropTypes.shape({}).isRequired })
.isRequired,
url: PropTypes.string.isRequired,
mediaData: PropTypes.shape({
"@id": PropTypes.string,
}),
Expand Down
28 changes: 9 additions & 19 deletions assets/admin/components/slide/slide-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import idFromUrl from "../util/helpers/id-from-url";
import FormInput from "../util/forms/form-input";
import ContentForm from "./content/content-form";
import LoadingComponent from "../util/loading-component/loading-component";
import SlidePreview from "./preview/slide-preview.jsx";
import SlidePreview from "./preview/slide-preview";
import FeedSelector from "./content/feed-selector";
import SelectPlaylistsTable from "../util/multi-and-table/select-playlists-table";
import localStorageKeys from "../util/local-storage-keys";
Expand All @@ -26,6 +26,7 @@ import "./slide-form.scss";
import Preview from "../preview/preview";
import StickyFooter from "../util/sticky-footer";
import Select from "../util/forms/select";
import { getConfig } from "../../../shared/slide-utils/templates";

/**
* The slide form component.
Expand Down Expand Up @@ -92,6 +93,7 @@ function SlideForm({
const [themesOptions, setThemesOptions] = useState();
const [displayPreview, setDisplayPreview] = useState(null);
const [templateError, setTemplateError] = useState(false);
const [disableLivePreview, setDisableLivePreview] = useState(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const [disableLivePreview, setDisableLivePreview] = useState(false);
const [enablePreview, setEnablePreview] = useState(true);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This state is never changed in the file......

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch :)


// Load templates.
const { data: templates, isLoading: loadingTemplates } =
Expand Down Expand Up @@ -157,19 +159,12 @@ function SlideForm({
const newSelectedTemplates = [];

if (selectedTemplate) {
// Get content form from template resources.
const contentFormUrl = selectedTemplate?.resources?.admin;
fetch(contentFormUrl)
.then((response) => response.json())
.then((data) => {
setContentFormElements(data);
})
.catch((er) => {
displayError(t("template-error"), er);
});

const slideConfig = getConfig(selectedTemplate['id']);
setContentFormElements(slideConfig.adminForm ?? []);
setDisableLivePreview(slideConfig?.options?.disableLivePreview ?? false);
newSelectedTemplates.push(selectedTemplate);
}

setSelectedTemplates(newSelectedTemplates);
}, [selectedTemplate]);

Expand Down Expand Up @@ -401,13 +396,12 @@ function SlideForm({
</Button>
</div>

{selectedTemplate?.resources?.options?.disableLivePreview && (
{disableLivePreview && (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{disableLivePreview && (
{enablePreview && (

<Alert variant="secondary" className="mt-3">
{t("slide-preview-disabled-preview")}
</Alert>
)}
{!selectedTemplate?.resources?.options?.disableLivePreview &&
selectedTemplate?.resources?.component && (
{!disableLivePreview && (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{!disableLivePreview && (
{!enablePreview && (

<>
{previewOrientation === "horizontal" && (
<div style={{ width: "100%" }}>
Expand Down Expand Up @@ -581,10 +575,6 @@ SlideForm.propTypes = {
selectTemplate: PropTypes.func.isRequired,
selectedTemplate: PropTypes.shape({
"@id": PropTypes.string,
resources: PropTypes.shape({
admin: PropTypes.string.isRequired,
component: PropTypes.string.isRequired,
}).isRequired,
}),
isLoading: PropTypes.bool,
loadingMessage: PropTypes.string,
Expand Down
2 changes: 1 addition & 1 deletion assets/admin/components/user/login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {MultiSelect} from "react-multi-select-component";
import UserContext from "../../context/user-context";
import FormInput from "../util/forms/form-input";
import {api} from "../../redux/api/api.generated.ts";
import AdminConfigLoader from "../../admin-config-loader.js";
import AdminConfigLoader from "../util/admin-config-loader.js";
import {displayError} from "../util/list/toast-component/display-toast";
import localStorageKeys from "../util/local-storage-keys";
import LoginSidebar from "../navigation/login-sidebar/login-sidebar";
Expand Down
2 changes: 1 addition & 1 deletion assets/client/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import Screen from "./components/screen.jsx";
import ContentService from "./service/content-service";
import ClientConfigLoader from "./client-config-loader.js";
import ClientConfigLoader from "./util/client-config-loader.js";
import logger from "./logger/logger";
import "./app.scss";
import fallback from "./assets/fallback.png";
Expand Down
2 changes: 1 addition & 1 deletion assets/client/components/region.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import PropTypes from "prop-types";
import "./region.scss";
import { createGridArea } from "../../shared/grid-generator/grid-generator";
import { TransitionGroup, CSSTransition } from "react-transition-group";
import Slide from "./slide.jsx";
import ErrorBoundary from "./error-boundary.jsx";
import idFromPath from "../util/id-from-path";
import logger from "../logger/logger";
import Slide from "./slide.jsx";

/**
* Region component.
Expand Down
2 changes: 1 addition & 1 deletion assets/client/components/screen.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Region from "./region.jsx";
import "./screen.scss";
import logger from "../logger/logger";
import TouchRegion from "./touch-region.jsx";
import ClientConfigLoader from "../client-config-loader.js";
import ClientConfigLoader from "../util/client-config-loader.js";

/**
* Screen component.
Expand Down
2 changes: 1 addition & 1 deletion assets/client/components/slide.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {React} from "react";
import "./slide.scss";
import ErrorBoundary from "./error-boundary.jsx";
import logger from "../logger/logger";
import renderSlide from "../../shared/template/slide.jsx";
import { renderSlide } from "../../shared/slide-utils/templates.js";

/**
* Slide component.
Expand Down
2 changes: 1 addition & 1 deletion assets/client/components/touch-region.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { React, useEffect, useState, createRef } from "react";
import PropTypes from "prop-types";
import "./touch-region.scss";
import { createGridArea } from "../../shared/grid-generator/grid-generator";
import Slide from "./slide.jsx";
import ErrorBoundary from "./error-boundary.jsx";
import idFromPath from "../util/id-from-path";
import IconClose from "../assets/icon-close.svg";
import IconPointer from "../assets/icon-pointer.svg";
import Slide from "./slide.jsx";

/**
* Region component.
Expand Down
2 changes: 1 addition & 1 deletion assets/client/service/content-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import logger from "../logger/logger";
import DataSync from "../data-sync/data-sync";
import ScheduleService from "./schedule-service";
import ClientConfigLoader from "../client-config-loader.js";
import ClientConfigLoader from "../util/client-config-loader.js";

/**
* ContentService.
Expand Down
2 changes: 1 addition & 1 deletion assets/client/service/release-service.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ReleaseLoader from "../util/release-loader";
import ClientConfigLoader from "../client-config-loader.js";
import ClientConfigLoader from "../util/client-config-loader.js";
import defaults from "../util/defaults";
import idFromPath from "../util/id-from-path";
import appStorage from "../util/app-storage";
Expand Down
4 changes: 2 additions & 2 deletions assets/client/service/schedule-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Md5 from "crypto-js/md5";
import Base64 from "crypto-js/enc-base64";
import isPublished from "../util/isPublished";
import logger from "../logger/logger";
import ClientConfigLoader from "../client-config-loader.js";
import ClientConfigLoader from "../util/client-config-loader.js";
import ScheduleUtils from "../util/schedule";

/**
Expand Down Expand Up @@ -138,7 +138,7 @@ class ScheduleService {

// Update region.
this.regions[regionId].hash = hash;
this.regions[regionId].slides = slides;
this.regions[regionId].slide = slides;

if (newContent) {
// Send slides to region.
Expand Down
2 changes: 1 addition & 1 deletion assets/client/service/token-service.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logger from "../logger/logger";
import appStorage from "../util/app-storage";
import ClientConfigLoader from "../client-config-loader.js";
import ClientConfigLoader from "../util/client-config-loader.js";
import defaults from "../util/defaults";
import statusService from "./status-service";
import constants from "../util/constants";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Only fetch new config if more than 15 minutes have passed.
import appStorage from "./util/app-storage";
import appStorage from "./app-storage.js";

const configFetchIntervalDefault = 15 * 60 * 1000;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"title": "Test",
"id": "01K2PREY1Q0XCTR9EK1YT5R4XK",
"options": {},
"adminForm": [
{
"key": "test-form-1",
"input": "header",
"text": "Skabelon: Test",
"formGroupClasses": "h4 mb-3"
},
{
"key": "test-form-title",
"input": "input",
"name": "title",
"type": "text",
"label": "Overskrift",
"helpText": "Her kan du skrive overskrift.",
"formGroupClasses": "mb-3"
}
]
}
58 changes: 58 additions & 0 deletions assets/shared/custom-templates-example/custom-template-example.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useEffect } from "react";
import templateConfig from "./custom-template-example.json";
import BaseSlideExecution from "../slide-utils/base-slide-execution.js";
import { ThemeStyles } from "../slide-utils/slide-util.jsx";

function id() {
return templateConfig.id;
}

function config() {
return templateConfig;
}

function renderSlide(slide, run, slideDone) {
return <CustomTemplateExample
slide={slide}
run={run}
slideDone={slideDone}
content={slide.content}
executionId={slide.executionId}
/>;
}

/**
* @param {object} props Props.
* @param {object} props.slide The slide.
* @param {object} props.content The slide content.
* @param {boolean} props.run Whether or not the slide should start running.
* @param {Function} props.slideDone Function to invoke when the slide is done playing.
* @param {string} props.executionId Unique id for the instance.
* @returns {JSX.Element} The component.
*/
function CustomTemplateExample({ slide, content, run, slideDone, executionId }) {
const { duration = 15000 } = content;
const { title = "Default title" } = content;

const slideExecution = new BaseSlideExecution(slide, slideDone);

useEffect(() => {
if (run) {
slideExecution.start(duration);
}

return function cleanup() {
slideExecution.stop();
};
}, [run]);

return (<>
<div className="custom-template-example">
<h1 className="title">{title}</h1>
</div>

<ThemeStyles id={executionId} css={slide?.theme?.cssStyles} />
</>);
}

export default { id, config, renderSlide };
Loading