Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: SingleEditorMode #8984

Open
wants to merge 94 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
6c92ba2
Add config
miya Jun 24, 2024
f6dbabc
Merge pull request #8915 from weseek/feat/142251-add-config-for-non-y…
yuki-takei Jun 24, 2024
8aef8c0
Merge branch 'master' into feat/non-yjs-mode
miya Jul 22, 2024
90e8436
Merge branch 'master' into feat/non-yjs-mode
miya Jul 24, 2024
36b9657
fix typo
miya Jul 24, 2024
f52185e
fix typo
miya Jul 24, 2024
b58c8db
Store server config values using swr
miya Jul 24, 2024
e560443
impl non-yjs mode
miya Jul 24, 2024
070cad0
rm logger
miya Jul 24, 2024
5c7ec72
simply
miya Jul 24, 2024
a76490c
rm unnecessary props
miya Jul 24, 2024
06623d7
fix comment
miya Jul 24, 2024
05bb9eb
impl useIsYjsEnable
miya Jul 24, 2024
468102a
relocate useEffect
miya Jul 24, 2024
f8bcf3d
rm logger
miya Jul 24, 2024
2187914
impl non-yjs mode badge
miya Jul 25, 2024
387396d
fix styles
miya Jul 25, 2024
3c32a1d
Changed implementation to one that does not useSWR
miya Jul 26, 2024
0e95a36
relocate useEffect
miya Jul 26, 2024
88682c3
Alert when editor is opened in non-yjs mode
miya Jul 26, 2024
fb6d8e9
i18n
miya Jul 26, 2024
29c872e
Merge pull request #8992 from weseek/feat/148850-non-yjs-mode-badge
yuki-takei Jul 26, 2024
42cfe74
imprv hooks
miya Jul 26, 2024
30340fd
Merge branch 'feat/non-yjs-mode' into feat/148852-when-the-editor-bec…
miya Jul 26, 2024
b60065a
imprv EditorNavbar
miya Jul 26, 2024
3012390
add comment
miya Jul 26, 2024
c7dcd94
imprv EditorNavbar
miya Jul 27, 2024
443b1ff
fix typo
miya Jul 27, 2024
fb1196e
Merge branch 'master' into feat/non-yjs-mode
miya Jul 29, 2024
e6c1991
Merge branch 'master' into feat/148852-when-the-editor-becomes-active…
miya Jul 29, 2024
e0c0877
Merge branch 'feat/non-yjs-mode' into feat/148852-when-the-editor-bec…
miya Jul 29, 2024
f9dd607
rm Origin.EditorOffline
miya Jul 29, 2024
80b2aef
fix i18n
miya Jul 30, 2024
a42a73a
In non-yjs mode, request including revisionId
miya Jul 30, 2024
9d38d52
fix lint error
miya Jul 31, 2024
ce7a2f7
Merge branch 'master' into feat/non-yjs-mode
miya Aug 1, 2024
86a8fb3
Merge branch 'feat/non-yjs-mode' into feat/148852-when-the-editor-bec…
miya Aug 1, 2024
cfc1f49
fix i18n
miya Aug 1, 2024
5e89fff
impl PageEditorSwitcher
miya Aug 1, 2024
3c16046
fix lint error
miya Aug 1, 2024
7c248a8
fix lint error
miya Aug 1, 2024
8ce1e84
fix fb (https://github.com/weseek/growi/pull/8990/files#r1698267852)
miya Aug 2, 2024
48df7bb
relocate hook
miya Aug 2, 2024
ca01305
non-yjs-alert -> single-editor-mode-alert
miya Aug 2, 2024
f6f8785
editor-offline -> editor-single
miya Aug 2, 2024
ebac8da
rm unnecessary code
miya Aug 2, 2024
cd5b6f7
Merge branch 'master' into feat/non-yjs-mode
miya Aug 2, 2024
677fd7a
Merge branch 'feat/non-yjs-mode' into feat/148852-when-the-editor-bec…
miya Aug 2, 2024
3bff2bd
rm unnecessary
miya Aug 2, 2024
e3d2c14
fix lint (https://github.com/weseek/growi/actions/runs/10209046076/jo…
miya Aug 2, 2024
8409966
Revert "fix lint (https://github.com/weseek/growi/actions/runs/102090…
miya Aug 2, 2024
f5da1e6
fix lint
miya Aug 2, 2024
775fd1b
Revert "fix lint"
miya Aug 2, 2024
8aa3eb6
PageEditorSwitcher -> PageEditorMainSwitcher
miya Aug 7, 2024
8d3b317
imprv hooks
miya Aug 8, 2024
677da54
Merge pull request #8990 from weseek/feat/148852-when-the-editor-beco…
miya Aug 8, 2024
b4a574e
Merge branch 'master' into feat/non-yjs-mode
miya Aug 8, 2024
4be00a5
fix lint error
miya Aug 8, 2024
49b8318
Revert "fix lint error"
miya Aug 9, 2024
1f5a1e6
Relocation of CodeMirrorEditorProps
miya Aug 9, 2024
94dff9e
fix module path
miya Aug 9, 2024
ae0e9c0
Merge pull request #9021 from weseek/fix/152245-lint-error
miya Aug 9, 2024
a49138f
bugFix
miya Aug 19, 2024
0afc54d
propsRef -> cmPropsRef
miya Aug 19, 2024
825fa74
Merge branch 'master' into feat/non-yjs-mode
miya Aug 19, 2024
37cceba
Merge branch 'feat/non-yjs-mode' into fix/152325-editor-configuration…
miya Aug 19, 2024
d4f7480
Merge pull request #9032 from weseek/fix/152325-editor-configuration-…
yuki-takei Aug 20, 2024
ab1e93b
Merge branch 'master' into feat/non-yjs-mode
miya Aug 22, 2024
753d67e
bugFIx
miya Aug 22, 2024
1f2f46a
Merge pull request #9038 from weseek/fix/152875-unable-to-update-the-…
yuki-takei Aug 26, 2024
e9e3c60
add testid
miya Aug 27, 2024
36aa8c2
add test
miya Aug 27, 2024
318620f
update env
miya Aug 27, 2024
7939d6e
test ci
miya Aug 27, 2024
cdc3e99
imprv test
miya Aug 27, 2024
5f1d437
add testid
miya Sep 2, 2024
b9e7181
imprv test
miya Sep 2, 2024
7ec7018
Create util (OpenEditor)
miya Sep 2, 2024
cef7ac5
Apply utils
miya Sep 2, 2024
0733f90
Revert "test ci"
miya Sep 2, 2024
533868f
Revert "Revert "test ci""
miya Sep 3, 2024
5ba02f5
imprv test
miya Sep 3, 2024
900c5b3
Create util (appendTextToEditor)
miya Sep 3, 2024
c6089a2
Apply utils
miya Sep 3, 2024
31345ca
Merge pull request #9052 from weseek/support/152368-add-playwright-te…
miya Sep 3, 2024
1b4aeb7
Merge branch 'master' into feat/non-yjs-mode
miya Sep 3, 2024
77bc05e
Merge branch 'master' into feat/non-yjs-mode
miya Sep 3, 2024
c05a58e
rm feat/non-yjs-mode
miya Sep 3, 2024
418e293
Merge branch 'master' into feat/non-yjs-mode
miya Sep 5, 2024
661e014
Merge branch 'master' into feat/non-yjs-mode
miya Sep 5, 2024
c3a2be8
Merge branch 'master' into feat/non-yjs-mode
miya Sep 9, 2024
bd00fff
Merge branch 'master' into feat/non-yjs-mode
miya Sep 12, 2024
4dff099
Merge branch 'master' into feat/non-yjs-mode
miya Sep 13, 2024
133f0a7
Merge branch 'master' into feat/non-yjs-mode
miya Sep 26, 2024
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
2 changes: 2 additions & 0 deletions apps/app/config/ci/.env.local.for-auto-install
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ AUTO_INSTALL_ADMIN_PASSWORD=adminadmin
AUTO_INSTALL_GLOBAL_LANG=en_US

AUTO_INSTALL_SERVER_DATE=2022-01-01T00:00:00.0

YJS_MAX_BODY_LENGTH=10000
21 changes: 9 additions & 12 deletions apps/app/playwright/20-basic-features/access-to-page.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { test, expect, type Page } from '@playwright/test';
import { test, expect } from '@playwright/test';

import { openEditor, appendTextToEditor } from '../utils';

const appendTextToEditorUntilContains = async(page: Page, text: string) => {
await page.locator('.cm-content').fill(text);
await expect(page.getByTestId('page-editor-preview-body')).toContainText(text);
};

test('has title', async({ page }) => {
await page.goto('/Sandbox');
Expand Down Expand Up @@ -43,8 +41,8 @@ test.describe.serial('PageEditor', () => {
test('Edit and save with save-page-btn', async({ page }) => {
await page.goto(targetPath);

await page.getByTestId('editor-button').click();
await appendTextToEditorUntilContains(page, body1);
await openEditor(page);
await appendTextToEditor(page, body1);
await page.getByTestId('save-page-btn').click();

await expect(page.locator('.wiki').first()).toContainText(body1);
Expand All @@ -55,12 +53,11 @@ test.describe.serial('PageEditor', () => {

await page.goto(targetPath);

await page.getByTestId('editor-button').click();

await openEditor(page);
await expect(page.locator('.cm-content')).toContainText(body1);
await expect(page.getByTestId('page-editor-preview-body')).toContainText(body1);

await appendTextToEditorUntilContains(page, body1 + body2);
await appendTextToEditor(page, body1 + body2);
await page.keyboard.press(savePageShortcutKey);
await page.getByTestId('view-button').click();

Expand Down Expand Up @@ -108,7 +105,7 @@ test.describe.serial('Access to Template Editing Mode', () => {

await page.getByTestId('template-button-children').click();

await appendTextToEditorUntilContains(page, templateBody1);
await appendTextToEditor(page, templateBody1);
await page.getByTestId('save-page-btn').click();

await expect(page.locator('.wiki').first()).toContainText(templateBody1);
Expand All @@ -133,7 +130,7 @@ test.describe.serial('Access to Template Editing Mode', () => {

await page.getByTestId('template-button-descendants').click();

await appendTextToEditorUntilContains(page, templateBody2);
await appendTextToEditor(page, templateBody2);
await page.getByTestId('save-page-btn').click();

await expect(page.locator('.wiki').first()).toContainText(templateBody2);
Expand Down
4 changes: 3 additions & 1 deletion apps/app/playwright/20-basic-features/comments.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { test, expect } from '@playwright/test';

import { openEditor } from '../utils';

test('Create comment page', async({ page }) => {
await page.goto('/comment');
await page.getByTestId('editor-button').click();
await openEditor(page);
await page.getByTestId('save-page-btn').click();
await expect(page.locator('.page-meta')).toBeVisible();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { test, expect } from '@playwright/test';

import { openEditor } from '../utils';

test.describe('Sticky features', () => {
test.beforeEach(async({ page }) => {
await page.goto('/');
Expand Down Expand Up @@ -31,7 +33,7 @@ test.describe('Sticky features', () => {
await expect(page.locator('.sticky-outer-wrapper').first()).toHaveClass(/active/);

// Click editor button
await page.getByTestId('editor-button').click();
await openEditor(page);
await expect(page.locator('.layout-root')).toHaveClass(/editing/);
});

Expand Down
70 changes: 70 additions & 0 deletions apps/app/playwright/23-editor/editor-mode.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { test, expect } from '@playwright/test';

import { openEditor, appendTextToEditor } from '../utils';

test.describe.serial('Collaborative editor mode', () => {
const text = 'hello';
const path = '/Sandbox/collaborative-editor-mode';

test.beforeEach(async({ page }) => {
await page.goto(path);
});

test('Expect the previous input content to be reflected even after reloading', async({ page }) => {
await openEditor(page);

await appendTextToEditor(page, text);

// Return to view
await page.getByTestId('view-button').click();
await expect(page.getByTestId('page-view-layout')).toBeVisible();

// Reload
await page.reload();
await openEditor(page);
await expect(page.getByTestId('page-editor-preview-body')).toHaveText(text);
});

test('Expect Collaborative editor mode when opening pages with content length below YJS_MAX_BODY_LENGTH', async({ page }) => {
await openEditor(page);

// Update
await page.getByTestId('save-page-btn').click();

// Back to editor
await openEditor(page);

// Expect to be in Collaborative Editor mode
await expect(page.getByTestId('editing-user-list')).toBeVisible();
await expect(page.getByTestId('single-editor-badge')).not.toBeVisible();
});
});

test.describe('Single editor mode', () => {
const text = 'a'.repeat(10001); // YJS_MAX_BODY_LENGTH + 1
const path = '/Sandbox/single-editor-mode';

test.beforeEach(async({ page }) => {
await page.goto(path);
});

test('Expect Single editor mode when opening pages with content length above YJS_MAX_BODY_LENGTH', async({ page }) => {
await openEditor(page);

await appendTextToEditor(page, text);

// Expect to be in Collaborative Editor mode
await expect(page.getByTestId('editing-user-list')).toBeVisible();
await expect(page.getByTestId('single-editor-badge')).not.toBeVisible();

// Update
await page.getByTestId('save-page-btn').click();

// Back to editor
await openEditor(page);

// Expect to be in Single Editor mode
await expect(page.getByTestId('editing-user-list')).not.toBeVisible();
await expect(page.getByTestId('single-editor-badge')).toBeVisible();
});
});
17 changes: 6 additions & 11 deletions apps/app/playwright/23-editor/saving.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import path from 'path';

import { test, expect, type Page } from '@playwright/test';
import { test, expect } from '@playwright/test';

const appendTextToEditorUntilContains = async(page: Page, text: string) => {
await page.locator('.cm-content').fill(text);
await expect(page.getByTestId('page-editor-preview-body')).toContainText(text);
};
import { openEditor, appendTextToEditor } from '../utils';


test('Successfully create page under specific path', async({ page }) => {
Expand Down Expand Up @@ -33,17 +30,15 @@ test('Successfully updating a page using a shortcut on a previously created page
await page.goto('/Sandbox/child');

// 1st
await page.getByTestId('editor-button').click();
await expect(page.getByTestId('grw-editor-navbar-bottom')).toBeVisible();
await appendTextToEditorUntilContains(page, body1);
await openEditor(page);
await appendTextToEditor(page, body1);
await page.keyboard.press(savePageShortcutKey);
await page.getByTestId('view-button').click();
await expect(page.locator('.main')).toContainText(body1);

// 2nd
await page.getByTestId('editor-button').click();
await expect(page.getByTestId('grw-editor-navbar-bottom')).toBeVisible();
await appendTextToEditorUntilContains(page, body1 + body2);
await openEditor(page);
await appendTextToEditor(page, body1 + body2);
await page.keyboard.press(savePageShortcutKey);
await page.getByTestId('view-button').click();
await expect(page.locator('.main')).toContainText(body1 + body2);
Expand Down
6 changes: 3 additions & 3 deletions apps/app/playwright/23-editor/template-modal.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { test, expect } from '@playwright/test';

import { openEditor } from '../utils';

test('Successfully select template and template locale', async({ page }) => {
const jaText = '今日の目標';
const enText = "TODAY'S GOALS";
await page.goto('/Sandbox/TemplateModal');

// move to edit mode
await page.getByTestId('editor-button').click();
await expect(page.getByTestId('grw-editor-navbar-bottom')).toBeVisible();
await openEditor(page);

// open TemplateModal
const templateModal = page.getByTestId('template-modal');
Expand Down
25 changes: 9 additions & 16 deletions apps/app/playwright/23-editor/with-navigation.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { readFileSync } from 'fs';
import path from 'path';

import { test, expect, type Page } from '@playwright/test';
import { test, expect } from '@playwright/test';

import { openEditor, appendTextToEditor } from '../utils';

/**
* for the issues:
Expand All @@ -12,8 +14,7 @@ test('should not be cleared and should prevent GrantSelector from modified', asy
await page.goto('/Sandbox/for-122040');

// Open Editor
await page.getByTestId('editor-button').click();
await expect(page.getByTestId('grw-editor-navbar-bottom')).toBeVisible();
await openEditor(page);

// Open GrantSelector and select "only me"
await page.getByTestId('grw-grant-selector').click();
Expand Down Expand Up @@ -53,11 +54,6 @@ test('should not be cleared and should prevent GrantSelector from modified', asy
await expect(page.getByTestId('page-grant-alert')).toContainText('Browsing of this page is restricted');
});

const appendTextToEditorUntilContains = async(page: Page, text: string) => {
await page.locator('.cm-content').fill(text);
await expect(page.getByTestId('page-editor-preview-body')).toContainText(text);
};

/**
* for the issue:
* @see https://redmine.weseek.co.jp/issues/115285
Expand All @@ -73,11 +69,10 @@ test('Successfully updating the page body', async({ page }) => {
await page.goto(page1Path);

// Open Editor (page1)
await page.getByTestId('editor-button').click();
await expect(page.getByTestId('grw-editor-navbar-bottom')).toBeVisible();
await openEditor(page);

// Append text
await appendTextToEditorUntilContains(page, page1Body);
await appendTextToEditor(page, page1Body);

// Save page
await page.getByTestId('save-page-btn').click();
Expand All @@ -92,21 +87,19 @@ test('Successfully updating the page body', async({ page }) => {
await page.getByTestId('btn-duplicate').click();

// Open Editor (page2)
await page.getByTestId('editor-button').click();
await expect(page.getByTestId('grw-editor-navbar-bottom')).toBeVisible();
await openEditor(page);

// Expect to see the text from which you are duplicating
await expect(page.getByTestId('page-editor-preview-body')).toContainText(page1Body);

// Append text
await appendTextToEditorUntilContains(page, page1Body + page2Body);
await appendTextToEditor(page, page1Body + page2Body);


await page.goto(page1Path);

// Open Editor (page1)
await page.getByTestId('editor-button').click();
await expect(page.getByTestId('grw-editor-navbar-bottom')).toBeVisible();
await openEditor(page);

await expect(page.getByTestId('page-editor-preview-body')).toContainText(page1Body);

Expand Down
6 changes: 6 additions & 0 deletions apps/app/playwright/utils/AppendTextToEditor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { expect, type Page } from '@playwright/test';

export const appendTextToEditor = async(page: Page, text: string): Promise<void> => {
await page.locator('.cm-content').fill(text);
await expect(page.getByTestId('page-editor-preview-body')).toHaveText(text);
};
8 changes: 8 additions & 0 deletions apps/app/playwright/utils/OpenEditor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { expect, type Page } from '@playwright/test';

export const openEditor = async(page: Page): Promise<void> => {
await expect(page.getByTestId('page-view-layout')).toBeVisible();
await page.getByTestId('editor-button').click();
await expect(page.getByTestId('grw-editor-navbar-bottom')).toBeVisible();
await expect(page.locator('.cm-editor')).toBeVisible();
};
2 changes: 2 additions & 0 deletions apps/app/playwright/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './CollapseSidebar';
export * from './Login';
export * from './OpenEditor';
export * from './AppendTextToEditor';
1 change: 1 addition & 0 deletions apps/app/public/static/locales/en_US/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@
"not_allowed_to_see_this_page": "You cannot see this page",
"Confirm": "Confirm",
"Successfully requested": "Successfully requested.",
"single-editor-mode-alert": "The collaborative editor is disabled because this page's content exceeds {{yjsMaxBodyLength}} characters. To enable it, reduce the content to within the threshold, save the page, and reopen the editor.",
"input_validation": {
"target": {
"page_name": "Page name",
Expand Down
2 changes: 2 additions & 0 deletions apps/app/public/static/locales/fr_FR/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@
"not_allowed_to_see_this_page": "Vous ne pouvez pas voir cette page",
"Confirm": "Confirmer",
"Successfully requested": "Demande envoyée.",
"single-editor-mode-alert": "L'éditeur collaboratif est désactivé car le contenu de cette page dépasse les caractères {{yjsMaxBodyLength}}. Pour l'activer, réduisez le contenu en deçà du seuil, enregistrez la page et ouvrez à nouveau l'éditeur.",

"input_validation": {
"target": {
"page_name": "Nom de la page",
Expand Down
1 change: 1 addition & 0 deletions apps/app/public/static/locales/ja_JP/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
"not_allowed_to_see_this_page": "このページは閲覧できません",
"Confirm": "確認",
"Successfully requested": "正常に処理を受け付けました",
"single-editor-mode-alert": "このページの本文は {{yjsMaxBodyLength}} 文字を超えているため、同時多人数編集は無効化されます。有効にするにはページ本文の文字数が閾値以下になるようにして保存し、再度エディターを開いてください。",
"input_validation": {
"target": {
"page_name": "ページ名",
Expand Down
2 changes: 2 additions & 0 deletions apps/app/public/static/locales/zh_CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@
"Confirm": "确定",
"Successfully requested": "进程成功接受",
"copied_to_clipboard": "它已复制到剪贴板。",
"single-editor-mode-alert": "由于此页面内容超过 {{yjsMaxBodyLength}} 字符数,协作编辑器已禁用。要启用协同编辑器,请将内容减少到阈值以内,保存页面并重新打开编辑器。",

"input_validation": {
"target": {
"page_name": "页面名称",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useMemo } from 'react';

import { PageHeader } from '~/client/components/PageHeader';
import { useIsYjsEnabled } from '~/client/services/yjs';
import { useEditingUsers } from '~/stores/use-editing-users';

import { EditingUserList } from './EditingUserList';
Expand All @@ -10,13 +12,37 @@ const moduleClass = styles['editor-navbar'] ?? '';

export const EditorNavbar = (): JSX.Element => {
const { data: editingUsers } = useEditingUsers();
const isYjsEnabled = useIsYjsEnabled();

const editorCondition = useMemo(() => {
if (isYjsEnabled) {
return (
<div data-testid="editing-user-list">
<EditingUserList userList={editingUsers?.userList ?? []} />
</div>
);
}

if (isYjsEnabled === false) {
return (
<div data-testid="single-editor-badge" className="text-warning bg-warning-subtle rounded-1 px-1">
<div className="d-flex align-items-center justify-content-center">
<span className="material-symbols-outlined fs-6 me-1">error</span>SINGLE
</div>
</div>
);
}

return <></>;
}, [editingUsers?.userList, isYjsEnabled]);

return (
<div className={`${moduleClass} d-flex flex-column flex-sm-row justify-content-between ps-3 ps-md-5 ps-xl-4 pe-4 py-1 align-items-sm-end`}>
<div className="order-2 order-sm-1"><PageHeader /></div>
<div className="order-1 order-sm-2"><EditingUserList
userList={editingUsers?.userList ?? []}
/>
<div className="order-2 order-sm-1">
<PageHeader />
</div>
<div className="order-1 order-sm-2">
{editorCondition}
</div>
</div>
);
Expand Down
Loading
Loading