mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-25 22:38:56 +08:00
feat: cloud sync playground (#662)
* feat: add workspace playground page * feat: add all demands to playground Co-authored-by: tzhangchi <terry.zhangchi@outlook.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: 💭 Questions and Help - Reddit
|
- name: 💭 Questions and Help - Reddit
|
||||||
url: https://www.reddit.com/r/Affine/
|
url: https://www.reddit.com/r/Affine/
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
name: I have a question
|
||||||
|
about: Feel free to ask us your questions!
|
||||||
|
title: '[Question]'
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
@@ -35,8 +35,6 @@ jobs:
|
|||||||
scope: '@toeverything'
|
scope: '@toeverything'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
|
||||||
- run: node scripts/module-resolve/ci.js
|
|
||||||
|
|
||||||
- name: Restore cache
|
- name: Restore cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
@@ -48,13 +46,8 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm install --no-frozen-lockfile
|
|
||||||
env:
|
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_GITHUB_AUTH_TOKEN }}
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: pnpm build
|
run: pnpm install && pnpm build
|
||||||
env:
|
env:
|
||||||
NEXT_PUBLIC_FIREBASE_API_KEY: ${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }}
|
NEXT_PUBLIC_FIREBASE_API_KEY: ${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }}
|
||||||
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${{ secrets.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN }}
|
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${{ secrets.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN }}
|
||||||
@@ -131,7 +124,7 @@ jobs:
|
|||||||
name: Build Community
|
name: Build Community
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/master'
|
||||||
runs-on: self-hosted
|
runs-on: self-hosted
|
||||||
environment: production
|
environment: development
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -235,7 +228,7 @@ jobs:
|
|||||||
name: Build LiveDemo
|
name: Build LiveDemo
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/master'
|
||||||
runs-on: self-hosted
|
runs-on: self-hosted
|
||||||
environment: production
|
environment: development
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|||||||
Vendored
+1
-1
@@ -3,5 +3,5 @@
|
|||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.formatOnSaveMode": "file",
|
"editor.formatOnSaveMode": "file",
|
||||||
"cSpell.words": ["blocksuite", "livedemo", "testid"]
|
"cSpell.words": ["blocksuite", "livedemo", "pnpm", "testid"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ Calling all developers, testers, tech writers and more! Contributions of all typ
|
|||||||
|
|
||||||
For **bug reports**, **feature requests** and other **suggestions** you can also [create a new issue](https://github.com/toeverything/AFFiNE/issues/new/choose) and choose the most appropiate template for your feedback.
|
For **bug reports**, **feature requests** and other **suggestions** you can also [create a new issue](https://github.com/toeverything/AFFiNE/issues/new/choose) and choose the most appropiate template for your feedback.
|
||||||
|
|
||||||
For **translation** and **language support** you can visit our docs for the [internationalization guide].(https://docs.affine.pro/affine/internationalization/welcome)
|
For **translation** and **language support** you can visit our docs for the [internationalization guide](https://docs.affine.pro/affine/internationalization/welcome).
|
||||||
|
|
||||||
Looking for **others ways to contribute** and wondering where to start? Check out the [AFFiNE Ambassador program](https://docs.affine.pro/affine/affine-ambassadors/welcome), we work closely with passionate members of our community and provide them with a wide-range of support and resources.
|
Looking for **others ways to contribute** and wondering where to start? Check out the [AFFiNE Ambassador program](https://docs.affine.pro/affine/affine-ambassadors/welcome), we work closely with passionate members of our community and provide them with a wide-range of support and resources.
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ We would also like to give thanks to open-source projects that make AFFiNE possi
|
|||||||
- [BlockSuite](https://github.com/toeverything/BlockSuite) - AFFiNE is built with and powered by BlockSuite.
|
- [BlockSuite](https://github.com/toeverything/BlockSuite) - AFFiNE is built with and powered by BlockSuite.
|
||||||
- [Yjs](https://github.com/yjs/yjs) & [Yrs](https://github.com/y-crdt/y-crdt) -- Fundamental support of CRDTs for our implementation on state management and data sync.
|
- [Yjs](https://github.com/yjs/yjs) & [Yrs](https://github.com/y-crdt/y-crdt) -- Fundamental support of CRDTs for our implementation on state management and data sync.
|
||||||
- [React](https://github.com/facebook/react) -- View layer support and web GUI framework.
|
- [React](https://github.com/facebook/react) -- View layer support and web GUI framework.
|
||||||
- [Rust](https://github.com/rust-lang/rust) -- High performance language that extends the ability and availability of our real-time backend, JWST.
|
- [Rust](https://github.com/rust-lang/rust) -- High performance language that extends the ability and availability of our real-time backend, OctoBase.
|
||||||
- [Fossil](https://www2.fossil-scm.org/home/doc/trunk/www/index.wiki) -- Source code management tool made with CRDTs which inspired our design on block data structure.
|
- [Fossil](https://www2.fossil-scm.org/home/doc/trunk/www/index.wiki) -- Source code management tool made with CRDTs which inspired our design on block data structure.
|
||||||
- [slatejs](https://github.com/ianstormtaylor/slate) -- Customizable rich-text editor.
|
- [slatejs](https://github.com/ianstormtaylor/slate) -- Customizable rich-text editor.
|
||||||
- [Jotai](https://github.com/pmndrs/jotai) -- Minimal state management tool for frontend.
|
- [Jotai](https://github.com/pmndrs/jotai) -- Minimal state management tool for frontend.
|
||||||
|
|||||||
@@ -70,4 +70,9 @@ const withDebugLocal = require('next-debug-local')(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
module.exports = withDebugLocal(nextConfig);
|
const withPWA = require('next-pwa')({
|
||||||
|
dest: 'public',
|
||||||
|
disable: process.env.NODE_ENV !== 'production',
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = withDebugLocal(withPWA(nextConfig));
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-i18next": "^11.18.4",
|
"react-i18next": "^11.18.4",
|
||||||
"yjs": "^13.5.43"
|
"yjs": "^13.5.44"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "18.7.18",
|
"@types/node": "18.7.18",
|
||||||
@@ -51,6 +51,7 @@
|
|||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
|
"next-pwa": "^5.6.0",
|
||||||
"typescript": "4.8.3"
|
"typescript": "4.8.3"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 8.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "AFFiNE",
|
||||||
|
"short_name": "AFFiNE",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#ffffff",
|
||||||
|
"background_color": "#ffffff",
|
||||||
|
"start_url": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"orientation": "portrait"
|
||||||
|
}
|
||||||
@@ -73,7 +73,11 @@ export const StyledInputContent = styled('div')(({ theme }) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
export const StyledShortcut = styled('div')(({ theme }) => {
|
export const StyledShortcut = styled('div')(({ theme }) => {
|
||||||
return { color: theme.colors.placeHolderColor, fontSize: theme.font.sm };
|
return {
|
||||||
|
color: theme.colors.placeHolderColor,
|
||||||
|
fontSize: theme.font.sm,
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
export const StyledLabel = styled('label')(({ theme }) => {
|
export const StyledLabel = styled('label')(({ theme }) => {
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import { useRouter } from 'next/router';
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
import { useAppState } from '@/providers/app-state-provider';
|
||||||
import { PageLoading } from '@/components/loading';
|
import { PageLoading } from '@/components/loading';
|
||||||
|
import Head from 'next/head';
|
||||||
|
|
||||||
const ThemeProvider = dynamic(() => import('@/providers/themeProvider'), {
|
const ThemeProvider = dynamic(() => import('@/providers/themeProvider'), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
});
|
});
|
||||||
@@ -37,6 +39,15 @@ const App = ({ Component, pageProps }: AppPropsWithLayout) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Head>
|
||||||
|
<meta name="theme-color" content="#fafafa" />
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="/icons/apple-touch-icon.png"
|
||||||
|
/>
|
||||||
|
</Head>
|
||||||
<Logger />
|
<Logger />
|
||||||
<ProviderComposer
|
<ProviderComposer
|
||||||
contexts={[
|
contexts={[
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import { styled } from '@/styles';
|
||||||
|
|
||||||
|
import { ReactElement, ReactNode } from 'react';
|
||||||
|
import WorkspaceLayout from '@/components/workspace-layout';
|
||||||
|
import { Button } from '@/ui/button';
|
||||||
|
|
||||||
|
export const FeatureCardDiv = styled('section')({
|
||||||
|
width: '800px',
|
||||||
|
border: '1px #eee solid',
|
||||||
|
margin: '20px auto',
|
||||||
|
minHeight: '100px',
|
||||||
|
padding: '15px',
|
||||||
|
});
|
||||||
|
const FeatureCard = (props: {
|
||||||
|
name: string;
|
||||||
|
children: ReactNode | ReactNode[];
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<FeatureCardDiv>
|
||||||
|
<h1>Feature - {props.name}</h1>
|
||||||
|
{props.children}
|
||||||
|
</FeatureCardDiv>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Playground = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FeatureCard name="Account">
|
||||||
|
<Button>Sign In</Button>
|
||||||
|
<Button>Sign Out</Button>
|
||||||
|
</FeatureCard>
|
||||||
|
|
||||||
|
<FeatureCard name="Workspace List">
|
||||||
|
<ul>
|
||||||
|
<li>AFFiNE Demo</li>
|
||||||
|
<li>AFFiNE XXX</li>
|
||||||
|
</ul>
|
||||||
|
<Button>New Workspace</Button>
|
||||||
|
</FeatureCard>
|
||||||
|
|
||||||
|
<FeatureCard name="Active Workspace">
|
||||||
|
<div>Workspace Name /[Workspace Members Count]/[Workspace Avatar]</div>
|
||||||
|
<div>Cloud Sync [Yes/No]</div>
|
||||||
|
<div>Auth [Public/Private]</div>
|
||||||
|
<div>
|
||||||
|
<Button>Update Workspace Name</Button>
|
||||||
|
<Button>Upload Workspace Avatar</Button>
|
||||||
|
<Button>Update Workspace Avatar</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Button>Leave Workspace</Button>
|
||||||
|
<Button>Delete Workspace </Button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Cloud Sync <Button>Enalbe</Button>
|
||||||
|
<Button>Disable</Button>
|
||||||
|
</div>
|
||||||
|
</FeatureCard>
|
||||||
|
|
||||||
|
<FeatureCard name="Workspace Members">
|
||||||
|
<Button>Add Member</Button>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
terrychinaz@gmail <button>Delete Members</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</FeatureCard>
|
||||||
|
|
||||||
|
<FeatureCard name="Cloud Search">
|
||||||
|
<input type="text" value="AFFiNE Keywords" />
|
||||||
|
<Button>Search</Button>
|
||||||
|
<ul></ul>
|
||||||
|
</FeatureCard>
|
||||||
|
|
||||||
|
<FeatureCard name="Import/Exeport Worpsace">
|
||||||
|
<div>Workspace Name</div>
|
||||||
|
<Button> Export Workspace</Button>
|
||||||
|
<Button> Import Workspace</Button>
|
||||||
|
</FeatureCard>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Playground.getLayout = function getLayout(page: ReactElement) {
|
||||||
|
return <WorkspaceLayout>{page}</WorkspaceLayout>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Playground;
|
||||||
@@ -18,7 +18,7 @@ Let us know what you think of this latest version.
|
|||||||
### In this release, you can now:
|
### In this release, you can now:
|
||||||
|
|
||||||
- Manage your pages from the collapsible **sidebar**, which allows you to add **favourites** and restore deleted files from the **trash**
|
- Manage your pages from the collapsible **sidebar**, which allows you to add **favourites** and restore deleted files from the **trash**
|
||||||
- Search through all your content with the quick search - activate with `Ctrl/⌘ + ?`
|
- Search through all your content with the quick search - activate with `Ctrl/⌘ + K`
|
||||||
- Quickly format text with the **pop-up toolbar** (highlight any text to give it a try)
|
- Quickly format text with the **pop-up toolbar** (highlight any text to give it a try)
|
||||||
- Copy and paste **images** into your pages, resize them and add captions
|
- Copy and paste **images** into your pages, resize them and add captions
|
||||||
- Add horizontal line dividers to your text with `---` and `***`
|
- Add horizontal line dividers to your text with `---` and `***`
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
CLIENT_APP?: boolean;
|
CLIENT_APP?: boolean;
|
||||||
|
__editoVersion?: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import getConfig from 'next/config';
|
import getConfig from 'next/config';
|
||||||
// import { isDev } from './env';
|
import { isDev } from './env';
|
||||||
type Config = {
|
type Config = {
|
||||||
BUILD_DATE: string;
|
BUILD_DATE: string;
|
||||||
NODE_ENV: string;
|
NODE_ENV: string;
|
||||||
@@ -14,9 +14,9 @@ const nextConfig = getConfig();
|
|||||||
const publicRuntimeConfig: Config = nextConfig.publicRuntimeConfig;
|
const publicRuntimeConfig: Config = nextConfig.publicRuntimeConfig;
|
||||||
|
|
||||||
const printBuildInfo = () => {
|
const printBuildInfo = () => {
|
||||||
// if (isDev) {
|
if (isDev) {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
console.group('Build info');
|
console.group('Build info');
|
||||||
console.log('Project:', publicRuntimeConfig.PROJECT_NAME);
|
console.log('Project:', publicRuntimeConfig.PROJECT_NAME);
|
||||||
console.log(
|
console.log(
|
||||||
@@ -30,6 +30,7 @@ const printBuildInfo = () => {
|
|||||||
`${publicRuntimeConfig.NODE_ENV}${publicRuntimeConfig.CI ? '(ci)' : ''}`
|
`${publicRuntimeConfig.NODE_ENV}${publicRuntimeConfig.CI ? '(ci)' : ''}`
|
||||||
);
|
);
|
||||||
console.log('Editor Version:', publicRuntimeConfig.EDITOR_VERSION);
|
console.log('Editor Version:', publicRuntimeConfig.EDITOR_VERSION);
|
||||||
|
|
||||||
console.log('Version:', publicRuntimeConfig.VERSION);
|
console.log('Version:', publicRuntimeConfig.VERSION);
|
||||||
console.log(
|
console.log(
|
||||||
'AFFiNE is an open source project, you can view its source code on GitHub!'
|
'AFFiNE is an open source project, you can view its source code on GitHub!'
|
||||||
@@ -40,6 +41,12 @@ const printBuildInfo = () => {
|
|||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function setWindowEditorVersion() {
|
||||||
|
// when it is not SSR
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
window.__editoVersion = publicRuntimeConfig.EDITOR_VERSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
printBuildInfo();
|
printBuildInfo();
|
||||||
|
setWindowEditorVersion();
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
Generated
+2291
-563
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
|||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import { loadPage } from './libs/load-page';
|
import { loadPage } from './libs/load-page';
|
||||||
import { clickPageMoreActions } from './libs/page-logic';
|
import { clickPageMoreActions } from './libs/page-logic';
|
||||||
|
|
||||||
loadPage();
|
loadPage();
|
||||||
|
|
||||||
test.describe('Change page mode(Paper or Edgeless)', () => {
|
test.describe('Change page mode(Paper or Edgeless)', () => {
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
import { loadPage } from './libs/load-page';
|
||||||
|
import pkg from './../packages/app/package.json';
|
||||||
|
|
||||||
|
loadPage();
|
||||||
|
|
||||||
|
test.describe('web console', () => {
|
||||||
|
test('editor version', async ({ page }) => {
|
||||||
|
// https://playwright.dev/docs/evaluating
|
||||||
|
// https://github.com/microsoft/playwright/issues/13059
|
||||||
|
// Get the handle to a specific function.
|
||||||
|
//Later on, call this function with some arguments.
|
||||||
|
// const msg = await getEditoVersionHandle.evaluate((post, args) => post);
|
||||||
|
// console.log(getEditoVersionHandle);
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
const editoVersion = await page.evaluate(
|
||||||
|
() => (window as any).__editoVersion
|
||||||
|
);
|
||||||
|
// const documentEditorVersion = await page.inputValue('input#editor-version');
|
||||||
|
const pkgEditorVersion = pkg.dependencies['@blocksuite/editor'];
|
||||||
|
|
||||||
|
expect(editoVersion).toBe(pkgEditorVersion);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -11,7 +11,6 @@ test.describe('Local first delete page', () => {
|
|||||||
await newPage(page);
|
await newPage(page);
|
||||||
await page.getByPlaceholder('Title').click();
|
await page.getByPlaceholder('Title').click();
|
||||||
await page.getByPlaceholder('Title').fill('this is a new page to restore');
|
await page.getByPlaceholder('Title').fill('this is a new page to restore');
|
||||||
const originPageUrl = page.url();
|
|
||||||
const newPageId = page.url().split('/').reverse()[0];
|
const newPageId = page.url().split('/').reverse()[0];
|
||||||
await page.getByRole('link', { name: 'All pages' }).click();
|
await page.getByRole('link', { name: 'All pages' }).click();
|
||||||
const cell = page.getByRole('cell', {
|
const cell = page.getByRole('cell', {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ loadPage();
|
|||||||
|
|
||||||
test.describe('Local first export page', () => {
|
test.describe('Local first export page', () => {
|
||||||
test('New a page ,then open it and export html', async ({ page }) => {
|
test('New a page ,then open it and export html', async ({ page }) => {
|
||||||
await page.getByText('New Page').click();
|
await newPage(page);
|
||||||
await page.getByPlaceholder('Title').click();
|
await page.getByPlaceholder('Title').click();
|
||||||
await page
|
await page
|
||||||
.getByPlaceholder('Title')
|
.getByPlaceholder('Title')
|
||||||
|
|||||||
Reference in New Issue
Block a user