Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions src/admin/components/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import { useConfig } from './utilities/Config';
import List from './views/collections/List';
import DefaultTemplate from './templates/Default';
import { requests } from '../api';
import Loading from './elements/Loading';
import StayLoggedIn from './modals/StayLoggedIn';
import Versions from './views/Versions';
import Version from './views/Version';
import { DocumentInfoProvider } from './utilities/DocumentInfo';
import { useLocale } from './utilities/Locale';
import { LoadingOverlayToggle } from './elements/Loading';

const Dashboard = lazy(() => import('./views/Dashboard'));
const ForgotPassword = lazy(() => import('./views/ForgotPassword'));
Expand Down Expand Up @@ -51,7 +51,7 @@ const Routes = () => {
globals,
} = config;


const isLoadingUser = Boolean(typeof user === 'undefined' || (user && typeof canAccessAdmin === 'undefined'));
const userCollection = collections.find(({ slug }) => slug === userSlug);

useEffect(() => {
Expand All @@ -73,7 +73,17 @@ const Routes = () => {
}, [i18n.language, routes, userCollection]);

return (
<Suspense fallback={<Loading />}>
<Suspense fallback={(
<LoadingOverlayToggle
show
name="route-suspense"
/>
)}
>
<LoadingOverlayToggle
name="route-loader"
show={isLoadingUser}
/>
<Route
path={routes.admin}
render={({ match }) => {
Expand All @@ -90,11 +100,7 @@ const Routes = () => {
);
}

if (initialized === true) {
if (typeof user === 'undefined' || (user && typeof canAccessAdmin === 'undefined')) {
return <Loading />;
}

if (initialized === true && !isLoadingUser) {
return (
<Switch>
{Array.isArray(customRoutes) && customRoutes.map(({ path, Component, strict, exact, sensitive }) => (
Expand Down Expand Up @@ -365,7 +371,10 @@ const Routes = () => {
return <Unauthorized />;
}

return <Loading />;
return (
// user without admin panel access
<div />
);
}

return <Redirect to={`${match.url}/login`} />;
Expand Down
45 changes: 45 additions & 0 deletions src/admin/components/elements/CodeEditor/CodeEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import Editor from '@monaco-editor/react';
import type { Props } from './types';
import { useTheme } from '../../utilities/Theme';

import './index.scss';
import { ShimmerEffect } from '../ShimmerEffect';

const baseClass = 'code-editor';

const CodeEditor: React.FC<Props> = (props) => {
const { readOnly, className, options, ...rest } = props;

const { theme } = useTheme();

const classes = [
baseClass,
className,
rest?.defaultLanguage ? `language--${rest.defaultLanguage}` : '',
].filter(Boolean).join(' ');

return (
<Editor
className={classes}
theme={theme === 'dark' ? 'vs-dark' : 'vs'}
loading={<ShimmerEffect height="35vh" />}
options={
{
detectIndentation: true,
minimap: {
enabled: false,
},
readOnly: Boolean(readOnly),
scrollBeyondLastLine: false,
tabSize: 2,
wordWrap: 'on',
...options,
}
}
{...rest}
/>
);
};

export default CodeEditor;
50 changes: 12 additions & 38 deletions src/admin/components/elements/CodeEditor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,18 @@
import React from 'react';
import Editor from '@monaco-editor/react';
import type { Props } from './types';
import { useTheme } from '../../utilities/Theme';
import React, { Suspense, lazy } from 'react';
import { ShimmerEffect } from '../ShimmerEffect';
import { Props } from './types';

import './index.scss';
const LazyEditor = lazy(() => import('./CodeEditor'));

const baseClass = 'code-editor';

const CodeEditor: React.FC<Props> = (props) => {
const { readOnly, className, options, ...rest } = props;

const { theme } = useTheme();

const classes = [
baseClass,
className,
rest?.defaultLanguage ? `language--${rest.defaultLanguage}` : '',
].filter(Boolean).join(' ');
export const CodeEditor: React.FC<Props> = (props) => {
const { height = '35vh' } = props;

return (
<Editor
height="35vh"
className={classes}
theme={theme === 'dark' ? 'vs-dark' : 'vs'}
options={
{
detectIndentation: true,
minimap: {
enabled: false,
},
readOnly: Boolean(readOnly),
scrollBeyondLastLine: false,
tabSize: 2,
wordWrap: 'on',
...options,
}
}
{...rest}
/>
<Suspense fallback={<ShimmerEffect height={height} />}>
<LazyEditor
{...props}
height={height}
/>
</Suspense>
);
};

export default CodeEditor;
4 changes: 2 additions & 2 deletions src/admin/components/elements/DatePicker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { Suspense, lazy } from 'react';
import Loading from '../Loading';
import { ShimmerEffect } from '../ShimmerEffect';
import { Props } from './types';

const DatePicker = lazy(() => import('./DatePicker'));

const DatePickerField: React.FC<Props> = (props) => (
<Suspense fallback={<Loading />}>
<Suspense fallback={<ShimmerEffect height={50} />}>
<DatePicker {...props} />
</Suspense>
);
Expand Down
141 changes: 141 additions & 0 deletions src/admin/components/elements/Loading/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
@import '../../../scss/styles';

.loading-overlay {
isolation: isolate;
height: 100%;
width: 100%;
left: 0;
top: 0;
bottom: 0;
position: fixed;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
pointer-events: none;
z-index: calc(var(--z-status) + 1);
transition-property: left, width;
transition: 250ms ease-in-out;

&.loading-overlay--entering {
opacity: 1;
animation: 500ms fade-in ease-in-out;
pointer-events: all;
}

&.loading-overlay--exiting {
opacity: 0;
animation: 500ms fade-out ease-in-out;
}

&.loading-overlay--withoutNav {
left: var(--nav-width);
width: calc(100% - var(--nav-width));
}

&:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--theme-elevation-0);
opacity: .85;
z-index: -1;
}

&__bars {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
gap: 7px;
align-items: center;
}

&__bar {
width: 2px;
background-color: currentColor;
height: 15px;

&:nth-child(1) {
transform: translateY(0);
animation: animate-bar--odd 1.25s infinite;
}

&:nth-child(2) {
transform: translateY(-2px);
animation: animate-bar--even 1.25s infinite;
}

&:nth-child(3) {
transform: translateY(0);
animation: animate-bar--odd 1.25s infinite;
}

&:nth-child(4) {
transform: translateY(-2px);
animation: animate-bar--even 1.25s infinite;
}

&:nth-child(5) {
transform: translateY(0);
animation: animate-bar--odd 1.25s infinite;
}
}

&__text {
margin-top: base(.75);
text-transform: uppercase;
font-family: var(--font-body);
font-size: base(.75);
letter-spacing: 3px;
}
}

@keyframes animate-bar--even {
0% {
transform: translateY(2px);
}

50% {
transform: translateY(-2px);
}

100% {
transform: translateY(2px);
}
}

@keyframes animate-bar--odd {
0% {
transform: translateY(-2px);
}

50% {
transform: translateY(2px);
}

100% {
transform: translateY(-2px);
}
}

@keyframes fade-in {
0% {
opacity: 0;
}

100% {
opacity: 1;
}
}

@keyframes fade-out {
0% {
opacity: 1;
}

100% {
opacity: 0;
}
}
Loading