diff --git a/ghost/admin-x-settings/src/App.tsx b/ghost/admin-x-settings/src/App.tsx index 1f34fb35f7..0e0df94e88 100644 --- a/ghost/admin-x-settings/src/App.tsx +++ b/ghost/admin-x-settings/src/App.tsx @@ -4,16 +4,18 @@ import Heading from './admin-x-ds/global/Heading'; import NiceModal from '@ebay/nice-modal-react'; import Settings from './components/Settings'; import Sidebar from './components/Sidebar'; +import {OfficialTheme} from './models/themes'; import {ServicesProvider} from './components/providers/ServiceProvider'; import {Toaster} from 'react-hot-toast'; interface AppProps { ghostVersion: string; + officialThemes: OfficialTheme[] } -function App({ghostVersion}: AppProps) { +function App({ghostVersion, officialThemes}: AppProps) { return ( - +
diff --git a/ghost/admin-x-settings/src/components/providers/ServiceProvider.tsx b/ghost/admin-x-settings/src/components/providers/ServiceProvider.tsx index 9597100567..feadd1cea5 100644 --- a/ghost/admin-x-settings/src/components/providers/ServiceProvider.tsx +++ b/ghost/admin-x-settings/src/components/providers/ServiceProvider.tsx @@ -1,25 +1,29 @@ import React, {createContext, useContext, useMemo} from 'react'; import setupGhostApi from '../../utils/api'; +import {OfficialTheme} from '../../models/themes'; export interface FileService { uploadImage: (file: File) => Promise; } interface ServicesContextProps { api: ReturnType; - fileService: FileService|null + fileService: FileService|null; + officialThemes: OfficialTheme[]; } interface ServicesProviderProps { children: React.ReactNode; ghostVersion: string; + officialThemes: OfficialTheme[]; } const ServicesContext = createContext({ api: setupGhostApi({ghostVersion: ''}), - fileService: null + fileService: null, + officialThemes: [] }); -const ServicesProvider: React.FC = ({children, ghostVersion}) => { +const ServicesProvider: React.FC = ({children, ghostVersion, officialThemes}) => { const apiService = useMemo(() => setupGhostApi({ghostVersion}), [ghostVersion]); const fileService = useMemo(() => ({ uploadImage: async (file: File): Promise => { @@ -31,7 +35,8 @@ const ServicesProvider: React.FC = ({children, ghostVersi return ( {children} @@ -40,6 +45,8 @@ const ServicesProvider: React.FC = ({children, ghostVersi export {ServicesContext, ServicesProvider}; -export const useServices = () => useContext(ServicesContext)!; +export const useServices = () => useContext(ServicesContext); export const useApi = () => useServices().api; + +export const useOfficialThemes = () => useServices().officialThemes; diff --git a/ghost/admin-x-settings/src/components/settings/site/theme/OfficialThemes.tsx b/ghost/admin-x-settings/src/components/settings/site/theme/OfficialThemes.tsx index a1349c8eae..d888ebcab4 100644 --- a/ghost/admin-x-settings/src/components/settings/site/theme/OfficialThemes.tsx +++ b/ghost/admin-x-settings/src/components/settings/site/theme/OfficialThemes.tsx @@ -2,132 +2,15 @@ import Heading from '../../../../admin-x-ds/global/Heading'; import React from 'react'; import {OfficialTheme} from '../../../../models/themes'; import {getGhostPaths} from '../../../../utils/helpers'; +import {useOfficialThemes} from '../../../providers/ServiceProvider'; const OfficialThemes: React.FC<{ onSelectTheme?: (theme: OfficialTheme) => void; }> = ({ onSelectTheme }) => { - const {assetRoot} = getGhostPaths(); - const officialThemes: OfficialTheme[] = [{ - 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' - }]; + const {adminRoot} = getGhostPaths(); + const officialThemes = useOfficialThemes(); return (
@@ -143,7 +26,7 @@ const OfficialThemes: React.FC<{ Headline Theme
diff --git a/ghost/admin-x-settings/src/main.tsx b/ghost/admin-x-settings/src/main.tsx index e879a38381..07f9f8057e 100644 --- a/ghost/admin-x-settings/src/main.tsx +++ b/ghost/admin-x-settings/src/main.tsx @@ -7,6 +7,7 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( ); diff --git a/ghost/admin/app/components/admin-x/settings.js b/ghost/admin/app/components/admin-x/settings.js index e5382fc9ac..307826d4a4 100644 --- a/ghost/admin/app/components/admin-x/settings.js +++ b/ghost/admin/app/components/admin-x/settings.js @@ -6,6 +6,127 @@ import {action} from '@ember/object'; import {inject} from 'ghost-admin/decorators/inject'; 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 { state = { hasError: false @@ -118,6 +239,7 @@ export default class AdminXSettings extends Component { Loading settings...

}>