mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-19 14:14:17 +00:00
refactor: readonly inputs in cuesheet
This commit is contained in:
committed by
Carlos Valente
parent
ed4d3ba265
commit
765d5d97cf
@@ -10,7 +10,12 @@
|
|||||||
padding-inline: 0.5em;
|
padding-inline: 0.5em;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&:hover:not(:disabled) {
|
&::placeholder {
|
||||||
|
color: $gray-500;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover:not(:disabled):not(:read-only) {
|
||||||
background-color: $gray-1100;
|
background-color: $gray-1100;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,9 +30,8 @@
|
|||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::placeholder {
|
&:read-only::placeholder {
|
||||||
color: $gray-500;
|
opacity: 0;
|
||||||
letter-spacing: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,13 @@
|
|||||||
border-radius: $component-border-radius-md;
|
border-radius: $component-border-radius-md;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
|
|
||||||
padding-inline: 0.5em;
|
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: $gray-500;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover:not(:disabled) {
|
&:hover:not(:disabled) {
|
||||||
background-color: $gray-1100;
|
background-color: $gray-1100;
|
||||||
}
|
}
|
||||||
@@ -26,21 +30,21 @@
|
|||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::placeholder {
|
&:read-only::placeholder {
|
||||||
color: $gray-500;
|
opacity: 0;
|
||||||
letter-spacing: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtle {
|
.subtle {
|
||||||
background-color: $gray-1200;
|
background-color: $gray-1200;
|
||||||
padding-top: 0.5em;
|
padding-inline: 0.5em;
|
||||||
|
padding-top: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ghosted {
|
.ghosted {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-top: 0.5em;
|
padding-top: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fluid {
|
.fluid {
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
.imageInput {
|
.imageInput {
|
||||||
&::placeholder {
|
&:not(:read-only)::placeholder {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
&:hover::placeholder {
|
&:not(:read-only):hover::placeholder {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-7
@@ -7,12 +7,13 @@ import style from './EditableImage.module.scss';
|
|||||||
|
|
||||||
interface EditableImageProps {
|
interface EditableImageProps {
|
||||||
initialValue: string;
|
initialValue: string;
|
||||||
|
readOnly?: boolean;
|
||||||
updateValue: (newValue: string) => void;
|
updateValue: (newValue: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default memo(EditableImage);
|
export default memo(EditableImage);
|
||||||
|
|
||||||
function EditableImage({ initialValue, updateValue }: EditableImageProps) {
|
function EditableImage({ initialValue, readOnly, updateValue }: EditableImageProps) {
|
||||||
const handleUpdate = (newValue: string) => {
|
const handleUpdate = (newValue: string) => {
|
||||||
if (newValue === initialValue) {
|
if (newValue === initialValue) {
|
||||||
return;
|
return;
|
||||||
@@ -35,6 +36,9 @@ function EditableImage({ initialValue, updateValue }: EditableImageProps) {
|
|||||||
variant='ghosted'
|
variant='ghosted'
|
||||||
className={style.imageInput}
|
className={style.imageInput}
|
||||||
fluid
|
fluid
|
||||||
|
readOnly={readOnly}
|
||||||
|
// we disable the field to prevent receiving focus
|
||||||
|
disabled={readOnly}
|
||||||
placeholder='Paste image URL'
|
placeholder='Paste image URL'
|
||||||
onBlur={(event) => handleUpdate(event.currentTarget.value)}
|
onBlur={(event) => handleUpdate(event.currentTarget.value)}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
@@ -49,12 +53,14 @@ function EditableImage({ initialValue, updateValue }: EditableImageProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.imageCell}>
|
<div className={style.imageCell}>
|
||||||
<div className={style.overlay}>
|
{!readOnly && (
|
||||||
<Button onClick={openInNewTab}>Preview</Button>
|
<div className={style.overlay}>
|
||||||
<Button variant='subtle-destructive' onClick={() => handleUpdate('')}>
|
<Button onClick={openInNewTab}>Preview</Button>
|
||||||
Delete
|
<Button variant='subtle-destructive' onClick={() => handleUpdate('')}>
|
||||||
</Button>
|
Delete
|
||||||
</div>
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{Boolean(initialValue) && <img loading='lazy' src={initialValue} className={style.image} />}
|
{Boolean(initialValue) && <img loading='lazy' src={initialValue} className={style.image} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
.ghostedText {
|
||||||
|
min-height: 2rem;
|
||||||
|
padding: 0;
|
||||||
|
padding-top: 0.25em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { PropsWithChildren } from 'react';
|
||||||
|
|
||||||
|
import style from './GhostedText.module.scss';
|
||||||
|
|
||||||
|
export default function GhostedText({ children }: PropsWithChildren) {
|
||||||
|
return <div className={style.ghostedText}>{children}</div>;
|
||||||
|
}
|
||||||
+20
-2
@@ -10,6 +10,7 @@ import { AppMode } from '../../../../ontimeConfig';
|
|||||||
import DurationInput from './DurationInput';
|
import DurationInput from './DurationInput';
|
||||||
import EditableImage from './EditableImage';
|
import EditableImage from './EditableImage';
|
||||||
import FlagCell from './FlagCell';
|
import FlagCell from './FlagCell';
|
||||||
|
import GhostedText from './GhostedText';
|
||||||
import MultiLineCell from './MultiLineCell';
|
import MultiLineCell from './MultiLineCell';
|
||||||
import MutedText from './MutedText';
|
import MutedText from './MutedText';
|
||||||
import SingleLineCell from './SingleLineCell';
|
import SingleLineCell from './SingleLineCell';
|
||||||
@@ -139,6 +140,11 @@ function MakeMultiLineField({ row, column, table }: CellContext<OntimeEntry, unk
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const canWrite = column.columnDef.meta?.canWrite;
|
||||||
|
if (!canWrite) {
|
||||||
|
return <GhostedText>{initialValue}</GhostedText>;
|
||||||
|
}
|
||||||
|
|
||||||
return <MultiLineCell initialValue={initialValue as string} handleUpdate={update} />;
|
return <MultiLineCell initialValue={initialValue as string} handleUpdate={update} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,8 +161,9 @@ function LazyImage({ row, column, table }: CellContext<OntimeEntry, unknown>) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const canWrite = column.columnDef.meta?.canWrite;
|
||||||
const initialValue = event.custom[column.id];
|
const initialValue = event.custom[column.id];
|
||||||
return <EditableImage initialValue={initialValue} updateValue={update} />;
|
return <EditableImage initialValue={initialValue} updateValue={update} readOnly={!canWrite} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
function MakeSingleLineField({ row, column, table }: CellContext<OntimeEntry, unknown>) {
|
function MakeSingleLineField({ row, column, table }: CellContext<OntimeEntry, unknown>) {
|
||||||
@@ -173,6 +180,11 @@ function MakeSingleLineField({ row, column, table }: CellContext<OntimeEntry, un
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const canWrite = column.columnDef.meta?.canWrite;
|
||||||
|
if (!canWrite) {
|
||||||
|
return <GhostedText>{initialValue}</GhostedText>;
|
||||||
|
}
|
||||||
|
|
||||||
return <SingleLineCell initialValue={initialValue as string} handleUpdate={update} />;
|
return <SingleLineCell initialValue={initialValue as string} handleUpdate={update} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,9 +209,15 @@ function MakeCustomField({ row, column, table }: CellContext<OntimeEntry, unknow
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fields will not contain the field if there is no value set by the user
|
// entries will not contain the field if there is no value set by the user
|
||||||
// event if there is no initial value, we still render the cell
|
// event if there is no initial value, we still render the cell
|
||||||
const initialValue = event.custom[column.id] ?? '';
|
const initialValue = event.custom[column.id] ?? '';
|
||||||
|
|
||||||
|
const canWrite = column.columnDef.meta?.canWrite;
|
||||||
|
if (!canWrite) {
|
||||||
|
return <GhostedText>{initialValue}</GhostedText>;
|
||||||
|
}
|
||||||
|
|
||||||
return <MultiLineCell initialValue={initialValue} handleUpdate={update} />;
|
return <MultiLineCell initialValue={initialValue} handleUpdate={update} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user