Просмотр исходного кода

Merge branch 'master' into feat/page-bulk-export

Futa Arai 1 год назад
Родитель
Сommit
d56ada8718
100 измененных файлов с 411 добавлено и 84 удалено
  1. 0 5
      .changeset/tasty-baboons-burn.md
  2. 0 1
      .devcontainer/devcontainer.json
  3. 15 7
      .github/workflows/reusable-app-prod.yml
  4. 27 1
      CHANGELOG.md
  5. 0 2
      apps/app/.prettierignore
  6. 1 1
      apps/app/docker/README.md
  7. 4 6
      apps/app/package.json
  8. 22 24
      apps/app/playwright.config.ts
  9. 30 0
      apps/app/playwright/20-basic-features/access-to-pagelist.spec.ts
  10. 50 0
      apps/app/playwright/20-basic-features/click-page-icons.spec.ts
  11. 49 0
      apps/app/playwright/20-basic-features/comments.spec.ts
  12. 47 0
      apps/app/playwright/20-basic-features/sticky-features.spec.ts
  13. 45 0
      apps/app/playwright/21-basic-features-for-guest/access-to-page.spec.ts
  14. 14 0
      apps/app/playwright/21-basic-features-for-guest/sticky-for-guest.spec.ts
  15. 37 0
      apps/app/playwright/22-sharelink/access-to-sharelink.spec.ts
  16. 5 20
      apps/app/playwright/auth.setup.ts
  17. 21 0
      apps/app/playwright/utils/CollapseSidebar.ts
  18. 24 0
      apps/app/playwright/utils/Login.ts
  19. 2 0
      apps/app/playwright/utils/index.ts
  20. 1 2
      apps/app/public/static/locales/en_US/translation.json
  21. 1 2
      apps/app/public/static/locales/fr_FR/translation.json
  22. 1 2
      apps/app/public/static/locales/ja_JP/translation.json
  23. 1 2
      apps/app/public/static/locales/zh_CN/translation.json
  24. 5 0
      apps/app/src/client/components/.eslintrc.js
  25. 0 0
      apps/app/src/client/components/Admin/AdminHome/AdminHome.jsx
  26. 0 0
      apps/app/src/client/components/Admin/AdminHome/EnvVarsTable.tsx
  27. 0 0
      apps/app/src/client/components/Admin/AdminHome/SystemInfomationTable.tsx
  28. 0 0
      apps/app/src/client/components/Admin/App/AppSetting.jsx
  29. 0 0
      apps/app/src/client/components/Admin/App/AppSettingsPageContents.tsx
  30. 0 0
      apps/app/src/client/components/Admin/App/AwsSetting.tsx
  31. 0 0
      apps/app/src/client/components/Admin/App/AzureSetting.tsx
  32. 0 0
      apps/app/src/client/components/Admin/App/ConfirmModal.tsx
  33. 0 0
      apps/app/src/client/components/Admin/App/FileUploadSetting.tsx
  34. 0 0
      apps/app/src/client/components/Admin/App/GcsSetting.tsx
  35. 0 0
      apps/app/src/client/components/Admin/App/MailSetting.tsx
  36. 0 0
      apps/app/src/client/components/Admin/App/MaintenanceMode.tsx
  37. 0 0
      apps/app/src/client/components/Admin/App/MaskedInput.module.scss
  38. 0 0
      apps/app/src/client/components/Admin/App/MaskedInput.tsx
  39. 0 0
      apps/app/src/client/components/Admin/App/QuestionnaireSettings.tsx
  40. 0 0
      apps/app/src/client/components/Admin/App/SesSetting.tsx
  41. 0 0
      apps/app/src/client/components/Admin/App/SiteUrlSetting.tsx
  42. 0 0
      apps/app/src/client/components/Admin/App/SmtpSetting.tsx
  43. 1 1
      apps/app/src/client/components/Admin/App/V5PageMigration.tsx
  44. 0 0
      apps/app/src/client/components/Admin/AuditLog/ActivityTable.tsx
  45. 0 0
      apps/app/src/client/components/Admin/AuditLog/AuditLogDisableMode.tsx
  46. 1 1
      apps/app/src/client/components/Admin/AuditLog/AuditLogSettings.tsx
  47. 0 0
      apps/app/src/client/components/Admin/AuditLog/DateRangePicker.tsx
  48. 0 0
      apps/app/src/client/components/Admin/AuditLog/SearchUsernameTypeahead.tsx
  49. 0 0
      apps/app/src/client/components/Admin/AuditLog/SelectActionDropdown.tsx
  50. 1 1
      apps/app/src/client/components/Admin/AuditLogManagement.tsx
  51. 0 0
      apps/app/src/client/components/Admin/Common/Accordion.jsx
  52. 0 0
      apps/app/src/client/components/Admin/Common/AdminInstallButtonRow.tsx
  53. 0 0
      apps/app/src/client/components/Admin/Common/AdminUpdateButtonRow.tsx
  54. 0 0
      apps/app/src/client/components/Admin/Common/LabeledProgressBar.tsx
  55. 0 0
      apps/app/src/client/components/Admin/Customize/Customize.jsx
  56. 0 0
      apps/app/src/client/components/Admin/Customize/CustomizeCssSetting.tsx
  57. 0 0
      apps/app/src/client/components/Admin/Customize/CustomizeFunctionOption.tsx
  58. 0 0
      apps/app/src/client/components/Admin/Customize/CustomizeFunctionSetting.tsx
  59. 1 1
      apps/app/src/client/components/Admin/Customize/CustomizeLayoutSetting.tsx
  60. 2 2
      apps/app/src/client/components/Admin/Customize/CustomizeLogoSetting.tsx
  61. 0 0
      apps/app/src/client/components/Admin/Customize/CustomizeNoscriptSetting.tsx
  62. 0 0
      apps/app/src/client/components/Admin/Customize/CustomizePresentationSetting.tsx
  63. 0 0
      apps/app/src/client/components/Admin/Customize/CustomizeScriptSetting.tsx
  64. 1 1
      apps/app/src/client/components/Admin/Customize/CustomizeSidebarSetting.tsx
  65. 0 0
      apps/app/src/client/components/Admin/Customize/CustomizeThemeOptions.tsx
  66. 0 0
      apps/app/src/client/components/Admin/Customize/CustomizeThemeSetting.tsx
  67. 1 1
      apps/app/src/client/components/Admin/Customize/CustomizeTitle.tsx
  68. 0 0
      apps/app/src/client/components/Admin/Customize/PagingSizeUncontrolledDropdown.jsx
  69. 0 0
      apps/app/src/client/components/Admin/Customize/ThemeColorBox.module.scss
  70. 0 0
      apps/app/src/client/components/Admin/Customize/ThemeColorBox.tsx
  71. 1 1
      apps/app/src/client/components/Admin/ElasticsearchManagement/ElasticsearchManagement.tsx
  72. 0 0
      apps/app/src/client/components/Admin/ElasticsearchManagement/NormalizeIndicesControls.tsx
  73. 0 0
      apps/app/src/client/components/Admin/ElasticsearchManagement/RebuildIndexControls.jsx
  74. 0 0
      apps/app/src/client/components/Admin/ElasticsearchManagement/ReconnectControls.tsx
  75. 0 0
      apps/app/src/client/components/Admin/ElasticsearchManagement/StatusTable.jsx
  76. 0 0
      apps/app/src/client/components/Admin/ExportArchiveData/ArchiveFilesTable.tsx
  77. 0 0
      apps/app/src/client/components/Admin/ExportArchiveData/ArchiveFilesTableMenu.tsx
  78. 0 0
      apps/app/src/client/components/Admin/ExportArchiveData/SelectCollectionsModal.tsx
  79. 0 0
      apps/app/src/client/components/Admin/ExportArchiveDataPage.tsx
  80. 0 0
      apps/app/src/client/components/Admin/ForbiddenPage.tsx
  81. 0 0
      apps/app/src/client/components/Admin/FullTextSearchManagement.tsx
  82. 0 0
      apps/app/src/client/components/Admin/G2GDataTransfer.tsx
  83. 0 0
      apps/app/src/client/components/Admin/G2GDataTransferExportForm.tsx
  84. 0 0
      apps/app/src/client/components/Admin/G2GDataTransferStatusIcon.tsx
  85. 0 0
      apps/app/src/client/components/Admin/ImportData/GrowiArchive/ErrorViewer.tsx
  86. 0 0
      apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportCollectionConfigurationModal.jsx
  87. 0 0
      apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportCollectionItem.jsx
  88. 0 0
      apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportForm.jsx
  89. 0 0
      apps/app/src/client/components/Admin/ImportData/GrowiArchive/UploadForm.jsx
  90. 0 0
      apps/app/src/client/components/Admin/ImportData/GrowiArchiveSection.jsx
  91. 0 0
      apps/app/src/client/components/Admin/ImportData/ImportDataPageContents.jsx
  92. 0 0
      apps/app/src/client/components/Admin/LegacySlackIntegration/LegacySlackIntegration.jsx
  93. 0 0
      apps/app/src/client/components/Admin/LegacySlackIntegration/SlackConfiguration.jsx
  94. 0 0
      apps/app/src/client/components/Admin/ManageExternalAccount.tsx
  95. 0 0
      apps/app/src/client/components/Admin/MarkdownSetting/IndentForm.tsx
  96. 0 0
      apps/app/src/client/components/Admin/MarkdownSetting/LineBreakForm.jsx
  97. 0 0
      apps/app/src/client/components/Admin/MarkdownSetting/MarkDownSettingContents.tsx
  98. 0 0
      apps/app/src/client/components/Admin/MarkdownSetting/WhitelistInput.tsx
  99. 0 0
      apps/app/src/client/components/Admin/MarkdownSetting/XssForm.jsx
  100. 0 0
      apps/app/src/client/components/Admin/NotFoundPage.tsx

+ 0 - 5
.changeset/tasty-baboons-burn.md

@@ -1,5 +0,0 @@
----
-'@growi/pluginkit': patch
----
-
-Update tsconfig.json module setting

+ 0 - 1
.devcontainer/devcontainer.json

@@ -23,7 +23,6 @@
     "msjsdiag.debugger-for-chrome",
     "firefox-devtools.vscode-firefox-debug",
     "editorconfig.editorconfig",
-    "esbenp.prettier-vscode",
     "shinnn.stylelint",
     "stylelint.vscode-stylelint",
     "vitest.explorer",

+ 15 - 7
.github/workflows/reusable-app-prod.yml

@@ -213,7 +213,7 @@ jobs:
       fail-fast: false
       matrix:
         # List string expressions that is comma separated ids of tests in "test/cypress/integration"
-        spec-group: ['20', '21', '22', '23', '30', '50']
+        spec-group: ['20', '21', '23', '30', '50']
 
     services:
       mongodb:
@@ -425,12 +425,6 @@ jobs:
       run: |
         cat config/ci/.env.local.for-auto-install >> .env.production.local
 
-    # - name: Copy dotenv file for automatic installation with allowing guest mode
-    #   if: ${{ matrix.spec-group == '21' }}
-    #   working-directory: ./apps/app
-    #   run: |
-    #     cat config/ci/.env.local.for-auto-install-with-allowing-guest >> .env.production.local
-
     - name: Playwright Run
       working-directory: ./apps/app
       run: |
@@ -440,6 +434,20 @@ jobs:
         MONGO_URI: mongodb://mongodb:27017/growi-playwright
         ELASTICSEARCH_URI: http://localhost:${{ job.services.elasticsearch.ports['9200'] }}/growi
 
+    - name: Copy dotenv file for automatic installation with allowing guest mode
+      working-directory: ./apps/app
+      run: |
+        cat config/ci/.env.local.for-auto-install-with-allowing-guest >> .env.production.local
+
+    - name: Playwright Run (--project=${browser}/guest-mode)
+      working-directory: ./apps/app
+      run: |
+        yarn playwright test --project=${{ matrix.browser }}/guest-mode --shard=${{ matrix.shard }}
+      env:
+        HOME: /root # ref: https://github.com/microsoft/playwright/issues/6500
+        MONGO_URI: mongodb://mongodb:27017/growi-playwright-guest-mode
+        ELASTICSEARCH_URI: http://localhost:${{ job.services.elasticsearch.ports['9200'] }}/growi
+
     - name: Slack Notification
       uses: weseek/ghaction-slack-notification@master
       if: failure()

+ 27 - 1
CHANGELOG.md

@@ -1,9 +1,35 @@
 # Changelog
 
-## [Unreleased](https://github.com/weseek/growi/compare/v7.0.10...HEAD)
+## [Unreleased](https://github.com/weseek/growi/compare/v7.0.11...HEAD)
 
 *Please do not manually update this file. We've automated the process.*
 
+## [v7.0.11](https://github.com/weseek/growi/compare/v7.0.10...v7.0.11) - 2024-06-25
+
+### 💎 Features
+
+### 🚀 Improvement
+
+* imprv: New marker color (#8891) @satof3
+* imprv: SSR performance (#8916) @yuki-takei
+
+### 🐛 Bug Fixes
+
+* fix: Vim keymap works correctly (#8901) @reiji-h
+* fix: Readonly editor prevents ctrl+v and paste. (#8902) @reiji-h
+* fix: Missing HTTP Response in SAML Login With ABLC Callback (#8879) @maeshinshin
+* fix: Set `z-0` to correct navbar and header overlap when the anchor is specified (#8905) @yuki-takei
+* fix: Minimum number of characters in password cannot be changed (#8896) @miya
+
+### 🧰 Maintenance
+
+* support: Replace tests with playwright (20-basic-features/20-basic-features--click-page-icons) (#8903) @miya
+* support: Relocate components dir (#8917) @yuki-takei
+* ci(deps): bump ws from 8.11.0 to 8.17.1 (#8906) @dependabot
+* support: Update module resolution settings (#8898) @yuki-takei
+* support: Decrease max SSR body length (#8895) @yuki-takei
+* support: Use typescript-transform-paths instead of tsconfig-paths (#8892) @yuki-takei
+
 ## [v7.0.10](https://github.com/weseek/growi/compare/v7.0.9...v7.0.10) - 2024-06-13
 
 ### 💎 Features

+ 0 - 2
apps/app/.prettierignore

@@ -1,2 +0,0 @@
-src/client/styles/bootstrap4/
-src/client/styles/scss/_override-bootstrap-variables.scss

+ 1 - 1
apps/app/docker/README.md

@@ -10,7 +10,7 @@ GROWI Official docker image
 Supported tags and respective Dockerfile links
 ------------------------------------------------
 
-* [`7.0.10`, `7.0`, `7`, `latest` (Dockerfile)](https://github.com/weseek/growi/blob/v7.0.10/apps/app/docker/Dockerfile)
+* [`7.0.11`, `7.0`, `7`, `latest` (Dockerfile)](https://github.com/weseek/growi/blob/v7.0.11/apps/app/docker/Dockerfile)
 * [`6.3.2`, `6.3`, `6` (Dockerfile)](https://github.com/weseek/growi/blob/v6.3.2/apps/app/docker/Dockerfile)
 * [`6.2.4`, `6.2` (Dockerfile)](https://github.com/weseek/growi/blob/v6.2.4/apps/app/docker/Dockerfile)
 * [`6.1.15`, `6.1` (Dockerfile)](https://github.com/weseek/growi/blob/v6.1.15/apps/app/docker/Dockerfile)

+ 4 - 6
apps/app/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/app",
-  "version": "7.0.11-RC.0",
+  "version": "7.0.12-RC.0",
   "license": "MIT",
   "private": "true",
   "scripts": {
@@ -72,6 +72,7 @@
     "@google-cloud/storage": "^5.8.5",
     "@growi/core": "link:../../packages/core",
     "@growi/pluginkit": "link:../../packages/pluginkit",
+    "@growi/presentation": "link:../../packages/presentation",
     "@growi/preset-templates": "link:../../packages/preset-templates",
     "@growi/preset-themes": "link:../../packages/preset-themes",
     "@growi/remark-attachment-refs": "link:../../packages/remark-attachment-refs",
@@ -144,6 +145,7 @@
     "multer-autoreap": "^1.0.3",
     "mustache": "^4.2.0",
     "next": "^14.1.3",
+    "next-dynamic-loading-props": "^0.1.1",
     "next-i18next": "^15.2.0",
     "next-superjson": "^0.0.4",
     "next-themes": "^0.2.1",
@@ -206,7 +208,7 @@
     "url-join": "^4.0.0",
     "usehooks-ts": "^2.6.0",
     "validator": "^13.7.0",
-    "ws": "^8.3.0",
+    "ws": "^8.17.1",
     "xss": "^1.0.14",
     "y-mongodb-provider": "^0.1.10",
     "y-socket.io": "^1.1.3",
@@ -221,7 +223,6 @@
     "@growi/core-styles": "link:../../packages/core-styles",
     "@growi/custom-icons": "link:../../packages/custom-icons",
     "@growi/editor": "link:../../packages/editor",
-    "@growi/presentation": "link:../../packages/presentation",
     "@growi/ui": "link:../../packages/ui",
     "@handsontable/react": "=2.1.0",
     "@next/bundle-analyzer": "^14.1.3",
@@ -239,8 +240,6 @@
     "@types/throttle-debounce": "^5.0.1",
     "@types/unzip-stream": "^0.3.4",
     "@types/url-join": "^4.0.2",
-    "@vitejs/plugin-react": "^4.3.0",
-    "@vitest/coverage-v8": "^0.34.6",
     "babel-loader": "^8.2.5",
     "bootstrap": "=5.3.2",
     "connect-browser-sync": "^2.1.0",
@@ -267,7 +266,6 @@
     "morgan": "^1.10.0",
     "null-loader": "^4.0.1",
     "plantuml-encoder": "^1.2.5",
-    "prettier": "^1.19.1",
     "pretty-bytes": "^6.1.1",
     "react-codemirror2": "^6.0.0",
     "react-copy-to-clipboard": "^5.0.1",

+ 22 - 24
apps/app/playwright.config.ts

@@ -1,10 +1,28 @@
 import fs from 'node:fs';
 import path from 'node:path';
 
-import { defineConfig, devices } from '@playwright/test';
+import { defineConfig, devices, type Project } from '@playwright/test';
 
 const authFile = path.resolve(__dirname, './playwright/.auth/admin.json');
 
+// Use prepared auth state.
+const storageState = fs.existsSync(authFile) ? authFile : undefined;
+
+const supportedBrowsers = ['chromium', 'firefox', 'webkit'] as const;
+
+const projects: Array<Project> = supportedBrowsers.map(browser => ({
+  name: browser,
+  use: { ...devices[`Desktop ${browser}`], storageState },
+  testIgnore: /(10-installer|21-basic-features-for-guest)\/.*\.spec\.ts/,
+  dependencies: ['setup', 'auth'],
+}));
+
+const projectsForGuestMode: Array<Project> = supportedBrowsers.map(browser => ({
+  name: `${browser}/guest-mode`,
+  use: { ...devices[`Desktop ${browser}`] }, // Do not use storageState
+  testMatch: /21-basic-features-for-guest\/.*\.spec\.ts/,
+}));
+
 /**
  * Read environment variables from file.
  * https://github.com/motdotla/dotenv
@@ -49,9 +67,6 @@ export default defineConfig({
     trace: 'on-first-retry',
 
     viewport: { width: 1400, height: 1024 },
-
-    // Use prepared auth state.
-    storageState: fs.existsSync(authFile) ? authFile : undefined,
   },
 
   /* Configure projects for major browsers */
@@ -62,31 +77,14 @@ export default defineConfig({
 
     {
       name: 'chromium/installer',
-      use: { ...devices['Desktop Chrome'] },
+      use: { ...devices['Desktop Chrome'], storageState },
       testMatch: /10-installer\/.*\.spec\.ts/,
       dependencies: ['setup'],
     },
 
-    {
-      name: 'chromium',
-      use: { ...devices['Desktop Chrome'] },
-      testIgnore: /10-installer\/.*\.spec\.ts/,
-      dependencies: ['setup', 'auth'],
-    },
-
-    {
-      name: 'firefox',
-      use: { ...devices['Desktop Firefox'] },
-      testIgnore: /10-installer\/.*\.spec\.ts/,
-      dependencies: ['setup', 'auth'],
-    },
+    ...projects,
 
-    {
-      name: 'webkit',
-      use: { ...devices['Desktop Safari'] },
-      testIgnore: /10-installer\/.*\.spec\.ts/,
-      dependencies: ['setup', 'auth'],
-    },
+    ...projectsForGuestMode,
 
     /* Test against mobile viewports. */
     // {

+ 30 - 0
apps/app/playwright/20-basic-features/access-to-pagelist.spec.ts

@@ -0,0 +1,30 @@
+import { test, expect, type Page } from '@playwright/test';
+
+const openPageAccessoriesModal = async(page: Page): Promise<void> => {
+  await page.goto('/');
+  await page.getByTestId('pageListButton').click();
+  await expect(page.getByTestId('descendants-page-list-modal')).toBeVisible();
+};
+
+test('Page list modal is successfully opened', async({ page }) => {
+  await openPageAccessoriesModal(page);
+  await expect(page.getByTestId('page-list-item-L').first()).not.toContainText('You cannot see this page');
+});
+
+test('Successfully open PageItemControl', async({ page }) => {
+  await openPageAccessoriesModal(page);
+  await page.getByTestId('page-list-item-L').first().getByTestId('open-page-item-control-btn').click();
+  await expect(page.locator('.dropdown-menu.show')).toBeVisible();
+});
+
+test('Successfully close modal', async({ page }) => {
+  await openPageAccessoriesModal(page);
+  await page.locator('.btn-close').click();
+  await expect(page.getByTestId('descendants-page-list-modal')).not.toBeVisible();
+});
+
+test('Timeline list successfully openend', async({ page }) => {
+  await openPageAccessoriesModal(page);
+  await page.getByTestId('timeline-tab-button').click();
+  await expect(page.locator('.card-timeline').first()).toBeVisible();
+});

+ 50 - 0
apps/app/playwright/20-basic-features/click-page-icons.spec.ts

@@ -0,0 +1,50 @@
+import { test, expect } from '@playwright/test';
+
+test.describe('Click page icons', () => {
+  test.beforeEach(async({ page }) => {
+    await page.goto('/Sandbox');
+  });
+
+  test('Successfully Subscribe/Unsubscribe a page', async({ page }) => {
+    const subscribeButton = page.locator('.btn-subscribe');
+
+    // Subscribe
+    await subscribeButton.click();
+    await expect(subscribeButton).toHaveClass(/active/);
+
+    // Unsubscribe
+    await subscribeButton.click();
+    await expect(subscribeButton).not.toHaveClass(/active/);
+  });
+
+  test('Successfully Like/Unlike a page', async({ page }) => {
+    const likeButton = page.locator('.btn-like').first();
+
+    // Like
+    await likeButton.click();
+    await expect(likeButton).toHaveClass(/active/);
+
+    // Unlike
+    await likeButton.click();
+    await expect(likeButton).not.toHaveClass(/active/);
+  });
+
+  test('Successfully Bookmark / Unbookmark a page', async({ page }) => {
+    const bookmarkButton = page.locator('.btn-bookmark').first();
+
+    // Bookmark
+    await bookmarkButton.click();
+    await expect(bookmarkButton).toHaveClass(/active/);
+
+    // Unbookmark
+    await page.locator('.grw-bookmark-folder-menu-item').click();
+    await expect(bookmarkButton).not.toHaveClass(/active/);
+  });
+
+  test('Successfully display list of "seen by user"', async({ page }) => {
+    await page.locator('.btn-seen-user').click();
+
+    const imgCount = await page.locator('.user-list-content').locator('img').count();
+    expect(imgCount).toBe(1);
+  });
+});

+ 49 - 0
apps/app/playwright/20-basic-features/comments.spec.ts

@@ -0,0 +1,49 @@
+import { test, expect } from '@playwright/test';
+
+test('Create comment page', async({ page }) => {
+  await page.goto('/comment');
+  await page.getByTestId('editor-button').click();
+  await page.getByTestId('save-page-btn').click();
+  await expect(page.locator('.page-meta')).toBeVisible();
+});
+
+test('Successfully add comments', async({ page }) => {
+  const commentText = 'add comment';
+  await page.goto('/comment');
+
+  // Add comment
+  await page.getByTestId('page-comment-button').click();
+  await page.getByTestId('open-comment-editor-button').click();
+  await page.locator('.cm-content').fill(commentText);
+  await page.getByTestId('comment-submit-button').first().click();
+
+  await expect(page.locator('.page-comment-body')).toHaveText(commentText);
+  await expect(page.getByTestId('page-comment-button').locator('.grw-count-badge')).toHaveText('1');
+});
+
+test('Successfully reply comments', async({ page }) => {
+  const commentText = 'reply comment';
+  await page.goto('/comment');
+
+  // Reply comment
+  await page.getByTestId('page-comment-button').click();
+  await page.getByTestId('comment-reply-button').click();
+  await page.locator('.cm-content').fill(commentText);
+  await page.getByTestId('comment-submit-button').first().click();
+
+  await expect(page.locator('.page-comment-body').nth(1)).toHaveText(commentText);
+  await expect(page.getByTestId('page-comment-button').locator('.grw-count-badge')).toHaveText('2');
+});
+
+// test('Successfully delete comments', async({ page }) => {
+//   await page.goto('/comment');
+
+//   await page.getByTestId('page-comment-button').click();
+//   await page.getByTestId('comment-delete-button').first().click({ force: true });
+//   await expect(page.getByTestId('page-comment-delete-modal')).toBeVisible();
+//   await page.getByTestId('delete-comment-button').click();
+
+//   await expect(page.getByTestId('page-comment-button').locator('.grw-count-badge')).toHaveText('0');
+// });
+
+// TODO: https://redmine.weseek.co.jp/issues/139520

+ 47 - 0
apps/app/playwright/20-basic-features/sticky-features.spec.ts

@@ -0,0 +1,47 @@
+import { test, expect } from '@playwright/test';
+
+test.describe('Sticky features', () => {
+  test.beforeEach(async({ page }) => {
+    await page.goto('/');
+  });
+
+  test('Subnavigation displays changes on scroll down and up', async({ page }) => {
+    // Scroll down to trigger sticky effect
+    await page.evaluate(() => window.scrollTo(0, 250));
+    await expect(page.locator('.sticky-outer-wrapper').first()).toHaveClass(/active/);
+
+    // Scroll back to top
+    await page.evaluate(() => window.scrollTo(0, 0));
+    await expect(page.locator('.sticky-outer-wrapper').first()).not.toHaveClass(/active/);
+  });
+
+  test('Subnavigation is not displayed when move to other pages', async({ page }) => {
+    // Scroll down to trigger sticky effect
+    await page.evaluate(() => window.scrollTo(0, 250));
+    await expect(page.locator('.sticky-outer-wrapper').first()).toHaveClass(/active/);
+
+    // Move to /Sandbox page
+    await page.goto('/Sandbox');
+    await expect(page.locator('.sticky-outer-wrapper').first()).not.toHaveClass(/active/);
+  });
+
+  test('Able to click buttons on subnavigation switcher when sticky', async({ page }) => {
+    // Scroll down to trigger sticky effect
+    await page.evaluate(() => window.scrollTo(0, 250));
+    await expect(page.locator('.sticky-outer-wrapper').first()).toHaveClass(/active/);
+
+    // Click editor button
+    await page.getByTestId('editor-button').click();
+    await expect(page.locator('.layout-root')).toHaveClass(/editing/);
+  });
+
+  test('Subnavigation is sticky when on small window', async({ page }) => {
+    // Scroll down to trigger sticky effect
+    await page.evaluate(() => window.scrollTo(0, 500));
+    await expect(page.locator('.sticky-outer-wrapper').first()).toHaveClass(/active/);
+
+    // Set viewport to small size
+    await page.setViewportSize({ width: 600, height: 1024 });
+    await expect(page.getByTestId('grw-contextual-sub-nav').getByTestId('grw-page-editor-mode-manager')).toBeVisible();
+  });
+});

+ 45 - 0
apps/app/playwright/21-basic-features-for-guest/access-to-page.spec.ts

@@ -0,0 +1,45 @@
+import { test, expect } from '@playwright/test';
+
+import { collapseSidebar } from '../utils';
+
+test('/Sandbox is successfully loaded', async({ page }) => {
+
+  await page.goto('/Sandbox');
+
+  // Expect a title "to contain" a substring.
+  await expect(page).toHaveTitle(/Sandbox/);
+});
+
+test('/Sandbox/math is successfully loaded', async({ page }) => {
+
+  await page.goto('/Sandbox/Math');
+
+  // Check if the math elements are visible
+  await expect(page.locator('.math').first()).toBeVisible();
+});
+
+test('Access to /me page', async({ page }) => {
+  await page.goto('/me');
+
+  // Expect to be redirected to /login when accessing /me
+  await expect(page.getByTestId('login-form')).toBeVisible();
+});
+
+test('Access to /trash page', async({ page }) => {
+  await page.goto('/trash');
+
+  // Expect the trash page specific elements to be present when accessing /trash
+  await expect(page.getByTestId('trash-page-list')).toBeVisible();
+});
+
+// TODO: Improve collapseSidebar (https://redmine.weseek.co.jp/issues/148538)
+// test('Access to /tags page', async({ page }) => {
+//   await page.goto('/tags');
+
+//   await collapseSidebar(page, false);
+//   await page.getByTestId('grw-sidebar-nav-primary-tags').click();
+//   await expect(page.getByTestId('grw-sidebar-content-tags')).toBeVisible();
+//   await expect(page.getByTestId('grw-tags-list').first()).toBeVisible();
+//   await expect(page.getByTestId('grw-tags-list').first()).toContainText('You have no tag, You can set tags on pages');
+//   await expect(page.getByTestId('tags-page')).toBeVisible();
+// });

+ 14 - 0
apps/app/playwright/21-basic-features-for-guest/sticky-for-guest.spec.ts

@@ -0,0 +1,14 @@
+import { test, expect } from '@playwright/test';
+
+
+test('Sub navigation sticky changes when scrolling down and up', async({ page }) => {
+  await page.goto('/Sandbox');
+
+  // Sticky
+  await page.evaluate(() => window.scrollTo(0, 250));
+  await expect(page.locator('.sticky-outer-wrapper').first()).toHaveClass(/active/);
+
+  // Not sticky
+  await page.evaluate(() => window.scrollTo(0, 0));
+  await expect(page.locator('.sticky-outer-wrapper').first()).not.toHaveClass(/active/);
+});

+ 37 - 0
apps/app/playwright/22-sharelink/access-to-sharelink.spec.ts

@@ -0,0 +1,37 @@
+import { test, expect } from '@playwright/test';
+
+import { login } from '../utils/Login';
+
+test.describe.serial('Access to sharelink by guest', () => {
+  let createdSharelink: string | null;
+
+  test('Prepare sharelink', async({ page }) => {
+    await page.goto('/Sandbox/Bootstrap5');
+
+    // Create Sharelink
+    await page.getByTestId('open-page-item-control-btn').click();
+    await page.getByTestId('open-page-accessories-modal-btn-with-share-link-management-data-tab').click();
+    await page.getByTestId('btn-sharelink-toggleform').click();
+    await page.getByTestId('btn-sharelink-issue').click();
+
+    // Get ShareLink
+    createdSharelink = await page.getByTestId('share-link').textContent();
+    expect(createdSharelink).toHaveLength(24);
+  });
+
+  test('The sharelink page is successfully loaded', async({ page }) => {
+    await page.goto('/');
+
+    // Logout
+    await page.getByTestId('personal-dropdown-button').click();
+    await expect(page.getByTestId('logout-button')).toBeVisible();
+    await page.getByTestId('logout-button').click();
+    await page.waitForURL('http://localhost:3000/login');
+
+    // Access sharelink
+    await page.goto(`/share/${createdSharelink}`);
+    await expect(page.locator('.page-meta')).toBeVisible();
+
+    await login(page);
+  });
+});

+ 5 - 20
apps/app/playwright/auth.setup.ts

@@ -1,24 +1,9 @@
-import path from 'node:path';
+import { test as setup } from '@playwright/test';
 
-import { test as setup, expect } from '@playwright/test';
-
-const authFile = path.resolve(__dirname, './.auth/admin.json');
+import { login } from './utils/Login';
 
+// Commonised login process for use elsewhere
+// see: https://github.com/microsoft/playwright/issues/22114
 setup('Authenticate as the "admin" user', async({ page }) => {
-  // Perform authentication steps. Replace these actions with your own.
-  await page.goto('/admin');
-
-  const loginForm = await page.$('form#login-form');
-
-  if (loginForm != null) {
-    await page.getByLabel('Username or E-mail').fill('admin');
-    await page.getByLabel('Password').fill('adminadmin');
-    await page.locator('[type=submit]').filter({ hasText: 'Login' }).click();
-  }
-
-  await page.waitForURL('/admin');
-  await expect(page).toHaveTitle(/Wiki Management Homepage/);
-
-  // End of authentication steps.
-  await page.context().storageState({ path: authFile });
+  await login(page);
 });

+ 21 - 0
apps/app/playwright/utils/CollapseSidebar.ts

@@ -0,0 +1,21 @@
+// TODO: https://redmine.weseek.co.jp/issues/148538
+import { expect, type Page } from '@playwright/test';
+
+export const collapseSidebar = async(page: Page, isCollapsed: boolean): Promise<void> => {
+  const isSidebarContentsHidden = !(await page.getByTestId('grw-sidebar-contents').isVisible());
+  if (isSidebarContentsHidden === isCollapsed) {
+    return;
+  }
+
+  const collapseSidebarToggle = page.getByTestId('btn-toggle-collapse');
+  await expect(collapseSidebarToggle).toBeVisible();
+
+  await collapseSidebarToggle.click();
+
+  if (isCollapsed) {
+    await expect(page.locator('.grw-sidebar-dock')).not.toBeVisible();
+  }
+  else {
+    await expect(page.locator('.grw-sidebar-dock')).toBeVisible();
+  }
+};

+ 24 - 0
apps/app/playwright/utils/Login.ts

@@ -0,0 +1,24 @@
+import path from 'node:path';
+
+import { expect, type Page } from '@playwright/test';
+
+const authFile = path.resolve(__dirname, '../.auth/admin.json');
+
+export const login = async(page: Page): Promise<void> => {
+  // Perform authentication steps. Replace these actions with your own.
+  await page.goto('/admin');
+
+  const loginForm = await page.$('form#login-form');
+
+  if (loginForm != null) {
+    await page.getByLabel('Username or E-mail').fill('admin');
+    await page.getByLabel('Password').fill('adminadmin');
+    await page.locator('[type=submit]').filter({ hasText: 'Login' }).click();
+  }
+
+  await page.waitForURL('/admin');
+  await expect(page).toHaveTitle(/Wiki Management Homepage/);
+
+  // End of authentication steps.
+  await page.context().storageState({ path: authFile });
+};

+ 2 - 0
apps/app/playwright/utils/index.ts

@@ -0,0 +1,2 @@
+export * from './CollapseSidebar';
+export * from './Login';

+ 1 - 2
apps/app/public/static/locales/en_US/translation.json

@@ -677,10 +677,9 @@
     "Email format is invalid": "Email format is invalid.",
     "Email field is required": "Email field is required.",
     "Password has invalid character": "Password has invalid character.",
-    "Password minimum character should be more than 8 characters": "Password minimum character should be more than 8 characters.",
+    "Password minimum character should be more than n characters": "Password minimum character should be more than {{number}} characters.",
     "Password field is required": "Password field is required.",
     "Username or E-mail has invalid characters": "Username or E-mail has invalid characters.",
-    "Password minimum character should be more than 6 characters": "Password minimum character should be more than 6 characters.",
     "user_not_found": "User not found.",
     "provider_duplicated_username_exception": "<p><strong><span class='material-symbols-outlined me-1'>cancel</span>DuplicatedUsernameException occured</strong></p><p class='mb-0'> Your {{ failedProviderForDuplicatedUsernameException }} authentication was succeeded, but a new user could not be created. See the issue <a href='https://github.com/weseek/growi/issues/193'>#193</a>.</p>"
   },

+ 1 - 2
apps/app/public/static/locales/fr_FR/translation.json

@@ -671,10 +671,9 @@
     "Email format is invalid": "Format d'adresse courriel invalide.",
     "Email field is required": "Adresse courriel requise.",
     "Password has invalid character": "Le mot de passe contient des caractères invalides",
-    "Password minimum character should be more than 8 characters": "Le mot de passe doit contenir plus de 8 caractères.",
+    "Password minimum character should be more than n characters": "Le mot de passe doit contenir plus de {{number}} caractères.",
     "Password field is required": "Mot de passe requis.",
     "Username or E-mail has invalid characters": "Le nom d'utilisateur ou l'adresse courriel contient des caractères invalides",
-    "Password minimum character should be more than 6 characters": "Le mot de passe doit contenir au moins 6 caractères.",
     "user_not_found": "Utilisateur introuvable.",
     "provider_duplicated_username_exception": "<p><strong><span class='material-symbols-outlined me-1'>cancel</span>DuplicatedUsernameException</strong></p><p class='mb-0'> L'authentification est réussie pour {{ failedProviderForDuplicatedUsernameException }} , mais la création d'un utilisateur a échouée. Voir <a href='https://github.com/weseek/growi/issues/193'>#193</a>.</p>"
   },

+ 1 - 2
apps/app/public/static/locales/ja_JP/translation.json

@@ -710,10 +710,9 @@
     "Email format is invalid": "メールアドレスのフォーマットが無効です",
     "Email field is required": "メールアドレスは必須項目です",
     "Password has invalid character": "パスワードに無効な文字があります",
-    "Password minimum character should be more than 8 characters": "パスワードの最小文字数は8文字以上です",
+    "Password minimum character should be more than n characters": "パスワードの最小文字数は{{number}}文字以上です",
     "Password field is required": "パスワードの欄は必ず入力してください",
     "Username or E-mail has invalid characters": "ユーザー名または、メールアドレスに無効な文字があります",
-    "Password minimum character should be more than 6 characters": "パスワードの最小文字数は6文字以上です",
     "user_not_found": "ユーザーが見つかりません",
     "provider_duplicated_username_exception": "<p><strong><span class='material-symbols-outlined me-1'>cancel</span>エラー: DuplicatedUsernameException</strong></p><p class='mb-0'> {{ failedProviderForDuplicatedUsernameException }} 認証は成功しましたが、新しいユーザーを作成できませんでした。詳しくは<a href='https://github.com/weseek/growi/issues/193'>こちら: #193</a>.</p>"
   },

+ 1 - 2
apps/app/public/static/locales/zh_CN/translation.json

@@ -680,10 +680,9 @@
     "Email format is invalid": "电子邮件的格式是无效的",
     "Email field is required": "电子邮件字段是必需的",
     "Password has invalid character": "密码有无效字符",
-    "Password minimum character should be more than 8 characters": "密码最小字符应超过8个字符",
+    "Password minimum character should be more than n characters": "密码最小字符应超过{{number}}个字符",
     "Password field is required": "密码字段是必需的",
     "Username or E-mail has invalid characters": "用户名或电子邮件有无效的字符",
-    "Password minimum character should be more than 6 characters": "密码最小字符应超过6个字符",
     "user_not_found": "未找到用户",
     "provider_duplicated_username_exception": "<p><strong><span class='material-symbols-outlined me-1'>cancel</span>发生了重复用户名异常</strong></p><p class='mb-0'> 你的 {{ failedProviderForDuplicatedUsernameException }} 认证成功了,但不能创建新的用户。参见问题<a href='https://github.com/weseek/growi/issues/193'>#193</a>.</p>"
   },

+ 5 - 0
apps/app/src/client/components/.eslintrc.js

@@ -0,0 +1,5 @@
+module.exports = {
+  extends: '../../../.eslintrc.js',
+  rules: {
+  },
+};

+ 0 - 0
apps/app/src/components/Admin/AdminHome/AdminHome.jsx → apps/app/src/client/components/Admin/AdminHome/AdminHome.jsx


+ 0 - 0
apps/app/src/components/Admin/AdminHome/EnvVarsTable.tsx → apps/app/src/client/components/Admin/AdminHome/EnvVarsTable.tsx


+ 0 - 0
apps/app/src/components/Admin/AdminHome/SystemInfomationTable.tsx → apps/app/src/client/components/Admin/AdminHome/SystemInfomationTable.tsx


+ 0 - 0
apps/app/src/components/Admin/App/AppSetting.jsx → apps/app/src/client/components/Admin/App/AppSetting.jsx


+ 0 - 0
apps/app/src/components/Admin/App/AppSettingsPageContents.tsx → apps/app/src/client/components/Admin/App/AppSettingsPageContents.tsx


+ 0 - 0
apps/app/src/components/Admin/App/AwsSetting.tsx → apps/app/src/client/components/Admin/App/AwsSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/App/AzureSetting.tsx → apps/app/src/client/components/Admin/App/AzureSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/App/ConfirmModal.tsx → apps/app/src/client/components/Admin/App/ConfirmModal.tsx


+ 0 - 0
apps/app/src/components/Admin/App/FileUploadSetting.tsx → apps/app/src/client/components/Admin/App/FileUploadSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/App/GcsSetting.tsx → apps/app/src/client/components/Admin/App/GcsSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/App/MailSetting.tsx → apps/app/src/client/components/Admin/App/MailSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/App/MaintenanceMode.tsx → apps/app/src/client/components/Admin/App/MaintenanceMode.tsx


+ 0 - 0
apps/app/src/components/Admin/App/MaskedInput.module.scss → apps/app/src/client/components/Admin/App/MaskedInput.module.scss


+ 0 - 0
apps/app/src/components/Admin/App/MaskedInput.tsx → apps/app/src/client/components/Admin/App/MaskedInput.tsx


+ 0 - 0
apps/app/src/components/Admin/App/QuestionnaireSettings.tsx → apps/app/src/client/components/Admin/App/QuestionnaireSettings.tsx


+ 0 - 0
apps/app/src/components/Admin/App/SesSetting.tsx → apps/app/src/client/components/Admin/App/SesSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/App/SiteUrlSetting.tsx → apps/app/src/client/components/Admin/App/SiteUrlSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/App/SmtpSetting.tsx → apps/app/src/client/components/Admin/App/SmtpSetting.tsx


+ 1 - 1
apps/app/src/components/Admin/App/V5PageMigration.tsx → apps/app/src/client/components/Admin/App/V5PageMigration.tsx

@@ -10,7 +10,7 @@ import {
 } from '~/interfaces/websocket';
 import { useGlobalAdminSocket } from '~/stores/websocket';
 
-import AdminAppContainer from '../../../client/services/AdminAppContainer';
+import AdminAppContainer from '../../../services/AdminAppContainer';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import LabeledProgressBar from '../Common/LabeledProgressBar';
 

+ 0 - 0
apps/app/src/components/Admin/AuditLog/ActivityTable.tsx → apps/app/src/client/components/Admin/AuditLog/ActivityTable.tsx


+ 0 - 0
apps/app/src/components/Admin/AuditLog/AuditLogDisableMode.tsx → apps/app/src/client/components/Admin/AuditLog/AuditLogDisableMode.tsx


+ 1 - 1
apps/app/src/components/Admin/AuditLog/AuditLogSettings.tsx → apps/app/src/client/components/Admin/AuditLog/AuditLogSettings.tsx

@@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
 import { Collapse } from 'reactstrap';
 
 import { AllSupportedActions } from '~/interfaces/activity';
-import { useActivityExpirationSeconds, useAuditLogAvailableActions } from '~/stores/context';
+import { useActivityExpirationSeconds, useAuditLogAvailableActions } from '~/stores-universal/context';
 
 export const AuditLogSettings: FC = () => {
   const { t } = useTranslation();

+ 0 - 0
apps/app/src/components/Admin/AuditLog/DateRangePicker.tsx → apps/app/src/client/components/Admin/AuditLog/DateRangePicker.tsx


+ 0 - 0
apps/app/src/components/Admin/AuditLog/SearchUsernameTypeahead.tsx → apps/app/src/client/components/Admin/AuditLog/SearchUsernameTypeahead.tsx


+ 0 - 0
apps/app/src/components/Admin/AuditLog/SelectActionDropdown.tsx → apps/app/src/client/components/Admin/AuditLog/SelectActionDropdown.tsx


+ 1 - 1
apps/app/src/components/Admin/AuditLogManagement.tsx → apps/app/src/client/components/Admin/AuditLogManagement.tsx

@@ -8,8 +8,8 @@ import { useTranslation } from 'react-i18next';
 import type { IClearable } from '~/client/interfaces/clearable';
 import { toastError } from '~/client/util/toastr';
 import type { SupportedActionType } from '~/interfaces/activity';
+import { useAuditLogEnabled, useAuditLogAvailableActions } from '~/stores-universal/context';
 import { useSWRxActivity } from '~/stores/activity';
-import { useAuditLogEnabled, useAuditLogAvailableActions } from '~/stores/context';
 
 import PaginationWrapper from '../PaginationWrapper';
 

+ 0 - 0
apps/app/src/components/Admin/Common/Accordion.jsx → apps/app/src/client/components/Admin/Common/Accordion.jsx


+ 0 - 0
apps/app/src/components/Admin/Common/AdminInstallButtonRow.tsx → apps/app/src/client/components/Admin/Common/AdminInstallButtonRow.tsx


+ 0 - 0
apps/app/src/components/Admin/Common/AdminUpdateButtonRow.tsx → apps/app/src/client/components/Admin/Common/AdminUpdateButtonRow.tsx


+ 0 - 0
apps/app/src/components/Admin/Common/LabeledProgressBar.tsx → apps/app/src/client/components/Admin/Common/LabeledProgressBar.tsx


+ 0 - 0
apps/app/src/components/Admin/Customize/Customize.jsx → apps/app/src/client/components/Admin/Customize/Customize.jsx


+ 0 - 0
apps/app/src/components/Admin/Customize/CustomizeCssSetting.tsx → apps/app/src/client/components/Admin/Customize/CustomizeCssSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/Customize/CustomizeFunctionOption.tsx → apps/app/src/client/components/Admin/Customize/CustomizeFunctionOption.tsx


+ 0 - 0
apps/app/src/components/Admin/Customize/CustomizeFunctionSetting.tsx → apps/app/src/client/components/Admin/Customize/CustomizeFunctionSetting.tsx


+ 1 - 1
apps/app/src/components/Admin/Customize/CustomizeLayoutSetting.tsx → apps/app/src/client/components/Admin/Customize/CustomizeLayoutSetting.tsx

@@ -6,8 +6,8 @@ import { LoadingSpinner } from '@growi/ui/dist/components';
 import { useTranslation } from 'next-i18next';
 
 import { toastSuccess, toastError } from '~/client/util/toastr';
+import { useNextThemes } from '~/stores-universal/use-next-themes';
 import { useSWRxLayoutSetting } from '~/stores/admin/customize';
-import { useNextThemes } from '~/stores/use-next-themes';
 
 const useIsContainerFluid = () => {
   const { data: layoutSetting, update: updateLayoutSetting } = useSWRxLayoutSetting();

+ 2 - 2
apps/app/src/components/Admin/Customize/CustomizeLogoSetting.tsx → apps/app/src/client/components/Admin/Customize/CustomizeLogoSetting.tsx

@@ -2,12 +2,12 @@ import React, { useCallback, useState } from 'react';
 
 import { useTranslation } from 'react-i18next';
 
+import ImageCropModal from '~/client/components/Common/ImageCropModal';
 import {
   apiv3Delete, apiv3PostForm, apiv3Put,
 } from '~/client/util/apiv3-client';
 import { toastError, toastSuccess } from '~/client/util/toastr';
-import ImageCropModal from '~/components/Common/ImageCropModal';
-import { useIsDefaultLogo, useIsCustomizedLogoUploaded } from '~/stores/context';
+import { useIsDefaultLogo, useIsCustomizedLogoUploaded } from '~/stores-universal/context';
 
 import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 

+ 0 - 0
apps/app/src/components/Admin/Customize/CustomizeNoscriptSetting.tsx → apps/app/src/client/components/Admin/Customize/CustomizeNoscriptSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/Customize/CustomizePresentationSetting.tsx → apps/app/src/client/components/Admin/Customize/CustomizePresentationSetting.tsx


+ 0 - 0
apps/app/src/components/Admin/Customize/CustomizeScriptSetting.tsx → apps/app/src/client/components/Admin/Customize/CustomizeScriptSetting.tsx


+ 1 - 1
apps/app/src/components/Admin/Customize/CustomizeSidebarSetting.tsx → apps/app/src/client/components/Admin/Customize/CustomizeSidebarSetting.tsx

@@ -5,8 +5,8 @@ import { useTranslation } from 'next-i18next';
 import { Card, CardBody } from 'reactstrap';
 
 import { toastSuccess, toastError } from '~/client/util/toastr';
+import { useNextThemes } from '~/stores-universal/use-next-themes';
 import { useSWRxSidebarConfig } from '~/stores/admin/sidebar-config';
-import { useNextThemes } from '~/stores/use-next-themes';
 
 const CustomizeSidebarsetting = (): JSX.Element => {
   const { t } = useTranslation(['admin', 'commons']);

+ 0 - 0
apps/app/src/components/Admin/Customize/CustomizeThemeOptions.tsx → apps/app/src/client/components/Admin/Customize/CustomizeThemeOptions.tsx


+ 0 - 0
apps/app/src/components/Admin/Customize/CustomizeThemeSetting.tsx → apps/app/src/client/components/Admin/Customize/CustomizeThemeSetting.tsx


+ 1 - 1
apps/app/src/components/Admin/Customize/CustomizeTitle.tsx → apps/app/src/client/components/Admin/Customize/CustomizeTitle.tsx

@@ -6,7 +6,7 @@ import { Card, CardBody } from 'reactstrap';
 
 import { apiv3Put } from '~/client/util/apiv3-client';
 import { toastSuccess, toastError } from '~/client/util/toastr';
-import { useCustomizeTitle } from '~/stores/context';
+import { useCustomizeTitle } from '~/stores-universal/context';
 
 import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 

+ 0 - 0
apps/app/src/components/Admin/Customize/PagingSizeUncontrolledDropdown.jsx → apps/app/src/client/components/Admin/Customize/PagingSizeUncontrolledDropdown.jsx


+ 0 - 0
apps/app/src/components/Admin/Customize/ThemeColorBox.module.scss → apps/app/src/client/components/Admin/Customize/ThemeColorBox.module.scss


+ 0 - 0
apps/app/src/components/Admin/Customize/ThemeColorBox.tsx → apps/app/src/client/components/Admin/Customize/ThemeColorBox.tsx


+ 1 - 1
apps/app/src/components/Admin/ElasticsearchManagement/ElasticsearchManagement.tsx → apps/app/src/client/components/Admin/ElasticsearchManagement/ElasticsearchManagement.tsx

@@ -6,7 +6,7 @@ import { useTranslation } from 'next-i18next';
 import { apiv3Get, apiv3Post, apiv3Put } from '~/client/util/apiv3-client';
 import { toastSuccess, toastError } from '~/client/util/toastr';
 import { SocketEventName } from '~/interfaces/websocket';
-import { useIsSearchServiceReachable } from '~/stores/context';
+import { useIsSearchServiceReachable } from '~/stores-universal/context';
 import { useAdminSocket } from '~/stores/socket-io';
 
 import NormalizeIndicesControls from './NormalizeIndicesControls';

+ 0 - 0
apps/app/src/components/Admin/ElasticsearchManagement/NormalizeIndicesControls.tsx → apps/app/src/client/components/Admin/ElasticsearchManagement/NormalizeIndicesControls.tsx


+ 0 - 0
apps/app/src/components/Admin/ElasticsearchManagement/RebuildIndexControls.jsx → apps/app/src/client/components/Admin/ElasticsearchManagement/RebuildIndexControls.jsx


+ 0 - 0
apps/app/src/components/Admin/ElasticsearchManagement/ReconnectControls.tsx → apps/app/src/client/components/Admin/ElasticsearchManagement/ReconnectControls.tsx


+ 0 - 0
apps/app/src/components/Admin/ElasticsearchManagement/StatusTable.jsx → apps/app/src/client/components/Admin/ElasticsearchManagement/StatusTable.jsx


+ 0 - 0
apps/app/src/components/Admin/ExportArchiveData/ArchiveFilesTable.tsx → apps/app/src/client/components/Admin/ExportArchiveData/ArchiveFilesTable.tsx


+ 0 - 0
apps/app/src/components/Admin/ExportArchiveData/ArchiveFilesTableMenu.tsx → apps/app/src/client/components/Admin/ExportArchiveData/ArchiveFilesTableMenu.tsx


+ 0 - 0
apps/app/src/components/Admin/ExportArchiveData/SelectCollectionsModal.tsx → apps/app/src/client/components/Admin/ExportArchiveData/SelectCollectionsModal.tsx


+ 0 - 0
apps/app/src/components/Admin/ExportArchiveDataPage.tsx → apps/app/src/client/components/Admin/ExportArchiveDataPage.tsx


+ 0 - 0
apps/app/src/components/Admin/ForbiddenPage.tsx → apps/app/src/client/components/Admin/ForbiddenPage.tsx


+ 0 - 0
apps/app/src/components/Admin/FullTextSearchManagement.tsx → apps/app/src/client/components/Admin/FullTextSearchManagement.tsx


+ 0 - 0
apps/app/src/components/Admin/G2GDataTransfer.tsx → apps/app/src/client/components/Admin/G2GDataTransfer.tsx


+ 0 - 0
apps/app/src/components/Admin/G2GDataTransferExportForm.tsx → apps/app/src/client/components/Admin/G2GDataTransferExportForm.tsx


+ 0 - 0
apps/app/src/components/Admin/G2GDataTransferStatusIcon.tsx → apps/app/src/client/components/Admin/G2GDataTransferStatusIcon.tsx


+ 0 - 0
apps/app/src/components/Admin/ImportData/GrowiArchive/ErrorViewer.tsx → apps/app/src/client/components/Admin/ImportData/GrowiArchive/ErrorViewer.tsx


+ 0 - 0
apps/app/src/components/Admin/ImportData/GrowiArchive/ImportCollectionConfigurationModal.jsx → apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportCollectionConfigurationModal.jsx


+ 0 - 0
apps/app/src/components/Admin/ImportData/GrowiArchive/ImportCollectionItem.jsx → apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportCollectionItem.jsx


+ 0 - 0
apps/app/src/components/Admin/ImportData/GrowiArchive/ImportForm.jsx → apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportForm.jsx


+ 0 - 0
apps/app/src/components/Admin/ImportData/GrowiArchive/UploadForm.jsx → apps/app/src/client/components/Admin/ImportData/GrowiArchive/UploadForm.jsx


+ 0 - 0
apps/app/src/components/Admin/ImportData/GrowiArchiveSection.jsx → apps/app/src/client/components/Admin/ImportData/GrowiArchiveSection.jsx


+ 0 - 0
apps/app/src/components/Admin/ImportData/ImportDataPageContents.jsx → apps/app/src/client/components/Admin/ImportData/ImportDataPageContents.jsx


+ 0 - 0
apps/app/src/components/Admin/LegacySlackIntegration/LegacySlackIntegration.jsx → apps/app/src/client/components/Admin/LegacySlackIntegration/LegacySlackIntegration.jsx


+ 0 - 0
apps/app/src/components/Admin/LegacySlackIntegration/SlackConfiguration.jsx → apps/app/src/client/components/Admin/LegacySlackIntegration/SlackConfiguration.jsx


+ 0 - 0
apps/app/src/components/Admin/ManageExternalAccount.tsx → apps/app/src/client/components/Admin/ManageExternalAccount.tsx


+ 0 - 0
apps/app/src/components/Admin/MarkdownSetting/IndentForm.tsx → apps/app/src/client/components/Admin/MarkdownSetting/IndentForm.tsx


+ 0 - 0
apps/app/src/components/Admin/MarkdownSetting/LineBreakForm.jsx → apps/app/src/client/components/Admin/MarkdownSetting/LineBreakForm.jsx


+ 0 - 0
apps/app/src/components/Admin/MarkdownSetting/MarkDownSettingContents.tsx → apps/app/src/client/components/Admin/MarkdownSetting/MarkDownSettingContents.tsx


+ 0 - 0
apps/app/src/components/Admin/MarkdownSetting/WhitelistInput.tsx → apps/app/src/client/components/Admin/MarkdownSetting/WhitelistInput.tsx


+ 0 - 0
apps/app/src/components/Admin/MarkdownSetting/XssForm.jsx → apps/app/src/client/components/Admin/MarkdownSetting/XssForm.jsx


+ 0 - 0
apps/app/src/components/Admin/NotFoundPage.tsx → apps/app/src/client/components/Admin/NotFoundPage.tsx


Некоторые файлы не были показаны из-за большого количества измененных файлов