Styles and keys refactor for enhanced performance.

Version 0.21.1
This commit is contained in:
francesco
2020-12-29 15:49:25 +01:00
parent 26a6126ff0
commit 33ca291ef7
32 changed files with 240 additions and 230 deletions

View File

@@ -1,6 +1,10 @@
# Change Log
## [0.21.0] - 2020-12-15
## [0.21.1] - 2020-12-30
### Changed
- Table performance improvements
## [0.21.0] - 2020-12-29
### Added
- Inline editing of tables. Tables are now editable by default. There are two new
parameters you can set in entity collection views.
@@ -8,7 +12,6 @@ parameters you can set in entity collection views.
edit or create new entities.
- `inlineEditing` defaults to true. If false, the users can still edit the
content, but the inline editing is disabled. The side panel is still enabled.
### Changed
- [BREAKING] The custom fields API has been refactored and simplified. The Formik
props have been abstracted away and only the relevant fields are exposed.

View File

@@ -1,6 +1,6 @@
{
"name": "@camberi/firecms",
"version": "0.21.0",
"version": "0.21.1",
"description": "Awesome Firestore based CMS",
"author": "camberi",
"license": "GPL-3.0",

View File

@@ -32,7 +32,7 @@ import { getIconForProperty } from "../util/property_icons";
import { CollectionTableToolbar } from "./CollectionTableToolbar";
import DeleteIcon from "@material-ui/icons/Delete";
import KeyboardTabIcon from "@material-ui/icons/KeyboardTab";
import SkeletonComponent, { renderSkeletonText } from "../preview/SkeletonComponent";
import SkeletonComponent, { renderSkeletonText } from "../preview/components/SkeletonComponent";
import ErrorBoundary from "../components/ErrorBoundary";
import { getPreviewSizeFrom } from "../preview/PreviewComponentProps";
import DeleteEntityDialog from "./DeleteEntityDialog";
@@ -388,20 +388,24 @@ export function CollectionTable<S extends EntitySchema<Key, P>,
if (column.type === "property") {
if (!editEnabled || !inlineEditing) {
return <PreviewTableCell
size={size}
align={column.align}>
<PreviewComponent
name={propertyKey}
value={entity.values[propertyKey]}
property={property}
size={getPreviewSizeFrom(size)}
entitySchema={schema}
/>
</PreviewTableCell>;
return (
<PreviewTableCell
key={`preview_cell_${propertyKey}_${rowIndex}_${columnIndex}`}
size={size}
align={column.align}>
<PreviewComponent
name={`preview_${propertyKey}_${rowIndex}_${columnIndex}`}
value={entity.values[propertyKey]}
property={property}
size={getPreviewSizeFrom(size)}
entitySchema={schema}
/>
</PreviewTableCell>
);
} else if (property.disabled || !editEnabled) {
return (
<DisabledTableCell
key={`disabled_cell_${propertyKey}_${rowIndex}_${columnIndex}`}
size={size}
align={column.align}>
<PreviewComponent
@@ -438,25 +442,27 @@ export function CollectionTable<S extends EntitySchema<Key, P>,
const isFocused = selected && focused;
return entity ?
<TableCell tableKey={tableKey}
size={size}
align={column.align}
name={propertyKey}
path={collectionPath}
entity={entity}
schema={schema}
selected={selected}
focused={isFocused}
setPreventOutsideClick={setPreventOutsideClick}
setFocused={setFocused}
value={entity.values[propertyKey]}
columnIndex={columnIndex}
rowIndex={rowIndex}
CollectionTable={CollectionTable}
property={property}
openPopup={openPopup}
select={onSelect}
createFormField={createFormField}/>
<TableCell
key={`table_cell_${propertyKey}_${rowIndex}_${columnIndex}`}
tableKey={tableKey}
size={size}
align={column.align}
name={propertyKey}
path={collectionPath}
entity={entity}
schema={schema}
selected={selected}
focused={isFocused}
setPreventOutsideClick={setPreventOutsideClick}
setFocused={setFocused}
value={entity.values[propertyKey]}
columnIndex={columnIndex}
rowIndex={rowIndex}
CollectionTable={CollectionTable}
property={property}
openPopup={openPopup}
select={onSelect}
createFormField={createFormField}/>
:
<SkeletonComponent property={property}
size={getPreviewSizeFrom(size)}/>;
@@ -608,7 +614,7 @@ export function CollectionTable<S extends EntitySchema<Key, P>,
key: orderByProperty,
order: currentOrder
} : undefined}
overscanRowCount={6}
overscanRowCount={2}
onColumnSort={onColumnSort}
onEndReachedThreshold={PIXEL_NEXT_PAGE_OFFSET}
onEndReached={loadNextPage}
@@ -632,7 +638,7 @@ export function CollectionTable<S extends EntitySchema<Key, P>,
{columns.map((column) =>
<Column
key={column.id}
key={`column_${tableKey}_${column.id}`}
type={column.type}
title={column.label}
className={classes.column}

View File

@@ -48,6 +48,7 @@ export function TableSelect(props: {
<Select
// TODO: related to prev. replace autofocus with ref, it makes the scroll jump when rendered
autoFocus
key={`table_select_${name}`}
// inputRef={ref}
className={classes.select}
classes={{ root: classes.selectRoot }}
@@ -88,7 +89,7 @@ export function TableSelect(props: {
small={true}/>;
if (multiple) {
return (
<MenuItem key={`select-${key}`}
<MenuItem key={`select-${name}-${key}`}
value={key}
dense={true}>
<Checkbox
@@ -98,7 +99,7 @@ export function TableSelect(props: {
);
} else {
return (
<MenuItem key={`select-${key}`} value={key}
<MenuItem key={`select-${name}-${key}`} value={key}
dense={true}>
{chip}
</MenuItem>

View File

@@ -105,7 +105,7 @@ export default function StringNumberFilterField({ name, property }: StringNumber
}}>
{possibleOperations.map((op) =>
<MenuItem
key={`filter_op_${op}`}
key={`filter_op_${name}_${op}`}
value={op}>{operationLabels[op]}</MenuItem>
)}
@@ -116,7 +116,7 @@ export default function StringNumberFilterField({ name, property }: StringNumber
{!enumValues && <Input
fullWidth
key={`filter-${name}`}
key={`filter_${name}`}
type={dataType === "number" ? "number" : undefined}
value={internalValue ? internalValue : ""}
onChange={(evt) => {
@@ -147,7 +147,7 @@ export default function StringNumberFilterField({ name, property }: StringNumber
</div>
) : undefined}>
{Object.entries(enumValues).map(([key, value]) => (
<MenuItem key={`select-${key}`}
<MenuItem key={`select_${name}_${key}`}
value={key}>
<CustomChip
colorKey={key as string}

View File

@@ -149,7 +149,7 @@ function PopupFormField<S extends EntitySchema>({
const form = entity && (
<div
key={`${tableKey}_${entity.id}_${rowIndex}`}
key={`popup_form_${tableKey}_${entity.id}_${rowIndex}`}
style={{
width: 470,
maxWidth: "100vw",
@@ -194,6 +194,7 @@ function PopupFormField<S extends EntitySchema>({
return (
<Portal container={document.body}>
<Draggable
key={`draggable_${name}_${rowIndex}`}
x={popupLocation?.x}
y={popupLocation?.y}
open={formPopupOpen}

View File

@@ -19,7 +19,8 @@ import { ErrorFocus } from "./ErrorFocus";
export const useStyles = makeStyles(theme => createStyles({
stickyButtons: {
marginTop: theme.spacing(2),
backgroundColor: "#ffffffb8",
background: "rgba(255,255,255,0.6)",
backdropFilter: "blur(3px)",
borderTop: "solid 1px #f9f9f9",
position: "sticky",
bottom: 0,
@@ -213,7 +214,7 @@ function EntityForm<S extends EntitySchema>({
Object.entries(underlyingChanges).forEach(([key, value]) => {
const formValue = values[key];
if (!deepEqual(value, formValue) && !touched[key]) {
console.debug("Updated value from Firestore:", key, value)
console.debug("Updated value from Firestore:", key, value);
setFieldValue(key, !!value ? value : null);
setFieldTouched(key, false);
}

View File

@@ -165,7 +165,7 @@ export default function ReferenceField<S extends EntitySchema>({
{listProperties && listProperties.map((key, index) => {
const propertyKey = schema.properties[key as string];
return (
<Box key={"ref_prev_" + key + index}
<Box
mt={0.5}
mb={0.5}>
<ErrorBoundary>{
@@ -221,7 +221,7 @@ export default function ReferenceField<S extends EntitySchema>({
</Box>
{entity &&
<Box key={"ref_prev_id"}
<Box
alignSelf={"center"}
m={1}>
<Tooltip title={value && value.path}>

View File

@@ -65,7 +65,7 @@ export default function Select<T extends EnumType>({
}>
{Object.entries(enumValues).map(([key, value]) => (
<MenuItem key={`select-${key}`} value={key}>
<MenuItem key={`select_${name}_${key}`} value={key}>
<CustomChip
colorKey={typeof key === "number" ? `${name}_${key}` : key as string}
label={value as string}

View File

@@ -398,16 +398,18 @@ export function StorageUpload({
);
}
return <StorageEntry
key={`storage_entry_${index}`}
entry={entry}
index={index}
dragType={"storage_card_" + name}
moveItem={moveItem}
onHover={setHoveredIndex}
hovered={hoveredIndex === index}>
{child}
</StorageEntry>;
return (
<StorageEntry
key={`storage_entry_${name}_${index}`}
entry={entry}
index={index}
dragType={"storage_card_" + name}
moveItem={moveItem}
onHover={setHoveredIndex}
hovered={hoveredIndex === index}>
{child}
</StorageEntry>
);
})
}

View File

@@ -1,7 +1,7 @@
import * as React from "react";
import { useEffect, useState } from "react";
import { EntitySchema } from "../models";
import { renderSkeletonText } from "./SkeletonComponent";
import { renderSkeletonText } from "./components/SkeletonComponent";
export interface AsyncPreviewComponentProps<S extends EntitySchema> {

View File

@@ -58,7 +58,7 @@ export default function EntityPreview<S extends EntitySchema>(
<TableContainer>
<Table aria-label="entity table">
<TableBody>
<TableRow key={"entity_prev_id"}>
<TableRow >
<TableCell align="right"
component="td"
scope="row"

View File

@@ -32,6 +32,8 @@ import ErrorIcon from "@material-ui/icons/Error";
import firebase from "firebase/app";
import { Box } from "@material-ui/core";
import { useStyles } from "./components/styles";
import clsx from "clsx";
export function PreviewComponent<T>(props: PreviewComponentProps<T>) {
let content: JSX.Element | any;
@@ -171,14 +173,14 @@ export function PreviewComponent<T>(props: PreviewComponentProps<T>) {
}
function buildWrongValueType() {
const classes = useStyles();
return (
<Box
display={"flex"}
alignItems={"center"}
m={1}>
<div
className={clsx(classes.flexCenter, classes.smallMargin)}>
<ErrorIcon fontSize={"small"} color={"error"}/>
<Box marginLeft={1}>Unexpected value</Box>
</Box>
</div>
);
}

View File

@@ -1,6 +1,6 @@
import React, { useEffect } from "react";
import { getDownloadURL } from "../firebase";
import { renderSkeletonImageThumbnail } from "./SkeletonComponent";
import { renderSkeletonImageThumbnail } from "./components/SkeletonComponent";
import {
PreviewComponentFactoryProps,
PreviewComponentProps

View File

@@ -5,22 +5,11 @@ import {
import React from "react";
import { Box, createStyles, makeStyles, Theme } from "@material-ui/core";
import ErrorBoundary from "../../components/ErrorBoundary";
import { EnumValues, NumberProperty, StringProperty } from "../../models";
import { CustomChip } from "./CustomChip";
import { useStyles } from "./styles";
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: "flex",
flexWrap: "wrap"
},
item: {
m: 0.2,
}
})
);
export function buildArrayEnumPreview(value: string[] | number[],
name: string,
@@ -30,10 +19,10 @@ export function buildArrayEnumPreview(value: string[] | number[],
const classes = useStyles();
return (
<div className={classes.root}>
<div className={classes.arrayRoot}>
{value &&
(value as any[]).map((v, index) => (
<div className={classes.item} key={`preview_array_ref_${name}_${index}`}>
<div className={classes.arrayItem} key={`preview_array_ref_${name}_${index}`}>
<ErrorBoundary>
<CustomChip
colorKey={typeof v == "number" ? `${name}_${v}` : v as string}

View File

@@ -16,16 +16,7 @@ import {
TableRow,
Theme
} from "@material-ui/core";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
tableNoBottomBorder: {
"&:last-child th, &:last-child td": {
borderBottom: 0
}
}
})
);
import { useStyles } from "./styles";
export function ArrayOfMapsPreview({
name,

View File

@@ -9,14 +9,7 @@ import React from "react";
import { createStyles, makeStyles, Theme } from "@material-ui/core";
import { default as ReferencePreview } from "./ReferencePreview";
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
margin: 0.2,
}
})
);
import { useStyles } from "./styles";
export function ArrayOfReferencesPreview({
name,
@@ -37,7 +30,7 @@ export function ArrayOfReferencesPreview({
<>
{value &&
value.map((v, index) =>
<div className={classes.root} key={`preview_array_ref_${name}_${index}`}>
<div className={classes.arrayItem} key={`preview_array_ref_${name}_${index}`}>
<ReferencePreview
name={`${name}[${index}]`}
entitySchema={entitySchema}

View File

@@ -9,6 +9,7 @@ import React from "react";
import { Box } from "@material-ui/core";
import ErrorBoundary from "../../components/ErrorBoundary";
import { PreviewComponent } from "../PreviewComponent";
import { useStyles } from "./styles";
export function ArrayOfStorageComponentsPreview({
@@ -24,14 +25,13 @@ export function ArrayOfStorageComponentsPreview({
throw Error("Picked wrong preview component ArrayOfStorageComponentsPreview");
const childSize: PreviewSize = size === "regular" ? "small" : "tiny";
const classes = useStyles();
return <Box
display={"flex"}
flexWrap="wrap">
return <div className={classes.arrayRoot}>
{value &&
value.map((v, index) =>
<Box m={0.2}
key={"preview_array_storage_" + name + v + index}>
<div className={classes.arrayItem}
key={`preview_array_storage_${name}_${index}`}>
<ErrorBoundary>
<PreviewComponent
name={name}
@@ -40,7 +40,7 @@ export function ArrayOfStorageComponentsPreview({
size={childSize}
entitySchema={entitySchema}/>
</ErrorBoundary>
</Box>
</div>
)}
</Box>;
</div>;
}

View File

@@ -6,10 +6,9 @@ import {
import React from "react";
import { Box } from "@material-ui/core";
import ErrorBoundary from "../../components/ErrorBoundary";
import { StringPreview } from "./StringPreview";
import { useStyles } from "./styles";
export function ArrayOfStringsPreview({
name,
@@ -19,6 +18,8 @@ export function ArrayOfStringsPreview({
entitySchema
}: PreviewComponentProps<string[]> & PreviewComponentFactoryProps) {
const classes = useStyles();
if (property.dataType !== "array" || property.of.dataType !== "string")
throw Error("Picked wrong preview component ArrayOfStringsPreview");
@@ -28,11 +29,10 @@ export function ArrayOfStringsPreview({
const stringProperty = property.of as StringProperty;
return (
<Box display={stringProperty.config?.previewAsTag ? "flex" : "block"}
flexWrap={"wrap"}>
<div className={classes.arrayRoot}>
{value &&
value.map((v, index) =>
<Box m={stringProperty.config?.previewAsTag ? 0.2 : 0.5}
<div className={classes.arrayItem}
key={`preview_array_strings_${name}_${index}`}>
<ErrorBoundary>
<StringPreview name={name}
@@ -41,8 +41,8 @@ export function ArrayOfStringsPreview({
size={size}
entitySchema={entitySchema}/>
</ErrorBoundary>
</Box>
</div>
)}
</Box>
</div>
);
}

View File

@@ -16,17 +16,7 @@ import {
Theme
} from "@material-ui/core";
import { PreviewComponent } from "../PreviewComponent";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
tableNoBottomBorder: {
"&:last-child th, &:last-child td": {
borderBottom: 0
}
}
})
);
import { useStyles } from "./styles";
export function ArrayPreview({
name,
@@ -37,6 +27,8 @@ export function ArrayPreview({
PreviewComponent
}: PreviewComponentProps<any[]> & PreviewComponentFactoryProps) {
const classes = useStyles();
if (property.dataType !== "array")
throw Error("Picked wrong preview component ArrayPreview");
@@ -47,11 +39,11 @@ export function ArrayPreview({
const childSize: PreviewSize = size === "regular" ? "small" : "tiny";
return (
<Grid>
<>
{values &&
values.map((value, index) =>
<React.Fragment key={"preview_array_" + value + "_" + index}>
<Box p={1}>
<div className={classes.arrayItemBig} >
<ErrorBoundary>
<PreviewComponent
name={name}
@@ -60,10 +52,10 @@ export function ArrayPreview({
size={childSize}
entitySchema={entitySchema}/>
</ErrorBoundary>
</Box>
</div>
{index < values.length - 1 && <Divider/>}
</React.Fragment>
)}
</Grid>
</>
);
}

View File

@@ -35,7 +35,6 @@ export function CustomChip({ colorKey, label, error, outlined, small }: EnumChip
label: classes.label
}}
size={small ? "small" : "medium"}
key={"preview_chip_" + colorKey}
variant={outlined ? "outlined" : "default"}
label={label}
/>

View File

@@ -13,7 +13,7 @@ export function EnumChipsPreview({
}: PreviewComponentProps<string>):React.ReactElement {
if (property.config?.enumValues) {
return <React.Fragment>{property.config?.enumValues[value]}</React.Fragment>;
return <>{property.config?.enumValues[value]}</>;
} else if (property.config?.previewAsTag) {
return (
<ErrorBoundary>
@@ -24,6 +24,6 @@ export function EnumChipsPreview({
/>
</ErrorBoundary>);
} else {
return <React.Fragment>{value}</React.Fragment>;
return <>{value}</>;
}
}

View File

@@ -1,15 +1,20 @@
import React, { CSSProperties, useState } from "react";
import { Box, IconButton } from "@material-ui/core";
import React, { CSSProperties, useMemo, useState } from "react";
import clsx from "clsx";
import { IconButton } from "@material-ui/core";
import OpenInNewIcon from "@material-ui/icons/OpenInNew";
import { getThumbnailMeasure, PreviewSize } from "./PreviewComponentProps";
import { getThumbnailMeasure, PreviewSize } from "../PreviewComponentProps";
import { useStyles } from "./styles";
type ImagePreviewProps = { size: PreviewSize, url: string };
function ImagePreview({ size, url }: ImagePreviewProps) {
const classes = useStyles();
const [onHover, setOnHover] = useState(false);
const imageSize = getThumbnailMeasure(size);
const imageSize = useMemo(() => getThumbnailMeasure(size), [size]);
if (size === "tiny") {
return (
@@ -34,22 +39,16 @@ function ImagePreview({ size, url }: ImagePreviewProps) {
};
return (
<Box
<div
className={clsx(classes.flexCenter, classes.imageWrap)}
key={"image_preview_" + url}
display="flex"
alignItems="center"
justifyContent="center"
style={{
position: "relative",
maxWidth: "100%",
maxHeight: "100%"
width: imageSize,
height: imageSize
}}
onMouseEnter={() => setOnHover(true)}
onMouseMove={() => setOnHover(true)}
onMouseLeave={() => setOnHover(false)}
width={imageSize}
height={imageSize}>
onMouseLeave={() => setOnHover(false)}>
<img src={url}
style={imageStyle}/>
@@ -71,7 +70,7 @@ function ImagePreview({ size, url }: ImagePreviewProps) {
</IconButton>
</a>
)}
</Box>
</div>
);
}

View File

@@ -59,7 +59,7 @@ export function MapPreview<T>({
if (size !== "regular")
return (
<React.Fragment>
<>
{mapProperties.map((key, index) => (
<ListItem
key={"map_preview_" + mapProperty.title + key + index}>
@@ -72,7 +72,7 @@ export function MapPreview<T>({
</ErrorBoundary>
</ListItem>
))}
</React.Fragment>
</>
);
return (
@@ -82,16 +82,16 @@ export function MapPreview<T>({
mapProperties.map((key, index) => {
return (
<TableRow
key={`map_preview_table_${mapProperty.title}_${index}`}
key={`map_preview_table_${name}_${index}`}
className={classes.tableNoBottomBorder}>
<TableCell key={`table-cell-title-${key}`}
<TableCell key={`table-cell-title-${name}-${key}`}
component="th">
<Typography variant={"caption"}
color={"textSecondary"}>
{mapProperty.properties[key].title}
</Typography>
</TableCell>
<TableCell key={`table-cell-${key}`} component="th">
<TableCell key={`table-cell-${name}-${key}`} component="th">
<ErrorBoundary>
<PreviewComponent
name={key}

View File

@@ -19,6 +19,6 @@ export function NumberPreview({
outlined={false}
small={size !== "regular"}/>;
} else {
return <React.Fragment>{value}</React.Fragment>;
return <>{value}</>;
}
}

View File

@@ -3,7 +3,6 @@ import { useEffect } from "react";
import clsx from "clsx";
import {
Box,
createStyles,
IconButton,
makeStyles,
@@ -20,7 +19,7 @@ import {
PreviewComponentProps,
PreviewSize
} from "../PreviewComponentProps";
import SkeletonComponent from "../SkeletonComponent";
import SkeletonComponent from "./SkeletonComponent";
import KeyboardTabIcon from "@material-ui/icons/KeyboardTab";
import { useSelectedEntityContext } from "../../side_dialog/SelectedEntityContext";
import ErrorIcon from "@material-ui/icons/Error";
@@ -31,8 +30,9 @@ import { useAppConfigContext } from "../../contexts/AppConfigContext";
import firebase from "firebase/app";
import "firebase/firestore";
import { PreviewComponent } from "../PreviewComponent";
import { useStyles } from "./styles";
const useStyles = makeStyles<Theme, { size: PreviewSize }>((theme: Theme) =>
const useReferenceStyles = makeStyles<Theme, { size: PreviewSize }>((theme: Theme) =>
createStyles({
paper: {
display: "flex",
@@ -95,7 +95,8 @@ export default React.memo<PreviewComponentProps<firebase.firestore.DocumentRefer
entitySchema
}: PreviewComponentProps<firebase.firestore.DocumentReference> & PreviewComponentFactoryProps) {
const classes = useStyles({ size });
const referenceClasses = useReferenceStyles({ size });
const classes = useStyles();
// TODO: remove when https://github.com/firebase/firebase-js-sdk/issues/4125 is fixed and replace with instance check of DocumentReference
const isFirestoreReference = value
@@ -135,13 +136,13 @@ export default React.memo<PreviewComponentProps<firebase.firestore.DocumentRefer
let body: JSX.Element;
function buildError(error: string) {
return <Box
display={"flex"}
alignItems={"center"}
m={1}>
return <div
className={clsx(classes.flexCenter, classes.smallMargin)}>
<ErrorIcon fontSize={"small"} color={"error"}/>
<Box marginLeft={1}>{error}</Box>
</Box>;
<div style={{
marginLeft: 1
}}>{error}</div>
</div>;
}
if (!value) {
@@ -160,11 +161,10 @@ export default React.memo<PreviewComponentProps<firebase.firestore.DocumentRefer
body = (
<>
<div className={classes.root}>
<div className={referenceClasses.root}>
{size !== "tiny" && entity &&
<div key={"ref_prev_id"}
className={classes.inner}>
<div className={referenceClasses.inner}>
<Typography variant={"caption"} className={"mono"}>
{entity.id}
</Typography>
@@ -175,7 +175,7 @@ export default React.memo<PreviewComponentProps<firebase.firestore.DocumentRefer
return (
<div key={"ref_prev" + property.title + key}
className={classes.inner}>
className={referenceClasses.inner}>
{entity && PreviewComponent ?
<PreviewComponent name={key as string}
value={entity.values[key as string]}
@@ -191,7 +191,7 @@ export default React.memo<PreviewComponentProps<firebase.firestore.DocumentRefer
})}
</div>
<div className={classes.marginAuto}>
<div className={referenceClasses.marginAuto}>
{entity &&
<Tooltip title={`See details for ${entity.id}`}>
<IconButton
@@ -212,12 +212,12 @@ export default React.memo<PreviewComponentProps<firebase.firestore.DocumentRefer
}
return (
<Paper elevation={0} className={clsx(classes.paper,
<Paper elevation={0} className={clsx(referenceClasses.paper,
{
[classes.regular]: size === "regular",
[classes.small]: size === "small",
[classes.tiny]: size === "tiny",
[classes.clickable]: !!onClick
[referenceClasses.regular]: size === "regular",
[referenceClasses.small]: size === "small",
[referenceClasses.tiny]: size === "tiny",
[referenceClasses.clickable]: !!onClick
})}
onClick={onClick}>

View File

@@ -5,41 +5,27 @@ import {
Properties,
Property,
StringProperty
} from "../models";
} from "../../models";
import React from "react";
import {
Box,
createStyles,
Divider,
Grid,
List,
ListItem,
makeStyles,
Table,
TableBody,
TableCell,
TableRow,
Theme
TableRow
} from "@material-ui/core";
import { Skeleton } from "@material-ui/lab";
import { getThumbnailMeasure, PreviewSize } from "./PreviewComponentProps";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
tableNoBottomBorder: {
"&:last-child th, &:last-child td": {
borderBottom: 0
}
}
})
);
import { getThumbnailMeasure, PreviewSize } from "../PreviewComponentProps";
import { useStyles } from "./styles";
export interface SkeletonComponentProps<T> {
property: Property,
size: PreviewSize
}
export default function SkeletonComponent<T>({
property,
size
@@ -188,9 +174,9 @@ function renderArrayOfStrings() {
<Grid>
{
[0, 1].map((value, index) => (
<React.Fragment key={"skeleton_array_strings_" + value}>
<>
{renderSkeletonText(index)}
</React.Fragment>
</>
))}
</Grid>
);
@@ -201,9 +187,9 @@ function renderArrayEnumTableCell<T extends EnumType>() {
<Grid>
{
[0, 1].map((value, index) =>
<React.Fragment key={"skeleton_array_enum_" + value}>
<>
{renderSkeletonText(index)}
</React.Fragment>
</>
)}
</Grid>
);
@@ -217,10 +203,10 @@ function renderGenericArrayCell(
{
[0, 1].map((value, index) =>
<React.Fragment key={"skeleton_array_" + value}>
<>
<SkeletonComponent property={property}
size={"small"}/>
</React.Fragment>
</>
)}
</Grid>
);
@@ -230,17 +216,21 @@ function renderShapedArray<T extends EnumType>(
properties: Property[]
) {
const classes = useStyles();
return (
<Grid>
{properties &&
properties.map((property, index) =>
<React.Fragment
key={"preview_array_" + properties[index] + "_" + index}>
{properties[index] && <Box m={1}>
<SkeletonComponent
property={property}
size={"small"}/>
</Box>}
{properties[index] && (
<div className={classes.smallMargin}>
<SkeletonComponent
property={property}
size={"small"}/>
</div>
)}
{properties[index] && index < properties.length - 1 &&
<Divider/>}
</React.Fragment>
@@ -300,26 +290,29 @@ function renderUrlComponent(property: StringProperty, size: PreviewSize = "regul
}
function renderUrlFile(size: PreviewSize) {
const classes = useStyles();
return (
<Box
display="flex"
alignItems="center"
justifyContent="center"
width={getThumbnailMeasure(size)}
height={getThumbnailMeasure(size)}>
<div
className={(classes as any)}
style={{
width: getThumbnailMeasure(size),
height: getThumbnailMeasure(size)
}}>
{renderSkeletonIcon()}
</Box>
</div>
);
}
export function renderSkeletonText(index?: number) {
return <Skeleton key={"skeleton_text_" + index} variant="text"/>;
return <Skeleton variant="text"/>;
}
export function renderSkeletonCaptionText(index?: number) {
return <Skeleton key={"skeleton_text_" + index}
height={20}
variant="text"/>;
return <Skeleton
height={20}
variant="text"/>;
}
export function renderSkeletonIcon() {

View File

@@ -29,6 +29,6 @@ export function StringPreview({
/>
</ErrorBoundary>);
} else {
return <React.Fragment>{value}</React.Fragment>;
return <>{value}</>;
}
}

View File

@@ -4,20 +4,23 @@ import {
} from "../PreviewComponentProps";
import React from "react";
import { MediaType } from "../../models";
import ImagePreview from "../ImagePreview";
import ImagePreview from "./ImagePreview";
import { Box, CardMedia, Link } from "@material-ui/core";
import { CardMedia, Link } from "@material-ui/core";
import DescriptionOutlinedIcon from "@material-ui/icons/DescriptionOutlined";
import OpenInNewIcon from "@material-ui/icons/OpenInNew";
import { useStyles } from "./styles";
export function UrlComponentPreview({
name,
value,
property,
size,
entitySchema
}: PreviewComponentProps<string>):React.ReactElement {
name,
value,
property,
size,
entitySchema
}: PreviewComponentProps<string>): React.ReactElement {
const classes = useStyles();
if (!value) return <div/>;
const url = value;
@@ -60,14 +63,13 @@ export function UrlComponentPreview({
rel="noopener noreferrer"
target="_blank"
onClick={(e) => e.stopPropagation()}>
<Box
display="flex"
alignItems="center"
justifyContent="center"
width={getThumbnailMeasure(size)}
height={getThumbnailMeasure(size)}>
<div className={classes.flexCenter}
style={{
width: getThumbnailMeasure(size),
height: getThumbnailMeasure(size)
}}>
<DescriptionOutlinedIcon/>
</Box>
</div>
</a>;
}
}

View File

@@ -0,0 +1,36 @@
import * as React from "react";
import { createStyles, makeStyles, Theme } from "@material-ui/core";
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
flexCenter: {
display:"flex",
alignItems:"center",
justifyContent:"center"
},
smallMargin: {
margin: theme.spacing(1)
},
arrayRoot: {
display: "flex",
flexWrap: "wrap"
},
arrayItem: {
m: 0.2,
},
arrayItemBig: {
m: theme.spacing(1),
},
tableNoBottomBorder: {
"&:last-child th, &:last-child td": {
borderBottom: 0
}
},
imageWrap:{
position: "relative",
maxWidth: "100%",
maxHeight: "100%"
}
})
);

View File

@@ -6,7 +6,7 @@ import StorageThumbnail from "./StorageThumbnail";
import AsyncPreviewComponent from "./AsyncPreviewComponent";
import EntityPreview from "./EntityPreview";
import PreviewComponent from "./PreviewComponent";
import SkeletonComponent from "./SkeletonComponent";
import SkeletonComponent from "./components/SkeletonComponent";
export {
PreviewComponent,

View File

@@ -26,7 +26,7 @@ function AdditionalViewRoute({
breadcrumbsContext.set({
breadcrumbs: [breadcrumb]
});
}, [url]);
}, []);
return <React.Fragment>
{additionalView.view}