Skip to content

Commit

Permalink
Add "Create series" route
Browse files Browse the repository at this point in the history
This route features an interface with can be used to configure
title, description and ACL for a new series and create said
series using the API endpoint from the previous commit.
  • Loading branch information
owi92 committed Feb 3, 2025
1 parent 837f983 commit c1db546
Show file tree
Hide file tree
Showing 12 changed files with 330 additions and 46 deletions.
13 changes: 9 additions & 4 deletions frontend/src/i18n/locales/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -307,22 +307,25 @@ upload:
angeschaut werden, sobald die Verarbeitung abgeschlossen ist. Sie können diese
Seite jetzt schließen.
metadata:
title: Videotitel
description: Beschreibung
required: Pflichtfeld
save: Speichern und fertigstellen
note-writable-series: >
Sie können Videos nur in Serien hochladen, auf die Sie Schreibzugriff haben.
Andere Serien sind daher hier nicht auswählbar.
errors:
failed-to-upload: Hochladen fehlgeschlagen.
unknown: Während des Dateiuploads ist ein unbekannter Fehler aufgetreten.
field-required: Dieses Feld darf nicht leer sein.
opencast-server-error: Opencast-Server-Fehler (unerwartete Antwort).
opencast-unreachable: 'Netzwerkfehler: Opencast kann nicht erreicht werden.'
jwt-invalid: 'Interner Fremdauthentifizierungsfehler: Opencast hat das Hochladen nicht autorisiert.'
failed-fetching-series-acl: Abruf der Serienzugangsberechtigungen fehlgeschlagen.

metadata-form:
title: Titel
description: Beschreibung
required: Pflichtfeld
errors:
field-required: Dieses Feld darf nicht leer sein.

acl:
unknown-user-note: unbekannt
no-entries: Keine Einträge
Expand Down Expand Up @@ -455,6 +458,8 @@ manage:
no-of-videos: '{{count}} Videos'
details:
title: Seriendetails
create:
title: Serie erstellen

my-videos:
title: Meine Videos
Expand Down
13 changes: 9 additions & 4 deletions frontend/src/i18n/locales/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -305,22 +305,25 @@ upload:
Your video was uploaded successfully and is now being processed. It can be
watched as soon as processing is done. You may close this page now.
metadata:
title: Video title
description: Description
required: required
save: Save and finish
note-writable-series: >
Videos can only be uploaded into series for which you have write-access.
Other series are therefore not listed as selectable here.
errors:
failed-to-upload: Failed to upload video.
unknown: Unknown error occurred during video upload.
field-required: This field is required (cannot be empty).
opencast-server-error: Opencast server error (unexpected response).
opencast-unreachable: 'Network error: Opencast cannot be reached.'
jwt-invalid: 'Internal cross-authentication error: Opencast did not authorize the upload.'
failed-fetching-series-acl: Failed to fetch series acl.

metadata-form:
title: Title
description: Description
required: required
errors:
field-required: This field is required (cannot be empty).

acl:
unknown-user-note: unknown
no-entries: No entries
Expand Down Expand Up @@ -437,6 +440,8 @@ manage:
no-of-videos: '{{count}} videos'
details:
title: Series details
create:
title: Create series

my-videos:
title: My videos
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/layout/header/UserBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";
import {
LuAlertTriangle, LuLogIn, LuMoon, LuSun, LuFolder, LuFilm,
LuUpload, LuVideo, LuLogOut, LuChevronDown, LuUserCheck,
LuFilePlus,
} from "react-icons/lu";
import { HiOutlineFire, HiOutlineTranslate } from "react-icons/hi";
import {
Expand All @@ -28,6 +29,7 @@ import { LoginLink } from "../../routes/util";
import { CREDENTIALS_STORAGE_KEY } from "../../routes/Video";
import { ManageSeriesRoute } from "../../routes/manage/Series";
import SeriesIcon from "../../icons/series.svg";
import { CreateSeriesRoute } from "../../routes/manage/Series/Create";



Expand Down Expand Up @@ -236,6 +238,12 @@ const LoggedIn: React.FC<LoggedInProps> = ({ user }) => {
children: t("upload.title"),
css: indent,
}] : [],
{
icon: <LuFilePlus />,
wrapper: <Link to={CreateSeriesRoute.url} />,
children: t("manage.my-series.create.title"),
css: indent,
},
...user.canUseStudio ? [{
icon: <LuVideo />,
wrapper: <ExternalLink
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { DirectPlaylistOCRoute, DirectPlaylistRoute } from "./routes/Playlist";
import { ManageSeriesRoute } from "./routes/manage/Series";
import { ManageSeriesDetailsRoute } from "./routes/manage/Series/Details";
import { ManageSeriesAccessRoute } from "./routes/manage/Series/Access";
import { CreateSeriesRoute } from "./routes/manage/Series/Create";



Expand Down Expand Up @@ -72,6 +73,7 @@ const {
ManageSeriesRoute,
ManageSeriesDetailsRoute,
UploadRoute,
CreateSeriesRoute,
AddChildRoute,
ManageRealmContentRoute,
EmbedVideoRoute,
Expand Down
25 changes: 7 additions & 18 deletions frontend/src/routes/Upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { VideoListSelector } from "../ui/SearchableSelect";
import { Breadcrumbs } from "../ui/Breadcrumbs";
import { ManageNav, ManageRoute } from "./manage";
import { COLORS } from "../color";
import { COMMON_ROLES } from "../util/roles";
import { defaultAclMap } from "../util/roles";
import { Acl, AclSelector, knownRolesFragment } from "../ui/Access";
import {
AccessKnownRolesData$data,
Expand Down Expand Up @@ -744,20 +744,7 @@ const MetaDataEdit: React.FC<MetaDataEditProps> = ({ onSave, disabled, knownRole
}
};

const defaultAcl: Acl = new Map([
[user.userRole, {
actions: new Set(["read", "write"]),
info: {
label: { "_": user.displayName },
implies: null,
large: false,
},
}],
[COMMON_ROLES.ANONYMOUS, {
actions: new Set(["read"]),
info: null,
}],
]);
const defaultAcl = defaultAclMap(user);

const { register, handleSubmit, control, formState: { isValid, errors } } = useForm<Metadata>({
mode: "onChange",
Expand All @@ -768,7 +755,9 @@ const MetaDataEdit: React.FC<MetaDataEditProps> = ({ onSave, disabled, knownRole
name: "series",
control,
rules: {
required: CONFIG.upload.requireSeries ? t("upload.errors.field-required") : false,
required: CONFIG.upload.requireSeries
? t("metadata-form.errors.field-required")
: false,
},
});

Expand Down Expand Up @@ -798,7 +787,7 @@ const MetaDataEdit: React.FC<MetaDataEditProps> = ({ onSave, disabled, knownRole
css={{ width: 400, maxWidth: "100%" }}
autoFocus
{...register("title", {
required: t("upload.errors.field-required") as string,
required: t("metadata-form.errors.field-required") as string,
})}
/>
{boxError(errors.title?.message)}
Expand All @@ -807,7 +796,7 @@ const MetaDataEdit: React.FC<MetaDataEditProps> = ({ onSave, disabled, knownRole
<div css={{ maxWidth: 750 }}>
{/* Description */}
<InputContainer>
<label htmlFor={descriptionFieldId}>{t("upload.metadata.description")}</label>
<label htmlFor={descriptionFieldId}>{t("metadata-form.description")}</label>
<TextArea id={descriptionFieldId} {...register("description")} />
</InputContainer>

Expand Down
Loading

0 comments on commit c1db546

Please sign in to comment.