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

Merge pull request #10043 from weseek/master

Release v7.2.7
mergify[bot] 10 месяцев назад
Родитель
Сommit
59b8f029a6
57 измененных файлов с 276 добавлено и 254 удалено
  1. 1 1
      apps/app/package.json
  2. 2 2
      apps/app/src/client/components/Admin/App/AppSetting.jsx
  3. 4 4
      apps/app/src/client/components/Admin/App/AwsSetting.tsx
  4. 8 8
      apps/app/src/client/components/Admin/App/AzureSetting.tsx
  5. 3 3
      apps/app/src/client/components/Admin/App/GcsSetting.tsx
  6. 1 1
      apps/app/src/client/components/Admin/App/MailSetting.tsx
  7. 3 3
      apps/app/src/client/components/Admin/App/MaskedInput.tsx
  8. 2 2
      apps/app/src/client/components/Admin/App/SesSetting.tsx
  9. 1 1
      apps/app/src/client/components/Admin/App/SiteUrlSetting.tsx
  10. 4 4
      apps/app/src/client/components/Admin/App/SmtpSetting.tsx
  11. 1 1
      apps/app/src/client/components/Admin/Customize/CustomizeCssSetting.tsx
  12. 1 1
      apps/app/src/client/components/Admin/Customize/CustomizeNoscriptSetting.tsx
  13. 1 1
      apps/app/src/client/components/Admin/Customize/CustomizeScriptSetting.tsx
  14. 1 1
      apps/app/src/client/components/Admin/Customize/CustomizeTitle.tsx
  15. 2 2
      apps/app/src/client/components/Admin/LegacySlackIntegration/SlackConfiguration.jsx
  16. 2 2
      apps/app/src/client/components/Admin/MarkdownSetting/WhitelistInput.tsx
  17. 1 1
      apps/app/src/client/components/Admin/Security/GitHubSecuritySettingContents.jsx
  18. 3 3
      apps/app/src/client/components/Admin/Security/GoogleSecuritySettingContents.jsx
  19. 10 10
      apps/app/src/client/components/Admin/Security/LdapSecuritySettingContents.jsx
  20. 1 1
      apps/app/src/client/components/Admin/Security/LocalSecuritySettingContents.jsx
  21. 16 16
      apps/app/src/client/components/Admin/Security/OidcSecuritySettingContents.jsx
  22. 9 9
      apps/app/src/client/components/Admin/Security/SamlSecuritySettingContents.jsx
  23. 1 1
      apps/app/src/client/components/Admin/Security/SecuritySetting.jsx
  24. 1 1
      apps/app/src/client/components/Admin/SlackIntegration/CustomBotWithProxySettings.jsx
  25. 2 2
      apps/app/src/client/components/Admin/SlackIntegration/CustomBotWithoutProxySecretTokenSection.jsx
  26. 1 1
      apps/app/src/client/components/Admin/SlackIntegration/ManageCommandsProcess.jsx
  27. 0 1
      apps/app/src/client/components/Sidebar/InAppNotification/PrimaryItemForNotification.tsx
  28. 15 4
      apps/app/src/client/components/Sidebar/SidebarContents.tsx
  29. 3 2
      apps/app/src/client/components/Sidebar/SidebarNav/PrimaryItems.tsx
  30. 4 2
      apps/app/src/client/services/page-operation.ts
  31. 11 6
      apps/app/src/features/openai/client/components/AiAssistant/OpenDefaultAiAssistantButton.tsx
  32. 10 10
      apps/app/src/server/routes/apiv3/security-settings/index.js
  33. 2 2
      apps/app/src/server/service/config-manager/config-definition.ts
  34. 1 1
      apps/slackbot-proxy/package.json
  35. 1 4
      biome.json
  36. 1 1
      package.json
  37. 1 0
      packages/preset-templates/.eslintignore
  38. 0 5
      packages/preset-templates/.eslintrc.js
  39. 2 1
      packages/preset-templates/package.json
  40. 7 8
      packages/preset-templates/test/index.test.ts
  41. 1 3
      packages/preset-templates/tsconfig.json
  42. 1 1
      packages/preset-themes/.eslintignore
  43. 0 2
      packages/preset-themes/.eslintrc.js
  44. 1 1
      packages/preset-themes/package.json
  45. 21 11
      packages/preset-themes/src/consts/preset-themes.ts
  46. 2 5
      packages/preset-themes/tsconfig.json
  47. 2 5
      packages/preset-themes/vite.libs.config.ts
  48. 1 3
      packages/preset-themes/vite.themes.config.ts
  49. 1 2
      packages/remark-drawio/.eslintignore
  50. 0 5
      packages/remark-drawio/.eslintrc.cjs
  51. 1 1
      packages/remark-drawio/package.json
  52. 49 39
      packages/remark-drawio/src/components/DrawioViewer.tsx
  53. 12 9
      packages/remark-drawio/src/interfaces/graph-viewer.ts
  54. 17 17
      packages/remark-drawio/src/services/renderer/remark-drawio.ts
  55. 18 16
      packages/remark-drawio/src/utils/embed.ts
  56. 8 2
      packages/remark-drawio/src/utils/global.ts
  57. 1 3
      packages/remark-drawio/tsconfig.json

+ 1 - 1
apps/app/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/app",
-  "version": "7.2.6",
+  "version": "7.2.7-RC.0",
   "license": "MIT",
   "private": "true",
   "scripts": {

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

@@ -40,7 +40,7 @@ const AppSetting = (props) => {
           <input
             className="form-control"
             type="text"
-            defaletValue={adminAppContainer.state.title || ''}
+            value={adminAppContainer.state.title || ''}
             onChange={(e) => {
               adminAppContainer.changeTitle(e.target.value);
             }}
@@ -60,7 +60,7 @@ const AppSetting = (props) => {
           <input
             className="form-control"
             type="text"
-            defaultValue={adminAppContainer.state.confidential || ''}
+            value={adminAppContainer.state.confidential || ''}
             onChange={(e) => {
               adminAppContainer.changeConfidential(e.target.value);
             }}

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

@@ -76,7 +76,7 @@ export const AwsSettingMolecule = (props: AwsSettingMoleculeProps): JSX.Element
           <input
             className="form-control"
             placeholder={`${t('eg')} ap-northeast-1`}
-            defaultValue={props.s3Region || ''}
+            value={props.s3Region || ''}
             onChange={(e) => {
               props?.onChangeS3Region(e.target.value);
             }}
@@ -93,7 +93,7 @@ export const AwsSettingMolecule = (props: AwsSettingMoleculeProps): JSX.Element
             className="form-control"
             type="text"
             placeholder={`${t('eg')} http://localhost:9000`}
-            defaultValue={props.s3CustomEndpoint || ''}
+            value={props.s3CustomEndpoint || ''}
             onChange={(e) => {
               props?.onChangeS3CustomEndpoint(e.target.value);
             }}
@@ -111,7 +111,7 @@ export const AwsSettingMolecule = (props: AwsSettingMoleculeProps): JSX.Element
             className="form-control"
             type="text"
             placeholder={`${t('eg')} crowi`}
-            defaultValue={props.s3Bucket || ''}
+            value={props.s3Bucket || ''}
             onChange={(e) => {
               props.onChangeS3Bucket(e.target.value);
             }}
@@ -127,7 +127,7 @@ export const AwsSettingMolecule = (props: AwsSettingMoleculeProps): JSX.Element
           <input
             className="form-control"
             type="text"
-            defaultValue={props.s3AccessKeyId || ''}
+            value={props.s3AccessKeyId || ''}
             onChange={(e) => {
               props?.onChangeS3AccessKeyId(e.target.value);
             }}

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

@@ -118,12 +118,12 @@ export const AzureSettingMolecule = (props: AzureSettingMoleculeProps): JSX.Elem
               <MaskedInput
                 name="azureTenantId"
                 readOnly={azureUseOnlyEnvVars}
-                defaultValue={azureTenantId}
+                value={azureTenantId}
                 onChange={e => props?.onChangeAzureTenantId(e.target.value)}
               />
             </td>
             <td>
-              <MaskedInput name="envAzureTenantId" defaultValue={envAzureTenantId || ''} readOnly tabIndex={-1} />
+              <MaskedInput name="envAzureTenantId" value={envAzureTenantId || ''} readOnly tabIndex={-1} />
               <p className="form-text text-muted">
                 {/* eslint-disable-next-line react/no-danger */}
                 <small dangerouslySetInnerHTML={{ __html: t('admin:app_setting.use_env_var_if_empty', { variable: 'AZURE_TENANT_ID' }) }} />
@@ -136,12 +136,12 @@ export const AzureSettingMolecule = (props: AzureSettingMoleculeProps): JSX.Elem
               <MaskedInput
                 name="azureClientId"
                 readOnly={azureUseOnlyEnvVars}
-                defaultValue={azureClientId}
+                value={azureClientId}
                 onChange={e => props?.onChangeAzureClientId(e.target.value)}
               />
             </td>
             <td>
-              <MaskedInput name="envAzureClientId" defaultValue={envAzureClientId || ''} readOnly tabIndex={-1} />
+              <MaskedInput name="envAzureClientId" value={envAzureClientId || ''} readOnly tabIndex={-1} />
               <p className="form-text text-muted">
                 {/* eslint-disable-next-line react/no-danger */}
                 <small dangerouslySetInnerHTML={{ __html: t('admin:app_setting.use_env_var_if_empty', { variable: 'AZURE_CLIENT_ID' }) }} />
@@ -154,12 +154,12 @@ export const AzureSettingMolecule = (props: AzureSettingMoleculeProps): JSX.Elem
               <MaskedInput
                 name="azureClientSecret"
                 readOnly={azureUseOnlyEnvVars}
-                defaultValue={azureClientSecret}
+                value={azureClientSecret}
                 onChange={e => props?.onChangeAzureClientSecret(e.target.value)}
               />
             </td>
             <td>
-              <MaskedInput name="envAzureClientSecret" defaultValue={envAzureClientSecret || ''} readOnly tabIndex={-1} />
+              <MaskedInput name="envAzureClientSecret" value={envAzureClientSecret || ''} readOnly tabIndex={-1} />
               <p className="form-text text-muted">
                 {/* eslint-disable-next-line react/no-danger */}
                 <small dangerouslySetInnerHTML={{ __html: t('admin:app_setting.use_env_var_if_empty', { variable: 'AZURE_CLIENT_SECRET' }) }} />
@@ -174,7 +174,7 @@ export const AzureSettingMolecule = (props: AzureSettingMoleculeProps): JSX.Elem
                 type="text"
                 name="azureStorageAccountName"
                 readOnly={azureUseOnlyEnvVars}
-                defaultValue={azureStorageAccountName}
+                value={azureStorageAccountName}
                 onChange={e => props?.onChangeAzureStorageAccountName(e.target.value)}
               />
             </td>
@@ -194,7 +194,7 @@ export const AzureSettingMolecule = (props: AzureSettingMoleculeProps): JSX.Elem
                 type="text"
                 name="azureStorageContainerName"
                 readOnly={azureUseOnlyEnvVars}
-                defaultValue={azureStorageContainerName}
+                value={azureStorageContainerName}
                 onChange={e => props?.onChangeAzureStorageContainerName(e.target.value)}
               />
             </td>

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

@@ -108,7 +108,7 @@ export const GcsSettingMolecule = (props: GcsSettingMoleculeProps): JSX.Element
                 type="text"
                 name="gcsApiKeyJsonPath"
                 readOnly={gcsUseOnlyEnvVars}
-                defaultValue={gcsApiKeyJsonPath}
+                value={gcsApiKeyJsonPath}
                 onChange={e => props?.onChangeGcsApiKeyJsonPath(e.target.value)}
               />
             </td>
@@ -128,7 +128,7 @@ export const GcsSettingMolecule = (props: GcsSettingMoleculeProps): JSX.Element
                 type="text"
                 name="gcsBucket"
                 readOnly={gcsUseOnlyEnvVars}
-                defaultValue={gcsBucket}
+                value={gcsBucket}
                 onChange={e => props?.onChangeGcsBucket(e.target.value)}
               />
             </td>
@@ -148,7 +148,7 @@ export const GcsSettingMolecule = (props: GcsSettingMoleculeProps): JSX.Element
                 type="text"
                 name="gcsUploadNamespace"
                 readOnly={gcsUseOnlyEnvVars}
-                defaultValue={gcsUploadNamespace}
+                value={gcsUploadNamespace}
                 onChange={e => props?.onChangeGcsUploadNamespace(e.target.value)}
               />
             </td>

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

@@ -56,7 +56,7 @@ const MailSetting = (props: Props) => {
             className="form-control"
             type="text"
             placeholder={`${t('eg')} mail@growi.org`}
-            defaultValue={adminAppContainer.state.fromAddress || ''}
+            value={adminAppContainer.state.fromAddress || ''}
             onChange={(e) => { adminAppContainer.changeFromAddress(e.target.value) }}
           />
         </div>

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

@@ -5,7 +5,7 @@ import styles from './MaskedInput.module.scss';
 type Props = {
   name: string
   readOnly: boolean
-  defaultValue: string
+  value: string
   onChange?: (e: any) => void
   tabIndex?: number | undefined
 };
@@ -17,7 +17,7 @@ export default function MaskedInput(props: Props): JSX.Element {
   };
 
   const {
-    name, readOnly, defaultValue, onChange, tabIndex,
+    name, readOnly, value, onChange, tabIndex,
   } = props;
 
   return (
@@ -27,7 +27,7 @@ export default function MaskedInput(props: Props): JSX.Element {
         type={passwordShown ? 'text' : 'password'}
         name={name}
         readOnly={readOnly}
-        defaultValue={defaultValue}
+        value={value}
         onChange={onChange}
         tabIndex={tabIndex}
       />

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

@@ -24,7 +24,7 @@ const SmtpSetting = (props: Props) => {
             <input
               className="form-control"
               type="text"
-              defaultValue={adminAppContainer.state.sesAccessKeyId || ''}
+              value={adminAppContainer.state.sesAccessKeyId || ''}
               onChange={(e) => {
                 adminAppContainer.changeSesAccessKeyId(e.target.value);
               }}
@@ -40,7 +40,7 @@ const SmtpSetting = (props: Props) => {
             <input
               className="form-control"
               type="text"
-              defaultValue={adminAppContainer.state.sesSecretAccessKey || ''}
+              value={adminAppContainer.state.sesSecretAccessKey || ''}
               onChange={(e) => {
                 adminAppContainer.changeSesSecretAccessKey(e.target.value);
               }}

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

@@ -70,7 +70,7 @@ const SiteUrlSetting = (props: Props) => {
                   className="form-control"
                   type="text"
                   name="settingForm[app:siteUrl]"
-                  defaultValue={adminAppContainer.state.siteUrl || ''}
+                  value={adminAppContainer.state.siteUrl || ''}
                   disabled={adminAppContainer.state.siteUrlUseOnlyEnvVars ?? true}
                   onChange={(e) => { adminAppContainer.changeSiteUrl(e.target.value) }}
                   placeholder="e.g. https://my.growi.org"

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

@@ -27,7 +27,7 @@ const SmtpSetting = (props: Props) => {
             <input
               className="form-control"
               type="text"
-              defaultValue={adminAppContainer.state.smtpHost || ''}
+              value={adminAppContainer.state.smtpHost || ''}
               onChange={(e) => { adminAppContainer.changeSmtpHost(e.target.value) }}
             />
           </div>
@@ -40,7 +40,7 @@ const SmtpSetting = (props: Props) => {
           <div className="col-md-6">
             <input
               className="form-control"
-              defaultValue={adminAppContainer.state.smtpPort || ''}
+              value={adminAppContainer.state.smtpPort || ''}
               onChange={(e) => { adminAppContainer.changeSmtpPort(e.target.value) }}
             />
           </div>
@@ -54,7 +54,7 @@ const SmtpSetting = (props: Props) => {
             <input
               className="form-control"
               type="text"
-              defaultValue={adminAppContainer.state.smtpUser || ''}
+              value={adminAppContainer.state.smtpUser || ''}
               onChange={(e) => { adminAppContainer.changeSmtpUser(e.target.value) }}
             />
           </div>
@@ -68,7 +68,7 @@ const SmtpSetting = (props: Props) => {
             <input
               className="form-control"
               type="password"
-              defaultValue={adminAppContainer.state.smtpPassword || ''}
+              value={adminAppContainer.state.smtpPassword || ''}
               onChange={(e) => { adminAppContainer.changeSmtpPassword(e.target.value) }}
             />
           </div>

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

@@ -46,7 +46,7 @@ const CustomizeCssSetting = (props: Props): JSX.Element => {
               className="form-control"
               name="customizeCss"
               rows={8}
-              defaultValue={adminCustomizeContainer.state.currentCustomizeCss || ''}
+              value={adminCustomizeContainer.state.currentCustomizeCss || ''}
               onChange={(e) => { adminCustomizeContainer.changeCustomizeCss(e.target.value) }}
             />
           </div>

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

@@ -50,7 +50,7 @@ const CustomizeNoscriptSetting = (props: Props): JSX.Element => {
               className="form-control mb-2"
               name="customizeNoscript"
               rows={8}
-              defaultValue={adminCustomizeContainer.state.currentCustomizeNoscript || ''}
+              value={adminCustomizeContainer.state.currentCustomizeNoscript || ''}
               onChange={(e) => { adminCustomizeContainer.changeCustomizeNoscript(e.target.value) }}
             />
           </div>

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

@@ -47,7 +47,7 @@ const CustomizeScriptSetting = (props: Props): JSX.Element => {
               className="form-control mb-2"
               name="customizeScript"
               rows={8}
-              defaultValue={adminCustomizeContainer.state.currentCustomizeScript || ''}
+              value={adminCustomizeContainer.state.currentCustomizeScript || ''}
               onChange={(e) => { adminCustomizeContainer.changeCustomizeScript(e.target.value) }}
             />
           </div>

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

@@ -67,7 +67,7 @@ export const CustomizeTitle: FC = () => {
         <div className="col-12">
           <input
             className="form-control"
-            defaultValue={currentCustomizeTitle}
+            value={currentCustomizeTitle}
             onChange={(e) => { setCrrentCustomizeTitle(e.target.value) }}
           />
         </div>

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

@@ -70,7 +70,7 @@ class SlackConfiguration extends React.Component {
                 <input
                   className="form-control"
                   type="text"
-                  defaultValue={adminSlackIntegrationLegacyContainer.state.webhookUrl || ''}
+                  value={adminSlackIntegrationLegacyContainer.state.webhookUrl || ''}
                   onChange={e => adminSlackIntegrationLegacyContainer.changeWebhookUrl(e.target.value)}
                 />
               </div>
@@ -122,7 +122,7 @@ class SlackConfiguration extends React.Component {
                   <input
                     className="form-control"
                     type="text"
-                    defaultValue={adminSlackIntegrationLegacyContainer.state.slackToken || ''}
+                    value={adminSlackIntegrationLegacyContainer.state.slackToken || ''}
                     onChange={e => adminSlackIntegrationLegacyContainer.changeSlackToken(e.target.value)}
                   />
                 </div>

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

@@ -52,7 +52,7 @@ export const WhitelistInput = (props: Props): JSX.Element => {
           name="recommendedTags"
           rows={6}
           cols={40}
-          defaultValue={adminMarkDownContainer.state.tagWhitelist}
+          value={adminMarkDownContainer.state.tagWhitelist}
           onChange={(e) => { adminMarkDownContainer.setState({ tagWhitelist: e.target.value }) }}
         />
       </div>
@@ -69,7 +69,7 @@ export const WhitelistInput = (props: Props): JSX.Element => {
           name="recommendedAttrs"
           rows={6}
           cols={40}
-          defaultValue={adminMarkDownContainer.state.attrWhitelist}
+          value={adminMarkDownContainer.state.attrWhitelist}
           onChange={(e) => { adminMarkDownContainer.setState({ attrWhitelist: e.target.value }) }}
         />
       </div>

+ 1 - 1
apps/app/src/client/components/Admin/Security/GitHubSecuritySettingContents.jsx

@@ -125,7 +125,7 @@ class GitHubSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="githubClientSecret"
-                  defaultValue={adminGitHubSecurityContainer.state.githubClientSecret || ''}
+                  value={adminGitHubSecurityContainer.state.githubClientSecret || ''}
                   onChange={e => adminGitHubSecurityContainer.changeGitHubClientSecret(e.target.value)}
                 />
                 <p className="form-text text-muted">

+ 3 - 3
apps/app/src/client/components/Admin/Security/GoogleSecuritySettingContents.jsx

@@ -108,7 +108,7 @@ class GoogleSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="googleClientId"
-                  defaultValue={adminGoogleSecurityContainer.state.googleClientId || ''}
+                  value={adminGoogleSecurityContainer.state.googleClientId || ''}
                   onChange={e => adminGoogleSecurityContainer.changeGoogleClientId(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -122,9 +122,9 @@ class GoogleSecurityManagementContents extends React.Component {
               <div className="col-6">
                 <input
                   className="form-control"
-                  type="text"
+                  type="password"
                   name="googleClientSecret"
-                  defaultValue={adminGoogleSecurityContainer.state.googleClientSecret || ''}
+                  value={adminGoogleSecurityContainer.state.googleClientSecret || ''}
                   onChange={e => adminGoogleSecurityContainer.changeGoogleClientSecret(e.target.value)}
                 />
                 <p className="form-text text-muted">

+ 10 - 10
apps/app/src/client/components/Admin/Security/LdapSecuritySettingContents.jsx

@@ -92,7 +92,7 @@ class LdapSecuritySettingContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="serverUrl"
-                  defaultValue={adminLdapSecurityContainer.state.serverUrl || ''}
+                  value={adminLdapSecurityContainer.state.serverUrl || ''}
                   onChange={e => adminLdapSecurityContainer.changeServerUrl(e.target.value)}
                 />
                 <small>
@@ -145,7 +145,7 @@ class LdapSecuritySettingContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="bindDN"
-                  defaultValue={adminLdapSecurityContainer.state.ldapBindDN || ''}
+                  value={adminLdapSecurityContainer.state.ldapBindDN || ''}
                   onChange={e => adminLdapSecurityContainer.changeBindDN(e.target.value)}
                 />
                 {(adminLdapSecurityContainer.state.isUserBind === true) ? (
@@ -194,7 +194,7 @@ class LdapSecuritySettingContents extends React.Component {
                         className="form-control passport-ldap-managerbind"
                         type="password"
                         name="bindDNPassword"
-                        defaultValue={adminLdapSecurityContainer.state.ldapBindDNPassword || ''}
+                        value={adminLdapSecurityContainer.state.ldapBindDNPassword || ''}
                         onChange={e => adminLdapSecurityContainer.changeBindDNPassword(e.target.value)}
                       />
                     </>
@@ -211,7 +211,7 @@ class LdapSecuritySettingContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="searchFilter"
-                  defaultValue={adminLdapSecurityContainer.state.ldapSearchFilter || ''}
+                  value={adminLdapSecurityContainer.state.ldapSearchFilter || ''}
                   onChange={e => adminLdapSecurityContainer.changeSearchFilter(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -248,7 +248,7 @@ class LdapSecuritySettingContents extends React.Component {
                   type="text"
                   placeholder="Default: uid"
                   name="attrMapUsername"
-                  defaultValue={adminLdapSecurityContainer.state.ldapAttrMapUsername || ''}
+                  value={adminLdapSecurityContainer.state.ldapAttrMapUsername || ''}
                   onChange={e => adminLdapSecurityContainer.changeAttrMapUsername(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -292,7 +292,7 @@ class LdapSecuritySettingContents extends React.Component {
                   type="text"
                   placeholder="Default: mail"
                   name="attrMapMail"
-                  defaultValue={adminLdapSecurityContainer.state.ldapAttrMapMail || ''}
+                  value={adminLdapSecurityContainer.state.ldapAttrMapMail || ''}
                   onChange={e => adminLdapSecurityContainer.changeAttrMapMail(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -312,7 +312,7 @@ class LdapSecuritySettingContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="attrMapName"
-                  defaultValue={adminLdapSecurityContainer.state.ldapAttrMapName || ''}
+                  value={adminLdapSecurityContainer.state.ldapAttrMapName || ''}
                   onChange={e => adminLdapSecurityContainer.changeAttrMapName(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -337,7 +337,7 @@ class LdapSecuritySettingContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="groupSearchBase"
-                  defaultValue={adminLdapSecurityContainer.state.ldapGroupSearchBase || ''}
+                  value={adminLdapSecurityContainer.state.ldapGroupSearchBase || ''}
                   onChange={e => adminLdapSecurityContainer.changeGroupSearchBase(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -359,7 +359,7 @@ class LdapSecuritySettingContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="groupSearchFilter"
-                  defaultValue={adminLdapSecurityContainer.state.ldapGroupSearchFilter || ''}
+                  value={adminLdapSecurityContainer.state.ldapGroupSearchFilter || ''}
                   onChange={e => adminLdapSecurityContainer.changeGroupSearchFilter(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -391,7 +391,7 @@ class LdapSecuritySettingContents extends React.Component {
                   type="text"
                   placeholder="Default: uid"
                   name="groupDnProperty"
-                  defaultValue={adminLdapSecurityContainer.state.ldapGroupDnProperty || ''}
+                  value={adminLdapSecurityContainer.state.ldapGroupDnProperty || ''}
                   onChange={e => adminLdapSecurityContainer.changeGroupDnProperty(e.target.value)}
                 />
                 <p className="form-text text-muted">

+ 1 - 1
apps/app/src/client/components/Admin/Security/LocalSecuritySettingContents.jsx

@@ -147,7 +147,7 @@ class LocalSecuritySettingContents extends React.Component {
                   className="form-control"
                   type="textarea"
                   name="registrationWhitelist"
-                  defaultValue={adminLocalSecurityContainer.state.registrationWhitelist.join('\n')}
+                  value={adminLocalSecurityContainer.state.registrationWhitelist.join('\n')}
                   onChange={e => adminLocalSecurityContainer.changeRegistrationWhitelist(e.target.value)}
                 />
                 <p className="form-text text-muted small">

+ 16 - 16
apps/app/src/client/components/Admin/Security/OidcSecuritySettingContents.jsx

@@ -101,7 +101,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcProviderName"
-                  defaultValue={adminOidcSecurityContainer.state.oidcProviderName || ''}
+                  value={adminOidcSecurityContainer.state.oidcProviderName || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcProviderName(e.target.value)}
                 />
               </div>
@@ -114,7 +114,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcIssuerHost"
-                  defaultValue={adminOidcSecurityContainer.state.oidcIssuerHost || ''}
+                  value={adminOidcSecurityContainer.state.oidcIssuerHost || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcIssuerHost(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -130,7 +130,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcClientId"
-                  defaultValue={adminOidcSecurityContainer.state.oidcClientId || ''}
+                  value={adminOidcSecurityContainer.state.oidcClientId || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcClientId(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -146,7 +146,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcClientSecret"
-                  defaultValue={adminOidcSecurityContainer.state.oidcClientSecret || ''}
+                  value={adminOidcSecurityContainer.state.oidcClientSecret || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcClientSecret(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -164,7 +164,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcAuthorizationEndpoint"
-                  defaultValue={adminOidcSecurityContainer.state.oidcAuthorizationEndpoint || ''}
+                  value={adminOidcSecurityContainer.state.oidcAuthorizationEndpoint || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcAuthorizationEndpoint(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -180,7 +180,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcTokenEndpoint"
-                  defaultValue={adminOidcSecurityContainer.state.oidcTokenEndpoint || ''}
+                  value={adminOidcSecurityContainer.state.oidcTokenEndpoint || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcTokenEndpoint(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -198,7 +198,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcRevocationEndpoint"
-                  defaultValue={adminOidcSecurityContainer.state.oidcRevocationEndpoint || ''}
+                  value={adminOidcSecurityContainer.state.oidcRevocationEndpoint || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcRevocationEndpoint(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -216,7 +216,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcIntrospectionEndpoint"
-                  defaultValue={adminOidcSecurityContainer.state.oidcIntrospectionEndpoint || ''}
+                  value={adminOidcSecurityContainer.state.oidcIntrospectionEndpoint || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcIntrospectionEndpoint(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -234,7 +234,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcUserInfoEndpoint"
-                  defaultValue={adminOidcSecurityContainer.state.oidcUserInfoEndpoint || ''}
+                  value={adminOidcSecurityContainer.state.oidcUserInfoEndpoint || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcUserInfoEndpoint(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -252,7 +252,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcEndSessionEndpoint"
-                  defaultValue={adminOidcSecurityContainer.state.oidcEndSessionEndpoint || ''}
+                  value={adminOidcSecurityContainer.state.oidcEndSessionEndpoint || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcEndSessionEndpoint(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -270,7 +270,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcRegistrationEndpoint"
-                  defaultValue={adminOidcSecurityContainer.state.oidcRegistrationEndpoint || ''}
+                  value={adminOidcSecurityContainer.state.oidcRegistrationEndpoint || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcRegistrationEndpoint(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -286,7 +286,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcJWKSUri"
-                  defaultValue={adminOidcSecurityContainer.state.oidcJWKSUri || ''}
+                  value={adminOidcSecurityContainer.state.oidcJWKSUri || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcJWKSUri(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -306,7 +306,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcAttrMapId"
-                  defaultValue={adminOidcSecurityContainer.state.oidcAttrMapId || ''}
+                  value={adminOidcSecurityContainer.state.oidcAttrMapId || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcAttrMapId(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -322,7 +322,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcAttrMapUserName"
-                  defaultValue={adminOidcSecurityContainer.state.oidcAttrMapUserName || ''}
+                  value={adminOidcSecurityContainer.state.oidcAttrMapUserName || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcAttrMapUserName(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -338,7 +338,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcAttrMapName"
-                  defaultValue={adminOidcSecurityContainer.state.oidcAttrMapName || ''}
+                  value={adminOidcSecurityContainer.state.oidcAttrMapName || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcAttrMapName(e.target.value)}
                 />
                 <p className="form-text text-muted">
@@ -354,7 +354,7 @@ class OidcSecurityManagementContents extends React.Component {
                   className="form-control"
                   type="text"
                   name="oidcAttrMapEmail"
-                  defaultValue={adminOidcSecurityContainer.state.oidcAttrMapEmail || ''}
+                  value={adminOidcSecurityContainer.state.oidcAttrMapEmail || ''}
                   onChange={e => adminOidcSecurityContainer.changeOidcAttrMapEmail(e.target.value)}
                 />
                 <p className="form-text text-muted">

+ 9 - 9
apps/app/src/client/components/Admin/Security/SamlSecuritySettingContents.jsx

@@ -150,7 +150,7 @@ class SamlSecurityManagementContents extends React.Component {
                       type="text"
                       name="samlEntryPoint"
                       readOnly={useOnlyEnvVars}
-                      defaultValue={adminSamlSecurityContainer.state.samlEntryPoint}
+                      value={adminSamlSecurityContainer.state.samlEntryPoint}
                       onChange={e => adminSamlSecurityContainer.changeSamlEntryPoint(e.target.value)}
                     />
                   </td>
@@ -174,7 +174,7 @@ class SamlSecurityManagementContents extends React.Component {
                       type="text"
                       name="samlEnvVarissuer"
                       readOnly={useOnlyEnvVars}
-                      defaultValue={adminSamlSecurityContainer.state.samlIssuer}
+                      value={adminSamlSecurityContainer.state.samlIssuer}
                       onChange={e => adminSamlSecurityContainer.changeSamlIssuer(e.target.value)}
                     />
                   </td>
@@ -199,7 +199,7 @@ class SamlSecurityManagementContents extends React.Component {
                       rows="5"
                       name="samlCert"
                       readOnly={useOnlyEnvVars}
-                      defaultValue={adminSamlSecurityContainer.state.samlCert}
+                      value={adminSamlSecurityContainer.state.samlCert}
                       onChange={e => adminSamlSecurityContainer.changeSamlCert(e.target.value)}
                     />
                     <p>
@@ -258,7 +258,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                     <input
                       className="form-control"
                       type="text"
-                      defaultValue={adminSamlSecurityContainer.state.samlAttrMapId}
+                      value={adminSamlSecurityContainer.state.samlAttrMapId}
                       onChange={e => adminSamlSecurityContainer.changeSamlAttrMapId(e.target.value)}
                     />
                     <p className="form-text text-muted">
@@ -285,7 +285,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                     <input
                       className="form-control"
                       type="text"
-                      defaultValue={adminSamlSecurityContainer.state.samlAttrMapUsername}
+                      value={adminSamlSecurityContainer.state.samlAttrMapUsername}
                       onChange={e => adminSamlSecurityContainer.changeSamlAttrMapUserName(e.target.value)}
                     />
                     <p className="form-text text-muted">
@@ -310,7 +310,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                     <input
                       className="form-control"
                       type="text"
-                      defaultValue={adminSamlSecurityContainer.state.samlAttrMapMail}
+                      value={adminSamlSecurityContainer.state.samlAttrMapMail}
                       onChange={e => adminSamlSecurityContainer.changeSamlAttrMapMail(e.target.value)}
                     />
                     <p className="form-text text-muted">
@@ -335,7 +335,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                     <input
                       className="form-control"
                       type="text"
-                      defaultValue={adminSamlSecurityContainer.state.samlAttrMapFirstName}
+                      value={adminSamlSecurityContainer.state.samlAttrMapFirstName}
                       onChange={e => adminSamlSecurityContainer.changeSamlAttrMapFirstName(e.target.value)}
                     />
                     <p className="form-text text-muted">
@@ -365,7 +365,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                     <input
                       className="form-control"
                       type="text"
-                      defaultValue={adminSamlSecurityContainer.state.samlAttrMapLastName}
+                      value={adminSamlSecurityContainer.state.samlAttrMapLastName}
                       onChange={e => adminSamlSecurityContainer.changeSamlAttrMapLastName(e.target.value)}
                     />
                     <p className="form-text text-muted">
@@ -462,7 +462,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                     <textarea
                       className="form-control"
                       type="text"
-                      defaultValue={adminSamlSecurityContainer.state.samlABLCRule || ''}
+                      value={adminSamlSecurityContainer.state.samlABLCRule || ''}
                       onChange={(e) => { adminSamlSecurityContainer.changeSamlABLCRule(e.target.value) }}
                     />
                     <div className="mt-2">

+ 1 - 1
apps/app/src/client/components/Admin/Security/SecuritySetting.jsx

@@ -591,7 +591,7 @@ class SecuritySetting extends React.Component {
             <input
               className="form-control col-md-4"
               type="text"
-              defaultValue={adminGeneralSecurityContainer.state.sessionMaxAge || ''}
+              value={adminGeneralSecurityContainer.state.sessionMaxAge || ''}
               onChange={(e) => {
                 adminGeneralSecurityContainer.setSessionMaxAge(e.target.value);
               }}

+ 1 - 1
apps/app/src/client/components/Admin/SlackIntegration/CustomBotWithProxySettings.jsx

@@ -111,7 +111,7 @@ const CustomBotWithProxySettings = (props) => {
                 className="form-control"
                 type="text"
                 name="settingForm[proxyUrl]"
-                defaultValue={newProxyServerUri}
+                value={newProxyServerUri}
                 onChange={(e) => { setNewProxyServerUri(e.target.value) }}
               />
             </div>

+ 2 - 2
apps/app/src/client/components/Admin/SlackIntegration/CustomBotWithoutProxySecretTokenSection.jsx

@@ -65,7 +65,7 @@ const CustomBotWithoutProxySecretTokenSection = (props) => {
           <input
             className="form-control"
             type="text"
-            defaultValue={slackSigningSecretEnv}
+            value={slackSigningSecretEnv}
             readOnly
           />
           <p className="form-text text-muted">
@@ -94,7 +94,7 @@ const CustomBotWithoutProxySecretTokenSection = (props) => {
           <input
             className="form-control"
             type="text"
-            defaultValue={slackBotTokenEnv}
+            value={slackBotTokenEnv}
             readOnly
           />
           <p className="form-text text-muted">

+ 1 - 1
apps/app/src/client/components/Admin/SlackIntegration/ManageCommandsProcess.jsx

@@ -147,7 +147,7 @@ const PermissionSettingForEachPermissionTypeComponent = ({
             className="form-control"
             type="textarea"
             name={keyName}
-            defaultValue={textareaDefaultValue}
+            value={textareaDefaultValue}
             onChange={onUpdateChannels}
           />
           <p className="form-text text-muted small">

+ 0 - 1
apps/app/src/client/components/Sidebar/InAppNotification/PrimaryItemForNotification.tsx

@@ -8,7 +8,6 @@ import { PrimaryItem, type PrimaryItemProps } from '../SidebarNav/PrimaryItem';
 
 type PrimaryItemForNotificationProps = Omit<PrimaryItemProps, 'onClick' | 'label' | 'iconName' | 'contents' | 'badgeContents' >
 
-// TODO(after v7 release): https://redmine.weseek.co.jp/issues/138463
 export const PrimaryItemForNotification = memo((props: PrimaryItemForNotificationProps) => {
   const { sidebarMode, onHover } = props;
 

+ 15 - 4
apps/app/src/client/components/Sidebar/SidebarContents.tsx

@@ -2,6 +2,7 @@ import React, { memo, useMemo } from 'react';
 
 import { AiAssistant } from '~/features/openai/client/components/AiAssistant/Sidebar/AiAssistant';
 import { SidebarContentsType } from '~/interfaces/ui';
+import { useIsAiEnabled, useIsGuestUser } from '~/stores-universal/context';
 import { useCollapsedContentsOpened, useCurrentSidebarContents, useSidebarMode } from '~/stores/ui';
 
 
@@ -17,8 +18,10 @@ import styles from './SidebarContents.module.scss';
 
 export const SidebarContents = memo(() => {
   const { isCollapsedMode } = useSidebarMode();
-  const { data: isCollapsedContentsOpened } = useCollapsedContentsOpened();
+  const { data: isGuestUser } = useIsGuestUser();
+  const { data: isAiEnabled } = useIsAiEnabled();
 
+  const { data: isCollapsedContentsOpened } = useCollapsedContentsOpened();
   const { data: currentSidebarContents } = useCurrentSidebarContents();
 
   const Contents = useMemo(() => {
@@ -32,13 +35,21 @@ export const SidebarContents = memo(() => {
       case SidebarContentsType.BOOKMARKS:
         return Bookmarks;
       case SidebarContentsType.NOTIFICATION:
-        return InAppNotification;
+        if (isGuestUser == null) return () => <></>; // wait for isGuestUser to be determined
+        if (!isGuestUser) {
+          return InAppNotification;
+        }
+        return PageTree;
       case SidebarContentsType.AI_ASSISTANT:
-        return AiAssistant;
+        if (isAiEnabled == null) return () => <></>; // wait for isAiEnabled to be determined
+        if (isAiEnabled) {
+          return AiAssistant;
+        }
+        return PageTree;
       default:
         return PageTree;
     }
-  }, [currentSidebarContents]);
+  }, [currentSidebarContents, isAiEnabled, isGuestUser]);
 
   const isHidden = isCollapsedMode() && !isCollapsedContentsOpened;
   const classToHide = isHidden ? 'd-none' : '';

+ 3 - 2
apps/app/src/client/components/Sidebar/SidebarNav/PrimaryItems.tsx

@@ -3,7 +3,7 @@ import { memo } from 'react';
 import dynamic from 'next/dynamic';
 
 import { SidebarContentsType } from '~/interfaces/ui';
-import { useIsAiEnabled } from '~/stores-universal/context';
+import { useIsAiEnabled, useIsGuestUser } from '~/stores-universal/context';
 import { useSidebarMode } from '~/stores/ui';
 
 import { PrimaryItem } from './PrimaryItem';
@@ -24,6 +24,7 @@ export const PrimaryItems = memo((props: Props) => {
 
   const { data: sidebarMode } = useSidebarMode();
   const { data: isAiEnabled } = useIsAiEnabled();
+  const { data: isGuestUser } = useIsGuestUser();
 
   if (sidebarMode == null) {
     return <></>;
@@ -36,7 +37,7 @@ export const PrimaryItems = memo((props: Props) => {
       <PrimaryItem sidebarMode={sidebarMode} contents={SidebarContentsType.RECENT} label="Recent Changes" iconName="update" onHover={onItemHover} />
       <PrimaryItem sidebarMode={sidebarMode} contents={SidebarContentsType.BOOKMARKS} label="Bookmarks" iconName="bookmarks" onHover={onItemHover} />
       <PrimaryItem sidebarMode={sidebarMode} contents={SidebarContentsType.TAG} label="Tags" iconName="local_offer" onHover={onItemHover} />
-      <PrimaryItemForNotification sidebarMode={sidebarMode} onHover={onItemHover} />
+      {isGuestUser === false && <PrimaryItemForNotification sidebarMode={sidebarMode} onHover={onItemHover} />}
       {isAiEnabled && (
         <PrimaryItem
           sidebarMode={sidebarMode}

+ 4 - 2
apps/app/src/client/services/page-operation.ts

@@ -5,6 +5,7 @@ import { SubscriptionStatusType } from '@growi/core';
 import urljoin from 'url-join';
 
 import type { SyncLatestRevisionBody } from '~/interfaces/yjs';
+import { useIsGuestUser } from '~/stores-universal/context';
 import { useEditingMarkdown, usePageTagsForEditors } from '~/stores/editor';
 import {
   useCurrentPageId, useSWRMUTxCurrentPage, useSWRxApplicableGrant, useSWRxTagsInfo,
@@ -103,8 +104,9 @@ export const useUpdateStateAfterSave = (pageId: string|undefined|null, opts?: Up
   const { mutate: mutateTagsInfo } = useSWRxTagsInfo(pageId);
   const { sync: syncTagsInfoForEditor } = usePageTagsForEditors(pageId);
   const { mutate: mutateEditingMarkdown } = useEditingMarkdown();
-  const { mutate: mutateCurrentGrantData } = useSWRxCurrentGrantData(pageId);
-  const { mutate: mutateApplicableGrant } = useSWRxApplicableGrant(pageId);
+  const { data: isGuestUser } = useIsGuestUser();
+  const { mutate: mutateCurrentGrantData } = useSWRxCurrentGrantData(isGuestUser ? null : pageId);
+  const { mutate: mutateApplicableGrant } = useSWRxApplicableGrant(isGuestUser ? null : pageId);
 
   // update swr 'currentPageId', 'currentPage', remote states
   return useCallback(async() => {

+ 11 - 6
apps/app/src/features/openai/client/components/AiAssistant/OpenDefaultAiAssistantButton.tsx

@@ -10,9 +10,8 @@ import { useAiAssistantSidebar, useSWRxAiAssistants } from '../../stores/ai-assi
 
 import styles from './OpenDefaultAiAssistantButton.module.scss';
 
-const OpenDefaultAiAssistantButton = (): JSX.Element => {
+const OpenDefaultAiAssistantButtonSubstance = (): JSX.Element => {
   const { t } = useTranslation();
-  const { data: isAiEnabled } = useIsAiEnabled();
   const { data: aiAssistantData } = useSWRxAiAssistants();
   const { openChat } = useAiAssistantSidebar();
 
@@ -33,10 +32,6 @@ const OpenDefaultAiAssistantButton = (): JSX.Element => {
     openChat(defaultAiAssistant);
   }, [defaultAiAssistant, openChat]);
 
-  if (!isAiEnabled) {
-    return <></>;
-  }
-
   return (
     <NotAvailableForGuest>
       <NotAvailable isDisabled={defaultAiAssistant == null} title={t('default_ai_assistant.not_set')}>
@@ -52,4 +47,14 @@ const OpenDefaultAiAssistantButton = (): JSX.Element => {
   );
 };
 
+const OpenDefaultAiAssistantButton = (): JSX.Element => {
+  const { data: isAiEnabled } = useIsAiEnabled();
+
+  if (!isAiEnabled) {
+    return <></>;
+  }
+
+  return <OpenDefaultAiAssistantButtonSubstance />;
+};
+
 export default OpenDefaultAiAssistantButton;

+ 10 - 10
apps/app/src/server/routes/apiv3/security-settings/index.js

@@ -1,4 +1,4 @@
-import { ConfigSource } from '@growi/core/dist/interfaces';
+import { ConfigSource, toNonBlankStringOrUndefined } from '@growi/core/dist/interfaces';
 import { ErrorV3 } from '@growi/core/dist/models';
 import xss from 'xss';
 
@@ -407,11 +407,11 @@ module.exports = (crowi) => {
 
   const activityEvent = crowi.event('activity');
 
-  async function updateAndReloadStrategySettings(authId, params) {
+  async function updateAndReloadStrategySettings(authId, params, opts = { removeIfUndefined: false }) {
     const { passportService } = crowi;
 
     // update config without publishing S2sMessage
-    await configManager.updateConfigs(params, { skipPubsub: true });
+    await configManager.updateConfigs(params, { skipPubsub: true, removeIfUndefined: opts.removeIfUndefined });
 
     await passportService.setupStrategyById(authId);
     passportService.publishUpdatedMessage(authId);
@@ -1262,15 +1262,15 @@ module.exports = (crowi) => {
    *                      $ref: '#/components/schemas/GoogleOAuthSetting'
    */
   router.put('/google-oauth', loginRequiredStrictly, adminRequired, addActivity, validator.googleOAuth, apiV3FormValidator, async(req, res) => {
-    const requestParams = {
-      'security:passport-google:clientId': req.body.googleClientId,
-      'security:passport-google:clientSecret': req.body.googleClientSecret,
-      'security:passport-google:isSameEmailTreatedAsIdenticalUser': req.body.isSameEmailTreatedAsIdenticalUser,
-    };
-
 
     try {
-      await updateAndReloadStrategySettings('google', requestParams);
+      await updateAndReloadStrategySettings('google', {
+        'security:passport-google:isSameEmailTreatedAsIdenticalUser': req.body.isSameEmailTreatedAsIdenticalUser,
+      });
+      await updateAndReloadStrategySettings('google', {
+        'security:passport-google:clientId': toNonBlankStringOrUndefined(req.body.googleClientId),
+        'security:passport-google:clientSecret': toNonBlankStringOrUndefined(req.body.googleClientSecret),
+      }, { removeIfUndefined: true });
 
       const securitySettingParams = {
         googleClientId: await configManager.getConfig('security:passport-google:clientId'),

+ 2 - 2
apps/app/src/server/service/config-manager/config-definition.ts

@@ -729,10 +729,10 @@ export const CONFIG_DEFINITIONS = {
   'security:passport-google:isEnabled': defineConfig<boolean>({
     defaultValue: false,
   }),
-  'security:passport-google:clientId': defineConfig<string | undefined>({
+  'security:passport-google:clientId': defineConfig<NonBlankString | undefined>({
     defaultValue: undefined,
   }),
-  'security:passport-google:clientSecret': defineConfig<string | undefined>({
+  'security:passport-google:clientSecret': defineConfig<NonBlankString | undefined>({
     defaultValue: undefined,
   }),
   'security:passport-google:isSameUsernameTreatedAsIdenticalUser': defineConfig<boolean>({

+ 1 - 1
apps/slackbot-proxy/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/slackbot-proxy",
-  "version": "7.2.6-slackbot-proxy.0",
+  "version": "7.2.7-slackbot-proxy.0",
   "license": "MIT",
   "private": "true",
   "scripts": {

+ 1 - 4
biome.json

@@ -26,10 +26,7 @@
       "./packages/pdf-converter-client/**",
       "./packages/pluginkit/**",
       "./packages/presentation/**",
-      "./packages/preset-templates/**",
-      "./packages/preset-themes/**",
-      "./packages/remark-attachment-refs/**",
-      "./packages/remark-drawio/**"
+      "./packages/remark-attachment-refs/**"
     ]
   },
   "formatter": {

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "growi",
-  "version": "7.2.6",
+  "version": "7.2.7-RC.0",
   "description": "Team collaboration software using markdown",
   "license": "MIT",
   "private": "true",

+ 1 - 0
packages/preset-templates/.eslintignore

@@ -0,0 +1 @@
+*

+ 0 - 5
packages/preset-templates/.eslintrc.js

@@ -1,5 +0,0 @@
-module.exports = {
-  extends: [
-    'plugin:vitest/recommended',
-  ],
-};

+ 2 - 1
packages/preset-templates/package.json

@@ -5,7 +5,8 @@
   "license": "MIT",
   "private": "true",
   "scripts": {
-    "test": "vitest run"
+    "test": "vitest run",
+    "lint": "biome check"
   },
   "dependencies": {},
   "devDependencies": {

+ 7 - 8
packages/preset-templates/test/index.test.ts

@@ -1,13 +1,14 @@
 import path from 'node:path';
 
-import { scanAllTemplates, validateTemplatePluginGrowiDirective, validateAllTemplateLocales } from '@growi/pluginkit/dist/v4/server';
-
+import {
+  scanAllTemplates,
+  validateAllTemplateLocales,
+  validateTemplatePluginGrowiDirective,
+} from '@growi/pluginkit/dist/v4/server';
 
 const projectDirRoot = path.resolve(__dirname, '../');
 
-
 it('Validation for package.json should be passed', () => {
-
   // when
   const caller = () => validateTemplatePluginGrowiDirective(projectDirRoot);
 
@@ -16,7 +17,6 @@ it('Validation for package.json should be passed', () => {
 });
 
 it('Validation for package.json should be return data', () => {
-
   // when
   const data = validateTemplatePluginGrowiDirective(projectDirRoot);
 
@@ -24,7 +24,7 @@ it('Validation for package.json should be return data', () => {
   expect(data).not.toBeNull();
 });
 
-it('Scanning the templates ends up with no errors', async() => {
+it('Scanning the templates ends up with no errors', async () => {
   // when
   const results = await scanAllTemplates(projectDirRoot);
 
@@ -32,8 +32,7 @@ it('Scanning the templates ends up with no errors', async() => {
   expect(results).not.toBeNull();
 });
 
-it('Scanning the templates ends up with no errors with opts.data', async() => {
-
+it('Scanning the templates ends up with no errors with opts.data', async () => {
   // setup
   const data = validateTemplatePluginGrowiDirective(projectDirRoot);
 

+ 1 - 3
packages/preset-templates/tsconfig.json

@@ -3,8 +3,6 @@
   "compilerOptions": {
     "esModuleInterop": true,
     "resolveJsonModule": true,
-    "types": [
-      "vitest/globals"
-    ]
+    "types": ["vitest/globals"]
   }
 }

+ 1 - 1
packages/preset-themes/.eslintignore

@@ -1 +1 @@
-/dist/**
+*

+ 0 - 2
packages/preset-themes/.eslintrc.js

@@ -1,2 +0,0 @@
-module.exports = {
-};

+ 1 - 1
packages/preset-themes/package.json

@@ -21,7 +21,7 @@
     "watch": "run-p watch:*",
     "watch:libs": "pnpm run dev:libs -w --emptyOutDir=false",
     "watch:themes": "pnpm run dev:themes -w --emptyOutDir=false",
-    "lint:eslint": "eslint \"**/*.{js,jsx,ts,tsx}\"",
+    "lint:biome": "biome check",
     "lint:styles": "stylelint \"src/**/*.scss\"",
     "lint:typecheck": "vue-tsc --noEmit",
     "lint": "run-p lint:*",

+ 21 - 11
packages/preset-themes/src/consts/preset-themes.ts

@@ -21,7 +21,7 @@ export const PresetThemes = {
   WOOD: 'wood',
   CLASSIC: 'classic',
 } as const;
-export type PresetThemes = typeof PresetThemes[keyof typeof PresetThemes];
+export type PresetThemes = (typeof PresetThemes)[keyof typeof PresetThemes];
 
 /* eslint-disable no-multi-spaces, */
 
@@ -74,7 +74,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#94351E',
     darkIcon: '#EE775B',
     createBtn: '#EA5532',
-  }, {
+  },
+  {
     name: PresetThemes.JADE_GREEN,
     schemeType: BOTH,
     lightBg: '#FFFFFF',
@@ -84,7 +85,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#3A8F6F',
     darkIcon: '#5FC2A2',
     createBtn: '#49B38A',
-  }, {
+  },
+  {
     name: PresetThemes.CLASSIC,
     schemeType: BOTH,
     lightBg: '#FFFFFF',
@@ -94,7 +96,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#53687E',
     darkIcon: '#869BB1',
     createBtn: '#3491CB',
-  }, {
+  },
+  {
     name: PresetThemes.CHRISTMAS,
     schemeType: BOTH,
     lightBg: '#FFFFFF',
@@ -116,7 +119,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#3F8421',
     darkIcon: '#1F4210',
     createBtn: '#4FA529',
-  }, {
+  },
+  {
     name: PresetThemes.WOOD,
     schemeType: LIGHT,
     lightBg: '#FFFFF5',
@@ -126,7 +130,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#86651A',
     darkIcon: '#43320D',
     createBtn: '#A77E21',
-  }, {
+  },
+  {
     name: PresetThemes.ISLAND,
     schemeType: LIGHT,
     lightBg: '#FFFFFF',
@@ -136,7 +141,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#51C2D3',
     darkIcon: '#204D54',
     createBtn: '#51C2D3',
-  }, {
+  },
+  {
     name: PresetThemes.ANTARCTIC,
     schemeType: LIGHT,
     lightBg: '#FAFEFF',
@@ -146,7 +152,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#2631AF',
     darkIcon: '#131857',
     createBtn: '#303DDB',
-  }, {
+  },
+  {
     name: PresetThemes.SPRING,
     schemeType: LIGHT,
     lightBg: '#FFFFFF',
@@ -156,7 +163,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#D76F7D',
     darkIcon: '#8A423F',
     createBtn: '#6ABA55',
-  }, {
+  },
+  {
     name: PresetThemes.KIBELA,
     schemeType: LIGHT,
     lightBg: '#FFFFFF',
@@ -178,7 +186,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#3F999B',
     darkIcon: '#99E5E6',
     createBtn: '#03A2A8',
-  }, {
+  },
+  {
     name: PresetThemes.HALLOWEEN,
     schemeType: DARK,
     lightBg: '#240E3E',
@@ -188,7 +197,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#8C3C03',
     darkIcon: '#DDB69B',
     createBtn: '#AA4A04',
-  }, {
+  },
+  {
     name: PresetThemes.BLACKBOARD,
     schemeType: DARK,
     lightBg: '#223323',

+ 2 - 5
packages/preset-themes/tsconfig.json

@@ -1,9 +1,6 @@
 {
   "$schema": "http://json.schemastore.org/tsconfig",
   "extends": "../../tsconfig.base.json",
-  "compilerOptions": {
-  },
-  "include": [
-    "src"
-  ]
+  "compilerOptions": {},
+  "include": ["src"]
 }

+ 2 - 5
packages/preset-themes/vite.libs.config.ts

@@ -3,9 +3,7 @@ import dts from 'vite-plugin-dts';
 
 // https://vitejs.dev/config/
 export default defineConfig({
-  plugins: [
-    dts({ copyDtsFiles: true }),
-  ],
+  plugins: [dts({ copyDtsFiles: true })],
   build: {
     outDir: 'dist/libs',
     sourcemap: true,
@@ -16,8 +14,7 @@ export default defineConfig({
       formats: ['es', 'umd'],
     },
     rollupOptions: {
-      external: [
-      ],
+      external: [],
     },
   },
 });

+ 1 - 3
packages/preset-themes/vite.themes.config.ts

@@ -28,9 +28,7 @@ export default defineConfig(({ mode }) => {
           '/src/styles/classic.scss',
         ],
         output: {
-          assetFileNames: isProd
-            ? undefined
-            : 'assets/[name].[ext]', // not attach hash
+          assetFileNames: isProd ? undefined : 'assets/[name].[ext]', // not attach hash
         },
       },
     },

+ 1 - 2
packages/remark-drawio/.eslintignore

@@ -1,2 +1 @@
-/dist/**
-/types/**
+*

+ 0 - 5
packages/remark-drawio/.eslintrc.cjs

@@ -1,5 +0,0 @@
-module.exports = {
-  extends: [
-    'weseek/react',
-  ],
-};

+ 1 - 1
packages/remark-drawio/package.json

@@ -25,7 +25,7 @@
     "clean": "shx rm -rf dist",
     "dev": "vite build --mode dev",
     "watch": "pnpm run dev -w --emptyOutDir=false",
-    "lint:js": "eslint **/*.{js,jsx,ts,tsx}",
+    "lint:js": "biome check",
     "lint:styles": "stylelint --allow-empty-input \"src/**/*.scss\" \"src/**/*.css\"",
     "lint:typecheck": "vue-tsc --noEmit",
     "lint": "run-p lint:*"

+ 49 - 39
packages/remark-drawio/src/components/DrawioViewer.tsx

@@ -1,6 +1,12 @@
 import {
-  type ReactNode, type JSX,
-  memo, useCallback, useEffect, useMemo, useRef, useState,
+  type JSX,
+  type ReactNode,
+  memo,
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
 } from 'react';
 
 import { debounce } from 'throttle-debounce';
@@ -9,35 +15,36 @@ import type { IGraphViewerGlobal } from '..';
 import { generateMxgraphData } from '../utils/embed';
 import { isGraphViewerGlobal } from '../utils/global';
 
-
 import styles from './DrawioViewer.module.scss';
 
-
 declare global {
   // eslint-disable-next-line vars-on-top, no-var
   var GraphViewer: IGraphViewerGlobal;
 }
 
-
 export type DrawioViewerProps = {
-  diagramIndex: number,
-  bol: number,
-  eol: number,
-  children?: ReactNode,
-  onRenderingStart?: () => void,
-  onRenderingUpdated?: (mxfile: string | null) => void,
-}
+  diagramIndex: number;
+  bol: number;
+  eol: number;
+  children?: ReactNode;
+  onRenderingStart?: () => void;
+  onRenderingUpdated?: (mxfile: string | null) => void;
+};
 
 export type DrawioEditByViewerProps = {
-  bol: number,
-  eol: number,
-  drawioMxFile: string,
-}
+  bol: number;
+  eol: number;
+  drawioMxFile: string;
+};
 
 export const DrawioViewer = memo((props: DrawioViewerProps): JSX.Element => {
   const {
-    diagramIndex, bol, eol, children,
-    onRenderingStart, onRenderingUpdated,
+    diagramIndex,
+    bol,
+    eol,
+    children,
+    onRenderingStart,
+    onRenderingUpdated,
   } = props;
 
   const drawioContainerRef = useRef<HTMLDivElement>(null);
@@ -56,7 +63,9 @@ export const DrawioViewer = memo((props: DrawioViewerProps): JSX.Element => {
       return;
     }
 
-    const mxgraphs = drawioContainerRef.current.getElementsByClassName('mxgraph') as HTMLCollectionOf<HTMLElement>;
+    const mxgraphs = drawioContainerRef.current.getElementsByClassName(
+      'mxgraph',
+    ) as HTMLCollectionOf<HTMLElement>;
     if (mxgraphs.length > 0) {
       // This component should have only one '.mxgraph' element
       const div = mxgraphs[0];
@@ -73,15 +82,17 @@ export const DrawioViewer = memo((props: DrawioViewerProps): JSX.Element => {
           GraphViewer.prototype.lightboxZIndex = 1055; // set $zindex-modal
           GraphViewer.prototype.toolbarZIndex = 1055; // set $zindex-modal
           GraphViewer.createViewerForElement(div);
-        }
-        catch (err) {
+        } catch (err) {
           setError(err);
         }
       }
     }
   }, []);
 
-  const renderDrawioWithDebounce = useMemo(() => debounce(200, renderDrawio), [renderDrawio]);
+  const renderDrawioWithDebounce = useMemo(
+    () => debounce(200, renderDrawio),
+    [renderDrawio],
+  );
 
   const mxgraphHtml = useMemo(() => {
     setError(undefined);
@@ -90,17 +101,16 @@ export const DrawioViewer = memo((props: DrawioViewerProps): JSX.Element => {
       return '';
     }
 
-    const code = children instanceof Array
+    const code = Array.isArray(children)
       ? children
-        .filter(elem => (typeof elem === 'string')) // omit non-string elements (e.g. br element generated by line-breaks option)
-        .join('')
+          .filter((elem) => typeof elem === 'string') // omit non-string elements (e.g. br element generated by line-breaks option)
+          .join('')
       : children.toString();
 
-    let mxgraphData;
+    let mxgraphData: string | undefined;
     try {
       mxgraphData = generateMxgraphData(code);
-    }
-    catch (err) {
+    } catch (err) {
       setError(err);
     }
 
@@ -125,8 +135,8 @@ export const DrawioViewer = memo((props: DrawioViewerProps): JSX.Element => {
     const container = drawioContainerRef.current;
     if (container == null) return;
 
-    const observerCallback = (mutationRecords:MutationRecord[]) => {
-      mutationRecords.forEach((record:MutationRecord) => {
+    const observerCallback = (mutationRecords: MutationRecord[]) => {
+      for (const record of mutationRecords) {
         const target = record.target as HTMLElement;
 
         const mxgraphData = target.dataset.mxgraph;
@@ -134,7 +144,7 @@ export const DrawioViewer = memo((props: DrawioViewerProps): JSX.Element => {
           const mxgraph = JSON.parse(mxgraphData);
           onRenderingUpdated?.(mxgraph.xml);
         }
-      });
+      }
     };
 
     const observer = new MutationObserver(observerCallback);
@@ -152,11 +162,11 @@ export const DrawioViewer = memo((props: DrawioViewerProps): JSX.Element => {
     }
 
     const observer = new ResizeObserver((entries) => {
-      entries.forEach(() => {
-        // setElementWidth(el.contentRect.width);
+      for (const entry of entries) {
+        // setElementWidth(entry.contentRect.width);
         onRenderingStart?.();
         renderDrawioWithDebounce();
-      });
+      }
     });
     observer.observe(drawioContainerRef.current);
     return () => {
@@ -174,18 +184,18 @@ export const DrawioViewer = memo((props: DrawioViewerProps): JSX.Element => {
       data-end-line-number-of-markdown={eol}
     >
       {/* show error */}
-      { error != null && (
+      {error != null && (
         <span className="text-muted">
           <span className="material-symbols-outlined me-1">error</span>
           {error.name && <strong>{error.name}: </strong>}
           {error.message}
         </span>
-      ) }
+      )}
 
-      { error == null && (
-        // eslint-disable-next-line react/no-danger
+      {error == null && (
+        // biome-ignore lint/security/noDangerouslySetInnerHtml: ignore
         <div dangerouslySetInnerHTML={{ __html: mxgraphHtml }} />
-      ) }
+      )}
     </div>
   );
 });

+ 12 - 9
packages/remark-drawio/src/interfaces/graph-viewer.ts

@@ -1,15 +1,18 @@
 export interface IGraphViewer {
-  checkVisibleState: boolean,
-  responsive: boolean,
-  lightboxZIndex: number,
-  toolbarZIndex: number,
-  xml: string,
+  checkVisibleState: boolean;
+  responsive: boolean;
+  lightboxZIndex: number;
+  toolbarZIndex: number;
+  xml: string;
 }
 
 export interface IGraphViewerGlobal {
-  processElements: () => void,
-  createViewerForElement: (element: Element, callback?: (viewer: IGraphViewer) => void) => void,
+  processElements: () => void;
+  createViewerForElement: (
+    element: Element,
+    callback?: (viewer: IGraphViewer) => void,
+  ) => void;
 
-  useResizeSensor: boolean,
-  prototype: IGraphViewer,
+  useResizeSensor: boolean;
+  prototype: IGraphViewer;
 }

+ 17 - 17
packages/remark-drawio/src/services/renderer/remark-drawio.ts

@@ -1,16 +1,14 @@
 import type { Properties } from 'hast';
 import type { Schema as SanitizeOption } from 'hast-util-sanitize';
-import type {
-  Code, Node, Paragraph,
-} from 'mdast';
+import type { Code, Node, Paragraph } from 'mdast';
 import type { Plugin } from 'unified';
 import { visit } from 'unist-util-visit';
 
 const SUPPORTED_ATTRIBUTES = ['diagramIndex', 'bol', 'eol'];
 
 interface Data {
-  hName?: string,
-  hProperties?: Properties,
+  hName?: string;
+  hProperties?: Properties;
 }
 
 type Lang = 'drawio';
@@ -20,11 +18,15 @@ function isDrawioBlock(lang?: string | null): lang is Lang {
 }
 
 function rewriteNode(node: Node, index: number) {
-
   node.type = 'paragraph';
-  (node as Paragraph).children = [{ type: 'text', value: (node as Code).value }];
-
-  const data: Data = node.data ?? (node.data = {});
+  (node as Paragraph).children = [
+    { type: 'text', value: (node as Code).value },
+  ];
+
+  if (node.data == null) {
+    node.data = {};
+  }
+  const data: Data = node.data;
   data.hName = 'drawio';
   data.hProperties = {
     diagramIndex: index,
@@ -34,14 +36,12 @@ function rewriteNode(node: Node, index: number) {
   };
 }
 
-export const remarkPlugin: Plugin = function() {
-  return (tree) => {
-    visit(tree, 'code', (node: Code, index) => {
-      if (isDrawioBlock(node.lang)) {
-        rewriteNode(node, index ?? 0);
-      }
-    });
-  };
+export const remarkPlugin: Plugin = () => (tree) => {
+  visit(tree, 'code', (node: Code, index) => {
+    if (isDrawioBlock(node.lang)) {
+      rewriteNode(node, index ?? 0);
+    }
+  });
 };
 
 export const sanitizeOption: SanitizeOption = {

+ 18 - 16
packages/remark-drawio/src/utils/embed.ts

@@ -1,7 +1,7 @@
 // transplanted from https://github.com/jgraph/drawio-tools/blob/d46977060ffad70cae5a9059a2cbfcd8bcf420de/tools/convert.html
 import pako from 'pako';
 
-const unconpressedDataRegexp = new RegExp('<mxGraphModel');
+const unconpressedDataRegexp = /<mxGraphModel/;
 const validateUncompressedData = (input: string): boolean => {
   return unconpressedDataRegexp.test(input);
 };
@@ -11,24 +11,24 @@ const validateCompressedData = (input: string): boolean => {
 
   try {
     data = Buffer.from(data, 'base64').toString('binary');
-  }
-  catch (e) {
+  } catch (e) {
     throw new Error(`Base64 to binary failed: ${e}`);
   }
 
   if (data.length > 0) {
     try {
-      data = pako.inflateRaw(Uint8Array.from(data, c => c.charCodeAt(0)), { to: 'string' });
-    }
-    catch (e) {
+      data = pako.inflateRaw(
+        Uint8Array.from(data, (c) => c.charCodeAt(0)),
+        { to: 'string' },
+      );
+    } catch (e) {
       throw new Error(`inflateRaw failed: ${e}`);
     }
   }
 
   try {
     data = decodeURIComponent(data);
-  }
-  catch (e) {
+  } catch (e) {
     throw new Error(`decodeURIComponent failed: ${e}`);
   }
 
@@ -40,14 +40,16 @@ const escapeHTML = (string): string => {
     return string;
   }
   return string.replace(/[&'`"<>]/g, (match): string => {
-    return {
-      '&': '&amp;',
-      "'": '&#x27;',
-      '`': '&#x60;',
-      '"': '&quot;',
-      '<': '&lt;',
-      '>': '&gt;',
-    }[match] ?? match;
+    return (
+      {
+        '&': '&amp;',
+        "'": '&#x27;',
+        '`': '&#x60;',
+        '"': '&quot;',
+        '<': '&lt;',
+        '>': '&gt;',
+      }[match] ?? match
+    );
   });
 };
 

+ 8 - 2
packages/remark-drawio/src/utils/global.ts

@@ -1,5 +1,11 @@
 import type { IGraphViewerGlobal } from '../interfaces/graph-viewer';
 
-export const isGraphViewerGlobal = (val: unknown): val is IGraphViewerGlobal => {
-  return (typeof val === 'function' && 'createViewerForElement' in val && 'processElements' in val);
+export const isGraphViewerGlobal = (
+  val: unknown,
+): val is IGraphViewerGlobal => {
+  return (
+    typeof val === 'function' &&
+    'createViewerForElement' in val &&
+    'processElements' in val
+  );
 };

+ 1 - 3
packages/remark-drawio/tsconfig.json

@@ -11,7 +11,5 @@
     "noImplicitAny": false,
     "noImplicitOverride": true
   },
-  "include": [
-    "src"
-  ]
+  "include": ["src"]
 }