Added ActivityPub playground (#20081)
ref MOM61 - Adds admin-x react app we’ll use as ActivityPub playground to the sidebar nav behind the feature flag. - Wired up routing to Ember - Setup the project as `admin-x-activitypub` --------- Co-authored-by: Ronald Langeveld <hi@ronaldlangeveld.com>
This commit is contained in:
parent
af02ca7044
commit
7a3bbfde10
4
.github/scripts/dev.js
vendored
4
.github/scripts/dev.js
vendored
@ -66,7 +66,7 @@ const COMMAND_TYPESCRIPT = {
|
||||
env: {}
|
||||
};
|
||||
|
||||
const adminXApps = '@tryghost/admin-x-demo,@tryghost/admin-x-settings';
|
||||
const adminXApps = '@tryghost/admin-x-demo,@tryghost/admin-x-settings,@tryghost/admin-x-activitypub';
|
||||
|
||||
const COMMANDS_ADMINX = [{
|
||||
name: 'adminXDeps',
|
||||
@ -77,7 +77,7 @@ const COMMANDS_ADMINX = [{
|
||||
}, {
|
||||
name: 'adminX',
|
||||
command: `nx run-many --projects=${adminXApps} --parallel=${adminXApps.length} --targets=dev`,
|
||||
cwd: path.resolve(__dirname, '../../apps/admin-x-settings'),
|
||||
cwd: path.resolve(__dirname, '../../apps/admin-x-settings', '../../apps/admin-x-activitypub'),
|
||||
prefixColor: '#C35831',
|
||||
env: {}
|
||||
}];
|
||||
|
1
apps/admin-x-activitypub/.eslintignore
Normal file
1
apps/admin-x-activitypub/.eslintignore
Normal file
@ -0,0 +1 @@
|
||||
tailwind.config.cjs
|
56
apps/admin-x-activitypub/.eslintrc.cjs
Normal file
56
apps/admin-x-activitypub/.eslintrc.cjs
Normal file
@ -0,0 +1,56 @@
|
||||
/* eslint-env node */
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
'plugin:ghost/ts',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended'
|
||||
],
|
||||
plugins: [
|
||||
'ghost',
|
||||
'react-refresh',
|
||||
'tailwindcss'
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect'
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
// sort multiple import lines into alphabetical groups
|
||||
'ghost/sort-imports-es6-autofix/sort-imports-es6': ['error', {
|
||||
memberSyntaxSortOrder: ['none', 'all', 'single', 'multiple']
|
||||
}],
|
||||
|
||||
// TODO: re-enable this (maybe fixed fast refresh?)
|
||||
'react-refresh/only-export-components': 'off',
|
||||
|
||||
// suppress errors for missing 'import React' in JSX files, as we don't need it
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
// ignore prop-types for now
|
||||
'react/prop-types': 'off',
|
||||
|
||||
// TODO: re-enable these if deemed useful
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
|
||||
// custom react rules
|
||||
'react/jsx-sort-props': ['error', {
|
||||
reservedFirst: true,
|
||||
callbacksLast: true,
|
||||
shorthandLast: true,
|
||||
locale: 'en'
|
||||
}],
|
||||
'react/button-has-type': 'error',
|
||||
'react/no-array-index-key': 'error',
|
||||
'react/jsx-key': 'off',
|
||||
|
||||
'tailwindcss/classnames-order': ['error', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/enforces-negative-arbitrary-values': ['warn', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/enforces-shorthand': ['warn', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/migration-from-tailwind-2': ['warn', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/no-arbitrary-value': 'off',
|
||||
'tailwindcss/no-custom-classname': 'off',
|
||||
'tailwindcss/no-contradicting-classname': ['error', {config: 'tailwind.config.cjs'}]
|
||||
}
|
||||
};
|
3
apps/admin-x-activitypub/.gitignore
vendored
Normal file
3
apps/admin-x-activitypub/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
dist
|
||||
playwright-report
|
||||
test-results
|
13
apps/admin-x-activitypub/index.html
Normal file
13
apps/admin-x-activitypub/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>AdminX Standalone</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/standalone.tsx"></script>
|
||||
</body>
|
||||
</html>
|
67
apps/admin-x-activitypub/package.json
Normal file
67
apps/admin-x-activitypub/package.json
Normal file
@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "@tryghost/admin-x-activitypub",
|
||||
"version": "0.0.1",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/TryGhost/Ghost/tree/main/apps/admin-x-activitypub"
|
||||
},
|
||||
"author": "Ghost Foundation",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"dist/"
|
||||
],
|
||||
"main": "./dist/admin-x-activitypub.umd.cjs",
|
||||
"module": "./dist/admin-x-activitypub.js",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org/"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite build --watch",
|
||||
"dev:start": "vite",
|
||||
"build": "concurrently \"tsc\" \"vite build\"",
|
||||
"lint": "yarn run lint:code && yarn run lint:test",
|
||||
"lint:code": "eslint --ext .js,.ts,.cjs,.tsx --cache src",
|
||||
"lint:test": "eslint -c test/.eslintrc.cjs --ext .js,.ts,.cjs,.tsx --cache test",
|
||||
"test:unit": "vitest run",
|
||||
"test:acceptance": "NODE_OPTIONS='--experimental-specifier-resolution=node --no-warnings' VITE_TEST=true playwright test",
|
||||
"test:acceptance:slowmo": "TIMEOUT=100000 PLAYWRIGHT_SLOWMO=100 yarn test:acceptance --headed",
|
||||
"test:acceptance:full": "ALL_BROWSERS=1 yarn test:acceptance",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "14.1.0",
|
||||
"@tryghost/admin-x-design-system": "0.0.0",
|
||||
"@tryghost/admin-x-framework": "0.0.0",
|
||||
"@types/react": "18.2.48",
|
||||
"@types/react-dom": "18.2.18",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
},
|
||||
"nx": {
|
||||
"targets": {
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"build",
|
||||
{"projects": ["@tryghost/admin-x-design-system", "@tryghost/admin-x-framework"], "target": "build"}
|
||||
]
|
||||
},
|
||||
"test:unit": {
|
||||
"dependsOn": [
|
||||
"build",
|
||||
"test:unit",
|
||||
{"projects": ["@tryghost/admin-x-design-system", "@tryghost/admin-x-framework"], "target": "build"}
|
||||
]
|
||||
},
|
||||
"test:acceptance": {
|
||||
"dependsOn": [
|
||||
"build",
|
||||
"test:acceptance",
|
||||
{"projects": ["@tryghost/admin-x-design-system", "@tryghost/admin-x-framework"], "target": "build"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
apps/admin-x-activitypub/playwright.config.mjs
Normal file
3
apps/admin-x-activitypub/playwright.config.mjs
Normal file
@ -0,0 +1,3 @@
|
||||
import {adminXPlaywrightConfig} from '@tryghost/admin-x-framework/playwright';
|
||||
|
||||
export default adminXPlaywrightConfig();
|
1
apps/admin-x-activitypub/postcss.config.cjs
Normal file
1
apps/admin-x-activitypub/postcss.config.cjs
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('@tryghost/admin-x-design-system/postcss.config.cjs');
|
23
apps/admin-x-activitypub/src/App.tsx
Normal file
23
apps/admin-x-activitypub/src/App.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import ListIndex from './components/ListIndex';
|
||||
import {DesignSystemApp, DesignSystemAppProps} from '@tryghost/admin-x-design-system';
|
||||
import {FrameworkProvider, TopLevelFrameworkProps} from '@tryghost/admin-x-framework';
|
||||
import {RoutingProvider} from '@tryghost/admin-x-framework/routing';
|
||||
|
||||
interface AppProps {
|
||||
framework: TopLevelFrameworkProps;
|
||||
designSystem: DesignSystemAppProps;
|
||||
}
|
||||
|
||||
const App: React.FC<AppProps> = ({framework, designSystem}) => {
|
||||
return (
|
||||
<FrameworkProvider {...framework}>
|
||||
<RoutingProvider basePath='activitypub'>
|
||||
<DesignSystemApp className='admin-x-activitypub' {...designSystem}>
|
||||
<ListIndex />
|
||||
</DesignSystemApp>
|
||||
</RoutingProvider>
|
||||
</FrameworkProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
26
apps/admin-x-activitypub/src/components/ListIndex.tsx
Normal file
26
apps/admin-x-activitypub/src/components/ListIndex.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
const ListIndex = () => {
|
||||
return (
|
||||
<div className='mx-auto my-0 w-full max-w-3xl p-12'>
|
||||
<h1 className='mb-6 text-black'>ActivityPub Demo</h1>
|
||||
<div className='flex flex-col'>
|
||||
<div className='mb-4 flex flex-col'>
|
||||
<h2 className='mb-2 text-2xl text-black'>This is a post title</h2>
|
||||
<p className='mb-2 text-lg text-grey-950'>This is some very short post content</p>
|
||||
<p className='text-md text-grey-700'>Publish McPublisher</p>
|
||||
</div>
|
||||
<div className='mb-4 flex flex-col'>
|
||||
<h2 className='mb-2 text-2xl text-black'>This is a post title</h2>
|
||||
<p className='mb-2 text-lg text-grey-950'>This is some very short post content</p>
|
||||
<p className='text-md text-grey-700'>Publish McPublisher</p>
|
||||
</div>
|
||||
<div className='mb-4 flex flex-col'>
|
||||
<h2 className='mb-2 text-2xl text-black'>This is a post title</h2>
|
||||
<p className='mb-2 text-lg text-grey-950'>This is some very short post content</p>
|
||||
<p className='text-md text-grey-700'>Publish McPublisher</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ListIndex;
|
6
apps/admin-x-activitypub/src/index.tsx
Normal file
6
apps/admin-x-activitypub/src/index.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
import './styles/index.css';
|
||||
import App from './App';
|
||||
|
||||
export {
|
||||
App as AdminXApp
|
||||
};
|
5
apps/admin-x-activitypub/src/standalone.tsx
Normal file
5
apps/admin-x-activitypub/src/standalone.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import './styles/index.css';
|
||||
import App from './App.tsx';
|
||||
import renderStandaloneApp from '@tryghost/admin-x-framework/test/render';
|
||||
|
||||
renderStandaloneApp(App, {});
|
1
apps/admin-x-activitypub/src/styles/index.css
Normal file
1
apps/admin-x-activitypub/src/styles/index.css
Normal file
@ -0,0 +1 @@
|
||||
@import '@tryghost/admin-x-design-system/styles.css';
|
6
apps/admin-x-activitypub/tailwind.config.cjs
Normal file
6
apps/admin-x-activitypub/tailwind.config.cjs
Normal file
@ -0,0 +1,6 @@
|
||||
const adminXPreset = require('@tryghost/admin-x-design-system/tailwind.cjs');
|
||||
|
||||
module.exports = {
|
||||
presets: [adminXPreset('.admin-x-activitypub')],
|
||||
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}', '../../node_modules/@tryghost/admin-x-design-system/es/**/*.{js,ts,jsx,tsx}']
|
||||
};
|
6
apps/admin-x-activitypub/test/.eslintrc.cjs
Normal file
6
apps/admin-x-activitypub/test/.eslintrc.cjs
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: ['ghost'],
|
||||
extends: [
|
||||
'plugin:ghost/ts-test'
|
||||
]
|
||||
};
|
10
apps/admin-x-activitypub/test/acceptance/app.test.ts
Normal file
10
apps/admin-x-activitypub/test/acceptance/app.test.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import {expect, test} from '@playwright/test';
|
||||
// import {mockApi, responseFixtures} from '@tryghost/admin-x-framework/test/acceptance';
|
||||
|
||||
test.describe('Demo', async () => {
|
||||
test('Renders the list page', async ({page}) => {
|
||||
await page.goto('/');
|
||||
|
||||
await expect(page.locator('body')).toContainText('ActivityPub Demo');
|
||||
});
|
||||
});
|
10
apps/admin-x-activitypub/test/unit/ListIndex.test.tsx
Normal file
10
apps/admin-x-activitypub/test/unit/ListIndex.test.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import ListIndex from '../../src/components/ListIndex';
|
||||
import {render, screen} from '@testing-library/react';
|
||||
|
||||
describe('Demo', function () {
|
||||
it('renders a component', async function () {
|
||||
render(<ListIndex/>);
|
||||
|
||||
expect(screen.getAllByRole('heading')[0].textContent).toEqual('ActivityPub Demo');
|
||||
});
|
||||
});
|
23
apps/admin-x-activitypub/tsconfig.json
Normal file
23
apps/admin-x-activitypub/tsconfig.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src", "test"]
|
||||
}
|
10
apps/admin-x-activitypub/vite.config.mjs
Normal file
10
apps/admin-x-activitypub/vite.config.mjs
Normal file
@ -0,0 +1,10 @@
|
||||
import adminXViteConfig from '@tryghost/admin-x-framework/vite';
|
||||
import pkg from './package.json';
|
||||
import {resolve} from 'path';
|
||||
|
||||
export default (function viteConfig() {
|
||||
return adminXViteConfig({
|
||||
packageName: pkg.name,
|
||||
entry: resolve(__dirname, 'src/index.tsx')
|
||||
});
|
||||
});
|
1
ghost/admin/app/components/admin-x/activitypub.hbs
Normal file
1
ghost/admin/app/components/admin-x/activitypub.hbs
Normal file
@ -0,0 +1 @@
|
||||
<div {{react-render this.ReactComponent}}></div>
|
8
ghost/admin/app/components/admin-x/activitypub.js
Normal file
8
ghost/admin/app/components/admin-x/activitypub.js
Normal file
@ -0,0 +1,8 @@
|
||||
import AdminXComponent from './admin-x-component';
|
||||
import {inject as service} from '@ember/service';
|
||||
|
||||
export default class AdminXActivityPub extends AdminXComponent {
|
||||
@service upgradeStatus;
|
||||
|
||||
static packageName = '@tryghost/admin-x-activitypub';
|
||||
}
|
@ -123,6 +123,11 @@
|
||||
<LinkTo @route="demo-x" @current-when="demo-x">{{svg-jar "star"}}AdminX Demo</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if (feature "ActivityPub")}}
|
||||
<li>
|
||||
<LinkTo @route="activitypub-x" @current-when="activitypub-x">{{svg-jar "star"}}ActivityPub Demo</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
|
||||
{{#if this.session.user.isOwnerOnly}}
|
||||
|
6
ghost/admin/app/controllers/activitypub-x.js
Normal file
6
ghost/admin/app/controllers/activitypub-x.js
Normal file
@ -0,0 +1,6 @@
|
||||
import Controller from '@ember/controller';
|
||||
import {inject as service} from '@ember/service';
|
||||
|
||||
export default class ActivitypubXController extends Controller {
|
||||
@service upgradeStatus;
|
||||
}
|
@ -56,6 +56,10 @@ Router.map(function () {
|
||||
this.route('settings-x', {path: '/*sub'});
|
||||
});
|
||||
|
||||
this.route('activitypub-x',{path: '/activitypub'}, function () {
|
||||
this.route('activitypub-x', {path: '/*sub'});
|
||||
});
|
||||
|
||||
// testing websockets
|
||||
this.route('websockets');
|
||||
|
||||
|
3
ghost/admin/app/routes/activitypub-x.js
Normal file
3
ghost/admin/app/routes/activitypub-x.js
Normal file
@ -0,0 +1,3 @@
|
||||
import AuthenticatedRoute from 'ghost-admin/routes/authenticated';
|
||||
|
||||
export default class AcitvitypubXRoute extends AuthenticatedRoute {}
|
@ -82,6 +82,7 @@ export default class FeatureService extends Service {
|
||||
@feature('portalImprovements') portalImprovements;
|
||||
@feature('onboardingChecklist') onboardingChecklist;
|
||||
@feature('membersSpamPrevention') membersSpamPrevention;
|
||||
@feature('ActivityPub') ActivityPub;
|
||||
@feature('internalLinking') internalLinking;
|
||||
|
||||
_user = null;
|
||||
|
1
ghost/admin/app/templates/activitypub-x.hbs
Normal file
1
ghost/admin/app/templates/activitypub-x.hbs
Normal file
@ -0,0 +1 @@
|
||||
<AdminX::Activitypub />
|
@ -6,7 +6,7 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const camelCase = require('lodash/camelCase');
|
||||
|
||||
const adminXApps = ['admin-x-demo', 'admin-x-settings'];
|
||||
const adminXApps = ['admin-x-demo', 'admin-x-settings', 'admin-x-activitypub'];
|
||||
|
||||
function generateHash(filePath) {
|
||||
const fileContents = fs.readFileSync(filePath, 'utf8');
|
||||
|
@ -181,7 +181,8 @@
|
||||
{
|
||||
"projects": [
|
||||
"@tryghost/admin-x-demo",
|
||||
"@tryghost/admin-x-settings"
|
||||
"@tryghost/admin-x-settings",
|
||||
"@tryghost/admin-x-activitypub"
|
||||
],
|
||||
"target": "build"
|
||||
}
|
||||
@ -193,7 +194,8 @@
|
||||
{
|
||||
"projects": [
|
||||
"@tryghost/admin-x-demo",
|
||||
"@tryghost/admin-x-settings"
|
||||
"@tryghost/admin-x-settings",
|
||||
"@tryghost/admin-x-activitypub"
|
||||
],
|
||||
"target": "build"
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ const ALPHA_FEATURES = [
|
||||
// 'adminXOffers',
|
||||
'adminXDemo',
|
||||
'membersSpamPrevention',
|
||||
'ActivityPub',
|
||||
'internalLinking'
|
||||
];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user