Skip to content

Commit 4f1acc0

Browse files
committed
Merge branch 'release/2.1.1'
2 parents 8255ee4 + 0f1b041 commit 4f1acc0

File tree

21 files changed

+17092
-15670
lines changed

21 files changed

+17092
-15670
lines changed

.docker/vhost.conf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ server {
77
proxy_set_header X-Forwarded-For $remote_addr;
88
proxy_set_header Host $http_host;
99
proxy_pass http://node:3000;
10+
11+
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
12+
add_header Pragma "no-cache";
13+
add_header Expires "0";
1014
}
1115

1216
location /admin/ws {

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
55

66
## [Unreleased]
77

8+
## [2.1.1] - 2024-10-23
9+
10+
- [#266](https://github.com/os2display/display-admin-client/pull/266)
11+
- Fixed search from local storage.
12+
- [#265](https://github.com/os2display/display-admin-client/pull/265)
13+
- Add no-cache directive
14+
- [#263](https://github.com/os2display/display-admin-client/pull/263)
15+
- Added prefix to local storage keys.
16+
- [#262](https://github.com/os2display/display-admin-client/pull/262)
17+
- Add multi select styling for `invalid` state
18+
- Add possibility of sending error via props to multiselect component
19+
- Add validation checking if layout is selected on screen before save
20+
- Add validation checking if template is selected on slide before save
21+
- [#260](https://github.com/os2display/display-admin-client/pull/260)
22+
- Bug in multiselect, fixed by removing duplicates by key both `@id`and `id`
23+
- [#265](https://github.com/os2display/display-admin-client/pull/265)
24+
- Bug in multiselect, fixed by removing duplicates by key both `@id`and `id`
25+
- [#259](https://github.com/os2display/display-admin-client/pull/259)
26+
- Add saving of playlists/groups with screen (as opposed to _after_)
27+
- Clean up `screen-manager.jsx`
28+
- Change bootstrap column class from `col-md-8` -> `col-md-12`
29+
- update api.generated.ts to match [related pr](https://github.com/os2display/display-api-service/pull/213)
30+
- Add @rtk-incubator/rtk-query-codegen-openapi to package.json in `src/redux/api`
31+
- Sort playlists based on weight in drag/drop component
32+
833
## [2.1.0] - 2024-10-23
934

1035
- [#258](https://github.com/os2display/display-admin-client/pull/258)

e2e/slides.spec.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,7 @@ test.describe("Create slide page works", () => {
145145
page.locator(".Toastify").locator(".Toastify__toast--error")
146146
).toBeVisible();
147147
await expect(
148-
page
149-
.locator(".Toastify")
150-
.locator(".Toastify__toast--error")
151-
.getByText(/An error occurred/)
152-
.first()
148+
page.locator(".Toastify").locator(".Toastify__toast--error").first()
153149
).toBeVisible();
154150
await expect(page).toHaveURL(/slide\/create/);
155151
});

infrastructure/itkdev/etc/confd/templates/default.conf.tmpl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ server {
44
root /var/www/html;
55
index index.html index.htm;
66

7+
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
8+
add_header Pragma "no-cache";
9+
add_header Expires "0";
10+
711
# Any route containing a file extension (e.g. /devicesfile.js)
812
location ~* ^{{ getenv "APP_ADMIN_CLIENT_PATH" "" }}/(.+\..+)$ {
913
rewrite ^{{ getenv "APP_ADMIN_CLIENT_PATH" "/" }}(.*) /$1 break;
14+
1015
try_files $uri =404;
1116
}
1217

1318
location ~* ^{{ getenv "APP_ADMIN_CLIENT_PATH" "/" }} {
1419
rewrite ^{{ getenv "APP_ADMIN_CLIENT_PATH" "/" }}(.*) /$1 break;
1520
autoindex off;
21+
1622
try_files $uri /index.html;
1723
}
1824

infrastructure/os2display/etc/confd/templates/default.conf.tmpl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ server {
44
root /var/www/html;
55
index index.html index.htm;
66

7+
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
8+
add_header Pragma "no-cache";
9+
add_header Expires "0";
10+
711
# Any route containing a file extension (e.g. /devicesfile.js)
812
location ~* ^{{ getenv "APP_ADMIN_CLIENT_PATH" "" }}/(.+\..+)$ {
913
rewrite ^{{ getenv "APP_ADMIN_CLIENT_PATH" "/" }}(.*) /$1 break;
14+
1015
try_files $uri =404;
1116
}
1217

1318
location ~* ^{{ getenv "APP_ADMIN_CLIENT_PATH" "/" }} {
1419
rewrite ^{{ getenv "APP_ADMIN_CLIENT_PATH" "/" }}(.*) /$1 break;
1520
autoindex off;
21+
1622
try_files $uri /index.html;
1723
}
1824

src/app.scss

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,8 @@ body,
5757
padding: 5em;
5858
z-index: 1021;
5959

60-
.spinner-container {
61-
display: flex;
62-
position: fixed;
63-
64-
.loading-spinner {
65-
margin-right: 1em;
66-
}
60+
.loading-spinner {
61+
margin-right: 0.6em;
6762
}
6863
}
6964

src/components/playlist-drag-and-drop/playlist-drag-and-drop.jsx

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,17 @@ import ScreenGanttChart from "../screen/util/screen-gantt-chart";
2020
* @param {string} props.name - The id of the form element
2121
* @param {string} props.screenId - The screen id for get request
2222
* @param {string} props.regionId - The region id for get request
23+
* @param {string} props.regionIdForInitializeCallback - The region id to add
24+
* regions to formstateobject.
2325
* @returns {object} A drag and drop component
2426
*/
25-
function PlaylistDragAndDrop({ handleChange, name, screenId, regionId }) {
27+
function PlaylistDragAndDrop({
28+
handleChange,
29+
name,
30+
screenId,
31+
regionId,
32+
regionIdForInitializeCallback,
33+
}) {
2634
const { t } = useTranslation("common", {
2735
keyPrefix: "playlist-drag-and-drop",
2836
});
@@ -49,16 +57,35 @@ function PlaylistDragAndDrop({ handleChange, name, screenId, regionId }) {
4957
sharedWithMe: onlySharedPlaylists,
5058
});
5159

60+
/**
61+
* @param regionsAndPlaylists This method initializes playlists, so the
62+
* initial formstate object in screen manager is not empty
63+
*/
64+
function callbackToinitializePlaylists(regionsAndPlaylists) {
65+
handleChange({
66+
target: {
67+
id: regionIdForInitializeCallback,
68+
value: regionsAndPlaylists["hydra:member"].map(
69+
({ playlist }) => playlist
70+
),
71+
},
72+
});
73+
}
74+
5275
/** Set loaded data into form state. */
5376
useEffect(() => {
5477
if (selectedPlaylistsByRegion) {
5578
setTotalItems(selectedPlaylistsByRegion["hydra:totalItems"]);
5679
const newPlaylists = selectedPlaylistsByRegion["hydra:member"].map(
57-
({ playlist }) => {
58-
return playlist;
59-
}
80+
({ playlist, weight }) => ({ ...playlist, weight })
81+
);
82+
83+
const selected = [...selectedData, ...newPlaylists].sort(
84+
(a, b) => a.weight - b.weight
6085
);
61-
setSelectedData([...selectedData, ...newPlaylists]);
86+
87+
setSelectedData(selected);
88+
callbackToinitializePlaylists(selectedPlaylistsByRegion);
6289
}
6390
}, [selectedPlaylistsByRegion]);
6491

@@ -157,6 +184,7 @@ function PlaylistDragAndDrop({ handleChange, name, screenId, regionId }) {
157184
PlaylistDragAndDrop.propTypes = {
158185
name: PropTypes.string.isRequired,
159186
screenId: PropTypes.string.isRequired,
187+
regionIdForInitializeCallback: PropTypes.string.isRequired,
160188
regionId: PropTypes.string.isRequired,
161189
handleChange: PropTypes.func.isRequired,
162190
};

src/components/screen/screen-form.jsx

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ function ScreenForm({
5050
const { t } = useTranslation("common", { keyPrefix: "screen-form" });
5151
const navigate = useNavigate();
5252
const dispatch = useDispatch();
53+
const [layoutError, setLayoutError] = useState(false);
5354
const [selectedLayout, setSelectedLayout] = useState();
5455
const [layoutOptions, setLayoutOptions] = useState();
5556
const [bindKey, setBindKey] = useState("");
@@ -59,6 +60,21 @@ function ScreenForm({
5960
order: { createdAt: "desc" },
6061
});
6162

63+
/** Check if published is set */
64+
const checkInputsHandleSubmit = () => {
65+
setLayoutError(false);
66+
let submit = true;
67+
if (!selectedLayout) {
68+
displayError(t("remember-layout-error"));
69+
setLayoutError(true);
70+
submit = false;
71+
}
72+
73+
if (submit) {
74+
handleSubmit();
75+
}
76+
};
77+
6278
useEffect(() => {
6379
if (layouts) {
6480
setLayoutOptions(layouts["hydra:member"]);
@@ -72,6 +88,11 @@ function ScreenForm({
7288
);
7389
if (localSelectedLayout) {
7490
setSelectedLayout(localSelectedLayout);
91+
// Initialize regions in the formstate object of screenmanager. used to save "empty" playlists, in the situation
92+
// we are deleting all playlists from a screen region
93+
handleInput({
94+
target: { id: "regions", value: localSelectedLayout.regions },
95+
});
7596
}
7697
}
7798
}, [screen.layout, layoutOptions]);
@@ -84,6 +105,7 @@ function ScreenForm({
84105
*/
85106
const handleAdd = ({ target }) => {
86107
const { value, id } = target;
108+
87109
setSelectedLayout(value);
88110
handleInput({
89111
target: { id, value: value.map((item) => item["@id"]).shift() },
@@ -250,7 +272,7 @@ function ScreenForm({
250272
noSelectedString={t("nothing-selected-resolution")}
251273
handleSelection={handleInput}
252274
options={resolutionOptions}
253-
selected={screen.resolution || ""}
275+
selected={screen.resolution || []}
254276
name="resolution"
255277
singleSelect
256278
/>
@@ -259,7 +281,7 @@ function ScreenForm({
259281
noSelectedString={t("nothing-selected-orientation")}
260282
handleSelection={handleInput}
261283
options={orientationOptions}
262-
selected={screen.orientation || ""}
284+
selected={screen.orientation || []}
263285
name="orientation"
264286
singleSelect
265287
/>
@@ -277,6 +299,7 @@ function ScreenForm({
277299
helpText={t("search-to-se-possible-selections")}
278300
selected={selectedLayout ? [selectedLayout] : []}
279301
name="layout"
302+
error={layoutError}
280303
singleSelect
281304
/>
282305
</div>
@@ -321,7 +344,7 @@ function ScreenForm({
321344
type="button"
322345
id="save_screen"
323346
size="lg"
324-
onClick={handleSubmit}
347+
onClick={checkInputsHandleSubmit}
325348
>
326349
{t("save-button")}
327350
</Button>
@@ -340,7 +363,11 @@ ScreenForm.propTypes = {
340363
enableColorSchemeChange: PropTypes.bool,
341364
layout: PropTypes.string,
342365
location: PropTypes.string,
343-
regions: PropTypes.arrayOf(PropTypes.string),
366+
regions: PropTypes.arrayOf(
367+
PropTypes.shape({
368+
"@id": PropTypes.string,
369+
})
370+
),
344371
screenUser: PropTypes.string,
345372
size: PropTypes.string,
346373
title: PropTypes.string,

0 commit comments

Comments
 (0)