Skip to content

Commit

Permalink
Merge pull request #94 from nebulabroadcast/93-rundown-edit
Browse files Browse the repository at this point in the history
Experimental: Rundown editing in the web interface
  • Loading branch information
martastain authored Nov 23, 2024
2 parents aabaf0f + 6e5f054 commit c94c0ed
Show file tree
Hide file tree
Showing 66 changed files with 2,374 additions and 1,013 deletions.
4 changes: 3 additions & 1 deletion backend/api/init/init_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ class InitResponseModel(ResponseModel):
),
] = None

experimental: Annotated[bool | None, Field(title="Enable experimental features")] = None
experimental: Annotated[
bool | None, Field(title="Enable experimental features")
] = None


class InitRequest(APIRequest):
Expand Down
2 changes: 1 addition & 1 deletion backend/schema/meta-aliases-cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
["source" , "Zdroj" , null , ""],
["id_folder" , "Složka" , null , ""],
["is_admin" , "Admin" , null , ""],
["run_mode" , "Run mode" , null , "Režim odbavení příspěvků"],
["run_mode" , "Režim" , "Režim" , "Režim odbavení příspěvků"],
["summary" , "Perex" , null , ""],
["description" , "Popis" , null , ""],
["file/format" , "Formát souboru" , null , ""],
Expand Down
2 changes: 1 addition & 1 deletion backend/schema/meta-aliases-en.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
["source" , "Source" , null , ""],
["id_folder" , "Folder" , null , ""],
["is_admin" , "Admin" , null , ""],
["run_mode" , "Run mode" , null , ""],
["run_mode" , "Run mode" , "Mode" , ""],
["summary" , "Summary" , null , ""],
["description" , "Description" , null , ""],
["file/format" , "File format" , null , ""],
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/actions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import nebula from '/src/nebula'
import { createSlice } from '@reduxjs/toolkit'
import { isNaN } from 'lodash'

const initialState = {
browserRefresh: 0,
Expand Down Expand Up @@ -49,6 +50,7 @@ const contextSlice = createSlice({
},

setFocusedAsset: (state, action) => {
if (isNaN(action.payload)) return
state.focusedAsset = action.payload
},

Expand Down
25 changes: 2 additions & 23 deletions frontend/src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useLocalStorage } from '/src/hooks'
import { Routes, Route, Navigate, BrowserRouter } from 'react-router-dom'

import WebsocketListener from '/src/websocket'
import NavBar from '/src/containers/Navbar'
import MainNavbar from '/src/containers/MainNavbar'
import LoginPage from '/src/pages/LoginPage'
import LoadingPage from '/src/pages/LoadingPage'
import MAMPage from '/src/pages/MAMPage'
Expand All @@ -15,14 +15,12 @@ import ServicesPage from '/src/pages/ServicesPage'
import ToolPage from '/src/pages/ToolPage'
import ProfilePage from '/src/pages/ProfilePage'
import UsersPage from '/src/pages/UsersPage'
import Dropdown from '/src/components/Dropdown'

const App = () => {
const [accessToken, setAccessToken] = useLocalStorage('accessToken', null)
const [errorCode, setErrorCode] = useState(null)
const [loading, setLoading] = useState(true)
const [initData, setInitData] = useState(null)
const [channels, setChannels] = useState([])

// Ensure server connection

Expand Down Expand Up @@ -58,28 +56,9 @@ const App = () => {
.finally(() => setLoading(false))
}, [accessToken])

useEffect(() => {
if (initData?.settings?.channels) {
setChannels(initData.settings.channels)
const mostRecentChannel = JSON.parse(
localStorage.getItem('currentChannel')
)
if (mostRecentChannel) {
setCurrentChannel(mostRecentChannel)
} else if (initData.settings.channels.length > 0) {
setCurrentChannel(initData.settings.channels[0])
}
}
}, [initData])

const handleChannelChange = (channel) => {
setCurrentChannel(channel)
}

// Render

if (loading) return <LoadingPage />

if (errorCode > 401) return <main className="center">server unavailable</main>

if (!initData.installed)
Expand All @@ -92,7 +71,7 @@ const App = () => {
<Suspense fallback={<LoadingPage />}>
<WebsocketListener />
<BrowserRouter>
<NavBar />
<MainNavbar />
<Routes>
<Route
path="/"
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/ContextMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ const ContextMenuWrapper = styled.div`
background-color: var(--color-surface-02);
min-width: 100px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.4);
box-shadow: 4px 4px 10px 4px rgba(0, 0, 0, 0.7);
z-index: 1;
hr {
margin: 0;
border: none;
border-top: 2px solid var(--color-surface-03);
border-top: 2px solid var(--color-surface-05);
}
button {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/Dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ const Dialog = ({
headerStyle,
bodyStyle,
footerStyle,
open = true,
}) => {
const dialogRef = useRef(null)

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/Dropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import clsx from 'clsx'
const DropdownContainer = styled.div`
position: relative;
display: inline-block;
z-index: 999;
.dropdown-content {
display: none;
position: absolute;
background-color: var(--color-surface-02);
min-width: 100px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.4);
box-shadow: 4px 4px 10px 4px rgba(0, 0, 0, 0.7);
z-index: 1;
hr {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const Form = styled.div`
min-width: 200px;
max-width: 200px;
padding-top: 0.5rem;
user-select: none;
user-drag: none;
}
.form-control {
Expand Down
25 changes: 22 additions & 3 deletions frontend/src/components/Progress.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useState, useEffect } from 'react'
import styled from 'styled-components'
import defaultTheme from './theme'

Expand All @@ -10,18 +11,36 @@ const BaseProgress = styled.div`
div {
height: 100%;
transition: width 0.3s linear;
background: ${(props) => props.theme.colors.cyan};
border-radius: ${(props) => props.theme.inputBorderRadius};
transition: ${(props) =>
props.disableTransition ? 'none' : 'width 0.3s linear'};
}
`
BaseProgress.defaultProps = {
theme: defaultTheme,
}

const Progress = ({ value, ...props }) => {
const [prevValue, setPrevValue] = useState(value)
const [disableTransition, setDisableTransition] = useState(false)

useEffect(() => {
if (value < prevValue) {
setDisableTransition(true)
} else {
setDisableTransition(false)
}
setPrevValue(value)
}, [value, prevValue])

return (
<BaseProgress {...props}>
<div style={{ width: `${value}%` }} />
<BaseProgress {...props} disableTransition={disableTransition}>
<div
className="progress"
style={{ width: `${value}%` }}
key={disableTransition ? 'no-transition' : 'transition'}
/>
</BaseProgress>
)
}
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/components/table/BodyCell.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const BodyCell = ({ rowData, column, cellFormatter }) => {
if (cellFormatter) return cellFormatter(rowData, column.name)
return <td>{rowData[column.name]}</td>
}
export default BodyCell
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,7 @@ import { useMemo } from 'react'
import { useDraggable } from '@dnd-kit/core'
import clsx from 'clsx'

const HeaderCell = ({ name, width, title, sortDirection, onSort }) => {
let sortArrowElement = null
if (onSort) {
if (sortDirection === 'asc') {
sortArrowElement = (
<span className="icon material-symbols-outlined">arrow_drop_up</span>
)
} else if (sortDirection === 'desc') {
sortArrowElement = (
<span className="icon material-symbols-outlined">arrow_drop_down</span>
)
} else {
sortArrowElement = (
<span className="icon material-symbols-outlined">more_vert</span>
)
}
}

const onClick = () => {
if (!onSort) return
if (sortDirection === 'asc') {
onSort(name, 'desc')
} else {
onSort(name, 'asc')
}
}
return (
<th style={{ width: width }} onClick={onClick}>
<div>
{title}
{sortArrowElement}
</div>
</th>
)
}

const BodyCell = ({ rowData, column, cellFormatter }) => {
if (cellFormatter) return cellFormatter(rowData, column.name)
return <td>{rowData[column.name]}</td>
}
import BodyCell from './BodyCell'

const DataRow = ({
rowData,
Expand All @@ -50,18 +11,32 @@ const DataRow = ({
rowHighlightColor,
rowHighlightStyle,
rowClass,
ident,
index,
selected = false,
draggableItems,
}) => {
const { attributes, listeners, setNodeRef, transform, isDragging } =
useDraggable({
id: rowData.id,
data: {
id: rowData.id,
type: 'asset',
duration: rowData.duration,
title: rowData.title,
subtitle: rowData.subtitle,
},
data:
draggableItems?.length &&
draggableItems.filter(
(item) =>
item.id === rowData.id && (item.type === rowData.type || 'asset')
).length
? draggableItems
: [
{
id: rowData.id,
type: rowData.type || 'asset',
title: rowData.title,
subtitle: rowData.subtitle,
duration: rowData.duration,
mark_in: rowData.mark_in,
mark_out: rowData.mark_out,
},
],
})

const handleClick = (event) => {
Expand All @@ -70,14 +45,10 @@ const DataRow = ({
// don't change the selection - just show the context menu
if (selected) return
}

if (onRowClick) onRowClick(rowData, event)
}

const rowStyle = {
opacity: isDragging ? 0.5 : 1,
}

const rowStyle = {}
let rowClassName = ''

// Left-border highlight color
Expand Down Expand Up @@ -119,14 +90,16 @@ const DataRow = ({
ref={setNodeRef}
onClick={handleClick}
onContextMenu={handleClick}
{...attributes}
{...listeners}
className={clsx(selected && 'selected', rowClassName)}
style={rowStyle}
data-key={ident}
data-index={index}
{...attributes}
{...listeners}
>
{rowContent}
</tr>
)
}

export { DataRow, HeaderCell }
export default DataRow
33 changes: 33 additions & 0 deletions frontend/src/components/table/HeaderCell.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useMemo } from 'react'

const SortIcon = ({ children }) => (
<span className="icon material-symbols-outlined">{children}</span>
)

const HeaderCell = ({ name, width, title, sortDirection, onSort }) => {
const sortArrowElement = useMemo(() => {
if (!onSort) return
if (sortDirection === 'asc') return <SortIcon>arrow_drop_up</SortIcon>
if (sortDirection === 'desc') return <SortIcon>arrow_drop_down</SortIcon>
return <SortIcon>more_vert</SortIcon>
}, [sortDirection, onSort])

const onClick = () => {
if (!onSort) return
if (sortDirection === 'asc') {
onSort(name, 'desc')
} else {
onSort(name, 'asc')
}
}
return (
<th style={{ width: width }} onClick={onClick}>
<div>
{title}
{sortArrowElement}
</div>
</th>
)
}

export default HeaderCell
Loading

0 comments on commit c94c0ed

Please sign in to comment.