mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-04 02:01:58 -05:00
Fixed official theme image assets not loading in adminX
refs https://github.com/TryGhost/Team/issues/3432 The admin assets url are modified by ember build process by adding cache busting, so the original urls can't be used directly in adminX. This change passes the image assets from ember admin, causing the right image urls to be passed to adminX and for loading images.
This commit is contained in:
parent
77e3b3e947
commit
eeabce2473
5 changed files with 143 additions and 128 deletions
|
@ -4,16 +4,18 @@ import Heading from './admin-x-ds/global/Heading';
|
||||||
import NiceModal from '@ebay/nice-modal-react';
|
import NiceModal from '@ebay/nice-modal-react';
|
||||||
import Settings from './components/Settings';
|
import Settings from './components/Settings';
|
||||||
import Sidebar from './components/Sidebar';
|
import Sidebar from './components/Sidebar';
|
||||||
|
import {OfficialTheme} from './models/themes';
|
||||||
import {ServicesProvider} from './components/providers/ServiceProvider';
|
import {ServicesProvider} from './components/providers/ServiceProvider';
|
||||||
import {Toaster} from 'react-hot-toast';
|
import {Toaster} from 'react-hot-toast';
|
||||||
|
|
||||||
interface AppProps {
|
interface AppProps {
|
||||||
ghostVersion: string;
|
ghostVersion: string;
|
||||||
|
officialThemes: OfficialTheme[]
|
||||||
}
|
}
|
||||||
|
|
||||||
function App({ghostVersion}: AppProps) {
|
function App({ghostVersion, officialThemes}: AppProps) {
|
||||||
return (
|
return (
|
||||||
<ServicesProvider ghostVersion={ghostVersion}>
|
<ServicesProvider ghostVersion={ghostVersion} officialThemes={officialThemes}>
|
||||||
<DataProvider>
|
<DataProvider>
|
||||||
<div className="admin-x-settings">
|
<div className="admin-x-settings">
|
||||||
<Toaster />
|
<Toaster />
|
||||||
|
|
|
@ -1,25 +1,29 @@
|
||||||
import React, {createContext, useContext, useMemo} from 'react';
|
import React, {createContext, useContext, useMemo} from 'react';
|
||||||
import setupGhostApi from '../../utils/api';
|
import setupGhostApi from '../../utils/api';
|
||||||
|
import {OfficialTheme} from '../../models/themes';
|
||||||
|
|
||||||
export interface FileService {
|
export interface FileService {
|
||||||
uploadImage: (file: File) => Promise<string>;
|
uploadImage: (file: File) => Promise<string>;
|
||||||
}
|
}
|
||||||
interface ServicesContextProps {
|
interface ServicesContextProps {
|
||||||
api: ReturnType<typeof setupGhostApi>;
|
api: ReturnType<typeof setupGhostApi>;
|
||||||
fileService: FileService|null
|
fileService: FileService|null;
|
||||||
|
officialThemes: OfficialTheme[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ServicesProviderProps {
|
interface ServicesProviderProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
ghostVersion: string;
|
ghostVersion: string;
|
||||||
|
officialThemes: OfficialTheme[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ServicesContext = createContext<ServicesContextProps>({
|
const ServicesContext = createContext<ServicesContextProps>({
|
||||||
api: setupGhostApi({ghostVersion: ''}),
|
api: setupGhostApi({ghostVersion: ''}),
|
||||||
fileService: null
|
fileService: null,
|
||||||
|
officialThemes: []
|
||||||
});
|
});
|
||||||
|
|
||||||
const ServicesProvider: React.FC<ServicesProviderProps> = ({children, ghostVersion}) => {
|
const ServicesProvider: React.FC<ServicesProviderProps> = ({children, ghostVersion, officialThemes}) => {
|
||||||
const apiService = useMemo(() => setupGhostApi({ghostVersion}), [ghostVersion]);
|
const apiService = useMemo(() => setupGhostApi({ghostVersion}), [ghostVersion]);
|
||||||
const fileService = useMemo(() => ({
|
const fileService = useMemo(() => ({
|
||||||
uploadImage: async (file: File): Promise<string> => {
|
uploadImage: async (file: File): Promise<string> => {
|
||||||
|
@ -31,7 +35,8 @@ const ServicesProvider: React.FC<ServicesProviderProps> = ({children, ghostVersi
|
||||||
return (
|
return (
|
||||||
<ServicesContext.Provider value={{
|
<ServicesContext.Provider value={{
|
||||||
api: apiService,
|
api: apiService,
|
||||||
fileService
|
fileService,
|
||||||
|
officialThemes
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</ServicesContext.Provider>
|
</ServicesContext.Provider>
|
||||||
|
@ -40,6 +45,8 @@ const ServicesProvider: React.FC<ServicesProviderProps> = ({children, ghostVersi
|
||||||
|
|
||||||
export {ServicesContext, ServicesProvider};
|
export {ServicesContext, ServicesProvider};
|
||||||
|
|
||||||
export const useServices = () => useContext(ServicesContext)!;
|
export const useServices = () => useContext(ServicesContext);
|
||||||
|
|
||||||
export const useApi = () => useServices().api;
|
export const useApi = () => useServices().api;
|
||||||
|
|
||||||
|
export const useOfficialThemes = () => useServices().officialThemes;
|
||||||
|
|
|
@ -2,132 +2,15 @@ import Heading from '../../../../admin-x-ds/global/Heading';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {OfficialTheme} from '../../../../models/themes';
|
import {OfficialTheme} from '../../../../models/themes';
|
||||||
import {getGhostPaths} from '../../../../utils/helpers';
|
import {getGhostPaths} from '../../../../utils/helpers';
|
||||||
|
import {useOfficialThemes} from '../../../providers/ServiceProvider';
|
||||||
|
|
||||||
const OfficialThemes: React.FC<{
|
const OfficialThemes: React.FC<{
|
||||||
onSelectTheme?: (theme: OfficialTheme) => void;
|
onSelectTheme?: (theme: OfficialTheme) => void;
|
||||||
}> = ({
|
}> = ({
|
||||||
onSelectTheme
|
onSelectTheme
|
||||||
}) => {
|
}) => {
|
||||||
const {assetRoot} = getGhostPaths();
|
const {adminRoot} = getGhostPaths();
|
||||||
const officialThemes: OfficialTheme[] = [{
|
const officialThemes = useOfficialThemes();
|
||||||
name: 'Casper',
|
|
||||||
category: 'Blog',
|
|
||||||
previewUrl: 'https://demo.ghost.io/',
|
|
||||||
ref: 'default',
|
|
||||||
image: 'img/themes/Casper.png'
|
|
||||||
}, {
|
|
||||||
name: 'Headline',
|
|
||||||
category: 'News',
|
|
||||||
url: 'https://github.com/TryGhost/Headline',
|
|
||||||
previewUrl: 'https://headline.ghost.io',
|
|
||||||
ref: 'TryGhost/Headline',
|
|
||||||
image: 'img/themes/Headline.png'
|
|
||||||
}, {
|
|
||||||
name: 'Edition',
|
|
||||||
category: 'Newsletter',
|
|
||||||
url: 'https://github.com/TryGhost/Edition',
|
|
||||||
previewUrl: 'https://edition.ghost.io/',
|
|
||||||
ref: 'TryGhost/Edition',
|
|
||||||
image: 'img/themes/Edition.png'
|
|
||||||
}, {
|
|
||||||
name: 'Solo',
|
|
||||||
category: 'Blog',
|
|
||||||
url: 'https://github.com/TryGhost/Solo',
|
|
||||||
previewUrl: 'https://solo.ghost.io',
|
|
||||||
ref: 'TryGhost/Solo',
|
|
||||||
image: 'img/themes/Solo.png'
|
|
||||||
}, {
|
|
||||||
name: 'Taste',
|
|
||||||
category: 'Blog',
|
|
||||||
url: 'https://github.com/TryGhost/Taste',
|
|
||||||
previewUrl: 'https://taste.ghost.io',
|
|
||||||
ref: 'TryGhost/Taste',
|
|
||||||
image: 'img/themes/Taste.png'
|
|
||||||
}, {
|
|
||||||
name: 'Episode',
|
|
||||||
category: 'Podcast',
|
|
||||||
url: 'https://github.com/TryGhost/Episode',
|
|
||||||
previewUrl: 'https://episode.ghost.io',
|
|
||||||
ref: 'TryGhost/Episode',
|
|
||||||
image: 'img/themes/Episode.png'
|
|
||||||
}, {
|
|
||||||
name: 'Digest',
|
|
||||||
category: 'Newsletter',
|
|
||||||
url: 'https://github.com/TryGhost/Digest',
|
|
||||||
previewUrl: 'https://digest.ghost.io/',
|
|
||||||
ref: 'TryGhost/Digest',
|
|
||||||
image: 'img/themes/Digest.png'
|
|
||||||
}, {
|
|
||||||
name: 'Bulletin',
|
|
||||||
category: 'Newsletter',
|
|
||||||
url: 'https://github.com/TryGhost/Bulletin',
|
|
||||||
previewUrl: 'https://bulletin.ghost.io/',
|
|
||||||
ref: 'TryGhost/Bulletin',
|
|
||||||
image: 'img/themes/Bulletin.png'
|
|
||||||
}, {
|
|
||||||
name: 'Alto',
|
|
||||||
category: 'Blog',
|
|
||||||
url: 'https://github.com/TryGhost/Alto',
|
|
||||||
previewUrl: 'https://alto.ghost.io',
|
|
||||||
ref: 'TryGhost/Alto',
|
|
||||||
image: 'img/themes/Alto.png'
|
|
||||||
}, {
|
|
||||||
name: 'Dope',
|
|
||||||
category: 'Magazine',
|
|
||||||
url: 'https://github.com/TryGhost/Dope',
|
|
||||||
previewUrl: 'https://dope.ghost.io',
|
|
||||||
ref: 'TryGhost/Dope',
|
|
||||||
image: 'img/themes/Dope.png'
|
|
||||||
}, {
|
|
||||||
name: 'Wave',
|
|
||||||
category: 'Podcast',
|
|
||||||
url: 'https://github.com/TryGhost/Wave',
|
|
||||||
previewUrl: 'https://wave.ghost.io',
|
|
||||||
ref: 'TryGhost/Wave',
|
|
||||||
image: 'img/themes/Wave.png'
|
|
||||||
}, {
|
|
||||||
name: 'Edge',
|
|
||||||
category: 'Photography',
|
|
||||||
url: 'https://github.com/TryGhost/Edge',
|
|
||||||
previewUrl: 'https://edge.ghost.io',
|
|
||||||
ref: 'TryGhost/Edge',
|
|
||||||
image: 'img/themes/Edge.png'
|
|
||||||
}, {
|
|
||||||
name: 'Dawn',
|
|
||||||
category: 'Newsletter',
|
|
||||||
url: 'https://github.com/TryGhost/Dawn',
|
|
||||||
previewUrl: 'https://dawn.ghost.io/',
|
|
||||||
ref: 'TryGhost/Dawn',
|
|
||||||
image: 'img/themes/Dawn.png'
|
|
||||||
}, {
|
|
||||||
name: 'Ease',
|
|
||||||
category: 'Documentation',
|
|
||||||
url: 'https://github.com/TryGhost/Ease',
|
|
||||||
previewUrl: 'https://ease.ghost.io',
|
|
||||||
ref: 'TryGhost/Ease',
|
|
||||||
image: 'img/themes/Ease.png'
|
|
||||||
}, {
|
|
||||||
name: 'Ruby',
|
|
||||||
category: 'Magazine',
|
|
||||||
url: 'https://github.com/TryGhost/Ruby',
|
|
||||||
previewUrl: 'https://ruby.ghost.io',
|
|
||||||
ref: 'TryGhost/Ruby',
|
|
||||||
image: 'img/themes/Ruby.png'
|
|
||||||
}, {
|
|
||||||
name: 'London',
|
|
||||||
category: 'Photography',
|
|
||||||
url: 'https://github.com/TryGhost/London',
|
|
||||||
previewUrl: 'https://london.ghost.io',
|
|
||||||
ref: 'TryGhost/London',
|
|
||||||
image: 'img/themes/London.png'
|
|
||||||
}, {
|
|
||||||
name: 'Journal',
|
|
||||||
category: 'Newsletter',
|
|
||||||
url: 'https://github.com/TryGhost/Journal',
|
|
||||||
previewUrl: 'https://journal.ghost.io/',
|
|
||||||
ref: 'TryGhost/Journal',
|
|
||||||
image: 'img/themes/Journal.png'
|
|
||||||
}];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='h-[calc(100vh-74px-40px)] overflow-y-auto overflow-x-hidden p-[8vmin] pt-5'>
|
<div className='h-[calc(100vh-74px-40px)] overflow-y-auto overflow-x-hidden p-[8vmin] pt-5'>
|
||||||
|
@ -143,7 +26,7 @@ const OfficialThemes: React.FC<{
|
||||||
<img
|
<img
|
||||||
alt="Headline Theme"
|
alt="Headline Theme"
|
||||||
className='h-full w-full object-contain'
|
className='h-full w-full object-contain'
|
||||||
src={`${assetRoot}/${theme.image}`}
|
src={`${adminRoot}${theme.image}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-3'>
|
<div className='mt-3'>
|
||||||
|
|
|
@ -7,6 +7,7 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App
|
<App
|
||||||
ghostVersion='5.x'
|
ghostVersion='5.x'
|
||||||
|
officialThemes={[]}
|
||||||
/>
|
/>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,6 +6,127 @@ import {action} from '@ember/object';
|
||||||
import {inject} from 'ghost-admin/decorators/inject';
|
import {inject} from 'ghost-admin/decorators/inject';
|
||||||
import {inject as service} from '@ember/service';
|
import {inject as service} from '@ember/service';
|
||||||
|
|
||||||
|
// TODO: Long term move asset management directly in AdminX
|
||||||
|
const officialThemes = [{
|
||||||
|
name: 'Casper',
|
||||||
|
category: 'Blog',
|
||||||
|
previewUrl: 'https://demo.ghost.io/',
|
||||||
|
ref: 'default',
|
||||||
|
image: 'assets/img/themes/Casper.png'
|
||||||
|
}, {
|
||||||
|
name: 'Headline',
|
||||||
|
category: 'News',
|
||||||
|
url: 'https://github.com/TryGhost/Headline',
|
||||||
|
previewUrl: 'https://headline.ghost.io',
|
||||||
|
ref: 'TryGhost/Headline',
|
||||||
|
image: 'assets/img/themes/Headline.png'
|
||||||
|
}, {
|
||||||
|
name: 'Edition',
|
||||||
|
category: 'Newsletter',
|
||||||
|
url: 'https://github.com/TryGhost/Edition',
|
||||||
|
previewUrl: 'https://edition.ghost.io/',
|
||||||
|
ref: 'TryGhost/Edition',
|
||||||
|
image: 'assets/img/themes/Edition.png'
|
||||||
|
}, {
|
||||||
|
name: 'Solo',
|
||||||
|
category: 'Blog',
|
||||||
|
url: 'https://github.com/TryGhost/Solo',
|
||||||
|
previewUrl: 'https://solo.ghost.io',
|
||||||
|
ref: 'TryGhost/Solo',
|
||||||
|
image: 'assets/img/themes/Solo.png'
|
||||||
|
}, {
|
||||||
|
name: 'Taste',
|
||||||
|
category: 'Blog',
|
||||||
|
url: 'https://github.com/TryGhost/Taste',
|
||||||
|
previewUrl: 'https://taste.ghost.io',
|
||||||
|
ref: 'TryGhost/Taste',
|
||||||
|
image: 'assets/img/themes/Taste.png'
|
||||||
|
}, {
|
||||||
|
name: 'Episode',
|
||||||
|
category: 'Podcast',
|
||||||
|
url: 'https://github.com/TryGhost/Episode',
|
||||||
|
previewUrl: 'https://episode.ghost.io',
|
||||||
|
ref: 'TryGhost/Episode',
|
||||||
|
image: 'assets/img/themes/Episode.png'
|
||||||
|
}, {
|
||||||
|
name: 'Digest',
|
||||||
|
category: 'Newsletter',
|
||||||
|
url: 'https://github.com/TryGhost/Digest',
|
||||||
|
previewUrl: 'https://digest.ghost.io/',
|
||||||
|
ref: 'TryGhost/Digest',
|
||||||
|
image: 'assets/img/themes/Digest.png'
|
||||||
|
}, {
|
||||||
|
name: 'Bulletin',
|
||||||
|
category: 'Newsletter',
|
||||||
|
url: 'https://github.com/TryGhost/Bulletin',
|
||||||
|
previewUrl: 'https://bulletin.ghost.io/',
|
||||||
|
ref: 'TryGhost/Bulletin',
|
||||||
|
image: 'assets/img/themes/Bulletin.png'
|
||||||
|
}, {
|
||||||
|
name: 'Alto',
|
||||||
|
category: 'Blog',
|
||||||
|
url: 'https://github.com/TryGhost/Alto',
|
||||||
|
previewUrl: 'https://alto.ghost.io',
|
||||||
|
ref: 'TryGhost/Alto',
|
||||||
|
image: 'assets/img/themes/Alto.png'
|
||||||
|
}, {
|
||||||
|
name: 'Dope',
|
||||||
|
category: 'Magazine',
|
||||||
|
url: 'https://github.com/TryGhost/Dope',
|
||||||
|
previewUrl: 'https://dope.ghost.io',
|
||||||
|
ref: 'TryGhost/Dope',
|
||||||
|
image: 'assets/img/themes/Dope.png'
|
||||||
|
}, {
|
||||||
|
name: 'Wave',
|
||||||
|
category: 'Podcast',
|
||||||
|
url: 'https://github.com/TryGhost/Wave',
|
||||||
|
previewUrl: 'https://wave.ghost.io',
|
||||||
|
ref: 'TryGhost/Wave',
|
||||||
|
image: 'assets/img/themes/Wave.png'
|
||||||
|
}, {
|
||||||
|
name: 'Edge',
|
||||||
|
category: 'Photography',
|
||||||
|
url: 'https://github.com/TryGhost/Edge',
|
||||||
|
previewUrl: 'https://edge.ghost.io',
|
||||||
|
ref: 'TryGhost/Edge',
|
||||||
|
image: 'assets/img/themes/Edge.png'
|
||||||
|
}, {
|
||||||
|
name: 'Dawn',
|
||||||
|
category: 'Newsletter',
|
||||||
|
url: 'https://github.com/TryGhost/Dawn',
|
||||||
|
previewUrl: 'https://dawn.ghost.io/',
|
||||||
|
ref: 'TryGhost/Dawn',
|
||||||
|
image: 'assets/img/themes/Dawn.png'
|
||||||
|
}, {
|
||||||
|
name: 'Ease',
|
||||||
|
category: 'Documentation',
|
||||||
|
url: 'https://github.com/TryGhost/Ease',
|
||||||
|
previewUrl: 'https://ease.ghost.io',
|
||||||
|
ref: 'TryGhost/Ease',
|
||||||
|
image: 'assets/img/themes/Ease.png'
|
||||||
|
}, {
|
||||||
|
name: 'Ruby',
|
||||||
|
category: 'Magazine',
|
||||||
|
url: 'https://github.com/TryGhost/Ruby',
|
||||||
|
previewUrl: 'https://ruby.ghost.io',
|
||||||
|
ref: 'TryGhost/Ruby',
|
||||||
|
image: 'assets/img/themes/Ruby.png'
|
||||||
|
}, {
|
||||||
|
name: 'London',
|
||||||
|
category: 'Photography',
|
||||||
|
url: 'https://github.com/TryGhost/London',
|
||||||
|
previewUrl: 'https://london.ghost.io',
|
||||||
|
ref: 'TryGhost/London',
|
||||||
|
image: 'assets/img/themes/London.png'
|
||||||
|
}, {
|
||||||
|
name: 'Journal',
|
||||||
|
category: 'Newsletter',
|
||||||
|
url: 'https://github.com/TryGhost/Journal',
|
||||||
|
previewUrl: 'https://journal.ghost.io/',
|
||||||
|
ref: 'TryGhost/Journal',
|
||||||
|
image: 'assets/img/themes/Journal.png'
|
||||||
|
}];
|
||||||
|
|
||||||
class ErrorHandler extends React.Component {
|
class ErrorHandler extends React.Component {
|
||||||
state = {
|
state = {
|
||||||
hasError: false
|
hasError: false
|
||||||
|
@ -118,6 +239,7 @@ export default class AdminXSettings extends Component {
|
||||||
<Suspense fallback={<p className="admin-x-settings-container--loading">Loading settings...</p>}>
|
<Suspense fallback={<p className="admin-x-settings-container--loading">Loading settings...</p>}>
|
||||||
<AdminXApp
|
<AdminXApp
|
||||||
ghostVersion={config.APP.version}
|
ghostVersion={config.APP.version}
|
||||||
|
officialThemes={officialThemes}
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</ErrorHandler>
|
</ErrorHandler>
|
||||||
|
|
Loading…
Add table
Reference in a new issue